diff --git a/.gitignore b/.gitignore index e79a7c0d..8f3c450e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,8 @@ node_modules/* npm-debug.log* /uploads/* env -package-lock.json \ No newline at end of file +package-lock.json +.flooignore +.floo +.o11n +.sass-cache diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables-checkout.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables-checkout.scssc new file mode 100644 index 00000000..62604b77 Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables-checkout.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables.scssc new file mode 100644 index 00000000..21ab2177 Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-embeddables.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms-offering.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms-offering.scssc new file mode 100644 index 00000000..e4626ceb Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms-offering.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms.scssc new file mode 100644 index 00000000..6e67c8da Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-forms.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-tier.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-tier.scssc new file mode 100644 index 00000000..c6e064ea Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_component-tier.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-content.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-content.scssc new file mode 100644 index 00000000..122dab48 Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-content.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-nav.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-nav.scssc new file mode 100644 index 00000000..17b7cf24 Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_layout-nav.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_mixins.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_mixins.scssc new file mode 100644 index 00000000..1114e6bd Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/_mixins.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/buttons.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/buttons.scssc new file mode 100644 index 00000000..a004edab Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/buttons.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/colors.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/colors.scssc new file mode 100644 index 00000000..a376af9a Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/colors.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/css-icons.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/css-icons.scssc new file mode 100644 index 00000000..1f45714e Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/css-icons.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/main.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/main.scssc new file mode 100644 index 00000000..cdeed3cd Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/main.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/text.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/text.scssc new file mode 100644 index 00000000..3ebde215 Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/text.scssc differ diff --git a/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/variables.scssc b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/variables.scssc new file mode 100644 index 00000000..a0068beb Binary files /dev/null and b/.sass-cache/20a3f4dcae81fbfe4ef832376f5dae3a4605db04/variables.scssc differ diff --git a/.sass-cache/c7930d7a225374ea83d22b96ae5410960b97c190/style.scssc b/.sass-cache/c7930d7a225374ea83d22b96ae5410960b97c190/style.scssc new file mode 100644 index 00000000..e353256e Binary files /dev/null and b/.sass-cache/c7930d7a225374ea83d22b96ae5410960b97c190/style.scssc differ diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 00000000..638f92c5 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,28 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + sass: { + dist:{ + options: { + style: 'expanded' + }, + files: { + 'public/css/main.css' : 'public/scss/main.scss', + 'plugins/core-embeddables/css/style.css' : 'plugins/core-embeddables/scss/style.scss' + } + } + }, + watch: { + css: { + files: ['public/scss/*.scss', 'plugins/**/scss/*.scss'], + tasks: ['sass'] + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-sass'); + + grunt.registerTask('default', ['watch']); + +}; \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..2c8e2275 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,57 @@ +def getRepo(){ + String name = "${env.JOB_NAME}"; + String[] value = name.split('/'); + return value[0]; +} + +def gitCredentials = "JenkinsGithub" + + +pipeline { + parameters { + booleanParam(defaultValue: true, description: 'Execute pipeline?', name: 'shouldBuild') + } + + agent any + stages { + stage("Check if should build"){ + steps{ + script { + result = sh (script: "git log -1 | grep '.*Jenkins version bump.*'", returnStatus: true) + if (result == 0) { + echo ("'Version bump' spotted in git commit. Aborting.") + env.shouldBuild = "false" + throw "Bad" + } + } + } + } + + stage('Build, bump version') { + when { + branch 'tiers' + expression { + return env.shouldBuild != "false" + } + + } + steps { + + withCredentials([string(credentialsId: 'npm-token', variable: 'NPM_TOKEN')]) { + sshagent(credentials: ["${gitCredentials}"]){ + + sh ''' + npm version patch -m "Jenkins version bump" + git push origin tiers + git push origin --tags + ''' + + + } + + } + + } + } + } +} diff --git a/api-docs/api-definitions.json b/api-docs/api-definitions.json index d5f4d465..2fea5a02 100644 --- a/api-docs/api-definitions.json +++ b/api-docs/api-definitions.json @@ -55,6 +55,16 @@ } } }, + "metric_change": { + "type": "object", + "properties": { + "value": { + "type": "integer", + "format": "int32", + "description": "New number of metric" + } + } + }, "service_instance_request": { "type": "object", "properties": { @@ -71,6 +81,40 @@ "type": "integer", "description": "Servicebot User ID, used for requesting a service instance for an existing User" }, + "payment_structure_template_id": { + "type": "integer", + "description": "Payment Structure Template ID, used to select a specific payment structure to be attached to the created Service Instance" + }, + "references": { + "type": "object", + "properties": { + "service_instance_properties": { + "type": "array", + "items": { + "$ref": "#/definitions/service_template_properties" + } + } + } + } + } + }, + "service_instance_request_response": { + "type": "object", + "properties": { + "token": { + "type": "string", + "format": "string", + "description": "Servicebot auth token for the user requested." + }, + "request": { + "type": "object", + "description": "Service Instance request details that were made", + "$ref": "#/definitions/service_instance_request" + }, + "webhook_responses": { + "type": "string", + "description": "Response from webhook if one is configured. Will only be there is webhook was configure to be synchronous." + }, "references": { "type": "object", "properties": { @@ -83,5 +127,33 @@ } } } + }, + "seat": { + "type": "object", + "properties": { + "user_id": { + "type": "integer", + "description": "User Id" + }, + "service_instance_id": { + "type": "integer", + "description": "Service Instance Id" + }, + "id": { + "type": "integer", + "description": "Seat Id" + }, + "references": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/users" + } + } + } + } + } } } \ No newline at end of file diff --git a/api-docs/api-paths.json b/api-docs/api-paths.json index e0dc254f..b5ce65f2 100644 --- a/api-docs/api-paths.json +++ b/api-docs/api-paths.json @@ -1,7 +1,8 @@ { "/users/{id}/avatar": { "get": { - "summary": "Gets User Avatar", + "summary": "Get User Avatar", + "description": "Gets a User Avatar image file", "tags": [ "users" ], @@ -33,17 +34,12 @@ "200": { "description": "User Avatar", "type": "file" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Adds a User Avatar", + "summary": "Add User Avatar", + "description": "Adds a User Avatar image file", "tags": [ "users" ], @@ -84,19 +80,14 @@ "schema": { "$ref": "#/definitions/files" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/users/register": { "post": { - "summary": "Registers a new User", + "summary": "Register a new User", + "description": "Registers a newly created User. User must be invited to be registered. More common process for adding user is for user to be generated with a Service Request.", "tags": [ "users" ], @@ -134,19 +125,14 @@ "$ref": "#/definitions/users" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/users/{id}/suspend": { "post": { - "summary": "Suspend the User", + "summary": "Suspend a User", + "description": "Suspends a User which will cancel all users services in Stripe and in Servicebot and mark the user as suspended. Users automatically become suspended if there are payment failures (like expired cards). You can also manually suspend users which will trigger a webhook which can notify your application for application access restriction.", "tags": [ "users" ], @@ -178,19 +164,14 @@ "schema": { "$ref": "#/definitions/users" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/users/{id}/unsuspend": { "post": { - "summary": "UnSuspend the User", + "summary": "Unsuspend a User", + "description": "Unsuspends a User changing their status from 'suspended' to 'active'. It does not resubscribe User to all previous subscriptions.", "tags": [ "users" ], @@ -222,19 +203,14 @@ "schema": { "$ref": "#/definitions/users" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/users/invite": { "post": { - "summary": "Invites a new User", + "summary": "Invite a new User", + "description": "Invites a new User responding with an invitation URL for the user to go to to complete registration. More common process for adding user is for user to be generated with a Service Request.", "tags": [ "users" ], @@ -264,12 +240,6 @@ "200": { "description": "Invitation URL", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } @@ -277,6 +247,7 @@ "/users/{id}/token": { "post": { "summary": "Get a token for a user", + "description": "As an authenticated admin, gets an auth token for a user.", "tags": [ "users" ], @@ -311,7 +282,8 @@ }, "/roles/manage-permissions": { "get": { - "summary": "Gets all roles with permissions", + "summary": "Gets all roles with array of permission ids", + "description": "Gets all the roles in the system with all the permissions in that role.", "tags": [ "roles" ], @@ -336,17 +308,12 @@ "$ref": "#/definitions/roles_permissions" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "post": { "summary": "Update role with permission", + "description": "Batch update roles with permission Ids.", "tags": [ "roles" ], @@ -382,19 +349,14 @@ "$ref": "#/definitions/roles_permissions" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-templates/public": { "get": { - "summary": "Gets all public service-templates", + "summary": "Get all public Service Templates", + "description": "Gets all published Service Templates. Templates default to published when created. Does not need Auth.", "tags": [ "service-templates" ], @@ -421,19 +383,14 @@ "$ref": "#/definitions/service_templates" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-templates/{id}/icon": { "get": { - "summary": "Gets Service Template Icon", + "summary": "Get Service Template Icon", + "description": "Gets Service Template Icon file", "tags": [ "service-templates" ], @@ -465,17 +422,12 @@ "200": { "description": "service-template File", "type": "file" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Adds a Service Template Icon", + "summary": "Add a Service Template Icon", + "description": "Adds a Service Template Icon file", "tags": [ "service-templates" ], @@ -515,17 +467,12 @@ "schema": { "$ref": "#/definitions/files" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "delete": { - "summary": "Deletes Service Template Icon", + "summary": "Delete Service Template Icon", + "description": "Deletes a Service Template Icon file", "tags": [ "service-templates" ], @@ -556,19 +503,14 @@ "200": { "description": "message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-templates/{id}/image": { "get": { - "summary": "Gets Service Template Image", + "summary": "Get Service Template Image", + "description": "Gets a Service Template Image file", "tags": [ "service-templates" ], @@ -600,17 +542,12 @@ "200": { "description": "service-template File", "type": "file" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Adds a Service Template Image", + "summary": "Add a Service Template Image", + "description": "Adds a Service Template Image file", "tags": [ "service-templates" ], @@ -650,17 +587,12 @@ "schema": { "$ref": "#/definitions/files" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "delete": { - "summary": "Deletes Service Template Image", + "summary": "Delete Service Template Image", + "description": "Deletes a Service Template Image file", "tags": [ "service-templates" ], @@ -691,19 +623,14 @@ "200": { "description": "message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-templates/{id}/request": { "get": { - "summary": "Gets a service-template Request", + "summary": "Get Service Request Template", + "description": "Gets a request template for requesting a Service Instance of the Service Template", "tags": [ "service-templates" ], @@ -735,18 +662,12 @@ "200": { "description": "A service-template request", "type": "object" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "post": { - "summary": "Requests a service-instance", - "description": "Can make this call unauthorized, but must also send 'email' and 'token_id' in the request JSON", + "summary": "Request a Service Instance", + "description": "Requests a Service Instance. Can make this call unauthorized, but must also send 'email', 'password' and 'token_id' in the request JSON. 'token_id' is a Stripe Token: https://stripe.com/docs/api#token_object Can use 'tok_visa' for testing. If using synchronous webhooks, you will find the response of the webhook in webhook_responses.", "tags": [ "service-templates" ], @@ -787,13 +708,7 @@ "200": { "description": "The newly provisioned service instance", "schema": { - "$ref": "#/definitions/service_instances" - } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" + "$ref": "#/definitions/service_instance_request_response" } } } @@ -801,7 +716,8 @@ }, "/service-instances/{id}/approve": { "post": { - "summary": "Approves a service-instance", + "summary": "Approve a Service Instance", + "description": "If an instance was requested by an admin, for a user, they must approve of the Service request. Approving the Service Instance will proceed with charges if there are any and begin the subscription.", "tags": [ "service-instances" ], @@ -835,19 +751,14 @@ "schema": { "$ref": "#/definitions/service_instances" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/reactivate": { "post": { - "summary": "Reactivates a cancelled service-instance", + "summary": "Reactivate a cancelled Service Instance", + "description": "Reactivates a cancelled Service Instance, triggering a webhook. Once subscription is reactivated, charges will resume.", "tags": [ "service-instances" ], @@ -881,19 +792,14 @@ "schema": { "$ref": "#/definitions/service_instances" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/change-price": { "post": { - "summary": "Change a service-instance payment plan", + "summary": "Change a Service Instance payment plan", + "description": "Updates the payment plan of a Service Instance. Use to modify price, period, interval, or trial.", "tags": [ "service-instances" ], @@ -914,7 +820,7 @@ { "name": "id", "in": "path", - "description": "service-instance id", + "description": "Service Instance id", "required": true, "type": "number", "format": "double" @@ -937,7 +843,7 @@ }, "currency": { "type": "string", - "description": "curency type" + "description": "Currency type" }, "interval": { "type": "string", @@ -965,19 +871,14 @@ "schema": { "$ref": "#/definitions/service_instances" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/change-properties": { "post": { - "summary": "Changes a service instance properties, can affect instance pricing if subscription.", + "summary": "Change a Service Instance properties", + "description": "Changes a Service Instance properties, can affect instance pricing if subscription and the properties modify price.", "tags": [ "service-instances" ], @@ -1003,19 +904,14 @@ "schema": { "$ref": "#/definitions/service_instances" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/cancel": { "post": { - "summary": "Cancel a service-instance", + "summary": "Cancel a Service Instance", + "description": "Cancels a Service Instance. Can only be performed by Admin or Staff.", "tags": [ "service-instances" ], @@ -1048,19 +944,14 @@ "schema": { "$ref": "#/definitions/service_instances" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/request-cancellation": { "post": { - "summary": "Request Cancellation of a service-instance", + "summary": "Request Cancellation of a Service Instance", + "description": "Requests Cancellation a Service Instance. Can be performed by Admin and Users.", "tags": [ "service-instances" ], @@ -1094,19 +985,14 @@ "schema": { "$ref": "#/definitions/service_instance_cancellations" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/add-charge": { "post": { - "summary": "Add a charge to a service-instance", + "summary": "Add a charge to a Service Instance", + "description": "Adds a charge to a Service Instance.", "tags": [ "service-instances" ], @@ -1131,6 +1017,15 @@ "required": true, "type": "number", "format": "double" + }, + { + "name": "charge", + "in": "body", + "description": "Charge to add to Service Instance", + "required": true, + "schema": { + "$ref": "#/definitions/charge_items" + } } ], "responses": { @@ -1139,19 +1034,14 @@ "schema": { "$ref": "#/definitions/charge_items" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/awaiting-charges": { "get": { - "summary": "Get service-instance awaiting charges", + "summary": "Get awaiting charges of Service Instance", + "description": "Gets not yet paid charges of Service Instance.", "tags": [ "service-instances" ], @@ -1188,19 +1078,14 @@ "$ref": "#/definitions/charge_items" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/approve-charges": { "post": { - "summary": "Approve a service-instance charges", + "summary": "Approve Charges on a Service Instance", + "description": "Approves pending charges on a Service Instance.", "tags": [ "service-instances" ], @@ -1237,11 +1122,268 @@ "$ref": "#/definitions/charge_items" } } + } + } + } + }, + "/service-instance/{id}/metric": { + "get": { + "summary": "Get metric", + "description": "Gets the value of an Instance's metric. Use this call along with the POST call to increment or set a metric from your app.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "get_service_id_metric", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "Metric", + "schema": { + "$ref": "#/definitions/metric_change" + } + } + } + }, + "post": { + "summary": "Change metric", + "description": "Modifies an Instance's metric. Automatically adjusts and prorates billing.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "post_service_id_metric", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "Metric", + "schema": { + "$ref": "#/definitions/metric_change" + } + } + } + } + }, + "/service-instances/{id}/seats": { + "get": { + "summary": "Get Seats on a service instance", + "description": "Gets the seats associated with a service instance.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "get_service_instances_id_seats", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "Seat", + "schema": { + "$ref": "#/definitions/seat" + } + } + } + }, + "post": { + "summary": "Add a seat to an instance", + "description": "Adds seat to an Instance using email. If user does not exist, invitation email is set (can be turned off with notification templates), and webhook is triggered.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "post_service_instances_id_seats", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "email", + "in": "body", + "description": "Email of user to add", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Seat", + "schema": { + "$ref": "#/definitions/seat" + } + } + } + } + }, + "/service-instances/{id}/seats/{seatId}": { + "delete": { + "summary": "Remove a seat from an instance", + "description": "Removes the seats associated with a service instance by Id.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "get_service_instances_id_seats", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" }, - "default": { - "description": "Unexpected error", + { + "name": "seatId", + "in": "path", + "description": "seat id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "Message", + "type": "string" + } + } + } + }, + "/service-instances/{id}/seats/{seatId}/reinvite": { + "post": { + "summary": "Resend invitation for seat", + "description": "Resends seat invitation using Seat Id. Invitation email is set (can be turned off with notification templates), and webhook is triggered.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "post_service_instances_id_seats_seatid_reinvite", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service-instance id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "seatId", + "in": "path", + "description": "seat id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "Seat", "schema": { - "$ref": "#/definitions/Error" + "$ref": "#/definitions/seat" } } } @@ -1249,7 +1391,8 @@ }, "/service-instances/{id}/files": { "post": { - "summary": "Add a service-instance Files", + "summary": "Add a Service Instance File", + "description": "Adds a Service Instance File", "tags": [ "service-instances" ], @@ -1296,17 +1439,12 @@ "$ref": "#/definitions/files" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "get": { - "summary": "Get service-instance files", + "summary": "Get Service Instance files", + "description": "Gets Service Instance files", "tags": [ "service-instances" ], @@ -1343,19 +1481,14 @@ "type": "file" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instances/{id}/files/{fid}": { "delete": { - "summary": "Add a service-instance Files", + "summary": "Delete a Service Instance File", + "description": "Deletes a Service Instance File", "tags": [ "service-instances" ], @@ -1395,17 +1528,12 @@ "200": { "description": "Message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "get": { - "summary": "Get service-instance files", + "summary": "Get Service Instance file by id", + "description": "Gets a Service Instance file by id", "tags": [ "service-instances" ], @@ -1445,19 +1573,14 @@ "200": { "description": "Service Instance File", "type": "file" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instance-cancellations/{id}/approve": { "post": { - "summary": "Approves a service-instance-cancellations", + "summary": "Approve a Service Instance Cancellation request", + "description": "Approves a Service Instance Cancellation request", "tags": [ "service-instance-cancellations" ], @@ -1490,19 +1613,14 @@ "schema": { "$ref": "#/definitions/service_instance_cancellations" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instance-cancellations/{id}/reject": { "post": { - "summary": "Rejects a service-instance-cancellations", + "summary": "Reject a Service Instance Cancellation request", + "description": "Rejects a Service Instance Cancellation request. For Admins.", "tags": [ "service-instance-cancellations" ], @@ -1535,19 +1653,14 @@ "schema": { "$ref": "#/definitions/service_instance_cancellations" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/service-instance-cancellations/{id}/undo": { "post": { - "summary": "Rejects a service-instance-cancellations for the user who created it", + "summary": "Undo a Service Instance Cancellation request", + "description": "Undoes a Service Instance Cancellation request for the user who requested it.", "tags": [ "service-instance-cancellations" ], @@ -1581,11 +1694,36 @@ "schema": { "$ref": "#/definitions/service_instance_cancellations" } - }, - "default": { - "description": "Unexpected error", + } + } + } + }, + "/service-instance-seats/own": { + "get": { + "summary": "Get own Seats", + "description": "Gets the seat data of the authenticated user.", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "x-roles": [ + "admin", + "staff", + "user" + ], + "operationId": "get_service_instance_seats_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "Seat", "schema": { - "$ref": "#/definitions/Error" + "$ref": "#/definitions/seat" } } } @@ -1623,12 +1761,6 @@ "200": { "description": "Template to Roles", "type": "object" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, @@ -1670,19 +1802,14 @@ "200": { "description": "Template to Roles", "type": "object" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/invoices/upcoming/{id}": { "get": { - "summary": "Gets upcoming Invoices", + "summary": "Get upcoming Invoices", + "description": "Gets the upcoming invoices for a User by id", "tags": [ "invoices" ], @@ -1716,19 +1843,14 @@ "schema": { "$ref": "#/definitions/invoices" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/invoices/{id}/refund": { "post": { - "summary": "Performs refund on Invoice", + "summary": "Refund Invoice", + "description": "Refunds an invoice by Id. Can perform partial refund by passing 'amount' field in body.", "tags": [ "invoices" ], @@ -1776,19 +1898,14 @@ "schema": { "$ref": "#/definitions/transactions" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/system-options": { "get": { - "summary": "Gets all System Options", + "summary": "Get all System Options", + "description": "Gets all System Options", "tags": [ "system-options" ], @@ -1813,17 +1930,12 @@ "$ref": "#/definitions/system_options" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Batch Updates System Options", + "summary": "Batch Update System Options", + "description": "Batch Updates System Options", "tags": [ "system-options" ], @@ -1862,19 +1974,14 @@ "$ref": "#/definitions/system_options" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/system-options/public": { "get": { - "summary": "Gets all public System Options", + "summary": "Get all public System Options", + "description": "Gets all public System Options", "tags": [ "system-options" ], @@ -1901,19 +2008,14 @@ "$ref": "#/definitions/system_options" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/system-options/{id}": { "get": { - "summary": "Gets a System Option", + "summary": "Get a System Option by Id", + "description": "Gets a System Option by Id", "tags": [ "system-options" ], @@ -1945,17 +2047,12 @@ "schema": { "$ref": "#/definitions/system_options" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Updates a System Option", + "summary": "Update a System Option", + "description": "Updates a System Option", "tags": [ "system-options" ], @@ -1999,19 +2096,14 @@ "$ref": "#/definitions/system_options" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/system-options/file/{id}": { "get": { - "summary": "Gets a System File Options. Ids are 'front_page_image', 'brand_logo'", + "summary": "Get a System File Option", + "description": "Gets a System File Option. Ids are 'front_page_image', 'brand_logo'.", "tags": [ "system-options" ], @@ -2043,17 +2135,12 @@ "200": { "description": "A System Options", "type": "file" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "put": { - "summary": "Updates a System Option. Ids are 'front_page_image', 'brand_logo'", + "summary": "Update a System Option", + "description": "Updates a System File Option. Ids are 'front_page_image', 'brand_logo'.", "tags": [ "system-options" ], @@ -2095,19 +2182,14 @@ "$ref": "#/definitions/files" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/system-options/version": { "get": { - "summary": "Gets System version", + "summary": "Get System version", + "description": "Gets System version", "tags": [ "system-options" ], @@ -2129,19 +2211,14 @@ "200": { "description": "System Version", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/charge/{id}/approve": { "post": { - "summary": "Approves a Charge Item", + "summary": "Approve a Charge Item", + "description": "Approves a Charge Item added onto a Service Instance. Use POST /service-instances/{id}/add-charge to add charges and GET /service-instances/{id}/awaiting-charges to get charges for an Instance.", "tags": [ "charge" ], @@ -2174,19 +2251,14 @@ "schema": { "$ref": "#/definitions/charge_items" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/charge/{id}/cancel": { "post": { - "summary": "Cancels a Charge Item", + "summary": "Cancel a Charge Item", + "description": "Cancels a Charge Item added onto a Service Instance. Use POST /service-instances/{id}/add-charge to add charges and GET /service-instances/{id}/awaiting-charges to get charges for an Instance.", "tags": [ "charge" ], @@ -2219,19 +2291,14 @@ "schema": { "$ref": "#/definitions/charge_items" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/auth/token": { "post": { - "summary": "Gets a Authorization Token", + "summary": "Get Authorization Token", + "description": "Gets an Authorization Token. Use to authenticate all other calls with the header 'Authorization' and value 'JWT generated_token'", "tags": [ "auth" ], @@ -2264,19 +2331,14 @@ "200": { "description": "Authorization Token", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/auth/session/clear": { "post": { - "summary": "Clears session", + "summary": "Clear session", + "description": "Clears authorized session for token used in call made.", "tags": [ "auth" ], @@ -2298,12 +2360,6 @@ "200": { "description": "Message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } @@ -2311,6 +2367,7 @@ "/auth/reset-password": { "post": { "summary": "Send Reset password email", + "description": "Sends Reset password email to user passed in body. No authorization needed.", "tags": [ "auth" ], @@ -2341,19 +2398,14 @@ "200": { "description": "Message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/auth/reset-password/{uid}/{token}": { "get": { - "summary": "Get User password reset token", + "summary": "Check valid password reset token", + "description": "Checks is the password reset token passed as parameter is valid, and returns true or false.", "tags": [ "auth" ], @@ -2390,19 +2442,14 @@ ], "responses": { "200": { - "description": "response message", + "description": "is valid token", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, "post": { "summary": "Reset user password", + "description": "Resets a user's password using the user's id, password reset token, and new password.", "tags": [ "auth" ], @@ -2448,20 +2495,14 @@ "200": { "description": "response message", "type": "string" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/analytics/data": { "get": { - "summary": "Gets Analytics Data", - "description": "Gets Analytics Data from instance", + "summary": "Get Analytics Data", + "description": "Gets all Analytics Data from Servicebot instance", "tags": [ "analytics" ], @@ -2482,19 +2523,14 @@ "200": { "description": "Analytics Data", "type": "object" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } }, "/analytics/properties/{id}": { "get": { - "summary": "Gets all instance properties based on template id", + "summary": "Get all instance properties from a template", + "description": "Get all instance properties from a template id. Gather analytics from a single Service template to see commonalities for the fields you are asking from your users in signup.", "tags": [ "analytics" ], @@ -2525,12 +2561,6 @@ "200": { "description": "Instance properties", "type": "object" - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } @@ -2562,12 +2592,6 @@ "$ref": "#/definitions/permissions" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } @@ -2608,12 +2632,6 @@ "$ref": "#/definitions/stripe_preconfigure" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, @@ -2652,12 +2670,6 @@ "type": "string", "name": "message" } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } }, @@ -2686,12 +2698,6 @@ "$ref": "#/definitions/stripe_keys" } } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } } } } diff --git a/api-docs/build-swagger.js b/api-docs/build-swagger.js index 678cec87..0490a225 100644 --- a/api-docs/build-swagger.js +++ b/api-docs/build-swagger.js @@ -37,7 +37,7 @@ async function buildModelResources() { swaggerResources[model.table] = await buildSwagger(model); } - fs.writeFile('swagger.json', JSON.stringify(swaggerResources), (err) => { + fs.writeFile('api-model-definitions.json', JSON.stringify(swaggerResources), (err) => { // throws an error, you could also catch it here if (err) throw err; @@ -208,7 +208,8 @@ function buildEntityPaths() { let {endpointName, resourceName, ownership, deletedRoutes} = resource; acc[`/${endpointName}`] = { get: { - "summary": "Get " + resourceName, + "summary": "Get all " + resourceName, + "description": "Gets all " + resourceName, "tags": [ endpointName ], @@ -236,7 +237,8 @@ function buildEntityPaths() { }; acc[`/${endpointName}/search`] = { get: { - "summary": "Get " + resourceName, + "summary": "Search for " + resourceName, + "description": "Search for " + resourceName + " with query parameters.", "tags": [ endpointName ], @@ -282,6 +284,7 @@ function buildEntityPaths() { acc[`/${endpointName}/{id}`] = { get: { "summary": "Get " + resourceName + " by id", + "description": "Gets " + resourceName + " by id.", "tags": [ endpointName ], @@ -320,7 +323,8 @@ function buildEntityPaths() { if (ownership) { acc[`/${endpointName}/own`] = { get: { - "summary": "Get requester's " + resourceName, + "summary": "Get requester's " + resourceName + "object or objects", + "description": "Gets the " + resourceName + " object or objects of the authenticated user.", "tags": [ endpointName ], @@ -351,6 +355,7 @@ function buildEntityPaths() { if (!deletedRoutes || !deletedRoutes.includes("post")) { acc[`/${endpointName}`]["post"] = { "summary": "Create new " + resourceName, + "description": "Creates a new " + resourceName, "tags": [ endpointName ], @@ -389,6 +394,7 @@ function buildEntityPaths() { if (!deletedRoutes || !deletedRoutes.includes("put")) { acc[`/${endpointName}/{id}`]["put"] = { "summary": "Update " + resourceName, + "description": "Updates a " + resourceName, "tags": [ endpointName ], @@ -435,6 +441,7 @@ function buildEntityPaths() { if (!deletedRoutes || !deletedRoutes.includes("delete")) { acc[`/${endpointName}/{id}`]["delete"] = { "summary": "Delete " + resourceName + " by id", + "description": "Deletes a " + resourceName + " by id", "tags": [ endpointName ], @@ -473,7 +480,7 @@ function buildEntityPaths() { }, {}); - fs.writeFile('model-paths.json', JSON.stringify(modelPaths), (err) => { + fs.writeFile('api-entity-paths.json', JSON.stringify(modelPaths), (err) => { // throws an error, you could also catch it here if (err) throw err; diff --git a/api/auth.js b/api/auth.js index 2f657907..37cb699f 100644 --- a/api/auth.js +++ b/api/auth.js @@ -13,11 +13,23 @@ let store = require("../config/redux/store"); module.exports = function(app, passport) { - //TODO: buff up security so each user has their own secret key - //TODO: security key..... no hardcoded strings plzzzz (along with the comment above) - app.post('/auth/token', passport.authenticate('local-login', {session:false}), function(req, res) { - console.log(req.user); - let token = jwt.sign({ uid: req.user.data.id }, process.env.SECRET_KEY, { expiresIn: '3h' }); + app.post('/auth/token', function(req, res, next){ + if(req.body.strategy){ + passport.authenticate(req.body.strategy)(req,res,next); + }else{ + passport.authenticate('local-login', {session:false})(req,res,next); + } + + }, async function(req, res) { + let payload = { uid: req.user.data.id }; + if(req.query.includeUser){ + await req.user.attachReferences(); + payload.user = req.user.data; + delete payload.user.password; + delete payload.user.references.funds; + } + let expiration = req.body.noExpiration ? undefined : "3h" + let token = jwt.sign(payload, process.env.SECRET_KEY, { expiresIn: expiration }); res.json({token:token}); }); @@ -28,7 +40,7 @@ module.exports = function(app, passport) { req.logout(); res.json({"message" : "successful logout"}); }); - + app.post("/auth/reset-password", function(req, res, next){ User.findOne("email", req.body.email, function(user){ if(user.data){ @@ -45,7 +57,11 @@ module.exports = function(app, passport) { hash: bcrypt.hashSync(token, 10) }); reset.create(function(err, newReset){ + let resetURL = store.getState().options.reset_url; let frontEndUrl = `${req.protocol}://${req.get('host')}/reset-password/${user.get("id")}/${token}`; + if(resetURL){ + frontEndUrl = `${resetURL}?uid=${user.get("id")}&resetToken=${token}` + } res.json({message: "Success"}); user.set("token", token); user.set("url", frontEndUrl); @@ -94,8 +110,10 @@ module.exports = function(app, passport) { }); + app.post('/auth/session', function(req,res,next){ - passport.authenticate('local-login', function(err, user, info) { + + let cb = function(err, user, info) { if (err) { console.error(err); return res.json({"error" : "Invalid username or password"}); } if (!user) { console.error("no user"); return res.json({"error" : "Invalid username or password"}) } req.logIn(user, {session:true}, function(err) { @@ -106,7 +124,12 @@ module.exports = function(app, passport) { return next(); }) }); - })(req, res, next); + }; + if(req.body.strategy) { + passport.authenticate(req.body.strategy, cb)(req, res, next); + }else{ + passport.authenticate('local-login', cb)(req, res, next); + } },require("../middleware/role-session")(), function(req, res, next){ let user_role = new Role({"id" : req.user.data.role_id}); user_role.getPermissions(function(perms){ @@ -116,4 +139,4 @@ module.exports = function(app, passport) { }); - }; \ No newline at end of file +}; \ No newline at end of file diff --git a/api/entity.js b/api/entity.js index 47a7a8f9..ebb123ef 100644 --- a/api/entity.js +++ b/api/entity.js @@ -115,23 +115,38 @@ module.exports = function (router, model, resourceName, userCorrelator) { router.put(`/${resourceName}/:id(\\d+)`, validate(model), auth(null, model, userCorrelator),async function (req, res, next) { try { let entity = res.locals.valid_object; - req.body.id = entity.get("id"); - Object.assign(entity.data, req.body); - let updatedEntity = await entity.update(); - let requestReferences = req.body.references || {}; - - //todo: combine updateReferences into a single transaction - for (let reference of references) { - let referenceData = requestReferences[reference.model.table] - if (referenceData) { - let upsertedReferences = await updatedEntity.updateReferences(referenceData, reference); + await model.database.transaction(async function (trx) { + let CreateEntity = require("../models/base/entity"); + let trxEntity = CreateEntity(model.table, model.references, model.primaryKey, trx); + + entity = new trxEntity(entity.data); + + + req.body.id = entity.get("id"); + Object.assign(entity.data, req.body); + let updatedEntity = await entity.update(); + let requestReferences = req.body.references || {}; + + //todo: combine updateReferences into a single transaction + updatedEntity.data.references = {}; + for (let reference of references) { + + let referenceData = requestReferences[reference.model.table] + if (referenceData) { + updatedEntity.data.references[reference.model.table] = await updatedEntity.updateReferences(referenceData, reference, true); + } } - } - res.locals.json = updatedEntity.data; - store.dispatchEvent(`${model.table}_updated`, updatedEntity); + res.locals.json = updatedEntity.data; + store.dispatchEvent(`${model.table}_updated`, updatedEntity); + }); next(); + }catch(error){ console.error("Server error updating entity: ", error); + if(error.code == 23503){ + res.status(400).send({error : error.constraint}); + + } res.status(500).send({error : "error updating"}); } }); @@ -157,46 +172,33 @@ module.exports = function (router, model, resourceName, userCorrelator) { router.post(`/${resourceName}`, auth(), function (req, res, next) { let entity = new model(req.body); - entity.create(function (err, newEntity) { + entity.create(async function (err, newEntity) { if(err){ console.error("Server error creating entity: " + err); res.status(500).send({ error: "Error creating new " + resourceName }) } else { - if (references.length === 0 || req.body.references === undefined || req.body.references.length == 0) { + if (references.length === 0 || req.body.references === undefined || Object.keys(req.body.references).length === 0) { res.locals.json = newEntity.data; + store.dispatchEvent(`${model.table}_created`, newEntity) EventLogs.logEvent(req.user.get('id'), `${resourceName} ${newEntity.get(model.primaryKey)} was created by user ${req.user.get('email')}`); next(); } else { let requestReferenceData = req.body.references; + newEntity.data.references = {}; - let counter = 0; for (let reference of references) { - if (!requestReferenceData[reference.model.table] || requestReferenceData[reference.model.table].length == 0) { - counter++; - if (counter == references.length) { - res.locals.json = newEntity.data; - store.dispatchEvent(`${model.table}_created`, newEntity) - - EventLogs.logEvent(req.user.get('id'), `${resourceName} ${newEntity.get(model.primaryKey)} was created by user ${req.user.get('email')}`); - next(); - } - } - else { - let referenceData = requestReferenceData[reference.model.table]; - newEntity.createReferences(referenceData, reference, function (modifiedEntity) { - counter++; - if (counter == references.length) { - res.locals.json = modifiedEntity.data; - store.dispatchEvent(`${model.table}_created`, modifiedEntity) - EventLogs.logEvent(req.user.get('id'), `${resourceName} ${newEntity.get(model.primaryKey)} was created by user ${req.user.get('email')}`); - next(); - } - }); + let referenceData = requestReferenceData[reference.model.table]; + if(referenceData) { + newEntity.data.references[reference.model.table] = await newEntity.updateReferences(referenceData, reference); } + res.locals.json= newEntity.data; } + store.dispatchEvent(`${model.table}_created`, newEntity) + EventLogs.logEvent(req.user.get('id'), `${resourceName} ${newEntity.get(model.primaryKey)} was created by user ${req.user.get('email')}`); + next(); } } }); diff --git a/api/service-categories.js b/api/service-categories.js index 57c4bd15..9c1cfa07 100644 --- a/api/service-categories.js +++ b/api/service-categories.js @@ -17,7 +17,7 @@ module.exports = function(router) { }); } else { - console.log("authorized person, go on"); + next(); } }); diff --git a/api/service-instance-messages.js b/api/service-instance-messages.js index 8dcf39f9..03882612 100644 --- a/api/service-instance-messages.js +++ b/api/service-instance-messages.js @@ -1,9 +1,10 @@ - +let auth = require('../middleware/auth'); +let validate = require('../middleware/validate'); let ServiceInstanceMessage = require('../models/service-instance-message'); let ServiceInstance = require("../models/service-instance"); module.exports = function(router) { - router.post(`/service-instance-messages`, async function(req,res,next){ + router.post(`/service-instance-messages`, validate(ServiceInstance), auth(null, ServiceInstance), async function(req,res,next){ let store = require("../config/redux/store"); //todo:movethiscodeintoaplugin let messageManager = store.getState(true).pluginbot.services.messageManager[0]; diff --git a/api/service-instances.js b/api/service-instances.js index 84c27407..6ad3cd0b 100644 --- a/api/service-instances.js +++ b/api/service-instances.js @@ -9,6 +9,7 @@ let mkdirp = require("mkdirp"); let path = require("path"); let multer= require("multer"); let _ = require('lodash'); +let PaymentStructureTemplate = require("../models/payment-structure-template"); let dispatchEvent = require("../config/redux/store").dispatchEvent; let store = require("../config/redux/store"); //todo - entity posting should have correct error handling, response should tell user what is wrong like if missing column @@ -26,6 +27,49 @@ let upload = () => { return multer({storage: fileManager.storage(serviceFilePath), limits : {fileSize : uploadLimit()}}) } +async function reactivate(instance_object, trialDays=0){ + if(instance_object.get("status") === "cancelled") { + let lifecycleManager = store.getState(true).pluginbot.services.lifecycleManager; + instance_object = await instance_object.attachReferences(); + if(lifecycleManager) { + lifecycleManager = lifecycleManager[0]; + await lifecycleManager.preReactivate({ + instance: instance_object + }); + } + let paymentPlan = instance_object.get("payment_plan"); + paymentPlan.trial_period_days = trialDays; + let updatedInstance = await instance_object.subscribe(paymentPlan); + if(lifecycleManager) { + lifecycleManager.postReactivate({ + instance: instance_object + }); + } + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if(accessManager){ + accessManager = accessManager[0]; + let token = await accessManager.createToken(instance_object.data.user_id); + instance_object.data.billing_settings_url = accessManager.createLink(instance_object.data.user_id, token); + } + + store.dispatchEvent("service_instance_resubscribed", instance_object); + + return updatedInstance; + + }else if (instance_object.get("status") === "cancellation_pending"){ + let sub = await instance_object.getSubscription(); + if(sub){ + let Stripe = require("../config/stripe"); + await Stripe().connection.subscriptions.update(instance_object.data.subscription_id, {cancel_at_period_end: false}); + instance_object.data.status = "running" + await instance_object.update(); + return instance_object; + } + }else{ + throw "Instance is not cancelled, cannot be reactivated" + } + +} module.exports = function(router) { @@ -36,6 +80,7 @@ module.exports = function(router) { delete req.body.user_id; delete req.body.payment_plan; delete req.body.subscription_id; + delete req.body.payment_structure_template_id; next(); }); @@ -56,46 +101,69 @@ module.exports = function(router) { }); + router.post('/service-instances/:id/reactivate', validate(ServiceInstance), auth(), async function(req, res, next) { let instance_object = res.locals.valid_object; - if(instance_object.get("status") === "cancelled") { - let lifecycleManager = store.getState(true).pluginbot.services.lifecycleManager; - instance_object = await instance_object.attachReferences(); - if(lifecycleManager) { - lifecycleManager = lifecycleManager[0]; - await lifecycleManager.preReactivate({ - instance: instance_object - }); - } - try { - let paymentPlan = instance_object.get("payment_plan"); - paymentPlan.trial_period_days = 0; - let updatedInstance = await instance_object.subscribe(paymentPlan); - res.json(updatedInstance); - if(lifecycleManager) { - lifecycleManager.postReactivate({ - instance: instance_object - }); - } - }catch(error){ - res.status(500).json({error}); - } - }else{ - res.status(400).json({"error" : "Instance is not cancelled, cannot be reactivated"}) + try{ + let updatedInstance = await reactivate(instance_object); + res.json(updatedInstance) + }catch(e){ + console.error(e); + res.status(400).json({error: e.message || e}); } }); - router.post('/service-instances/:id/change-price', validate(ServiceInstance), auth(), function(req, res, next) { + router.post('/service-instances/:id/change-price', validate(ServiceInstance), auth(), async function(req, res, next) { let instance_object = res.locals.valid_object; - instance_object.changePaymentPlan(req.body).then(function (updated_subscription) { - res.json(updated_subscription); - store.dispatchEvent("service_instance_updated", updated_subscription); + if(instance_object.get("status") === "cancelled" && req.body["trial_period_days"] > 0){ + try{ + let updated_subscription = await reactivate(instance_object, req.body["trial_period_days"]); + res.json(updated_subscription); + store.dispatchEvent("service_instance_updated", updated_subscription); + + }catch(error){ + res.json({error}) + } + }else { + let disableProration = req.body["trial_period_days"] > 0 || req.body.disableProration; + instance_object.changePaymentPlan(req.body, false, disableProration).then(function (updated_subscription) { + res.json(updated_subscription); + store.dispatchEvent("service_instance_updated", updated_subscription); + }).catch(function (error) { + res.json({error}); + }); + } + }); + router.post('/service-instances/:id/apply-payment-structure/:payment_structure_id(\\d+)', validate(ServiceInstance), auth(), async function(req, res, next) { + let instance_object = await res.locals.valid_object.attachReferences(); + let newPaymentStructure = (await PaymentStructureTemplate.find({id: req.params.payment_structure_id}))[0]; + let permission_array = res.locals.permissions; + let hasPermission = (permission_array.some(p => p.get("permission_name") === "can_administrate" || p.get("permission_name") === "can_manage")); + if((instance_object.data.type === "custom" || newPaymentStructure.data.type === "custom" ) && !hasPermission){ + return res.status(403).json({error: "Unauthorized"}); + } + instance_object.applyPaymentStructure(req.params.payment_structure_id, true).then(async function (updatedInstance) { + res.json(updatedInstance.data); + store.dispatchEvent("service_instance_updated", updatedInstance); + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if(accessManager){ + accessManager = accessManager[0]; + let token = await accessManager.createToken(updatedInstance.data.user_id); + updatedInstance.data.billing_settings_url = accessManager.createLink(instance_object.data.user_id, token); + } + store.dispatchEvent("service_instance_plan_change", updatedInstance); }).catch(function (error) { - res.json({error}); + console.error(error); + if(error.message){ + res.status(400).json({error : error.message}); + }else { + res.status(500).json({error}); + } }); }); + router.post('/service-instances/:id/change-properties', validate(ServiceInstance),auth(), async function(req, res, next) { let instance_object = res.locals.valid_object; try { @@ -112,8 +180,15 @@ module.exports = function(router) { router.post('/service-instances/:id/cancel', validate(ServiceInstance), auth(), async function(req, res, next) { let instance_object = res.locals.valid_object; try { - let result = await instance_object.unsubscribe(); + let result = await instance_object.scheduleCancellation(); res.json(result); + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if(accessManager){ + accessManager = accessManager[0]; + let token = await accessManager.createToken(instance_object.data.user_id); + instance_object.data.billing_settings_url = accessManager.createLink(instance_object.data.user_id, token); + } + store.dispatchEvent("service_instance_cancellation_requested", instance_object); } catch (err) { console.error(err); @@ -125,10 +200,23 @@ module.exports = function(router) { router.post('/service-instances/:id/request-cancellation', validate(ServiceInstance), auth(), function(req, res, next) { let instance_object = res.locals.valid_object; - instance_object.requestCancellation(function(result){ + instance_object.scheduleCancellation().then(async result => { res.locals.json = result; next(); + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if(accessManager){ + accessManager = accessManager[0]; + let token = await accessManager.createToken(instance_object.data.user_id); + console.log("OK!", token); + instance_object.data.billing_settings_url = accessManager.createLink(instance_object.data.user_id, token); + console.log(instance_object.data.billing_settings_url, "URL TIME"); + }else{ + console.log("NOTHING!"); + } + store.dispatchEvent("service_instance_cancellation_requested", instance_object); + }).catch(e => { + console.error("Error cancelling", e); }); }); diff --git a/api/service-templates.js b/api/service-templates.js index b7f562bd..93d42407 100644 --- a/api/service-templates.js +++ b/api/service-templates.js @@ -22,6 +22,8 @@ let iconFilePath = ServiceTemplate.iconFilePath; let imageFilePath = ServiceTemplate.imageFilePath; let slug = require("slug"); let validateProperties = require("../lib/handleInputs").validateProperties; +let Tier = require("../models/tier"); +let PaymentStructureTemplate = require("../models/payment-structure-template"); let fileManager = store.getState(true).pluginbot.services.fileManager[0]; let jwt = require('jsonwebtoken'); @@ -135,9 +137,11 @@ module.exports = function (router) { }); - router.get('/service-templates/:id/request', validate(ServiceTemplate), function (req, res, next) { + router.get('/service-templates/:id/request', validate(ServiceTemplate), async function (req, res, next) { let serviceTemplate = res.locals.valid_object; + let tiers = await Tier.find({service_template_id: serviceTemplate.data.id}, true); serviceTemplate.data.references = {}; + res.locals.valid_object.data.references.tiers = tiers.map(tier => tier.data); serviceTemplate.getRelated(ServiceTemplateProperty, function (props) { //this object for authenticated call res.locals.valid_object.data.references[ServiceTemplateProperty.table] = props.map(entity => entity.data); @@ -202,6 +206,19 @@ module.exports = function (router) { let props = (await serviceTemplate.getRelated(ServiceTemplateProperty)) || null; let req_body = req.body; let reqProps = req_body.references && req_body.references.service_template_properties || []; + let paymentStructureTemplate = (await PaymentStructureTemplate.find({id: req_body.payment_structure_template_id}))[0]; + + //check if the payment structure exists + if(!paymentStructureTemplate){ + return res.status(400).json({error: 'Payment structure template not found'}); + } + let tier = (await Tier.find({id: paymentStructureTemplate.data.tier_id, service_template_id: serviceTemplate.data.id}))[0]; + + //check if the structure's tier belongs to the template + if(!tier){ + return res.status(400).json({error: 'Payment Structure does not belong to this service template'}); + } + res.locals.tier = tier; await authPromise(req, res); let permission_array = res.locals.permissions || []; let handlers = (store.getState(true).pluginbot.services.inputHandler || []).reduce((acc, handler) => { @@ -210,9 +227,9 @@ module.exports = function (router) { }, {}); //this is true when user can override things let hasPermission = (permission_array.some(p => p.get("permission_name") === "can_administrate" || p.get("permission_name") === "can_manage")); - let templatePrice = serviceTemplate.get("amount"); + let templatePrice = paymentStructureTemplate.get("amount"); let price = hasPermission ? (req_body.amount || templatePrice) : templatePrice; - let trialPeriod = serviceTemplate.get("trial_period_days"); + let trialPeriod = paymentStructureTemplate.get("trial_period_days"); //todo: this doesn't do anthing yet, needs to check the "passed" props not the ones on the original... // let validationResult = props ? validateProperties(props, handlers) : []; @@ -221,12 +238,22 @@ module.exports = function (router) { // } //todo: less looping later - let mergedProps = props.map(prop => { + let metricIndex = null; + let mergedProps = props.map((prop, index) => { let propToMerge = reqProps.find(reqProp => reqProp.id === prop.data.id); - return propToMerge ? {...prop.data, "data" : propToMerge.data} : prop + let mergedProp = propToMerge ? {...prop.data, "data" : propToMerge.data} : prop + if(mergedProp.type === "metric" && mergedProp.config.pricing && mergedProp.config.pricing.tiers && !mergedProp.config.pricing.tiers.includes(tier.data.name)){ + metricIndex = index; + } + return mergedProp; }); if (props) { - price = require("../lib/handleInputs").getPrice(mergedProps, handlers, price); + let priceProps = [...mergedProps]; + if(metricIndex !== null){ + priceProps.splice(metricIndex, 1); + } + + price = require("../lib/handleInputs").getPrice(priceProps, handlers, price); } @@ -235,7 +262,8 @@ module.exports = function (router) { res.locals.adjusted_price = price; res.locals.merged_props = mergedProps; - if (!req.isAuthenticated()) { + res.locals.payment_structure_template = paymentStructureTemplate; + if (!req.isAuthenticated() || (req_body.hasOwnProperty("email") && req.user.data.email !== req_body.email)) { if (req_body.hasOwnProperty("email")) { let mailFormat = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; @@ -252,6 +280,11 @@ module.exports = function (router) { let user = await User.findOne("email", req_body.email); if (user.data) { + if(hasPermission){ + req.body.client_id = user.get("id"); + res.locals.request_for = user; + return next(); + } let invitation = await Invitation.findOne("user_id", user.get("id")); if (invitation.data) { return res.status(400).json({error: 'User has already been invited'}); @@ -280,11 +313,17 @@ module.exports = function (router) { */ router.post("/service-templates/:id/request", validate(ServiceTemplate), validateServiceRequest, async function (req, res, next) { + let isNew; + let user; try { let serviceTemplate = res.locals.valid_object; let references = serviceTemplate.references; + let paymentStructureTemplate = res.locals.payment_structure_template; let props = references ? references.service_template_properties : null; let req_body = req.body; + if(!req_body.references){ + req_body.references = {}; + } req_body.references.service_template_properties = res.locals.merged_props; let Promise = require("bluebird"); let permission_array = res.locals.permissions || []; @@ -292,10 +331,10 @@ module.exports = function (router) { let responseJSON = {}; //using promiseProxy for non-standard callbacks - let user = req.user; + user = req.user; //is the user authenticated (are they logged in)? - let isNew = !req.isAuthenticated(); + isNew = !req.isAuthenticated() || (req_body.hasOwnProperty("email") && !req_body.hasOwnProperty("client_id") && req.user.data.email !== req_body.email); let store = require('../config/redux/store'); //todo: once in plugin this code needs big changes @@ -313,62 +352,70 @@ module.exports = function (router) { } //if it's a new user request we need to create an account, invitation + //todo: move this part into a function if (isNew && serviceTemplate.get('published')) { let globalProps = store.getState().options; let roleId = globalProps['default_user_role']; - let newUser = new User({"email": req_body.email, "role_id": roleId, "status": "invited"}); + let newUser = new User({"email": req_body.email, "role_id": roleId, "status": "active"}); if(req_body.password){ let password = require("bcryptjs").hashSync(req_body.password, 10); newUser.set("password", password) newUser.set("status", "active"); } + if(req_body.userName){ + newUser.set("name", req_body.userName); + } + if(req_body.token){ + newUser.set("google_user_id", req_body.token); + } //promisify the createWithStripe function let createUser = Promise.promisify(newUser.createWithStripe, {context: newUser}); //create the new user let createdUser = await createUser(); - if(!req_body.password) { - let invite = new Invitation({"user_id": createdUser.get("id")}); - let createInvite = Promise.promisify(invite.create, {context: invite}); - //create the invitation for the user. - let createdInvite = await createInvite(); - responseJSON.api = req.protocol + '://' + req.get('host') + "/api/v1/users/register?token=" + createdInvite.get("token"); - responseJSON.url = req.protocol + '://' + req.get('host') + "/invitation/" + createdInvite.get("token"); - - } - responseJSON.token = jwt.sign({ uid: createdUser.get("id") }, process.env.SECRET_KEY, { expiresIn: '1h' }); + // if(!req_body.password) { + // let invite = new Invitation({"user_id": createdUser.get("id")}); + // let createInvite = Promise.promisify(invite.create, {context: invite}); + // //create the invitation for the user. + // let createdInvite = await createInvite(); + // responseJSON.api = req.protocol + '://' + req.get('host') + "/api/v1/users/register?token=" + createdInvite.get("token"); + // responseJSON.url = req.protocol + '://' + req.get('host') + "/invitation/" + createdInvite.get("token"); + // + // } let user_role = new Role({id : createdUser.get("role_id")}) ; // todo : remove this once it supports promises - let permissionPromise = new Promise(resolve => { - user_role.getPermissions(function (perms) { - let permission_names = perms.map(perm => perm.data.permission_name); - return resolve(permission_names); + if(!req.isAuthenticated()) { + let permissionPromise = new Promise(resolve => { + user_role.getPermissions(function (perms) { + let permission_names = perms.map(perm => perm.data.permission_name); + return resolve(permission_names); + }); }); - }); - let loginPromise = new Promise((resolve, reject) => { - req.logIn(createdUser, {session: true}, (err) => { - if (err) { - reject(err); - } - else{ - resolve(); - } - }); + let loginPromise = new Promise((resolve, reject) => { + req.logIn(createdUser, {session: true}, (err) => { + if (err) { + reject(err); + } + else { + resolve(); + } + }); - }); + }); - //log in the user (give them a cookie) - await loginPromise; + //log in the user (give them a cookie) + await loginPromise; - //set some data for the response + //set some data for the response - //currently the permissions that the client app sets get passed here. - responseJSON.permissions = await permissionPromise; + //currently the permissions that the client app sets get passed here. + responseJSON.permissions = await permissionPromise; + } responseJSON.uid = createdUser.get("id"); user = createdUser; @@ -382,7 +429,7 @@ module.exports = function (router) { let newFund = null; //if token_id exists, create/update the user's fund if (req_body.token_id && req_body.token_id !== '') { - newFund = Fund.promiseFundCreateOrUpdate(user.get('id'), req_body.token_id); + newFund = Fund.promiseFundCreateOrUpdate(req_body.client_id || user.get('id'), req_body.token_id); } //create the service instance @@ -392,19 +439,19 @@ module.exports = function (router) { //elevated accounts can override things if (hasPermission) { res.locals.overrides = { - user_id : req_body.client_id || req.user.get("id"), + user_id : req_body.client_id || user.get("id"), requested_by : req.user.get("id"), description : req_body.description || serviceTemplate.get("description"), name : req_body.name || serviceTemplate.get("name"), - trial_period_days : req_body.trial_period_days || serviceTemplate.get("trial_period_days") + trial_period_days : req_body.trial_period_days || paymentStructureTemplate.get("trial_period_days") }; }else{ res.locals.overrides = { - user_id : req.user.get("id"), + user_id : user.get("id"), requested_by : req.user.get("id"), - trial_period_days : serviceTemplate.get("trial_period_days") || 0 + trial_period_days : paymentStructureTemplate.get("trial_period_days") || 0 } } @@ -415,6 +462,7 @@ module.exports = function (router) { ...res.locals.overrides, }); + newInstance = await newInstance.attachReferences(); let postData = {}; if(lifecycleManager) { @@ -424,6 +472,10 @@ module.exports = function (router) { template: serviceTemplate }); } + if(isNew){ + let newUser = (await User.find({id: user.get("id")}, true))[0]; + responseJSON.token = jwt.sign({ uid: user.get("id"), user: newUser.data }, process.env.SECRET_KEY, { expiresIn: '1h' }); + } res.json({ ...responseJSON, ...newInstance.data, @@ -432,16 +484,23 @@ module.exports = function (router) { }); try { - if (isNew && req_body.password === undefined) { - - newInstance.set("api", responseJSON.api); - newInstance.set("url", responseJSON.url); - store.dispatchEvent("service_instance_requested_new_user", newInstance); + newInstance.data.properties = newInstance.data.references.service_instance_properties.reduce((acc, prop) => { + acc[prop.name] = prop.data && prop.data.value; + return acc; + }, {}); + if(newInstance.data.references.payment_structure_templates[0].type === "custom"){ + store.dispatchEvent("service_instance_custom_requested_by_user", newInstance); + }else if (isNew && req_body.password === undefined) { + + // newInstance.set("api", responseJSON.api); + // newInstance.set("url", responseJSON.url); + // store.dispatchEvent("service_instance_requested_new_user", newInstance); + store.dispatchEvent("service_instance_requested_by_user", newInstance); }else if(isNew){ - + store.dispatchEvent("service_instance_requested_by_user", newInstance); }else if (req.uid !== newInstance.get("user_id")) { - store.dispatchEvent("service_instance_requested_for_user", newInstance); + store.dispatchEvent("service_instance_requested_by_user", newInstance); } else { store.dispatchEvent("service_instance_requested_by_user", newInstance); @@ -452,6 +511,11 @@ module.exports = function (router) { } catch (error) { console.error(error); + if(isNew && user){ + user.deleteWithStripe(function(err, result){ + console.log("deleted user: ", result, err); + }); + } return res.status(500).json({error}); } @@ -461,9 +525,21 @@ module.exports = function (router) { router.post("/service-templates", auth(), function (req, res, next) { req.body.created_by = req.user.get("id"); - req.body.trial_period_days = req.body.trial_period_days || 0; - req.body.currency = store.getState().options.currency; + // req.body.trial_period_days = req.body.trial_period_days || 0; + // req.body.currency = store.getState().options.currency; let properties = req.body.references && req.body.references.service_template_properties; + let tiers = req.body.references && req.body.references.tiers; + + if(tiers) { + req.body.references.tiers = tiers.map(tier => { + let paymentTemplates = tier.references && tier.references.payment_structure_templates || []; + tier.references.payment_structure_templates = paymentTemplates.map(payment => { + payment.currency = store.getState().options.currency; + return payment; + }) + return tier; + }) + } if(properties){ req.body.references.service_template_properties = properties.map(prop => { return { @@ -472,6 +548,7 @@ module.exports = function (router) { }; }); } + ServiceTemplate.findAll("name", req.body.name, (templates) => { if (templates && templates.length > 0) { res.status(400).json({error: "Service template name already in use"}) diff --git a/api/system-options.js b/api/system-options.js index 08e5e46f..48a449d8 100644 --- a/api/system-options.js +++ b/api/system-options.js @@ -35,7 +35,8 @@ module.exports = function (router) { } else { //todo: make less hardcoded.. maybe seperate api calls again if(req.params.id == "brand_logo"){ - return res.sendFile(path.resolve(__dirname, "../public/assets/logos/v1/servicebot-logo-full-white.png")); + //return res.sendFile(path.resolve(__dirname, "../public/assets/logos/v1/servicebot-logo-full-white.png")); + return res.sendFile(path.resolve(__dirname, "../public/assets/logos/v1/servicebot-logo-full-blue.png")); } else if(req.params.id == "loader_logo") { return res.sendFile(path.resolve(__dirname, "../public/assets/logos/v1/servicebot-logo-full-blue.png")); } else { diff --git a/api/tiers.js b/api/tiers.js new file mode 100644 index 00000000..19eaf816 --- /dev/null +++ b/api/tiers.js @@ -0,0 +1,25 @@ + + +module.exports = function(router) { + let Tier = require('../models/tier'); + // router.get("/service-categories", function(req, res, next){ + // if (!req.isAuthenticated()) { + // let key = req.query.key; + // let value = req.query.value; + // if (!key || !value) { + // key = undefined; + // value = undefined; + // } + // ServiceCategories.findAll(key, value, function (templates) { + // res.json(templates.map(entity => entity.data)) + // }); + // } + // else { + // console.log("authorized person, go on"); + // next(); + // } + // }); + require("./entity")(router, Tier, "tiers"); + + return router; +}; \ No newline at end of file diff --git a/api/users.js b/api/users.js index 4cebb65e..3936f512 100644 --- a/api/users.js +++ b/api/users.js @@ -73,6 +73,30 @@ module.exports = function (router, passport) { }); //TODO better error handling //TODO use next + router.post("/users/create", auth(), function(req,res,next){ + if (res.locals.permissions.some(p => p.get("permission_name") == "can_administrate")){ + if (req.body.name && req.body.email && req.body.password) { + if (!req.body.email.match(mailRegex)) { + res.status(400).json({error: 'Invalid email format'}); + } + else { + let newUser = new User(req.body); + newUser.set("password", bcrypt.hashSync(req.body.password, 10)); + newUser.createWithStripe(function (err, result) { + if (err) { + res.status(403).json({error: err}); + } else { + res.locals.json = result.data; + res.locals.valid_object = result; + next(); + } + }); + } + } else { + res.status(403).json({error: "Name, email, and password are all required!"}); + } + } + }); router.post("/users/register", function (req, res, next) { let token = req.query.token; if (token) { @@ -82,22 +106,38 @@ module.exports = function (router, passport) { } else { User.findById(foundInvitation.get("user_id"), function (newUser) { req.body.id = newUser.get("id"); - req.body.password = bcrypt.hashSync(req.body.password, 10); + if(req.body.password) { + req.body.password = bcrypt.hashSync(req.body.password, 10); + }else if(!req.body.google_user_id){ + return res.status(500).json({error: "No password specified"}) + } Object.assign(newUser.data, req.body); newUser.set("status", "active"); newUser.update(function (err, updatedUser) { - foundInvitation.delete(function (response) { - EventLogs.logEvent(updatedUser.get('id'), `user ${updatedUser.get('id')} ${updatedUser.get('email')} registered`); - res.locals.json = updatedUser.data; - res.locals.valid_object = updatedUser; - next(); + if(err){ + //todo: maybe think about moving full error into this err? + let message = err.match(/google_user_id/) ? "There is a user already connected to this Google account, try logging in" : "Error registering user" + return res.status(500).json({error: message}); + } + foundInvitation.delete(async function (response) { + let payload = { uid: updatedUser.data.id }; + await updatedUser.attachReferences(); + payload.user = updatedUser.data; + delete payload.user.password; + let token = jwt.sign(payload, process.env.SECRET_KEY, { expiresIn: '3h' }); + // res.json({token:token}); + // + // EventLogs.logEvent(updatedUser.get('id'), `user ${updatedUser.get('id')} ${updatedUser.get('email')} registered`); + return res.json({token}); + // res.locals.valid_object = updatedUser; + // next(); }) }) }); } }); - } else if (res.locals.sysprops.allow_registration == "true") { + } else if (res.locals.sysprops.allow_registration == "true"){ if (req.body.name && req.body.email && req.body.password) { if (!req.body.email.match(mailRegex)) { res.status(400).json({error: 'Invalid email format'}); @@ -299,14 +339,13 @@ module.exports = function (router, passport) { //Strip passwords from all user things router.all("*", function (req, res, next) { if (res.locals.json) { - if (res.locals.json.password) { - delete res.locals.json.password; - - } else if (Array.isArray(res.locals.json)) { + if (Array.isArray(res.locals.json)) { res.locals.json = res.locals.json.map(user => { delete user.password; return user; }) + }else{ + delete res.locals.json.password } } next(); diff --git a/config/db.js b/config/db.js index 0dd1157e..ba5a6e3d 100644 --- a/config/db.js +++ b/config/db.js @@ -6,6 +6,10 @@ var config = { port: process.env.POSTGRES_DB_PORT }; +//this is for parsing bigints +var pg = require('pg') +pg.types.setTypeParser(20, 'text', parseInt) + var knex = require('knex')({ client: 'pg', connection: config, diff --git a/config/default-notifications.js b/config/default-notifications.js index 280118a5..22088aef 100644 --- a/config/default-notifications.js +++ b/config/default-notifications.js @@ -1,124 +1,550 @@ let default_notifications = {}; default_notifications.templates = [ - {name:"request_service_instance_admin", - event_name:"service_instance_requested_for_user", - message:"Your service [[name]] has been requested for you. Please login to your account and approve the service.", - subject:"ServiceBot Instance needs approval", - description:"This notification it triggered when a service is requested by an admin on behalf of a user and the user needs to approve it", - model:"service-instance", - send_email:true - }, - {name:"request_service_instance_user", - event_name:"service_instance_requested_by_user", - message:"Your service request for [[name]] has been completed. Please login to your account to view and access your service.", - subject:"ServiceBot Instance requested", - description:"This notification it triggered when a service is requested by a user", - model:"service-instance", - send_email:true - }, - {name:"request_service_instance_new_user", - event_name:"service_instance_requested_new_user", - message:"Your service request for [[name]] has been completed. Please click the link to complete user registration in order to view your services. Once registered you can access your service.", - subject:"ServiceBot Instance requested", - description:"This notification it triggered when a service is requested by a new user. They are sent the link to complete registration", - model:"service-instance", - send_email:true - }, - {name:"service_requires_payment_approval", - event_name:"service_instance_charge_added", - message:"There are additional charges added to your service, [[name]]. Please login to your account and approve the charges.", - subject:"ServiceBot Instance has additional charges", - description:"This notification it triggered when a service has been updated with a new charge that needs approval", - model:"service-instance", - send_email:true - }, - {name:"service_cancellation_submitted", - event_name:"service_instance_cancellation_requested", - message:"Your cancellation request for [[name]] has been submitted. You will receive another notification when it has been approved.", - subject:"ServiceBot Instance cancellation submitted", - description:"This notification it triggered when a service instance cancellation has been requested by a user", - model:"service-instance", - send_email:true - }, - {name:"service_instance_update", - event_name:"service_instance_updated", - message:"Your Service Instance [[name]] has been updated. You can use this link to view your instance details.", - subject:"ServiceBot Instance updated", - description:"This notification it triggered when a service instance has been updated", - model:"service-instance", - send_email:true - }, - {name:"instance_cancellation_approved", - event_name:"service_instance_cancellation_approved", - message:"Your cancellation request has been approved.", - subject:"ServiceBot Instance cancellation request approved", - description:"This notification it triggered when a service cancellation request has been approved", - model:"service-instance-cancellation", - send_email:true - }, - {name:"instance_cancellation_rejected", - event_name:"service_instance_cancellation_rejected", - message:"Your cancellation request for has been rejected. For more information, contact your service provider or comment on your service and we will get back to you shortly.", - subject:"ServiceBot Instance cancellation request rejected", - description:"This notification it triggered when a service cancellation request has been rejected", - model:"service-instance-cancellation", - send_email:true + { + name: "service_cancellation", + event_name: "service_instance_cancellation_requested", + message: `
+
+
+ +
+ +
+ + + View Subscription +
+ + +
+
Powered by
+
`, + subject: "User just cancelled a subscription", + description: "Sent when a service cancellation has been requested by a user", + model: "service-instance", + send_email: false, + send_to_owner: false +}, + { + name: "password_reset", + event_name: "password_reset_request_created", + message: `
+
+
+ +
+ +
+ + + Reset Password +
+ + +
+
Powered by
+
`, + subject: "Password Reset", + description: "Sent when a user requests a password reset", + model: "user", + send_email: true }, - {name:"password_reset", - event_name:"password_reset_request_created", - message:"Follow the following link to reset your password.", - subject:"ServiceBot password reset", - description:"This notification it triggered when a user requests a password reset", - model:"user", - send_email:true + { + name: "registration_admin", + event_name: "service_instance_requested_by_user", + message: `
+
+
+ +
+ +
+ + + + View account detail +
+ + +
+
Powered by
+
`, + subject: "New signup for [[_company_name]]!", + description: "Sent to admins when a new user has signed up", + model: "service-instance", + send_email: true, + send_to_owner: false + }, + { + name: "payment_failure", + event_name: "payment_failure", + message: `
+
+
+ +
+ +
+ + + Update credit card + +
+ + +
+
Powered by
+
`, + subject: "Oh no, your payment failed", + description: "Sent when a payment has failed to go through. It notifies the user to update their payment method", + model: "user", + send_email: true }, {name:"invitation", event_name:"user_invited", - message:"Hello there, \r\nYou have been invited to use the [[_company_name]] ServiceBot System. From here you can request new services, manage your services, and see other service options. Please click the link to begin user registration.", - subject:"ServiceBot Invitation!", - description:"This notification it triggered when a user is invited to they system by an admin", + message:`
+
+
+ +
+ +
+ + + Active Account +
+ + +
+
Powered by
+
`, + subject:"Invitation", + description:"Sent when a user is invited to they system by an admin", model:"user", send_email:true }, - {name:"registration_user", - event_name:"user_registered", - message:"Your registration has been completed! You can now access your account at here. Thank you for choosing [[_company_name]].", - subject:"ServiceBot registration complete", - description:"This notification it triggered when registration has been completed", - model:"user", - send_email:true + { + name: "registration_user", + event_name: "service_instance_requested_by_user", + message: `
+
+
+ +
+ +
+ + + + Access Account +
+ + +
+
Powered by
+
`, + subject: "Welcome to [[_company_name]]", + description: "Sent to users when they sign up", + model: "service-instance", + send_email: false, + send_to_owner: true + }, + { + name: "new_invoice", + event_name: "new_invoice", + message: `
+
+
+ +
+ +
+ + + +
+ + + + + + + + + + +
+ +
+ + +
+
+ Powered by + + +
+
`, + subject: "Thank you for the payment", + description: "Sent to users when a new invoice is generated", + model: "invoice", + send_email: false, + send_to_owner: true + }, + { + name: "resubscribe_notification_admin", + event_name: "service_instance_resubscribed", + message: `
+
+
+ +
+ +
+ + + View account detail +
+ + +
+
Powered by
+
`, + subject: "Account has resubscribed to [[_company_name]]!", + description: "Sent to admins when a user resubscribed", + model: "service-instance", + send_email: false, + send_to_owner: false + }, + { + name: "resubscribe_notification_user", + event_name: "service_instance_resubscribed", + message: `
+
+
+ +
+ +
+ + + View Account Detail + +
+ + +
+
Powered by
+
`, + subject: "We are happy to see you back!", + description: "Sent to users when they resubscribe", + model: "service-instance", + send_email: false, + send_to_owner: true + }, + { + name: "service_cancellation_goodbye", + event_name: "service_instance_cancellation_requested", + message: `
+
+
+ +
+ +
+ + + + Reactivate Account + +
+ + +
+
Powered by
+
`, + subject: "We're sad to let you go", + description: "Sent to a user after they cancel their subscription", + model: "service-instance-cancellation", + send_email: false + }, + { + name: "registration_enterprise_user", + event_name: "service_instance_custom_requested_by_user", + message: `
+
+
+ +
+ +
+ + +
+ + +
+
Powered by
+
`, + subject: "Pricing request received", + description: "Sent to customer when an enterprise service is requested", + model: "service-instance", + send_email: false, + send_to_owner: true }, - {name:"registration_admin", - event_name:"user_registered", - message:"You have gained a new user! [[name]] - [[email]] has just joined your ServiceBot system.", - subject:"New ServiceBot User", - description:"This notification it triggered for an admin when a new user has joined the system", - model:"user", - send_email:true, - send_to_owner:false + { + name: "registration_enterprise_admin", + event_name: "service_instance_custom_requested_by_user", + message: `
+
+
+ +
+ +
+ + + View Request +
+ + +
+
Powered by
+
`, + subject: "New pricing request", + description: "Sent to admins when an enterprise service is requested", + model: "service-instance", + send_email: true, + send_to_owner: false }, - {name:"user_suspension", - event_name:"user_suspended", - message:"Your ServiceBot account has been suspended. Please contact your service provider and check the state of your account.", - subject:"ServiceBot Account Suspended", - description:"This notification it triggered when an account has been suspended", - model:"user", - send_email:true + { + name: "service_instance_plan_change_user", + event_name: "service_instance_plan_change", + message: `
+
+
+ +
+ +
+ + + View Account + +
+ + +
+
Powered by
+
`, + subject: "Your [[_company_name]] plan has changed", + description: "Sent to users when a payment plan has been changed", + model: "service-instance", + send_email: false, + send_to_owner: true + }, - {name:"payment_failure", - event_name:"payment_failure", - message:"Your payment failed. Please log into your account and check your payment plan.", - subject:"ServiceBot Payment Failure", - description:"This notification it triggered when a payment has failed to go through. It notifies the user to update their payment method", - model:"user", - send_email:true + { + name: "service_instance_plan_change_admin", + event_name: "service_instance_plan_change", + message: `
+
+
+ +
+ +
+ + + View The Changed Plan +
+ + +
+
Powered by
+
`, + subject: "[[references.users.email]] has changed their plan", + description: "Sent to admins when a service payment plan has been changed", + model: "service-instance", + send_email: false, + send_to_owner: false + + }, + { + name: "trial_expiration", + event_name: "service_instance_trial_expired", + message: `
+
+
+ +
+ +
+ + + Reactivate Account + +
+ + +
+
Powered by
+
`, + subject: "Your free trial has expired", + description: "Sent when a free trial has ended", + model: "service-instance", + send_email: false, + send_to_owner: true } ]; //Setting the registration_admin role to admin +//todo: no more hardcoded id... default_notifications.templates_to_roles = [ - { - notification_template_id:12, - role_id:1 - }, + { + notification_template_id: 3, + role_id: 1 + }, + { + notification_template_id: 1, + role_id: 1 + }, { + notification_template_id: 8, + role_id: 1 + }, + { + notification_template_id: 12, + role_id: 1 + } ]; module.exports = default_notifications; \ No newline at end of file diff --git a/config/passport.js b/config/passport.js index 18fe10d5..2ff3ff58 100644 --- a/config/passport.js +++ b/config/passport.js @@ -7,7 +7,7 @@ var JwtStrategy = require('passport-jwt').Strategy; var ExtractJwt = require('passport-jwt').ExtractJwt; process.on('unhandledRejection', function (e) { - console.log(e.message, e.stack) + }) // create the pool somewhere globally so its lifetime @@ -82,8 +82,8 @@ module.exports = function (passport) { // find a user whose email is the same as the forms email // we are checking to see if the user trying to login already exists User.findOne('email', name.toLowerCase(), function (result) { - console.log("checking name"); - console.log(result); + + if (result.data) { return done(null, false, req.flash('signupMessage', 'That email is already taken.')); @@ -91,7 +91,7 @@ module.exports = function (passport) { else { var newUser = new User({"email": name, "password": bcrypt.hashSync(password, 10), "role_id": 1}); newUser.createWithStripe(function (err, result) { - console.log(result.get('id')); + return done(err, result); }) } @@ -156,14 +156,17 @@ module.exports = function (passport) { passport.use(new JwtStrategy(opts, async function (jwt_payload, done) { let query = jwt_payload.email ? {email: jwt_payload.email} : {id: jwt_payload.uid}; + if(!jwt_payload.uid && !jwt_payload.email){ + return done("Invalid token"); + } let user = (await User.find(query))[0]; - if (user.data) { + if (user && user.data) { if (user.data.status === "suspended") { return done(null, false, {"message": "account suspended"}); } done(null, user); } else { - done(null, false); + done("User does not exist", false); } })); diff --git a/config/pluginbot.config.js b/config/pluginbot.config.js index dc528b63..4835b1ab 100644 --- a/config/pluginbot.config.js +++ b/config/pluginbot.config.js @@ -113,7 +113,12 @@ let basePlugins = function() { {"path" : `${PLUGIN_DIRECTORY}/client-plugins/ga`}, {"path" : `${PLUGIN_DIRECTORY}/updates`, "interval" : 86400000, "master" : "https://hub.serviceshop.io/api/v1/announcements"}, {"path" : `${PLUGIN_DIRECTORY}/file-manager`}, - {"path" : `${PLUGIN_DIRECTORY}/webhooks`} + {"path" : `${PLUGIN_DIRECTORY}/webhooks`}, + {"path" : `${PLUGIN_DIRECTORY}/hosted-page-manager`}, + {"path" : `${PLUGIN_DIRECTORY}/core-embeddables`}, + {"path" : `${PLUGIN_DIRECTORY}/initial-state`} + + ]; }; @@ -133,6 +138,7 @@ let getAppConf = function(){ "configPath" : __dirname + "/pluginbot.config.js", "port" : process.env.PORT || 3000, "bundle_path" : process.env.BUNDLE_PATH || "/build/bundle.js", + "vendor_path" : process.env.vendor_path || "/build/vendor.js", "ssl_port" : process.env.SSL_PORT || 3001, "certificate_path" : process.env.CERTIFICATES || null, //ssl not mandatory }; diff --git a/config/redux/actions.js b/config/redux/actions.js index f61b43f7..8a271bcc 100644 --- a/config/redux/actions.js +++ b/config/redux/actions.js @@ -22,7 +22,7 @@ actions.setEventSagas = function(event_sagas){ } actions.setOptions = function(options){ - console.log("SET OPTION!"); + return { type: actions.SET_OPTIONS, options } } diff --git a/config/transporter.js b/config/transporter.js index 865d6456..eff86a72 100644 --- a/config/transporter.js +++ b/config/transporter.js @@ -23,7 +23,7 @@ var transporter = nodemailer.createTransport(smtpConfig); // verify connection configuration transporter.verify(function(error, success) { if (error) { - console.log(error); + console.error(error); } else { console.log("MAILER CONNECTION VERIFIED"); } diff --git a/lib/handleInputs.js b/lib/handleInputs.js index 28f2f9d3..c17c5d87 100644 --- a/lib/handleInputs.js +++ b/lib/handleInputs.js @@ -78,7 +78,16 @@ module.exports = { } } - return (currentPrice - additions)/multiplication; + //make sure not dividing by 0 + if(multiplication === 0){ + multiplication = 1; + } + + let basePrice = (currentPrice - additions)/multiplication; + if(basePrice < 0){ + basePrice = 0; + } + return basePrice; }, getPrice : function(properties, handlers, basePrice, cents=false){ let adjustments = []; @@ -87,7 +96,7 @@ module.exports = { }catch(e){ console.error("price error", e); } - return (basePrice + adjustments.reduce((acc, adjustment) => { + let price = (basePrice + adjustments.reduce((acc, adjustment) => { let operation = adjustment.operation; if(adjustment.value === null || adjustment.value === undefined){ return acc; @@ -111,8 +120,10 @@ module.exports = { } return acc; }, 0)); - - + if(price < 0){ + price = 0; + } + return price; }, validateProperties: function (properties, handlers) { // let handlers = getHandlers(handlerArray); diff --git a/lib/mailer.js b/lib/mailer.js index 5828cfb3..7ef3584e 100644 --- a/lib/mailer.js +++ b/lib/mailer.js @@ -10,15 +10,21 @@ let sendMail = function (address, message, subject) { let company_name = result.filter(option => { return option.data.option == 'company_name' })[0].get("value"); + let from_address = result.filter(option => { + return option.data.option == 'from_address' + })[0]; + if(from_address){ + from_address = from_address.get("value"); + } let mailOptions = { - from: `"${company_name}" <${company_email}>`, // sender address + from: `"${company_name}" <${from_address || company_email}>`, // sender address to: address, // list of receivers subject: subject, // Subject line html: message, // html body text: message // text only body }; - console.log("MAILING!"); - console.log(mailOptions); + + // send mail with defined transport object transporter.sendMail(mailOptions, function (error, info) { if (error) { diff --git a/models/base/entity.js b/models/base/entity.js index f5a74cf2..124fd8b2 100644 --- a/models/base/entity.js +++ b/models/base/entity.js @@ -16,7 +16,7 @@ var whereFilter = require('knex-filter-loopback').whereFilter; * @returns {Entity} */ -module.exports = function (tableName, references = [], primaryKey = 'id', database = knex) { +var CreateEntity = function (tableName, references = [], primaryKey = 'id', database = knex) { var Entity = function (data) { let self = this; this.data = data; @@ -25,7 +25,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa // let reference = references.find(ref => ref.model.table === name); // try { // if (!reference) { - // console.log(name); + // // throw `Reference is not defined on ${Entity.table}.` // } // return await self.getRelated(reference.model) @@ -98,7 +98,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa throw err }); }; - Entity.prototype.create = function (callback) { + let create = function (callback) { let self = this; Entity.database(Entity.table).columnInfo() .then(function (info) { @@ -141,7 +141,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa }; - Entity.prototype.delete = function (callback) { + let deleteE = function (callback) { let id = this.get('id'); Entity.database(Entity.table).where('id', id).del() .then(function (res) { @@ -174,12 +174,12 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa Entity.prototype.createReferences = function (referenceData, reference, callback) { let self = this; if (reference.readOnly) { - console.log("Reference is readonly"); + callback(self); } else { referenceData.forEach(newChild => (newChild[reference.referenceField] = this.get(primaryKey))); - //console.log("referenceDate"); + // //console.log(referenceData); reference.model.batchCreate(referenceData, function (response) { if (reference.direction == "to") { @@ -199,23 +199,30 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa //todo - combine stuff into a single query //todo - possibly dispatch events - Entity.prototype.updateReferences = async function (referenceData, reference) { + Entity.prototype.updateReferences = async function (referenceData, reference, isTransaction=false) { let self = this; if (reference.readOnly) { - console.log("Reference is readonly"); + this; } else { - - // + console.error(referenceData, reference); let ids = referenceData.reduce((acc, refInstance) => acc.concat(refInstance.id || []), []); referenceData.forEach(newChild => (newChild[reference.referenceField] = this.get(primaryKey))); + let references = await this.getRelated(reference.model.table); let removedReferences = await reference.model.batchDelete({ not: {id: {"in": ids}}, [reference.referenceField]: self.get(primaryKey) }); - let upsertedReferences = await reference.model.batchUpdate(referenceData); + + let upsertedReferences = await reference.model.batchUpdate(referenceData, true, isTransaction); + + //change "to" reference if it's different + if(reference.direction === "to" && upsertedReferences[0][reference.model.primaryKey] !== self.get(reference.referenceField)){ + self.set(reference.referenceField, upsertedReferences[0][reference.model.primaryKey]); + await self.update(); + } return upsertedReferences; @@ -236,15 +243,19 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(entities); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; //best one! (todo... clean up ORM cuz it sucks) Entity.find = async function (filter = {}, attatchReferences = false) { try { - let entities = await Entity.database(Entity.table).where(whereFilter(filter)); - return entities ? entities.map(e => new Entity(e)) : []; + let result = await Entity.database(Entity.table).where(whereFilter(filter)); + let entities = result ? result.map(e => new Entity(e)) : []; + if(attatchReferences){ + entities = await Entity.batchAttatchReference(entities); + } + return entities; } catch (err) { console.error(err); return []; @@ -268,7 +279,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(entities); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; @@ -281,7 +292,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(new Entity(result[0])); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; //Generic findById function. Finds the record by passing the id. @@ -294,7 +305,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(new Entity(result[0])); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; @@ -338,7 +349,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(entities); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; @@ -353,7 +364,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(result[0].count); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; @@ -367,7 +378,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(result[0].sum); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; //get objects created between dates @@ -381,7 +392,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(entities); }) .catch(function (err) { - console.log(err); + console.error(err); }); }; @@ -425,9 +436,18 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa for(let reference of Entity.references){ let referenceData = await getReferences(reference, filter); entities = entities.map(entity => { + let entityReferences = referenceData[entity.data[Entity.primaryKey]] || [] + + //todo: maybe come up with a better answer to password stripping... + if(reference.model.table === "users"){ + entityReferences = entityReferences.map(user => { + delete user.password; + return user; + }) + } entity.data["references"] = { ...entity.data["references"], - [reference.model.table] : referenceData[entity.data[Entity.primaryKey]] || [] + [reference.model.table] : entityReferences } return entity; }) @@ -436,7 +456,7 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa }; Entity.batchDelete = async function (filter) { - return knex(Entity.table).where(whereFilter(filter)).del(); + return knex(Entity.table).where(whereFilter(filter)).del().returning("*"); }; /** * @@ -458,40 +478,78 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa callback(result) }) .catch(function (err) { - console.log("WHOAH!"); - console.log(err); + console.error(err); }) }) }; - //TODO this batch update work - let batchUpdate = function (dataArray, callback) { + //TODO: figure out if updateReferences is even needed, if it is figure out how to remove it. + Entity.batchUpdate = async function (dataArray, updateReferences, isTransaction=false) { + let columns = await Entity.database(Entity.table).columnInfo() + let data = dataArray.map(function (entity) { + return _.pick(entity, _.keys(columns)); + }) + let transaction = Entity.database.transaction; + if(isTransaction){ + transaction = async (callback) => { + return callback(Entity.database); + } + } + return await transaction(async function (trx) { + return Promise.map(data, async function (entityData, index) { + let record; + if (entityData[Entity.primaryKey]) { + record = (await trx.from(Entity.table).where(Entity.primaryKey, entityData[Entity.primaryKey]).update(entityData).returning("*"))[0]; + } else { + record = (await trx.from(Entity.table).insert(entityData).returning("*"))[0]; + } + + if(updateReferences && dataArray[index].references){ + record.references = dataArray[index].references; + for(let [refName, refValues] of Object.entries(dataArray[index].references)){ + let reference = references.find(ref => ref.model.table === refName); + if(reference && !reference.readOnly){ + let trxReference = CreateEntity(reference.model.table, reference.model.references, reference.model.primaryKey, trx); + let ids = refValues.reduce((acc, refInstance) => acc.concat(refInstance.id || []), []); + let removedReferences = await trxReference.batchDelete({ + not: {id: {"in": ids}}, + [reference.referenceField]: record[Entity.primaryKey] + }); + let refsToUpdate = refValues.reduce((acc, val) => { + if(val[reference.model.primaryKey]){ + + //make sure that the referenceField is pointing properly + if(reference.direction === "from" && val[reference.referenceField] === record[Entity.primaryKey]){ + acc.push(val); + + }else if(reference.direction === "to" && record[reference.referenceField] === val[reference.model.primaryKey]){ + acc.push(val); + } + }else{ + if(reference.direction === "from"){ + + val[reference.referenceField] = record[Entity.primaryKey]; + acc.push(val); + + } + } + return acc; + }, []); + record.references[reference.model.table] = (await trxReference.batchUpdate(refsToUpdate, true, true)) || []; + - Entity.database(Entity.table).columnInfo() - .then(function (info) { - return dataArray.map(function (entity) { - return _.pick(entity, _.keys(info)); - }) - }) - .then(function (data) { - Entity.database.transaction(function (trx) { - return Promise.map(data, function (entityData) { - if (entityData[Entity.primaryKey]) { - return trx.from(Entity.table).where(Entity.primaryKey, entityData[Entity.primaryKey]).update(entityData).returning("*"); - } else { - return trx.from(Entity.table).insert(entityData).returning("*"); } - }); + } + } - }).then(function (result) { - callback(result); - }).catch(function (err) { - console.log(err); - }) + return record; }); + }); + }; - Entity.batchUpdate = promiseProxy(batchUpdate) Entity.prototype.update = promiseProxy(update, false); + Entity.prototype.delete = promiseProxy(deleteE, false); + Entity.prototype.create = promiseProxy(create, false); Entity.findOne = promiseProxy(findOne); Entity.prototype.attachReferences = promiseProxy(attachReferences); Entity.prototype.getRelated = promiseProxy(getRelated); @@ -500,4 +558,5 @@ module.exports = function (tableName, references = [], primaryKey = 'id', databa return Entity; -} \ No newline at end of file +} +module.exports = CreateEntity; \ No newline at end of file diff --git a/models/charge.js b/models/charge.js index 4e545f9b..7ff74612 100644 --- a/models/charge.js +++ b/models/charge.js @@ -89,7 +89,7 @@ Charge.prototype.cancel = function (callback) { } ], function (err, result) { if(!err){ - console.log(`Charge has been removed! - ${result}`); + callback(result); } else { callback(err); diff --git a/models/event-log.js b/models/event-log.js index e99ba091..4504bb1d 100644 --- a/models/event-log.js +++ b/models/event-log.js @@ -15,8 +15,8 @@ EventLog.logEvent = function (userId, logMessage, logType = 'CORE', logLevel = ' let eventData = EventLog.getLogObj(userId, logMessage, logType, logLevel); let newEvent = new EventLog(eventData); newEvent.create(function(err, result){ - console.log("log created: "); - console.log(result.data); + + }); }; diff --git a/models/invitation.js b/models/invitation.js index 466cdce1..721b891b 100644 --- a/models/invitation.js +++ b/models/invitation.js @@ -11,7 +11,7 @@ Invitation.prototype.create = function (callback) { self.set("token", buffer.toString('hex')); knex('invitations').columnInfo().returning('id').insert(self.data) .then(function(result){ - console.log(self) + self.set("id", result[0]); callback(null, self); }) diff --git a/models/invoice.js b/models/invoice.js index e6927cd0..d8bb641a 100644 --- a/models/invoice.js +++ b/models/invoice.js @@ -12,6 +12,7 @@ let references = [ {"model": Transactions, "referenceField": "invoice_id", "direction":"from"} ]; let Invoice = require("./base/entity")("user_invoices", references); +let store = require("../config/redux/store"); Invoice.prototype.refund = function (amount=null, reason=null, callback) { @@ -66,7 +67,7 @@ Invoice.prototype.sync = function (new_invoice) { }); }); })).then(function () { - console.log('Invoice lines deleted'); + return resolveall('Invoice lines deleted'); }).catch(function (err) { return rejectall(err); @@ -202,16 +203,28 @@ Invoice.insertInvoice = function (raw_invoice, user) { }) }).then(function (invoice) { //Insert all line items - return new Promise(function (resolve, reject) { + return new Promise(async function (resolve, reject) { let reference_data = invoice.data.references; for (let reference of references){ if(reference_data[reference.model.table] && reference_data[reference.model.table].length > 0){ let referenceData = reference_data[reference.model.table]; invoice.createReferences(referenceData, reference, function (modifiedEntity) { - //console.log('Invoice references created!'); + // }); } } + if(invoice.data.amount_due > 0){ + let currMap = require("currency-symbol-map"); + invoice.data.parsed_amount_due = `${currMap(store.getState().options.currency || "USD")}${(invoice.data.amount_due/100).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')}`; + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if(accessManager){ + accessManager = accessManager[0]; + let token = await accessManager.createToken(invoice.data.user_id); + invoice.data.billing_settings_url = accessManager.createLink(invoice.data.user_id, token); + } + store.dispatchEvent("new_invoice", invoice); + } + // invoice = await invoice.attachReferences(); return resolve(invoice); }); }); diff --git a/models/notification-template.js b/models/notification-template.js index 3bcc16bb..a4d9c05e 100644 --- a/models/notification-template.js +++ b/models/notification-template.js @@ -21,7 +21,7 @@ NotificationTemplate.prototype.getRoles = function (callback) { }).then(function (result) { callback(result.map(p => new Role(p))); }).catch(function (err) { - console.log(err); + console.error(err); }) }; @@ -39,11 +39,15 @@ NotificationTemplate.prototype.setRoles = function (roleIds, callback) { NotificationTemplate.prototype.build = function (map, callback) { let parseTemplate = function (match, replaceString, offset, string) { let splitStr = replaceString.split("."); - if (splitStr.length > 1) { + if (splitStr.length > 1 && splitStr[0] != "properties") { splitStr[1] += "[0]"; replaceString = splitStr.join("."); } - return _.get(map, replaceString); + let result = _.get(map, replaceString, ""); + if( (typeof result === "object") && (result !== null) ){ + result = JSON.stringify(result); + } + return result }; const regex = /\[\[([\w, \.]+)]]/gm; @@ -57,7 +61,7 @@ NotificationTemplate.prototype.build = function (map, callback) { let createNotifications = function(recipients, message, subject, notificationTemplate){ if(notificationTemplate.get('create_notification')) { - console.log("CREATING A NOTIFICATION!"); + return Promise.all(recipients.map(recipient => { return new Promise((resolve, reject) => { let notificationAttributes = { @@ -69,14 +73,14 @@ let createNotifications = function(recipients, message, subject, notificationTem let newNotification = new Notification(notificationAttributes); newNotification.create(function (err, notification) { if (!err) { - console.log("notification created: " + notification.get("id")); + return resolve(notification); } else { return reject(err); } }); }).catch(e => { - console.log('error when creating notification: ', e) + console.error('error when creating notification: ', e) }) })) } @@ -91,15 +95,16 @@ let createEmailNotifications = function(recipients, message, subject, notificati let additionalRecipients = notificationTemplate.get('additional_recipients'); let emailArray = recipients.map(recipient => recipient.get('email')); emailArray = _.union(emailArray, additionalRecipients); - console.log("email array") - console.log(emailArray) + + return Promise.all(emailArray.map(email => { return new Promise(resolve => { + console.log("sending email"); mailer(email, message, subject); return resolve(); }) })).catch(e => { - console.log("error sending email notifications", e) + console.error("error sending email notifications", e) }) } else{ @@ -145,7 +150,7 @@ let getNotificationContents = function(template, targetObject){ return new Promise(function (resolve, reject) { //Build Message and Subject from template template.build(updatedObject, function (message, subject) { - console.log("Built Notification message") + return resolve({message: message, subject: subject}) }); }); diff --git a/models/payment-structure-template.js b/models/payment-structure-template.js new file mode 100644 index 00000000..574ab032 --- /dev/null +++ b/models/payment-structure-template.js @@ -0,0 +1,8 @@ +let references = [ {"model": require("./base/entity")("tiers"), "referenceField": "tier_id", "direction": "to", "readOnly": true}]; + +let PaymentStructureTemplate = require("./base/entity")("payment_structure_templates",references); + + +//Notification.createFromTemplate() + +module.exports = PaymentStructureTemplate; \ No newline at end of file diff --git a/models/permission.js b/models/permission.js index 8d503711..9a315076 100644 --- a/models/permission.js +++ b/models/permission.js @@ -19,12 +19,12 @@ Permission.prototype.delete = function (callback) { knex('roles_to_permissions').where('permission_id', id).del() .then(callback()) .catch(function(err){ - console.log(err); + console.error(err); }); knex('user_permissions').where('id', id).del() .then(callback()) .catch(function(err){ - console.log(err); + console.error(err); }); }; @@ -35,11 +35,10 @@ Permission.findByName = function (name, callback) { if(!result){ result = []; } - console.log(result); callback(new Permission(result[0])) }) .catch(function(err){ - console.log(err); + console.error(err); }); }; diff --git a/models/role.js b/models/role.js index d99ede78..f92b224c 100644 --- a/models/role.js +++ b/models/role.js @@ -49,7 +49,7 @@ Role.prototype.assignPermission = function (permissions, callback) { callback(self); }) .catch(function(err){ - console.log("error creating : " + err); + console.error("error creating : " + err); }); }; @@ -79,7 +79,7 @@ let getPermissions = function(callback){ }).then(function(result){ callback(result.map(p => new Permission(p))); }).catch(function(err){ - console.log(err); + console.error(err); }) }; @@ -106,11 +106,11 @@ Role.prototype.hasPermission = function (permission, callback) { } let permissionId = permissionEntity.get('id'); - console.log("roleid: " + roleId + " permissionId :" + permissionId); + knex('roles_to_permissions').where('role_id', roleId).andWhere('permission_id', permissionId) .then(function (result) { - //console.log(result); + // if (result.length > 0) { callback(true); } @@ -119,7 +119,7 @@ Role.prototype.hasPermission = function (permission, callback) { } }) .catch(function (err) { - console.log(err); + console.error(err); }); }); @@ -140,7 +140,7 @@ Role.findByName = function (name, callback) { callback(new Role(result[0])) }) .catch(function(err){ - console.log(err); + console.error(err); }); }; diff --git a/models/service-instance-property.js b/models/service-instance-property.js index 2a958d08..8722e115 100644 --- a/models/service-instance-property.js +++ b/models/service-instance-property.js @@ -15,7 +15,7 @@ InstanceProperty.getByTemplateId = function(templateId, callback){ callback(entities); }) .catch(function(err){ - console.log(err); + console.error(err); }); }); diff --git a/models/service-instance.js b/models/service-instance.js index a65d3615..c4159c96 100644 --- a/models/service-instance.js +++ b/models/service-instance.js @@ -2,6 +2,8 @@ let File = require("./file"); let async = require('async'); let ServiceTemplates = require("./service-template"); +let Tier = require("./tier"); +let PaymentStructureTemplate = require("./payment-structure-template"); let ServiceTemplateProperties = require("../models/service-template-property"); let ServiceInstanceProperties = require("./service-instance-property"); let ServiceInstanceMessages = require("./service-instance-message"); @@ -12,9 +14,12 @@ let store = require("../config/redux/store"); let promisify = require("bluebird").promisify; let promisifyProxy = require("../lib/promiseProxy"); let User = require('./user'); +let schedule = require("node-schedule"); let _ = require("lodash"); let references = [ + {"model": ServiceTemplates, "referenceField": "service_id", "direction": "to", "readOnly": true}, {"model": ServiceInstanceProperties, "referenceField": "parent_id", "direction": "from", "readOnly": true}, + {"model": require('./base/entity')("service_instance_seats", []), "referenceField":"service_instance_id", "direction": "from", "readOnly" : true}, {"model": ServiceInstanceMessages, "referenceField": "service_instance_id", "direction": "from", "readOnly": true}, {"model": ServiceInstanceCharges, "referenceField": "service_instance_id", "direction": "from", "readOnly": true}, { @@ -23,7 +28,14 @@ let references = [ "direction": "from", "readOnly": true }, - {"model": User, "referenceField": "user_id", "direction": "to", "readOnly": true} + {"model": User, "referenceField": "user_id", "direction": "to", "readOnly": true}, + { + "model": PaymentStructureTemplate, + "referenceField": "payment_structure_template_id", + "direction": "to", + "readOnly": true + } + ]; let ServiceInstance = require("./base/entity")("service_instances", references); let Stripe = require('../config/stripe'); @@ -35,7 +47,8 @@ let buildPayStructure = function (payment_object, callback) { let plan_arr = ['name', 'amount', 'currency', 'interval', 'interval_count', 'statement_descriptor', 'trial_period_days']; let random_code = Math.random().toString(36).substring(10, 12) + Math.random().toString(36).substring(10, 12); let default_plan = { - 'id': `${payment_object.name.replace(/ +/g, '-')}-ID${self.get("id")}-${random_code}`, + 'name' : "servicebot-subscription", + 'id': `${(payment_object.name || "sb-subscription").replace(/ +/g, '-')}-ID${self.get("id")}-${random_code}`, 'currency': 'usd', 'interval': 'month', 'interval_count': 1, @@ -47,17 +60,17 @@ let buildPayStructure = function (payment_object, callback) { if (plan.amount === null) { plan.amount = 0; } - plan.statement_descriptor = plan.statement_descriptor.substring(0, 22); - console.log(plan); - + plan.statement_descriptor = (plan.statement_descriptor || "Subscription").substring(0, 22); callback(plan); }; ServiceInstance.prototype.createPayPlan = async function (plan = null) { if (plan === null) { - let template = (await ServiceTemplates.find({"id": this.data.service_id}))[0]; - plan = await this.buildPayStructure(template.data); + let paymentStructure = (await PaymentStructureTemplate.find({id: this.data.payment_structure_template_id}))[0]; + + // let template = (await ServiceTemplates.find({"id": this.data.service_id}))[0]; + plan = await this.buildPayStructure({...paymentStructure.data, name:this.data.name}); } if (plan.trial_period_days === null) { plan.trial_period_days = 0; @@ -69,7 +82,7 @@ ServiceInstance.prototype.createPayPlan = async function (plan = null) { } catch (error) { try { this.data.payment_plan = await Stripe().connection.plans.create(plan); - }catch(error){ + } catch (error) { this.data.status = "missing_payment"; await this.update() throw error; @@ -83,27 +96,33 @@ ServiceInstance.prototype.deletePayPlan = async function () { let self = this; if (self.data.payment_plan.id) { //Remove the plan from Stripe - await Stripe().connection.plans.del(self.data.payment_plan.id); + try { + await Stripe().connection.plans.del(self.data.payment_plan.id); + }catch(e){ + console.error("Error deleting payment plan", e); + } self.data.payment_plan = null; return await self.update() } else { - throw('Service is has no current payment plan!'); + return self; + // throw('Service is has no current payment plan!'); } }; -ServiceInstance.prototype.subscribe = async function (paymentPlan=null) { +ServiceInstance.prototype.subscribe = async function (paymentPlan = null) { let self = this; if (self.data.subscription_id) { throw "Instance is already subscribed" } - if(paymentPlan){ - self = await this.changePaymentPlan(paymentPlan); - } let user = (await User.find({"id": self.data.user_id}))[0]; if (user && user.data.status === "suspended") { throw "User is suspended, unable to subscribe" } + + if (paymentPlan) { + self = await this.changePaymentPlan(paymentPlan); + } let sub_obj = { "customer": user.data.customer_id, "plan": self.data.payment_plan.id @@ -134,16 +153,16 @@ let requestCancellation = function (callback) { "service_instance_id": self.data.id, "user_id": self.data.user_id }; - if(approve_cancellation){ + if (approve_cancellation) { cancellationData.status = "approved" } let newServiceCancellation = new ServiceInstanceCancellations(cancellationData); newServiceCancellation.create(async function (err, result) { //Update the service instance status - if(approve_cancellation){ + if (approve_cancellation) { let unsub = await self.unsubscribe() callback(result); - }else { + } else { self.data.status = "waiting_cancellation"; self.update(function (err, updated_instance) { callback(result); @@ -229,7 +248,7 @@ let deleteFiles = function (callback) { ServiceInstance.prototype.changeProperties = async function (properties) { let updatedInstance = await this.attachReferences(); - let oldInstance = {data : {...updatedInstance.data}} + let oldInstance = {data: {...updatedInstance.data}}; //todo: support creating new properties, shouldn't be bad... just need to validate the config if (properties.some(prop => prop.id === null || prop.parent_id !== updatedInstance.get("id"))) { throw "prop id bad or parent id does not match" @@ -240,15 +259,22 @@ ServiceInstance.prototype.changeProperties = async function (properties) { lifecycleManager = lifecycleManager[0]; await lifecycleManager.prePropertyChange({ instance: updatedInstance, - property_updates : properties + property_updates: properties }); } + let paymentStructure = (await PaymentStructureTemplate.find({id : updatedInstance.data.payment_structure_template_id}, true))[0]; - let mergedProps = oldProperties.map(prop => { + let metricIndexToUnprice = null; + let mergedProps = oldProperties.map((prop, index) => { let propToMerge = properties.find(reqProp => reqProp.id === prop.id); - return propToMerge ? {...prop, "data": propToMerge.data} : prop + let finalProp = propToMerge ? {...prop, "data": propToMerge.data} : prop + if(finalProp.type === "metric"){ + if(!finalProp.config.pricing.tiers.includes(paymentStructure.data.references.tiers[0].name)) { + metricIndexToUnprice = index + } + } + return finalProp; }); - if (this.get("type") === "subscription") { let paymentPlan = this.get("payment_plan"); if (paymentPlan === null || paymentPlan.amount === null) { @@ -258,17 +284,27 @@ ServiceInstance.prototype.changeProperties = async function (properties) { acc[handler.name] = handler.handler; return acc; }, {}); - let basePrice = require("../lib/handleInputs").getBasePrice(oldProperties, handlers, paymentPlan.amount); - let newPrice = require("../lib/handleInputs").getPrice(mergedProps, handlers, basePrice); + let baseProps = [...oldProperties]; + let newProps = [...mergedProps]; + if(metricIndexToUnprice !== null){ + baseProps.splice(metricIndexToUnprice, 1); + newProps.splice(metricIndexToUnprice, 1); + } + + let basePrice = require("../lib/handleInputs").getBasePrice(baseProps, handlers, paymentPlan.amount); + if(basePrice === 0){ + basePrice = this.data.references.payment_structure_templates[0].amount; + } + let newPrice = require("../lib/handleInputs").getPrice(newProps, handlers, basePrice); paymentPlan.amount = newPrice; updatedInstance = await this.changePaymentPlan(paymentPlan, true); } } let updatedProps = await ServiceInstanceProperties.batchUpdate(mergedProps); if (lifecycleManager) { - await updatedInstance.attachReferences() + await updatedInstance.attachReferences(); await lifecycleManager.postPropertyChange({ - old_instance : oldInstance, + old_instance: oldInstance, instance: updatedInstance, }); } @@ -276,28 +312,144 @@ ServiceInstance.prototype.changeProperties = async function (properties) { return updatedInstance; }; -ServiceInstance.prototype.changePaymentPlan = async function (newPlan, ignorePlanTrial) { +ServiceInstance.prototype.applyPaymentStructure = async function (paymentStructureId, ignoreTrial) { + let instance_object = await this.attachReferences(); + let {payment_plan, references : {service_instance_properties, payment_structure_templates}} = instance_object.data; + let currentStructure = payment_structure_templates[0]; + let handlers = (store.getState(true).pluginbot.services.inputHandler || []).reduce((acc, handler) => { + acc[handler.name] = handler.handler; + return acc; + }, {}); + + if (!currentStructure) { + throw "Instance has no payment structure"; + } + + let paymentStructureTemplate = (await PaymentStructureTemplate.find({id: paymentStructureId}))[0]; + if (!paymentStructureTemplate) { + throw "Payment Structure Not Found"; + + } + + let tier = (await Tier.find({ + service_template_id: instance_object.data.service_id, + id: paymentStructureTemplate.data.tier_id + }))[0]; + if (!tier) { + throw "Incompatible Payment Structure"; + } + + let lifecycleManager = store.getState(true).pluginbot.services.lifecycleManager; + if (lifecycleManager) { + lifecycleManager = lifecycleManager[0]; + await lifecycleManager.prePaymentStructureChange({ + instance: instance_object, + payment_structure_template: paymentStructureTemplate, + }); + } + let applicableProperties = service_instance_properties.filter(property => { + if(property.config && property.config.pricing && property.config.pricing.tiers){ + return property.config.pricing.tiers.includes(tier.data.name); + }else{ + return true; + } + }); + let newPrice = require("../lib/handleInputs").getPrice(applicableProperties, handlers, paymentStructureTemplate.data.amount); + + let paymentPlan = { + ...paymentStructureTemplate.data, + name : tier.data.name + "-" + paymentStructureTemplate.data.id, + amount : newPrice + }; + + + let newInstance = await (await instance_object.changePaymentPlan(paymentPlan, ignoreTrial)).attachReferences(); + newInstance.data.payment_structure_template_id = paymentStructureId; + await newInstance.update(); + + if (lifecycleManager) { + let response = await lifecycleManager.postPaymentStructureChange({ + old_instance: instance_object, + instance: newInstance + }); + if (response) { + newInstance.data = { + ...newInstance.data, + ...response + } + } + } + return newInstance; + + +}; + +ServiceInstance.prototype.changePaymentPlan = async function (newPlan, ignorePlanTrial, disableProration) { await this.deletePayPlan(); let planStructure = await this.buildPayStructure(newPlan); let updatedInstance = await this.createPayPlan(planStructure); - if(this.data.subscription_id !== null) { - let payload = {plan: updatedInstance.data.payment_plan.id} - if(ignorePlanTrial){ + if (this.data.subscription_id !== null) { + let payload = {plan: updatedInstance.data.payment_plan.id}; + if (ignorePlanTrial || newPlan.trial_period_days == null) { payload.trial_from_plan = false; } + if(disableProration){ + payload.prorate = false; + } let stripeSubscription = await Stripe().connection.subscriptions.update(this.data.subscription_id, payload); let oldTrial = updatedInstance.data.trial_end; - updatedInstance.data.trial_end = stripeSubscription.trial_end - if(oldTrial !== stripeSubscription.trial_end){ - + updatedInstance.data.trial_end = stripeSubscription.trial_end; + // if (newPlan.id) { + // updatedInstance.data.payment_structure_template_id = newPlan.id + // } + if (oldTrial !== stripeSubscription.trial_end) { + updatedInstance = await updatedInstance.update() //todo: handle this better, don't like dispatching here. store.dispatchEvent("service_instance_trial_change", updatedInstance); } + } - updatedInstance.data.type = updatedInstance.data.payment_plan.amount > 0 ? "subscription" : "custom"; - return await updatedInstance.update(); + // updatedInstance.data.type = updatedInstance.data.payment_plan.amount > 0 ? "subscription" : "custom"; + return updatedInstance; }; +ServiceInstance.prototype.getSubscription = async function(){ + return await Stripe().connection.subscriptions.retrieve(this.data.subscription_id); +} +ServiceInstance.prototype.finishCancellation = async function (){ + let current = (await ServiceInstance.find({id: this.data.id}))[0]; + if(current.data.status === "cancellation_pending"){ + await current.unsubscribe(); + } +} +ServiceInstance.prototype.scheduleCancellation = async function(endDate){ + let subscription = await this.getSubscription(); + console.log(subscription); + if(subscription && subscription.status !== "canceled"){ + if(endDate){ + + }else{ + endDate = new Date(subscription.current_period_end * 1000); + await Stripe().connection.subscriptions.update(this.data.subscription_id, {cancel_at_period_end: true}); + this.data.status = "cancellation_pending"; + await this.update(); + console.log("scheduling canellation for ", endDate); + var job = schedule.scheduleJob(endDate, this.finishCancellation.bind(this)); + let lifecycleManager = store.getState(true).pluginbot.services.lifecycleManager; + if (lifecycleManager) { + lifecycleManager = lifecycleManager[0]; + await lifecycleManager.postCancellationPending({ + instance: this, + end_date: endDate + }) + } + return this.data; + + } + }else{ + this.unsubscribe(); + } +} ServiceInstance.prototype.unsubscribe = async function () { try { let lifecycleManager = store.getState(true).pluginbot.services.lifecycleManager; @@ -309,7 +461,16 @@ ServiceInstance.prototype.unsubscribe = async function () { } if (this.data.subscription_id) { //Remove the subscription from Stripe - await Stripe().connection.subscriptions.del(this.data.subscription_id); + try { + await Stripe().connection.subscriptions.del(this.data.subscription_id); + }catch(e){ + if(e.code === "resource_missing") { + console.log("Missing stripe subscription to delete, continuing"); + }else{ + console.error(e); + throw e + } + } } this.data.subscription_id = null; this.data.status = "cancelled"; @@ -327,7 +488,7 @@ ServiceInstance.prototype.unsubscribe = async function () { console.error(error); throw error; } -} +}; //todo: clean this up so they really support promises. diff --git a/models/service-template.js b/models/service-template.js index 9bb10f53..0226a2d9 100644 --- a/models/service-template.js +++ b/models/service-template.js @@ -3,6 +3,8 @@ let ServiceCategory = require('./service-category'); let ServiceInstance = require('./service-instance'); let User = require('./user'); let File = require("./file"); +let Tier = require("./tier"); +let PaymentStructureTemplate = require("./payment-structure-template"); let Charges = require("./charge"); @@ -10,7 +12,8 @@ let Charges = require("./charge"); let references = [ {"model":ServiceTemplateProperty, "referenceField": "parent_id", "direction":"from", "readOnly":false}, {"model":ServiceCategory, "referenceField": "category_id", "direction":"to", "readOnly":true}, - {"model":User, "referenceField": "created_by", "direction":"to", "readOnly": true} + {"model":User, "referenceField": "created_by", "direction":"to", "readOnly": true}, + {"model" :Tier, "referenceField": "service_template_id", "direction" : "from", "readOnly" : false} ]; var ServiceTemplate = require("./base/entity")("service_templates", references); ServiceTemplate.iconFilePath = "uploads/templates/icons"; @@ -22,6 +25,7 @@ ServiceTemplate.prototype.requestPromise = async function (instanceRequest) { let service_user_id = ""; let service_description = self.data.description; let service_name = self.data.name; + let paymentStructure = (await PaymentStructureTemplate.find({id: instanceRequest.payment_structure_template_id}))[0] if (self.data.detail) { //todo : strip out XSS @@ -34,32 +38,31 @@ ServiceTemplate.prototype.requestPromise = async function (instanceRequest) { requested_by: instanceRequest.requested_by, user_id: instanceRequest.user_id, service_id: self.get("id"), - type: self.get("type"), - split_configuration : self.get("split_configuration"), - status : "requested" + type: paymentStructure.get("type"), + split_configuration : paymentStructure.get("split_configuration"), + status : "requested", + payment_structure_template_id: paymentStructure.data.id }; - let submittedProperties = instanceRequest.references.service_template_properties; let ServiceInstance = require('../models/service-instance'); let service = new ServiceInstance(await ServiceInstance.createPromise(instanceAttributes)); let props = await service.generateProps(submittedProperties); - if (self.data.type === 'one_time') { + if (paymentStructure.data.type === 'one_time') { let charge_obj = { 'user_id': service.get('user_id'), 'service_instance_id': service.get('id'), - 'currency': self.get('currency'), - 'amount': instanceRequest.amount || self.get('amount') || 0, + 'currency': paymentStructure.get('currency'), + 'amount': instanceRequest.amount || paymentStructure.get('amount') || 0, 'description': service.get('name') }; let charge = await Charges.createPromise(charge_obj); } - let plan = (self.data.type === 'one_time' || self.data.type === 'custom' || self.data.type === "split") ? {...self.data, amount : 0, interval : "day"} : instanceRequest; - let payStructure = (instanceRequest.amount === 0 || instanceRequest.amount === undefined) ? null : (await service.buildPayStructure(plan)); + let plan = (paymentStructure.data.type === 'one_time' || paymentStructure.data.type === 'custom' || paymentStructure.data.type === "split") ? {...paymentStructure.data, amount : 0, interval : "day"} : {...paymentStructure.data, ...instanceRequest}; + let payStructure = ((instanceRequest.amount === 0 && paymentStructure.data.type !== "subscription") || instanceRequest.amount === undefined) ? null : (await service.buildPayStructure(plan)); let payPlan = await service.createPayPlan(payStructure); - - if (instanceAttributes.requested_by === instanceAttributes.user_id) { - await service.subscribe(); - } + // if (instanceAttributes.requested_by === instanceAttributes.user_id) { + await service.subscribe(); + // } return service; }catch(e){ diff --git a/models/tier.js b/models/tier.js new file mode 100644 index 00000000..dd50abb7 --- /dev/null +++ b/models/tier.js @@ -0,0 +1,9 @@ +let PaymentStructureTemplate = require("./payment-structure-template"); +let references = [ + {"model" :PaymentStructureTemplate, "referenceField": "tier_id", "direction" : "from", "readOnly" : false} +]; + +let Tier = require("./base/entity")("tiers", references); + + +module.exports = Tier; \ No newline at end of file diff --git a/models/user.js b/models/user.js index f93a48cb..649692dd 100644 --- a/models/user.js +++ b/models/user.js @@ -6,6 +6,8 @@ let Fund = require('./fund'); let promisifyProxy = require("../lib/promiseProxy"); let references = [ {"model": Role, "referenceField": "role_id", "direction": "to", "readOnly": true}, + {"model": require('./base/entity')("service_instances", []), "referenceField":"user_id", "direction": "from", "readOnly" : true}, + {"model": require('./base/entity')("service_instance_seats", []), "referenceField":"user_id", "direction": "from", "readOnly" : true}, {"model": Fund, "referenceField": "user_id", "direction": "from", "readOnly": true} ]; let User = require('./base/entity')("users", references); diff --git a/package.json b/package.json index ca7620fe..5ae1205c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "servicebot", - "version": "0.9.11", + "version": "0.11.163", "license": "GPL-3.0", "scripts": { "start": "node ./bin/start", @@ -8,7 +8,8 @@ "dev-client": "./node_modules/.bin/webpack-dev-server --port 3002 --content-base public/", "fullStart": "./node_modules/.bin/webpack && node ./bin/start", "debug": "node $NODE_DEBUG_OPTION ./bin/start", - "test": "jest" + "test": "jest", + "linked": "npm-list-linked" }, "repository": { "type": "git", @@ -16,13 +17,6 @@ }, "dependencies": { "async": "^2.5.0", - "babel": "^6.23.0", - "babel-core": "^6.26.0", - "babel-loader": "^6.4.1", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-plugin-transform-runtime": "^6.23.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", "bcryptjs": "^2.4.3", "body-parser": "^1.18.2", "chart.js": "^2.7.0", @@ -30,12 +24,8 @@ "connect-session-knex": "^1.4.0", "cookie-parser": "^1.4.3", "crypto": "0.0.3", - "css-loader": "^0.26.4", "currency-symbol-map": "^4.0.4", - "datatables.net": "^2.1.1", - "datatables.net-bs": "^2.1.1", "debug": "^2.6.9", - "dollars-to-cents": "^1.0.3", "dotenv": "^4.0.0", "express": "^4.16.1", "express-handlebars": "^3.0.0", @@ -43,6 +33,7 @@ "fetch-retry": "^1.2.1", "form-data": "^2.3.1", "glob": "^7.1.2", + "globalize": "^1.4.0", "helmet": "^3.9.0", "http": "0.0.0", "immutability-helper": "^2.4.0", @@ -57,42 +48,45 @@ "mkdirp": "^0.5.1", "morgan": "^1.9.0", "multer": "^1.3.0", + "mustache": "^3.0.1", "node-fetch": "^2.1.2", "node-schedule": "^1.2.5", "nodemailer": "^2.7.2", - "npm": "^4.6.1", "object.values": "^1.0.4", "passport": "^0.3.2", + "passport-custom": "^1.0.5", "passport-jwt": "^2.2.1", "passport-local": "^1.0.0", "pg": "^6.4.2", - "pluginbot": "^0.2.0", - "pluginbot-react": "^0.1.1", + "pluginbot": "^0.2.3", + "pluginbot-react": "^0.1.2", "promise-polyfill": "^6.0.2", - "prop-types": "^15.6.0", - "react": "^15.6.2", - "react-addons-css-transition-group": "^15.6.2", + "prop-types": "^15.6.2", + "react": "^16.4.0", "react-bootstrap-table": "^4.1.1", "react-breadcrumbs": "^1.6.6", "react-chartjs2": "^1.1.2", "react-collapsible": "^2.0.3", "react-color": "^2.13.8", "react-cookie": "^1.0.5", - "react-currency-input": "^1.3.4", + "react-copy-to-clipboard": "^5.0.1", "react-currency-masked-input": "^2.1.0", - "react-dom": "^15.6.2", + "react-dom": "^16.4.0", + "react-dragscroll": "^2.0.1", "react-ga": "^2.3.5", + "react-loadable": "^5.4.0", "react-multistep": "^2.2.12", + "react-number-format": "^3.4.2", "react-redux": "^5.0.6", "react-router": "^3.2.0", "react-router-redux": "^4.0.8", "react-s-alert": "^1.3.1", - "react-stepzilla": "^4.6.3", "react-sticky": "^6.0.2", "react-stripe-elements": "^1.2.0", + "react-syntax-highlighter": "^7.0.4", "react-tagsinput": "^3.19.0", - "react-tinymce": "^0.6.0", "react-tooltip": "^3.3.1", + "react-transition-group": "^1.2.1", "redux": "^3.7.2", "redux-form": "^7.1.0", "redux-form-validators": "^2.0.1", @@ -104,24 +98,40 @@ "semver-sort": "0.0.4", "serve-favicon": "^2.5.0", "server-destroy": "^1.0.1", + "servicebot-base-form": "0.0.50", + "servicebot-billing-settings-embed": "^0.2.105", + "servicebot-checkout-embed": "^0.2.119", "slug": "^0.9.1", "stripe": "^4.25.0", "style-loader": "^0.13.2", "swagger-jsdoc": "^1.9.7", "underscore": "^1.8.3", "wait-for-port": "0.0.2", - "webpack": "^3.8.1", "whatwg-fetch": "^2.0.4", "xss": "^0.3.4" }, "devDependencies": { + "babel": "^6.23.0", + "babel-core": "^6.26.0", + "babel-loader": "^6.4.1", "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "css-loader": "^0.26.4", + "grunt": "^1.0.3", + "grunt-contrib-sass": "^1.0.0", + "grunt-contrib-watch": "^1.1.0", "jest": "^22.4.3", - "react-hot-loader": "^3.0.0-beta.7", + "node-sass": "^4.9.0", + "react-hot-loader": "^4.0.1", + "react-to-print": "^2.0.0-alpha-6", + "sass-loader": "^7.0.3", "servicebot-client": "^1.0.3", "supertest": "^3.0.0", - "tape": "^4.8.0", "uglifyjs-webpack-plugin": "^1.2.4", + "webpack": "^3.12.0", "webpack-dev-server": "^1.14.1" } } diff --git a/plugins/analytics/analytics.js b/plugins/analytics/analytics.js index 0b72787f..2c06db98 100644 --- a/plugins/analytics/analytics.js +++ b/plugins/analytics/analytics.js @@ -6,20 +6,66 @@ let serviceInstanceCancellation = require("../../models/service-instance-cancell let serviceInstanceProperty = require("../../models/service-instance-property"); let serviceTemplate = require("../../models/service-template"); let transaction = require("../../models/transaction"); -let invoice = require("../../models/invoice") +let invoice = require("../../models/invoice"); let user = require("../../models/user"); let fund = require("../../models/fund"); let webhook = require("../../models/base/entity")("webhooks"); let properties = require("../../models/system-options"); + + +//Reusable functions +let getARR = function (payPlan) { + let arr = 0; + //Build the logic for ARR & MRR + if(payPlan) { + if(payPlan.interval === 'day') { + arr += (payPlan.amount * (365/payPlan.interval_count)); + } else if(payPlan.interval === 'week') { + arr += (payPlan.amount * (52/payPlan.interval_count)); + } else if(payPlan.interval === 'month') { + arr += (payPlan.amount * (12/payPlan.interval_count)); + } else if(payPlan.interval === 'year') { + arr += (payPlan.amount / (payPlan.interval_count)); + } + } + return arr; +}; +let getFunding = function (users, funds, instance) { + let fundingData = { + hasFunding : false, + fundingCount : 0, + flagged : false, + flagCount : 0 + }; + //Check if account is paid + let fundAvailable = funds.filter(card => card.data.user_id === instance.data.user_id); + let user = users.filter(user => user.data.id === instance.data.user_id); + if(fundAvailable.length > 0){ + //if(user.length > 0 && user[0].data.status !== 'flagged') { + if(user.length > 0) { + fundingData.hasFunding = true; + fundingData.fundingCount++; + } + if(user.length > 0 && user[0].data.status === 'flagged') { + fundingData.flagged = true; + fundingData.flagCount++; + } + } + return fundingData; +} + module.exports = { getAnalyticsData: () => { return new Promise(async (resolve, reject) => { let props = (await properties.find()).reduce((acc, prop) => {acc[prop.data.option] = prop.data.value; return acc;}, {}); let users = (await user.find()); + let funds = (await fund.find()); let templates = (await serviceTemplate.find()); let instances = (await serviceInstance.find()); let charges = (await charge.find()); + let transactions = (await transaction.find()); + let invoices = (await invoice.find()); async.parallel({ customerStats: function (callback) { let stats = {}; @@ -35,24 +81,19 @@ module.exports = { }, offeringStats: function (callback) { let stats = {}; - stats.totalSubscription = stats.totalOneTime = stats.totalSplit = stats.totalQuote = 0; stats.total = templates.length; - templates.map(template => { - if(template.data.type === 'subscription') { stats.totalSubscription++; } - else if(template.data.type === 'one_time') { stats.totalOneTime++; } - else if(template.data.type === 'split') { stats.totalSplit++; } - else if(template.data.type === 'custom') { stats.totalQuote++; } - }); callback(null, stats); }, salesStats: function (callback) { let stats = {}; - let activeSales = requested = waitingCancellation = cancelled = 0; + let activeSales = requested = waitingCancellation = cancelled = subCancelled = 0; let usersWithActiveOffering = []; - let subActive = subAnnual = subMonth = subTotalCharges = subPaidCharges = subPayAnnually = subPayMonthly = subPayWeekly = subPayDaily = 0; + let arr = arrForecast = 0; + let inTrial = inTrialPaying = inPaying = inFlagged = inPayingCancelled = 0; + let subActive = subAnnual = subTotalCharges = subPaidCharges = 0; let singleActive = singleAllCharges = singleApproved = singleWaiting = 0; - let splitActive = splitTotalNum = splitTotalAmt = splitPaidNum = splitPaidAmt = 0; let customActive = customTotalAmt = customTotalPaidAmt = 0; + let allCharges = allChargesApproved = 0; instances.map(instance => { //Currently most analytical data is from the active instances. if(instance.data.subscription_id !== null) { @@ -61,58 +102,60 @@ module.exports = { if(instance.data.type === 'subscription') { subActive++; let payPlan = instance.data.payment_plan; - //Build the logic for ARR & MRR - if(payPlan) { - if(payPlan.interval === 'day') { - subPayDaily++; - subAnnual += (payPlan.amount * (365/payPlan.interval_count)); - } else if(payPlan.interval === 'week') { - subPayWeekly++; - subAnnual += (payPlan.amount * (52/payPlan.interval_count)); - } else if(payPlan.interval === 'month') { - subPayMonthly++; - subAnnual += (payPlan.amount * (12/payPlan.interval_count)); - } else if(payPlan.interval === 'year') { - subPayAnnually++; - subAnnual += (payPlan.amount / (payPlan.interval_count)); - } + let trial = instance.data.payment_plan.trial_period_days; + let trialEnd = instance.data.trial_end; + //Get forecast ARR + arrForecast += getARR(payPlan); + let currentDate = new Date(); + let trialEndDate = new Date(trialEnd * 1000); + let userFunding = getFunding(users, funds, instance); + //If user is paying, then add to ARR + if(userFunding.fundingCount > 0) { + arr += getARR(payPlan); } - } - else if(instance.data.type === 'one_time') { singleActive++; } - else if(instance.data.type === 'split') { - splitActive++; - if(instance.data.split_configuration && instance.data.split_configuration.splits.length > 0) { - splitTotalNum += instance.data.split_configuration.splits.length; - instance.data.split_configuration.splits.map(split => { - splitTotalAmt += split.amount; - }); + //Service is trialing if the expiration is after current date + if(trial > 0 && currentDate < trialEndDate) { + inTrial++; + inTrialPaying += userFunding.fundingCount; } + //Check if account is paid + inPaying += userFunding.fundingCount; + inFlagged += userFunding.flagCount; } + else if(instance.data.type === 'one_time') { singleActive++; } else if(instance.data.type === 'custom') { customActive++; } } - charges.map(charge => { - if(instance.data.id === charge.data.service_instance_id) { - if(instance.data.type === 'one_time') { - singleAllCharges += charge.data.amount; - if(charge.data.item_id !== null) { singleApproved += charge.data.amount; } - else { singleWaiting += charge.data.amount; } - } else if(instance.data.subscription_id !== null && instance.data.type === 'split') { - splitPaidNum ++; - splitPaidAmt += charge.data.amount; - } else if(instance.data.subscription_id !== null && instance.data.type === 'custom') { - customTotalAmt += charge.data.amount; - if(charge.data.item_id !== null) { customTotalPaidAmt += charge.data.amount; } - } else if(instance.data.subscription_id !== null && instance.data.type === 'subscription') { - subTotalCharges += charge.data.amount; - if(charge.data.item_id !== null) { subPaidCharges += charge.data.amount; } - } - } - }); //Check for types if(instance.data.status === 'requested') { requested++; } else if(instance.data.status === 'waiting_cancellation') { waitingCancellation++; } - else if(instance.data.status === 'cancelled') { cancelled++; } + else if(instance.data.status === 'cancelled') { + cancelled++; + if(instance.data.type === 'subscription') { + subCancelled++; + } + //Find the paying cancelled accounts + inPayingCancelled += (getFunding(users, funds, instance)).fundingCount; + } + }); + charges.map(charge => { + allCharges += charge.data.amount; + if(charge.data.item_id !== null) { + allChargesApproved += charge.data.amount; + } }); + //Calculate multi-level metrics + let averageConversion = 0; + if(inPaying > 0) { + averageConversion = inPaying/(subActive + subCancelled); + } + //Calculate ARPA & Churn + let arpa = 0; + let churn = 0; + if(inPaying > 0) { + arpa = ((Math.ceil(arr/12))/inPaying).toFixed(2); + churn = ((inPayingCancelled / (inPaying + inPayingCancelled))*100).toFixed(2); + } + stats.overall = {}; stats.overall.total = instances.length; stats.overall.activeSales = activeSales; @@ -120,36 +163,30 @@ module.exports = { stats.overall.waitingCancellation = waitingCancellation; stats.overall.cancelled = cancelled; stats.overall.customersWithOfferings = (Array.from(new Set(usersWithActiveOffering))).length; - stats.overall.remainingCharges = ((subTotalCharges - subPaidCharges)+(singleWaiting)+(splitTotalAmt - splitPaidAmt)+(customTotalAmt - customTotalPaidAmt)); + stats.overall.remainingCharges = ((subTotalCharges - subPaidCharges)+(singleWaiting)+(customTotalAmt - customTotalPaidAmt)); stats.subscriptionStats = {}; - stats.subscriptionStats.active = subActive; - stats.subscriptionStats.annual = Math.ceil(subAnnual); - stats.subscriptionStats.month = Math.ceil(subAnnual/12); + stats.subscriptionStats.all = subActive + subCancelled; + stats.subscriptionStats.running = subActive; + stats.subscriptionStats.active = subActive - inTrial; + stats.subscriptionStats.cancelled = subCancelled; + stats.subscriptionStats.paying = inPaying; + stats.subscriptionStats.trials = inTrial; + stats.subscriptionStats.trialPaying = inTrialPaying; + stats.subscriptionStats.flagged = inFlagged; + stats.subscriptionStats.payingCancelled = inPayingCancelled; + stats.subscriptionStats.arrForecast = Math.ceil(((arrForecast-arr)*averageConversion)+arr); + stats.subscriptionStats.mrrForecast = Math.ceil(arrForecast/12); + stats.subscriptionStats.arr = Math.ceil(arr); + stats.subscriptionStats.mrr = Math.ceil(arr/12); + stats.subscriptionStats.arpa = arpa; + stats.subscriptionStats.churn = churn; + stats.subscriptionStats.averageConversion = (averageConversion * 100).toFixed(2); stats.subscriptionStats.totalCharges = subTotalCharges; stats.subscriptionStats.totaPaidCharges = subPaidCharges; stats.subscriptionStats.totalRemainingCharges = subTotalCharges - subPaidCharges; - stats.subscriptionStats.payAnnually = subPayAnnually; - stats.subscriptionStats.payMonthly = subPayMonthly; - stats.subscriptionStats.payWeekly = subPayWeekly; - stats.subscriptionStats.payDaily = subPayDaily; stats.oneTimeStats = {}; - stats.oneTimeStats.active = singleActive; - stats.oneTimeStats.allCharges = singleAllCharges; - stats.oneTimeStats.singleApprove = singleApproved; - stats.oneTimeStats.singleWaiting = singleWaiting; - stats.split = {}; - stats.split.active = splitActive; - stats.split.splitTotalNum = splitTotalNum; - stats.split.splitTotalAmt = splitTotalAmt; - stats.split.splitPaidNum = splitPaidNum; - stats.split.splotPaidAmt = splitPaidAmt; - stats.split.splitRemainingNum = splitTotalNum - splitPaidNum; - stats.split.splitRemainingAmt = splitTotalAmt - splitPaidAmt; - stats.quote = {}; - stats.quote.active = customActive; - stats.quote.customTotalAmt = customTotalAmt; - stats.quote.customTotalPaidAmt = customTotalPaidAmt; - stats.quote.customTotalRemaining = customTotalAmt - customTotalPaidAmt; + stats.oneTimeStats.allCharges = allCharges; + stats.oneTimeStats.approvedCharges = allChargesApproved; callback(null, stats); }, hasStripeKeys:function(callback){ @@ -248,11 +285,21 @@ module.exports = { callback(null, total); }) }, - totalSales: function (callback) { - transaction.getSumOfColumnFiltered('amount', 'paid', 'true', function (totalSales) { - let total = (totalSales == null ? 0 : totalSales); - callback(null, total); + totalInvoiced: function (callback) { + let total = 0; + invoices.map(inv => { + total += inv.data.total; }); + callback(null, total); + }, + totalSales: function (callback) { + let total = 0; + transactions.map(payment => { + if(payment.data.paid === true) { + total += payment.data.amount; + } + }) + callback(null, total); }, totalServiceInstanceCancellations: function (callback) { serviceInstanceCancellation.getRowCountByKey(null, null, function (totalCancellations) { diff --git a/plugins/api-gateway/app.js b/plugins/api-gateway/app.js index 70fbc985..3d77c6e4 100644 --- a/plugins/api-gateway/app.js +++ b/plugins/api-gateway/app.js @@ -39,6 +39,7 @@ module.exports = { app.use(function(req, res, next) { res.header("Access-Control-Allow-Credentials", true); res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Methods", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"); next(); }); @@ -117,7 +118,11 @@ module.exports = { //initialize api route var api = express.Router(); + var pages = express.Router(); + app.use("/api/v1", api); + app.use("/page", pages) + yield provide({"pageRouter" : pages}); require("../../api/auth")(api, passport); //force all requests to api route to look for token, if token is present in header the user will be logged in with taht token @@ -158,6 +163,7 @@ module.exports = { require('../../api/notifications')(api); require('../../api/permissions')(api); require('../../api/roles')(api); + require('../../api/tiers')(api); require('../../api/webhooks')(api); let routeConsumer = require("./router"); let authService = yield consume(services.authService); @@ -182,7 +188,7 @@ module.exports = { let configBuilder = require("pluginbot/config"); let clientPlugins = Object.keys((await configBuilder.buildClientConfig(CONFIG_PATH)).plugins); let {site_title, site_description, hostname} = store.getState().options; - res.render("main", {bundle : appConfig.bundle_path, plugins : clientPlugins, site_title, site_description, hostname}); + res.render("main", {vendor: appConfig.vendor_path, bundle : appConfig.bundle_path, plugins : clientPlugins, site_title, site_description, hostname}); }) diff --git a/plugins/client-plugins/ga/index.js b/plugins/client-plugins/ga/index.js index 03e84d7d..5ab3b5e7 100644 --- a/plugins/client-plugins/ga/index.js +++ b/plugins/client-plugins/ga/index.js @@ -1,8 +1,6 @@ import {call, put, all, select, fork, spawn, take, takeEvery} from "redux-saga/effects"; import consume from "pluginbot/effects/consume" import ReactGA from 'react-ga'; - - let actionHandler = function(action, state){ switch(action.type){ case "@@redux-form/SET_SUBMIT_SUCCEEDED": @@ -34,7 +32,7 @@ let actionHandler = function(action, state){ function* run(config, provide, channels) { //todo pull initialize from channel? - let { initialState } = yield take("INITIALIZE"); + let { initialState } = yield take("INITIALIZE"); if(initialState.options.google_analytics && initialState.options.google_analytics.value ){ ReactGA.initialize(initialState.options.google_analytics.value); if(initialState.uid){ @@ -48,6 +46,7 @@ function* run(config, provide, channels) { ReactGA.set({ page: action.payload.pathname}); ReactGA.pageview(action.payload.pathname); }) + } } export {run}; \ No newline at end of file diff --git a/plugins/core-embeddables/client.js b/plugins/core-embeddables/client.js new file mode 100644 index 00000000..384ed7da --- /dev/null +++ b/plugins/core-embeddables/client.js @@ -0,0 +1,9 @@ +let consume = require("pluginbot/effects/consume"); +import Billing from "./embeddables/billing-settings"; +import Checkout from "./embeddables/checkout"; +module.exports = { + run: function* (config, provide, services) { + yield provide({embeddable : [Checkout, Billing]}); + } + +}; \ No newline at end of file diff --git a/plugins/core-embeddables/css/style.css b/plugins/core-embeddables/css/style.css new file mode 100644 index 00000000..29876feb --- /dev/null +++ b/plugins/core-embeddables/css/style.css @@ -0,0 +1,5 @@ +.checkout-embed { + color: white; +} + +/*# sourceMappingURL=style.css.map */ diff --git a/plugins/core-embeddables/css/style.css.map b/plugins/core-embeddables/css/style.css.map new file mode 100644 index 00000000..aeb4a7e2 --- /dev/null +++ b/plugins/core-embeddables/css/style.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AACA,eAAe;EACb,KAAK,EAAE,KAAK", +"sources": ["../scss/style.scss"], +"names": [], +"file": "style.css" +} diff --git a/plugins/core-embeddables/embeddables/billing-settings.js b/plugins/core-embeddables/embeddables/billing-settings.js new file mode 100644 index 00000000..ab8bc2a9 --- /dev/null +++ b/plugins/core-embeddables/embeddables/billing-settings.js @@ -0,0 +1,212 @@ +import React from "react"; +import {Fetcher} from "servicebot-base-form"; +import { duotoneDark } from 'react-syntax-highlighter/styles/prism'; +import SyntaxHighlighter from 'react-syntax-highlighter/prism'; +import {CopyToClipboard} from 'react-copy-to-clipboard'; +import Load from '../../../views/components/utilities/load.jsx'; + +class ManagementEmbed extends React.Component { + constructor(props){ + super(props); + this.state = { + loading:true, + selectedServer: "node", + copied: false, + }; + this.changeServer = this.changeServer.bind(this); + this.handleCopy = this.handleCopy(this); + } + async componentDidMount(){ + let secretKey = (await Fetcher(`/api/v1/system-options/secret`)).secret; + this.setState({secretKey, loading:false}); + } + changeServer(e) { + const selectedServer = e.currentTarget.value; + this.setState({selectedServer}); + } + handleCopy(){ + let self = this; + this.setState({'copied': true}, function () { + setTimeout(function(){ self.setState({'copied': false}) }, 3000); + }); + } + render() { + if(this.state.loading){ + return ; + } + let server; + switch (this.state.selectedServer) { + case "node": + server = `function generateJWT(email, key) { + var crypto = require('crypto'); + var hmac = crypto.createHmac('sha256', key); + + var payload = { + "email": email + }; + var header = { + "alg": "HS256", + "typ": "JWT" + }; + function cleanBase64(string) { + return string.replace(/=/g, "").replace(/\\+/g, "-").replace(/\\//g, "_") + } + + function base64encode(object) { + return cleanBase64(Buffer.from(JSON.stringify(object)).toString("base64")); + } + + var data = base64encode(header) + "." + base64encode(payload); + hmac.update(data); + return data + "." + cleanBase64(hmac.digest('base64')); +} +var SECRET_KEY = "${this.state.secretKey}"; //keep this key safe! +var userToken = generateJWT(user.email, SECRET_KEY);`; + break; + case "php": + server = `function generateJWT($email, $secret) { + function cleanBase64($string) { + return str_replace("/", "_", str_replace("+", "-", str_replace("=", "", $string))); + }; + function base64encode($object) { + return cleanBase64(base64_encode(json_encode($object))); + }; + $header = new stdClass(); + $header->alg = "HS256"; + $header->typ = "JWT"; + $payload = new stdClass(); + $payload->email = $email; + $data = base64encode($header) . "." . base64encode($payload); + return $data . "." . cleanBase64(base64_encode(pack('H*', hash_hmac('sha256', // hash function + $data, + $secret + )))); +} +$SECRET_KEY = "${this.state.secretKey}"; +$userToken = generateJWT($user->email, $SECRET_KEY); +`; + break; + case "ruby": + server = `require "openssl" +require "base64" +require "json" + +def generateJWT(email, secret) + def clearPadding(string) + string.gsub! "=", "" + return string + end + + def encodeClear(obj) + return clearPadding(Base64.urlsafe_encode64(JSON.generate(obj))) + end + + header = {:alg => "HS256", :typ => "JWT"} + payload = {:email => email} + data = encodeClear(header) + "." + encodeClear(payload) + return data + "." + clearPadding(Base64.urlsafe_encode64(OpenSSL::HMAC.digest('sha256', secret, data))) +end + +SECRET_KEY = "${this.state.secretKey}" #Keep this key safe! +userToken = generateJWT(user[:email], SECRET_KEY) +`; + break; + case "python": + server = `#Requires PyJWT package, "pip install PyJWT" +import jwt +def generateJWT(email, secret): + encoded = jwt.encode({'email': email}, secret) + return encoded + +SECRET_KEY = "${this.state.secretKey}" #Keep this key safe! +token = generateJWT(user.email, SECRET_KEY)`; + break; + case "other": + server = `Generate a JSON Web Token using the following specifications: + - Algorithm: HS256 + - HMAC Secret: ${this.state.secretKey} + - Payload should contain a customer email address, for example: {"email" : "customer-email@example.com"}`; + break; + default: + break; + } + let clientCode = `
+ + + +`; + + let {copied, selectedServer} = this.state; + + let selectedLang = ( selected )=> { + switch (selected){ + case "node" || 'other': + return 'javascript'; break; + default: + return selected; + } + }; + + return ( +
+
+ +

1Select a Language or Framework

+
+

In order to embed the management so users can add cards, cancel, and resubscribe + you need to generate a token which will authenticate your users and be used by + the client-side javascript. +

+
+ +
+
+
+
+ +

2Server-side Embed Code

+
+

DO NOT EXPOSE THE SECRET KEY TO THE PUBLIC, make sure not to commit + it into version control or send under insecure channels or expose to client +

+ {server} + + + +
+
+
+
+ +

3Client-side Embed Code

+
+

With the token generated on the server, use this HTML on the client...(with the proper token) for technical documentation, see here

+ {clientCode} + + + +
+
+
+
+ ); + } +} + +export default {component : ManagementEmbed, name: "Billing Settings", description: "Test reload", iconUrl: "data:image/svg+xml;utf8,%3Csvg width='56px' height='56px' viewBox='0 0 56 56' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3C!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch --%3E%3Ctitle%3ESB/Icon/EmbedPage/Billing%3C/title%3E%3Cdesc%3ECreated with Sketch.%3C/desc%3E%3Cdefs%3E%3C/defs%3E%3Cg id='SB/Icon/EmbedPage/Billing' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg id='Group-7' transform='translate(4.000000, 6.000000)' fill='%234C82FC' fill-rule='nonzero'%3E%3Cg id='credit-card-(1)' transform='translate(17.066667, 22.500000)'%3E%3Cpath d='M2.76000015,1.06153846 C1.82196566,1.06153846 1.06153846,1.82196566 1.06153846,2.76000015 L1.06153846,19.7399998 C1.06153846,20.6780343 1.82196566,21.4384615 2.76000015,21.4384615 L28.1733332,21.4384615 C29.1113677,21.4384615 29.8717949,20.6780343 29.8717949,19.7399998 L29.8717949,2.76000015 C29.8717949,1.82196566 29.1113677,1.06153846 28.1733332,1.06153846 L2.76000015,1.06153846 Z M2.76000015,-1.06153846 L28.1733332,-1.06153846 C30.2839107,-1.06153846 31.9948718,0.649422655 31.9948718,2.76000015 L31.9948718,19.7399998 C31.9948718,21.8505773 30.2839107,23.5615385 28.1733332,23.5615385 L2.76000015,23.5615385 C0.649422655,23.5615385 -1.06153846,21.8505773 -1.06153846,19.7399998 L-1.06153846,2.76000015 C-1.06153846,0.649422655 0.649422655,-1.06153846 2.76000015,-1.06153846 Z' id='Rectangle-path'%3E%3C/path%3E%3Cpath d='M0,9.49903846 C-0.586271504,9.49903846 -1.06153846,9.0237715 -1.06153846,8.4375 C-1.06153846,7.8512285 -0.586271504,7.37596154 0,7.37596154 L30.9333333,7.37596154 C31.5196048,7.37596154 31.9948718,7.8512285 31.9948718,8.4375 C31.9948718,9.0237715 31.5196048,9.49903846 30.9333333,9.49903846 L0,9.49903846 Z' id='Shape'%3E%3C/path%3E%3C/g%3E%3Cg id='settings-(3)-copy'%3E%3Cpath d='M22.88037,15.1220564 C23.1346505,15.6503136 22.9125486,16.2846858 22.3842914,16.5389664 C21.8560342,16.793247 21.221662,16.571145 20.9673814,16.0428879 C20.3468924,14.7538481 19.0480981,13.9186813 17.6,13.9186813 C15.5363658,13.9186813 13.8615385,15.6009856 13.8615385,17.6785714 C13.8615385,18.7402597 14.2998891,19.7284622 15.0587396,20.4362254 C15.4874767,20.8360989 15.5108752,21.5078205 15.1110016,21.9365575 C14.7111281,22.3652945 14.0394065,22.388693 13.6106695,21.9888195 C12.4253659,20.8833131 11.7384615,19.3347795 11.7384615,17.6785714 C11.7384615,14.4305543 14.3617006,11.7956044 17.6,11.7956044 C19.8724679,11.7956044 21.9097558,13.1056464 22.88037,15.1220564 Z' id='Oval'%3E%3C/path%3E%3Cpath d='M9.30346664,6.29602535 L9.20414106,6.19625613 C8.78485344,5.77462788 8.21654945,5.53799174 7.62424242,5.53799174 C7.0319354,5.53799174 6.46363141,5.77462788 6.04351059,6.19709304 C5.62284967,6.61916209 5.38621761,7.19254169 5.38621761,7.79074675 C5.38621761,8.38895181 5.62284967,8.96233141 6.0439273,9.38481881 L6.15105044,9.49251167 C7.2304409,10.6009049 7.52924774,12.2562269 6.93136446,13.6117406 C6.3959872,15.0739124 5.02367926,16.0598125 3.44533333,16.0966034 L3.2969697,16.0966034 C2.06343622,16.0966034 1.06153846,17.1029739 1.06153846,18.3467532 C1.06153846,19.5905326 2.06343622,20.5969031 3.2969697,20.5969031 L3.58146477,20.5969116 C5.0898097,20.6029543 6.44964312,21.5075265 7.03828893,22.8872694 C7.66112652,24.3048121 7.36231969,25.960134 6.27471518,27.0768695 L6.17538938,27.1766385 C5.75472846,27.5987075 5.51809639,28.1720871 5.51809639,28.7702922 C5.51809639,29.3684973 5.75472846,29.9418769 6.17622257,30.3647828 C6.5955102,30.7864111 7.16381419,31.0230472 7.75612121,31.0230472 C8.34842824,31.0230472 8.91673222,30.7864111 9.33643633,30.3643643 L9.44365179,30.2567617 C10.5489929,29.1707112 12.2025458,28.8695527 13.618091,29.4970783 C14.154058,29.7346779 14.3959326,30.3617776 14.158333,30.8977447 C13.9207334,31.4337117 13.2936337,31.6755863 12.7576666,31.4379867 C12.1386845,31.1635857 11.4160349,31.2952005 10.9399273,31.7629085 L10.8414347,31.8618405 C10.0239086,32.6839304 8.91390668,33.1461241 7.75612121,33.1461241 C6.59833574,33.1461241 5.48833382,32.6839304 4.67164093,31.8626775 C3.8541114,31.0424113 3.39501947,29.9299926 3.39501947,28.7702922 C3.39501947,27.6105919 3.8541114,26.4981731 4.67122421,25.6783253 L4.76191926,25.5873169 C5.2375969,25.098858 5.36963998,24.3673693 5.09004983,23.7308873 C4.82906508,23.1192267 4.23284333,22.7226151 3.57721212,22.71998 L3.2969697,22.71998 C0.888771007,22.71998 -1.06153846,20.7609638 -1.06153846,18.3467532 C-1.06153846,15.9325427 0.888771007,13.9735265 3.2969697,13.9735265 L3.42039894,13.9738194 C4.10012118,13.957849 4.70205732,13.5254032 4.96268077,12.8197369 C5.23776119,12.1936696 5.10571811,11.462181 4.63825451,10.9820643 L4.53976214,10.883132 C3.72223261,10.0628658 3.26314068,8.9504471 3.26314068,7.79074675 C3.26314068,6.6310464 3.72223261,5.51862766 4.53892894,4.69919842 C5.35645503,3.87710859 6.46645695,3.41491482 7.62424242,3.41491482 C8.7820279,3.41491482 9.89202981,3.87710859 10.7091394,4.69877985 L10.7997422,4.78987857 C11.2841561,5.26583848 12.0068058,5.39745331 12.6257878,5.12305229 C12.7217111,5.08052852 12.823186,5.05255876 12.9268645,5.03985186 C13.4441236,4.74820804 13.7724226,4.19635111 13.7748252,3.59318182 L13.7748252,3.31168831 C13.7748252,0.897477746 15.7251346,-1.06153846 18.1333333,-1.06153846 C20.541532,-1.06153846 22.4918415,0.897477746 22.4918415,3.31168831 L22.4918331,3.45649936 C22.4944815,4.12348304 22.8906038,4.72429805 23.5090001,4.99058475 C24.1279821,5.26498578 24.8506317,5.13337095 25.3267394,4.66566296 L25.425232,4.56673089 C26.2427581,3.74464106 27.35276,3.28244729 28.5105455,3.28244729 C29.6683309,3.28244729 30.7783328,3.74464106 31.5950257,4.56589397 C32.4125553,5.38616013 32.8716472,6.49857887 32.8716472,7.65827922 C32.8716472,8.81797957 32.4125553,9.93039831 31.5954425,10.7502461 L31.5047474,10.8412546 C31.0290698,11.3297135 30.8970267,12.0612021 31.1721071,12.6872694 C31.214321,12.7833458 31.2419612,12.8849337 31.2543239,12.9886817 C31.5445173,13.5094794 32.0923476,13.8386591 32.6894545,13.8410589 L32.969697,13.8410589 C33.5559685,13.8410589 34.0312354,14.3163259 34.0312354,14.9025974 C34.0312354,15.4888689 33.5559685,15.9641359 32.969697,15.9641359 L32.6852019,15.9641273 C31.176857,15.9580847 29.8170235,15.0535124 29.223868,13.6633549 C29.178148,13.5562026 29.1504499,13.4424258 29.1417124,13.3266172 C28.6374503,11.9592967 28.9588197,10.4125057 29.9919515,9.35170193 L30.0912773,9.25193293 C30.5119382,8.82986388 30.7485703,8.25648428 30.7485703,7.65827922 C30.7485703,7.06007416 30.5119382,6.48669456 30.0904441,6.06378859 C29.6711565,5.64216035 29.1028525,5.40552421 28.5105455,5.40552421 C27.9182384,5.40552421 27.3499344,5.64216035 26.9302303,6.06420717 L26.8230149,6.17180974 C25.7176738,7.25786021 24.0641209,7.55901872 22.659039,6.93606449 C21.2740507,6.33982647 20.3747722,4.97585391 20.3687646,3.46071429 L20.3687646,3.31168831 C20.3687646,2.06790898 19.3668668,1.06153846 18.1333333,1.06153846 C16.8997999,1.06153846 15.8979021,2.06790898 15.8979021,3.31168831 L15.8978937,3.59739675 C15.8918944,5.10832144 14.992616,6.472294 13.6076277,7.06853202 C13.5003573,7.11471196 13.3863785,7.14279875 13.270316,7.15183923 C11.905246,7.65909078 10.3609471,7.33513643 9.30346664,6.29602535 Z' id='Shape'%3E%3C/path%3E%3C/g%3E%3Cpath d='M22.3974359,35.8879121 L22.3974359,35.8978022 L42.6692308,35.8978022 L42.6692308,35.8879121 L22.3974359,35.8879121 Z M22.3974359,34.8263736 L42.6692308,34.8263736 C43.2555023,34.8263736 43.7307692,35.3016406 43.7307692,35.8879121 L43.7307692,35.8978022 C43.7307692,36.4840737 43.2555023,36.9593407 42.6692308,36.9593407 L22.3974359,36.9593407 C21.8111644,36.9593407 21.3358974,36.4840737 21.3358974,35.8978022 L21.3358974,35.8879121 C21.3358974,35.3016406 21.8111644,34.8263736 22.3974359,34.8263736 Z' id='Rectangle-6'%3E%3C/path%3E%3Cpath d='M22.3974359,39.1021978 L22.3974359,39.1120879 L33.0692308,39.1120879 L33.0692308,39.1021978 L22.3974359,39.1021978 Z M22.3974359,38.0406593 L33.0692308,38.0406593 C33.6555023,38.0406593 34.1307692,38.5159263 34.1307692,39.1021978 L34.1307692,39.1120879 C34.1307692,39.6983594 33.6555023,40.1736264 33.0692308,40.1736264 L22.3974359,40.1736264 C21.8111644,40.1736264 21.3358974,39.6983594 21.3358974,39.1120879 L21.3358974,39.1021978 C21.3358974,38.5159263 21.8111644,38.0406593 22.3974359,38.0406593 Z' id='Rectangle-6-Copy'%3E%3C/path%3E%3Cpath d='M40.5307692,39.1021978 L40.5307692,39.1120879 L42.6692308,39.1120879 L42.6692308,39.1021978 L40.5307692,39.1021978 Z M40.5307692,38.0406593 L42.6692308,38.0406593 C43.2555023,38.0406593 43.7307692,38.5159263 43.7307692,39.1021978 L43.7307692,39.1120879 C43.7307692,39.6983594 43.2555023,40.1736264 42.6692308,40.1736264 L40.5307692,40.1736264 C39.9444977,40.1736264 39.4692308,39.6983594 39.4692308,39.1120879 L39.4692308,39.1021978 C39.4692308,38.5159263 39.9444977,38.0406593 40.5307692,38.0406593 Z' id='Rectangle-6-Copy-2'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E"} \ No newline at end of file diff --git a/plugins/core-embeddables/embeddables/checkout.js b/plugins/core-embeddables/embeddables/checkout.js new file mode 100644 index 00000000..36b3856d --- /dev/null +++ b/plugins/core-embeddables/embeddables/checkout.js @@ -0,0 +1,444 @@ +import React from "react"; +import cookie from "react-cookie"; +import {Fetcher, inputField, iconToggleField, ServicebotBaseForm} from "servicebot-base-form"; +import {change, Field, FieldArray, FormSection, formValueSelector, getFormValues} from 'redux-form' +import {connect} from "react-redux"; +import {RenderWidget, WidgetList, widgets} from "../../../views/components/utilities/widgets"; +import slug from "slug" +import {numericality, required} from 'redux-form-validators' +const CHECKOUT_FORM = "checkoutForm"; +const selector = formValueSelector(CHECKOUT_FORM); // <-- same as form name +import { duotoneDark } from 'react-syntax-highlighter/styles/prism'; +import SyntaxHighlighter from 'react-syntax-highlighter/prism'; +import {CopyToClipboard} from 'react-copy-to-clipboard'; +import Load from '../../../views/components/utilities/load.jsx'; + +class CustomField extends React.Component { + + constructor(props) { + super(props); + + } + + componentWillReceiveProps(nextProps) { + let props = this.props; + if ((nextProps.myValues.type !== props.myValues.type) && (nextProps.length === props.length)) { + props.clearConfig(); + props.clearValue(); + } + if ((props.templateType && nextProps.templateType !== props.templateType)) { + props.clearPricing(); + } + } + + render() { + + let props = this.props; + let { + willAutoFocus, index, typeValue, member, myValues, privateValue, requiredValue, promptValue, configValue, + setPrivate, setRequired, setPrompt, changePrivate, changeRequired, changePrompt, templateType, currency + } = props; + + if (myValues.prop_label) { + willAutoFocus = false; + } + if(typeValue === "metric"){ + return
+ } + return ( +
+
+ +
+ +
+ +
+ +
+ {!privateValue && !requiredValue && + + } + {!privateValue && + + } + {!requiredValue && !promptValue && + + } +
+
+ {typeValue && + } +
+
+ ) + }; +} + +CustomField = connect((state, ownProps) => { + return { + "privateValue": selector(state, "references.service_template_properties")[ownProps.index].private, + "requiredValue": selector(state, "references.service_template_properties")[ownProps.index].required, + "promptValue": selector(state, "references.service_template_properties")[ownProps.index].prompt_user, + "typeValue": selector(state, "references.service_template_properties")[ownProps.index].type, + "configValue": selector(state, `references.service_template_properties`)[ownProps.index].config, + "myValues": selector(state, `references.${ownProps.member}`), + + + } +}, (dispatch, ownProps) => { + return { + "setPrivate": (val) => { + if (val == true) { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, true)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.required`, false)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, false)); + } else { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, false)); + } + }, + "setRequired": (val) => { + if (val == true) { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.required`, true)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, false)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, true)); + } else { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.required`, false)); + } + }, + "setPrompt": (val) => { + if (val == true) { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, true)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, false)); + } else { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, false)); + } + }, + "changePrivate": (event) => { + if (!event.currentTarget.value || event.currentTarget.value == 'false') { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.required`, false)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, false)); + } + }, + "changeRequired": (event) => { + if (!event.currentTarget.value || event.currentTarget.value == 'false') { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, false)); + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.prompt_user`, true)); + } + }, + "changePrompt": (event) => { + if (!event.currentTarget.value || event.currentTarget.value == 'false') { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.private`, false)); + } + }, + "clearConfig": () => { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.config`, {})); + }, + "clearPricing": () => { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.config.pricing`, null)); + }, + "clearValue": () => { + dispatch(change(CHECKOUT_FORM, `references.${ownProps.member}.data`, null)); + } + } +})(CustomField); + + +//Custom property +class renderCustomProperty extends React.Component { + + constructor(props) { + super(props); + + this.state = { + customFields: [], + }; + + + this.onAdd = this.onAdd.bind(this); + } + + onAdd(e) { + e.preventDefault(); + const {privateValue, fields, meta: {touched, error}} = this.props; + return (fields.push({})); + } + + render() { + let props = this.props; + const {templateType, currency, privateValue, fields, meta: {touched, error}} = props; + + return ( + +
    + {fields.map((customProperty, index) =>{ + let property = fields.get(index); + if(property.name && property.name.slice(0, 2) === "__"){ + return
    + } + return (
  • +
    + {/*{fields.get(index).prop_label ?*/} + {/*

    {fields.get(index).prop_label}

    :

    Field #{index + 1}

    */} + {/*}*/} + +
    + +
  • ) + } + )} +
  • +
    + +
    + {/**/} + {touched && error && {error}} +
  • +
+
+ ) + }; +} + +let CheckoutForm = function(props){ + return + + + + + + +}; + + +//The full form + + + + + +class CheckoutPage extends React.Component { + constructor(props){ + super(props); + this.state = { + loading: true, + selectedTemplate: 0, + selectedTier: null, + selectedPlan: null, + tier: null, + templates: [], + copied: false, + } + this.changeTemplate = this.changeTemplate.bind(this); + this.changeTier = this.changeTier.bind(this); + this.changePlan = this.changePlan.bind(this); + this.generateEmbedCode = this.generateEmbedCode.bind(this); + this.handleCopy = this.handleCopy.bind(this); + + } + generateEmbedCode(){ + let {selectedPlan, selectedTemplate} = this.state; + return `
+ + + ` + } + async componentDidMount(){ + let templates = await Fetcher(`/api/v1/service-templates/`); + this.setState({ templates, loading: false}); + } + async changeTemplate(e) { + const selectedTemplate = e.currentTarget.value; + let currentTemplate = this.state.templates.find(template => template.id == selectedTemplate) + + let selectedTier = currentTemplate.references.tiers[0].id; + let tier = await Fetcher(`/api/v1/tiers/${selectedTier}`); + + this.setState({selectedTemplate, selectedTier, tier, selectedPlan: null}); + + } + async changeTier(e) { + const selectedTier = e.currentTarget.value; + let tier = await Fetcher(`/api/v1/tiers/${selectedTier}`); + this.setState({selectedTier, tier, selectedPlan: null}); + + } + changePlan(e) { + const selectedPlan = e.currentTarget.value; + this.setState({selectedPlan}); + + } + handleCopy(){ + let self = this; + this.setState({'copied': true}, function () { + setTimeout(function(){ self.setState({'copied': false}) }, 3000); + }); + } + + render(props) { + let formHTML; + let {loading, selectedTemplate, templates, selectedPlan, selectedTier, tier, copied} = this.state; + console.log(tier, "TIERRR") + if(loading){ + return ; + } + + if (selectedTemplate === null || selectedTemplate == 0) { + formHTML = "Select a service from the list to embed" + } + let submissionRequest = { + 'method': 'PUT', + 'url': `/api/v1/service-templates/${selectedTemplate}` + }; + let currentTemplate = templates.find(template => template.id == selectedTemplate) + let formEmbed = ( +
+
+ +

1Select a service

+
+ +
+
+
+ +

2Build your checkout form

+
+ { selectedTemplate ? + : +
+ } +
+
+
+ +

3Copy and Embed your code

+ { selectedTemplate ? + +
+

Paste the generated HTML on the page you want to embed + a request form. You can find more detailed documentation + here +

+ +
+
+ + +
+ {selectedTier && +
+ + +
+ } +
+
+ {selectedPlan && +
+ {this.generateEmbedCode()} + + + +
+
+ } + : +
+ } +
+
+ ); + return formEmbed + + } +} +export default {component : CheckoutPage, name: "Checkout Page", description: "Get checkout embed code", iconUrl: "data:image/svg+xml;utf8,%3Csvg width='56px' height='56px' viewBox='0 0 56 56' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3C!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch --%3E%3Ctitle%3ESB/Icon/EmbedPage/Checkout%3C/title%3E%3Cdesc%3ECreated with Sketch.%3C/desc%3E%3Cdefs%3E%3C/defs%3E%3Cg id='SB/Icon/EmbedPage/Checkout' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg id='Group-5' transform='translate(3.000000, 5.000000)' fill='%234C82FC' fill-rule='nonzero'%3E%3Cg id='shopping-cart-(2)' transform='translate(7.000000, 20.000000)'%3E%3Cpath d='M10.5454545,28 C9.27066263,28 8.22727273,26.9823094 8.22727273,25.7142857 C8.22727273,24.4462621 9.27066263,23.4285714 10.5454545,23.4285714 C11.8202465,23.4285714 12.8636364,24.4462621 12.8636364,25.7142857 C12.8636364,26.9823094 11.8202465,28 10.5454545,28 Z M10.5454545,26 C10.7266861,26 10.8636364,25.8664229 10.8636364,25.7142857 C10.8636364,25.5621486 10.7266861,25.4285714 10.5454545,25.4285714 C10.364223,25.4285714 10.2272727,25.5621486 10.2272727,25.7142857 C10.2272727,25.8664229 10.364223,26 10.5454545,26 Z' id='Oval'%3E%3C/path%3E%3Cpath d='M25.0454545,28 C23.7706626,28 22.7272727,26.9823094 22.7272727,25.7142857 C22.7272727,24.4462621 23.7706626,23.4285714 25.0454545,23.4285714 C26.3202465,23.4285714 27.3636364,24.4462621 27.3636364,25.7142857 C27.3636364,26.9823094 26.3202465,28 25.0454545,28 Z M25.0454545,26 C25.2266861,26 25.3636364,25.8664229 25.3636364,25.7142857 C25.3636364,25.5621486 25.2266861,25.4285714 25.0454545,25.4285714 C24.864223,25.4285714 24.7272727,25.5621486 24.7272727,25.7142857 C24.7272727,25.8664229 24.864223,26 25.0454545,26 Z' id='Oval'%3E%3C/path%3E%3Cpath d='M4.45709374,1 L0,1 C-0.55228475,1 -1,0.55228475 -1,0 C-1,-0.55228475 -0.55228475,-1 0,-1 L5.27272727,-1 C5.74753002,-1 6.15687292,-0.666126203 6.25231542,-0.201015056 L7.4075267,5.42857143 L29,5.42857143 C29.6292879,5.42857143 30.1021686,6.00286312 29.9814173,6.62045711 L27.8707983,17.4152568 C27.5249015,19.1138449 25.9908453,20.3183435 24.2545455,20.2857143 L11.4605067,20.2855396 C9.70551832,20.3183435 8.17146209,19.1138449 7.82586639,17.4167293 L5.62213392,6.67748295 C5.61423177,6.64663604 5.6077642,6.61521541 5.6028063,6.58329545 L4.45709374,1 Z M7.81793385,7.42857143 L9.78534373,17.0161718 C9.93702627,17.7610362 10.6244939,18.3008169 11.4418182,18.2857143 L24.273234,18.2858889 C25.0718697,18.3008169 25.7593374,17.7610362 25.9094918,17.0238286 L27.7855465,7.42857143 L7.81793385,7.42857143 Z' id='Shape'%3E%3C/path%3E%3C/g%3E%3Cpath d='M2.5,25.941402 C2.5,26.4936867 2.05228475,26.941402 1.5,26.941402 C0.94771525,26.941402 0.5,26.4936867 0.5,25.941402 L0.5,4.1 C0.5,2.1117749 2.1117749,0.5 4.1,0.5 L45.6546075,0.5 C47.6428326,0.5 49.2546075,2.1117749 49.2546075,4.1 L49.2546075,36.9 C49.2546075,38.8882251 47.6428326,40.5 45.6546075,40.5 L41.3189127,40.5 C40.7666279,40.5 40.3189127,40.0522847 40.3189127,39.5 C40.3189127,38.9477153 40.7666279,38.5 41.3189127,38.5 L45.6546075,38.5 C46.5382631,38.5 47.2546075,37.7836556 47.2546075,36.9 L47.2546075,4.1 C47.2546075,3.2163444 46.5382631,2.5 45.6546075,2.5 L4.1,2.5 C3.2163444,2.5 2.5,3.2163444 2.5,4.1 L2.5,25.941402 Z' id='Path-6'%3E%3C/path%3E%3Cpath d='M6,7.5 C5.17157288,7.5 4.5,6.82842712 4.5,6 C4.5,5.17157288 5.17157288,4.5 6,4.5 C6.82842712,4.5 7.5,5.17157288 7.5,6 C7.5,6.82842712 6.82842712,7.5 6,7.5 Z M6,6.5 C6.27614237,6.5 6.5,6.27614237 6.5,6 C6.5,5.72385763 6.27614237,5.5 6,5.5 C5.72385763,5.5 5.5,5.72385763 5.5,6 C5.5,6.27614237 5.72385763,6.5 6,6.5 Z' id='Oval-4'%3E%3C/path%3E%3Cpath d='M10,7.5 C9.17157288,7.5 8.5,6.82842712 8.5,6 C8.5,5.17157288 9.17157288,4.5 10,4.5 C10.8284271,4.5 11.5,5.17157288 11.5,6 C11.5,6.82842712 10.8284271,7.5 10,7.5 Z M10,6.5 C10.2761424,6.5 10.5,6.27614237 10.5,6 C10.5,5.72385763 10.2761424,5.5 10,5.5 C9.72385763,5.5 9.5,5.72385763 9.5,6 C9.5,6.27614237 9.72385763,6.5 10,6.5 Z' id='Oval-4-Copy'%3E%3C/path%3E%3Cpath d='M14,7.5 C13.1715729,7.5 12.5,6.82842712 12.5,6 C12.5,5.17157288 13.1715729,4.5 14,4.5 C14.8284271,4.5 15.5,5.17157288 15.5,6 C15.5,6.82842712 14.8284271,7.5 14,7.5 Z M14,6.5 C14.2761424,6.5 14.5,6.27614237 14.5,6 C14.5,5.72385763 14.2761424,5.5 14,5.5 C13.7238576,5.5 13.5,5.72385763 13.5,6 C13.5,6.27614237 13.7238576,6.5 14,6.5 Z' id='Oval-4-Copy-2'%3E%3C/path%3E%3Cpolygon id='Path-7' points='1.5 11.5 1.5 9.5 47.457928 9.5 47.457928 11.5'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/svg%3E"} \ No newline at end of file diff --git a/plugins/core-embeddables/main.js b/plugins/core-embeddables/main.js new file mode 100644 index 00000000..4a25edfc --- /dev/null +++ b/plugins/core-embeddables/main.js @@ -0,0 +1,23 @@ +let {call, put, all, select, fork, spawn, take} = require("redux-saga/effects"); +let consume = require("pluginbot/effects/consume"); +let path = require("path") +function* run(config, provide, channels) { + let database = yield consume(channels.database); + let pages = [ + { + name: "payment", + path: path.join(__dirname, "./pages/payment.handlebars") + }, + { + name: "billing", + needsToken: true, + path: path.join(__dirname, "./pages/billing.handlebars") + }, + { + name: "checkout", + path: path.join(__dirname, "./pages/checkout.handlebars") + }, + ] + yield provide({hostedPage: pages}); +} +module.exports = {run}; \ No newline at end of file diff --git a/plugins/core-embeddables/package.json b/plugins/core-embeddables/package.json new file mode 100644 index 00000000..6b523f53 --- /dev/null +++ b/plugins/core-embeddables/package.json @@ -0,0 +1,16 @@ +{ + "name": "core-embeddables", + "version": "0.0.1", + "dependencies": { + + }, + "pluginbot": { + "client": { + "main" : "client.js" + }, + "server": { + "main" : "main.js", + "consumes" : ["database"] + } + } +} diff --git a/plugins/core-embeddables/pages/billing.handlebars b/plugins/core-embeddables/pages/billing.handlebars new file mode 100644 index 00000000..fbdbc22a --- /dev/null +++ b/plugins/core-embeddables/pages/billing.handlebars @@ -0,0 +1,21 @@ + + + + {{company_name}} Billing Settings + + + + + + +
+ +
+ + + \ No newline at end of file diff --git a/plugins/core-embeddables/pages/checkout.handlebars b/plugins/core-embeddables/pages/checkout.handlebars new file mode 100644 index 00000000..e69de29b diff --git a/plugins/core-embeddables/pages/payment.handlebars b/plugins/core-embeddables/pages/payment.handlebars new file mode 100644 index 00000000..af840aa4 --- /dev/null +++ b/plugins/core-embeddables/pages/payment.handlebars @@ -0,0 +1,3 @@ + + Placeholder + \ No newline at end of file diff --git a/plugins/core-embeddables/scss/style.scss b/plugins/core-embeddables/scss/style.scss new file mode 100644 index 00000000..8e369e6d --- /dev/null +++ b/plugins/core-embeddables/scss/style.scss @@ -0,0 +1,4 @@ +// Plugin - Core Embeddable Styles +.checkout-embed{ + color: white; +} \ No newline at end of file diff --git a/plugins/core-input-types/checkbox/widget.js b/plugins/core-input-types/checkbox/widget.js index efdb546b..fbbf5522 100644 --- a/plugins/core-input-types/checkbox/widget.js +++ b/plugins/core-input-types/checkbox/widget.js @@ -1,23 +1,17 @@ import React from "react"; import handler from "./widgetHandler"; -import CurrencyInput from 'react-currency-input'; import PriceAdjustment from '../../../views/components/utilities/widget-inputs/WidgetPriceAdjustment'; import WidgetPricingInput from '../../../views/components/utilities/widget-inputs/WidgetPricingInput.jsx'; -import {OnOffToggleField} from "../../../views/components/elements/forms/servicebot-base-field.jsx"; +import {OnOffToggleField} from "servicebot-base-form"; let Checkbox = (props) => { - let {input, configValue, label} = props; + let {input, configValue, label, currency} = props; + console.log(currency, "CHECKCURR"); return ( -
-
- {label && } -
-
- - {configValue && configValue.pricing && configValue.pricing.value && } -
- {/**/} -
-
+
+ {label && } + + {configValue && configValue.pricing && configValue.pricing.value && } +
); }; @@ -25,11 +19,8 @@ let Price = (props) => { let config = props.configValue; return (
-
- - {/**/} +
+
); diff --git a/plugins/core-input-types/secure-string/widget.js b/plugins/core-input-types/secure-string/widget.js index f3048ad1..a6d1acee 100644 --- a/plugins/core-input-types/secure-string/widget.js +++ b/plugins/core-input-types/secure-string/widget.js @@ -3,8 +3,8 @@ import React from "react"; let SecureString = (props) => { return ( -
- +
+
); }; diff --git a/plugins/core-input-types/select/widget.js b/plugins/core-input-types/select/widget.js index 17be857f..d2ed394e 100644 --- a/plugins/core-input-types/select/widget.js +++ b/plugins/core-input-types/select/widget.js @@ -2,21 +2,17 @@ import React from "react"; import TagsInput from "react-tagsinput" //todo: all the imports from the main app will result in duplicate code.... need to fix this! -import {priceField} from "../../../views/components/elements/forms/servicebot-base-field.jsx"; import handler from "./widgetHandler"; -import CurrencyInput from 'react-currency-input'; import WidgetPricingInput from '../../../views/components/utilities/widget-inputs/WidgetPricingInput.jsx'; -import PriceAdjustment from '../../../views/components/utilities/widget-inputs/WidgetPriceAdjustment'; +import {adjust} from '../../../views/components/utilities/widget-inputs/WidgetPriceAdjustment'; let Tags = (props) => { return ( -
- -
- -
+
+ +
); }; @@ -31,7 +27,7 @@ class SelectPricing extends React.Component { componentDidUpdate(prevProps, prevState) { let self = this; - if (prevProps.configValue && prevProps.configValue.value && prevProps.configValue.value.length > this.props.configValue.value.length) { + if (this.props.configValue.value && prevProps.configValue && prevProps.configValue.value && prevProps.configValue.value.length > this.props.configValue.value.length) { let propsToRemove = prevProps.configValue.value.filter(prop => self.props.configValue.value.indexOf(prop) < 0); let newState = propsToRemove.reduce((acc, prop) => { acc[prop] = undefined; @@ -72,7 +68,7 @@ class SelectPricing extends React.Component { let input = { onChange : self.handleChange(option), name : option, - value : pricingValue && pricingValue[option] + value : (pricingValue && pricingValue[option]) || 0 }; return (
{option} :
); @@ -86,17 +82,16 @@ class SelectPricing extends React.Component { let SelectWidget = (props) => { let {input, configValue, label} = props; - console.log(input); return ( -
- {label && } +
+ {label && }
- { configValue && configValue.value && configValue.value.map((option, index) => { let price = configValue.pricing && configValue.pricing.value && configValue.pricing.value[option]; return } )} diff --git a/plugins/core-input-types/text/widget.js b/plugins/core-input-types/text/widget.js index 5eaf6c28..48a0bc15 100644 --- a/plugins/core-input-types/text/widget.js +++ b/plugins/core-input-types/text/widget.js @@ -3,8 +3,8 @@ import React from "react"; let Text = (props) => { return ( -
- +
+
); }; diff --git a/plugins/database/database.js b/plugins/database/database.js index 41ba07b6..6bfc2f34 100644 --- a/plugins/database/database.js +++ b/plugins/database/database.js @@ -22,6 +22,10 @@ module.exports = { console.log("got a config"); } + //this is so bigints are parsed properly... + var pg = require('pg') + pg.types.setTypeParser(20, 'text', parseInt) + let database = require('knex')({ client: 'pg', connection: dbConf diff --git a/plugins/database/initialize.js b/plugins/database/initialize.js index e0199466..28ed4f7e 100644 --- a/plugins/database/initialize.js +++ b/plugins/database/initialize.js @@ -1,7 +1,7 @@ let consume = require("pluginbot/effects/consume") let {call, put} = require("redux-saga/effects") -let createTable = function(knex){ - return async function(tableName, tableFunction){ +let createTable = function (knex) { + return async function (tableName, tableFunction) { let table = await knex.schema.createTable(tableName, tableFunction); console.log("Created table : " + tableName); return table @@ -11,321 +11,357 @@ let createTable = function(knex){ //todo: split this up into multiple plugins. -let buildTables = async function(knex) { - - - console.log("Creating tables..."); - let create = createTable(knex); - - await create('user_roles', function (table) { - table.increments(); - table.string('role_name').unique(); - table.timestamps(true, true); - - }); - - await create('user_permissions', function (table) { - table.increments(); - table.string('permission_name').unique(); - table.timestamps(true, true); - - }); - await create('roles_to_permissions', function (table) { - table.increments(); - table.integer('role_id').references('user_roles.id').onDelete('cascade'); - table.integer('permission_id').references('user_permissions.id').onDelete('cascade'); - table.timestamps(true, true); - - }); - await create('users', function (table) { - table.increments(); - table.integer('role_id').references('user_roles.id'); - table.string('name'); - table.string('email').notNullable().unique(); - table.string('password'); - table.string('provider').defaultTo("local"); - table.enu('status', ['active', 'suspended', 'invited', 'flagged', 'disconnected']).defaultTo('active'); - table.string('customer_id'); - table.string('phone'); - table.timestamp('last_login'); - table.timestamps(true, true); - - }); - await create('funds', function (table) { - table.increments(); - table.integer('user_id').references('users.id').onDelete('cascade'); - table.boolean('flagged').defaultTo(false); - table.jsonb('source'); - table.timestamps(true, true); - - }); - await create('invitations', function (table) { - table.increments(); - table.string('token'); - table.integer('user_id').references('users.id').onDelete('cascade'); - table.timestamps(true, true); - - }); - await create('system_options', function (table) { - table.string('option').primary(); - table.string('value'); - table.boolean("public").defaultTo(false); - table.string('type'); - table.string('data_type'); - table.timestamps(true, true); - - }); - await create('event_logs', function (table) { - table.increments(); - table.integer('user_id'); - table.string('log_level'); - table.string('log_type'); - table.string('log'); - table.timestamps(true, true); - - }); - await create('files', function (table) { - table.increments(); - table.integer('user_id').references('users.id').onDelete('cascade'); - table.string('path'); - table.integer('size'); - table.string('name'); - table.string('mimetype'); - table.timestamps(true, true); - - }); - await create('notification_templates', function (table) { - table.increments(); - table.string('name'); - table.string('event_name'); - table.text('message', 'longtext'); - table.string('subject'); - table.string('description'); - table.string("model"); - table.specificType('additional_recipients', 'text[]'); - table.boolean("send_email").defaultTo(false); - table.boolean("send_to_owner").defaultTo(true); - table.boolean("create_notification").default(true); - table.timestamps(true, true); - - }); - await create("notification_templates_to_roles", function (table) { - table.increments(); - table.integer("notification_template_id").references("notification_templates.id"); - table.integer("role_id").references("user_roles.id"); - table.timestamps(true, true); - - }); - await create('notifications', function (table) { - table.increments(); - table.string("source_id").unique(); - table.text('message', 'longtext'); - table.string("type"); - table.integer("user_id").references("users.id").onDelete('cascade'); - table.string("subject"); - table.string("affected_versions").defaultTo("*"); - table.boolean("read").defaultTo(false); - table.boolean("email_delivered").defaultTo(false); - table.boolean("email_read").defaultTo(false); - table.timestamp('created_at').defaultTo(knex.fn.now()); - - }); - await create('service_categories', function (table) { - table.increments(); - table.string('name'); - table.string('description'); - table.timestamps(true, true); - - }); - await create('service_templates', function (table) { - table.increments(); - table.integer('category_id').references('service_categories.id'); - table.integer('created_by').references('users.id'); - table.string('name').notNullable().unique(); - table.string('description'); - table.text('details', 'longtext'); - table.boolean('published').defaultTo(false); - table.string('statement_descriptor'); - table.integer('trial_period_days'); - table.float('amount'); - table.float('overhead'); - table.string('currency').defaultTo('usd'); - table.string('interval'); - table.integer('interval_count').defaultTo(1); - table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); - table.boolean('subscription_prorate').defaultTo(true); - table.jsonb('split_configuration'); - table.timestamps(true, true); - - }); - await create('service_instances', function (table) { - table.increments(); - table.integer('service_id').references('service_templates.id'); - table.integer('user_id').references('users.id'); - table.integer('requested_by').references('users.id'); - table.jsonb('payment_plan'); - table.string('name'); - table.text('description', 'longtext'); - table.string('subscription_id'); - table.bigInteger('subscribed_at'); - table.bigInteger('trial_end'); - table.enu('status', ['running', 'requested', 'in_progress', 'waiting_cancellation', 'missing_payment', 'cancelled', 'completed']).defaultTo('missing_payment'); - table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); - table.jsonb('split_configuration'); - table.timestamps(true, true); - - }); - await create('service_instance_messages', function (table) { - table.increments(); - table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); - table.integer('user_id').references('users.id'); - table.string('message'); - table.timestamps(true, true); - - }); - await create('service_instance_cancellations', function (table) { - table.increments(); - table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); - table.integer('user_id').references('users.id'); - table.enu('status', ['waiting', 'approved', 'rejected']).defaultTo('waiting'); - table.integer('fulfilled_by').references('users.id'); - table.timestamps(true, true); - - }); - await create('properties', function (table) { - table.increments(); - table.string('name'); - table.string('type'); - table.jsonb('data'); - table.jsonb('config'); - table.string('prop_class'); - table.string('prop_label'); - table.string('prop_description'); - table.timestamps(true, true); - - }); - await create('service_template_properties', function (table) { - //Inherits the properties table. - table.inherits('properties'); - table.increments(); - table.integer('parent_id').references('service_templates.id').onDelete('cascade'); - table.boolean('private').defaultTo(false); - table.boolean('prompt_user').defaultTo(true); - table.boolean('required').defaultTo(false); - table.timestamps(true, true); - - }); - await create('service_instance_properties', function (table) { - //Inherits the properties table. - table.inherits('properties'); - table.increments(); - table.integer('parent_id').references('service_instances.id').onDelete('cascade'); - table.boolean('private').defaultTo(false); - table.boolean('prompt_user').defaultTo(true); - table.boolean('required').defaultTo(false); - table.timestamps(true, true); - - }); - await create('user_invoices', function (table) { - table.increments(); - table.integer('user_id').references('users.id'); - table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); - table.string('invoice_id').unique(); - table.string('subscription'); - table.string('charge'); - table.string('description'); - table.float('amount_due'); - table.float('discount'); - table.integer('attempt_count'); - table.boolean('closed'); - table.string('currency'); - table.boolean('forgiven'); - table.bigInteger('date'); - table.bigInteger('next_attempt'); - table.boolean('paid'); - table.bigInteger('period_end'); - table.bigInteger('period_start'); - table.string('receipt_number'); - table.float('starting_balance'); - table.float('ending_balance'); - table.float('total'); - table.boolean('livemode'); - table.timestamps(true, true); - - }); - await create('charge_items', function (table) { - table.increments(); - table.integer('user_id').references('users.id'); - table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); - table.boolean('approved').defaultTo(false); - table.string('subscription_id'); - table.string('item_id'); - table.float('amount'); - table.string('currency').defaultTo('usd'); - table.string('description'); - table.bigInteger('period_start'); - table.bigInteger('period_end'); - table.timestamps(true, true); - - }) - await create('user_invoice_lines', function (table) { - table.increments(); - table.integer('invoice_id').references('user_invoices.id').onDelete('cascade'); - table.string('line_item_id'); - table.float('amount'); - table.string('currency'); - table.string('description'); - table.boolean('proration'); - table.integer('quantity'); - table.string('type'); - table.boolean('livemode'); - table.timestamps(true, true); - - }); - await create('transactions', function (table) { - table.increments(); - table.integer('invoice_id').references('user_invoices.id').onDelete('cascade'); - table.integer('user_id').references('users.id'); - table.string('charge_id'); - table.string('invoice'); - table.float('amount'); - table.boolean('refunded'); - table.float('amount_refunded'); - table.jsonb('refunds'); - table.boolean('captured'); - table.string('currency'); - table.string('dispute'); - table.boolean('paid'); - table.string('description'); - table.string('failure_code'); - table.string('failure_message'); - table.string('statement_descriptor'); - table.string('status'); - table.boolean('livemode'); - table.timestamps(true, true); - - }); - await create('user_upcoming_invoice', function (table) { - table.increments(); - table.integer('user_id').references('users.id').onDelete('cascade'); - table.bigInteger('next_payment'); - table.jsonb('invoice_json'); - table.timestamps(true, true); - console.log("Created 'user_upcoming_invoice' table."); - - }); - await create('password_reset_request', function (table) { - table.increments(); - table.integer('user_id').references('users.id').onDelete('cascade'); - table.string('hash'); - table.timestamps(true, true); - }); +let buildTables = async function (knex) { + + + console.log("Creating tables..."); + let create = createTable(knex); + + await create('user_roles', function (table) { + table.increments(); + table.string('role_name').unique(); + table.timestamps(true, true); + + }); + + await create('user_permissions', function (table) { + table.increments(); + table.string('permission_name').unique(); + table.timestamps(true, true); + + }); + await create('roles_to_permissions', function (table) { + table.increments(); + table.integer('role_id').references('user_roles.id').onDelete('cascade'); + table.integer('permission_id').references('user_permissions.id').onDelete('cascade'); + table.timestamps(true, true); + + }); + await create('users', function (table) { + table.increments(); + table.integer('role_id').references('user_roles.id'); + table.string('name'); + table.string('email').notNullable().unique(); + table.string('password'); + table.string('provider').defaultTo("local"); + table.enu('status', ['active', 'suspended', 'invited', 'flagged', 'disconnected']).defaultTo('active'); + table.string('customer_id'); + table.string('phone'); + table.string('google_user_id').unique(); + table.string('google_refresh_token'); + table.timestamp('last_login'); + table.timestamps(true, true); + + }); + await create('funds', function (table) { + table.increments(); + table.integer('user_id').references('users.id').onDelete('cascade'); + table.boolean('flagged').defaultTo(false); + table.jsonb('source'); + table.timestamps(true, true); + + }); + await create('invitations', function (table) { + table.increments(); + table.string('token'); + table.integer('user_id').references('users.id').onDelete('cascade'); + table.timestamps(true, true); + + }); + await create('system_options', function (table) { + table.string('option').primary(); + table.string('value'); + table.boolean("public").defaultTo(false); + table.string('type'); + table.string('data_type'); + table.timestamps(true, true); + + }); + await create('event_logs', function (table) { + table.increments(); + table.integer('user_id'); + table.string('log_level'); + table.string('log_type'); + table.string('log'); + table.timestamps(true, true); + + }); + await create('files', function (table) { + table.increments(); + table.integer('user_id').references('users.id').onDelete('cascade'); + table.string('path'); + table.integer('size'); + table.string('name'); + table.string('mimetype'); + table.timestamps(true, true); + + }); + await create('notification_templates', function (table) { + table.increments(); + table.string('name'); + table.string('event_name'); + table.text('message', 'longtext'); + table.string('subject'); + table.string('description'); + table.string("model"); + table.specificType('additional_recipients', 'text[]'); + table.boolean("send_email").defaultTo(false); + table.boolean("send_to_owner").defaultTo(true); + table.boolean("create_notification").default(true); + table.timestamps(true, true); + + }); + await create("notification_templates_to_roles", function (table) { + table.increments(); + table.integer("notification_template_id").references("notification_templates.id"); + table.integer("role_id").references("user_roles.id"); + table.timestamps(true, true); + + }); + await create('notifications', function (table) { + table.increments(); + table.string("source_id").unique(); + table.text('message', 'longtext'); + table.string("type"); + table.integer("user_id").references("users.id").onDelete('cascade'); + table.string("subject"); + table.string("affected_versions").defaultTo("*"); + table.boolean("read").defaultTo(false); + table.boolean("email_delivered").defaultTo(false); + table.boolean("email_read").defaultTo(false); + table.timestamp('created_at').defaultTo(knex.fn.now()); + + }); + await create('service_categories', function (table) { + table.increments(); + table.string('name'); + table.string('description'); + table.timestamps(true, true); + + }); + await create('service_templates', function (table) { + table.increments(); + table.integer('category_id').references('service_categories.id'); + table.integer('created_by').references('users.id'); + table.string('name').notNullable().unique(); + // table.string('description'); + // table.text('details', 'longtext'); + table.boolean('published').defaultTo(false); + // table.string('statement_descriptor'); + // table.integer('trial_period_days'); + // table.float('amount'); + // table.float('overhead'); + // table.string('currency').defaultTo('usd'); + // table.string('interval'); + // table.integer('interval_count').defaultTo(1); + // table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); + // table.boolean('subscription_prorate').defaultTo(true); + // table.jsonb('split_configuration'); + table.timestamps(true, true); + + }); + await create("tiers", table => { + table.increments(); + table.string("name").notNullable(); + table.specificType('features', 'text[]').defaultTo("{}"); + table.integer('service_template_id').notNullable().references('service_templates.id').onDelete('cascade'); + table.unique(['service_template_id', "name"]); + table.timestamps(true, true); + }); + await create("payment_structure_templates", table => { + table.increments(); + table.integer('tier_id').references('tiers.id').onDelete('cascade'); + table.integer('trial_period_days'); + table.bigInteger('amount'); + table.string('currency').defaultTo('usd'); + table.string('interval'); + table.integer('interval_count').defaultTo(1); + table.boolean('subscription_prorate').defaultTo(true); + table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); + table.string('statement_descriptor'); + table.jsonb('split_configuration'); + table.timestamps(true, true); + }); + + await create('service_instances', function (table) { + table.increments(); + table.integer('service_id').references('service_templates.id'); + table.integer('user_id').references('users.id'); + table.integer('requested_by').references('users.id'); + table.jsonb('payment_plan'); + table.string('name'); + table.text('description', 'longtext'); + table.string('subscription_id'); + table.bigInteger('subscribed_at'); + table.bigInteger('trial_end'); + table.integer('payment_structure_template_id').references('payment_structure_templates.id'); + table.enu('status', ['running', 'requested', 'in_progress', 'waiting_cancellation', 'missing_payment', 'cancelled', 'completed', 'cancellation_pending']).defaultTo('missing_payment'); + table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); + table.jsonb('split_configuration'); + table.timestamps(true, true); + + }); + await create('service_instance_messages', function (table) { + table.increments(); + table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); + table.integer('user_id').references('users.id'); + table.string('message'); + table.timestamps(true, true); + + }); + await create('service_instance_cancellations', function (table) { + table.increments(); + table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); + table.integer('user_id').references('users.id'); + table.enu('status', ['waiting', 'approved', 'rejected']).defaultTo('waiting'); + table.integer('fulfilled_by').references('users.id'); + table.timestamps(true, true); + + }); + await create('properties', function (table) { + table.increments(); + table.string('name'); + table.string('type'); + table.jsonb('data'); + table.jsonb('config'); + table.string('prop_class'); + table.string('prop_label'); + table.string('prop_description'); + table.timestamps(true, true); + + }); + await create('service_template_properties', function (table) { + //Inherits the properties table. + table.inherits('properties'); + table.increments(); + table.integer('parent_id').references('service_templates.id').onDelete('cascade'); + table.boolean('private').defaultTo(false); + table.boolean('prompt_user').defaultTo(true); + table.boolean('required').defaultTo(false); + table.timestamps(true, true); + + }); + await create('service_instance_properties', function (table) { + //Inherits the properties table. + table.inherits('properties'); + table.increments(); + table.integer('parent_id').references('service_instances.id').onDelete('cascade'); + table.boolean('private').defaultTo(false); + table.boolean('prompt_user').defaultTo(true); + table.boolean('required').defaultTo(false); + table.timestamps(true, true); + + }); + await create('user_invoices', function (table) { + table.increments(); + table.integer('user_id').references('users.id'); + table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); + table.string('invoice_id').unique(); + table.string('subscription'); + table.string('charge'); + table.string('description'); + table.float('amount_due'); + table.float('discount'); + table.integer('attempt_count'); + table.boolean('closed'); + table.string('currency'); + table.boolean('forgiven'); + table.bigInteger('date'); + table.bigInteger('next_attempt'); + table.boolean('paid'); + table.bigInteger('period_end'); + table.bigInteger('period_start'); + table.string('receipt_number'); + table.float('starting_balance'); + table.float('ending_balance'); + table.float('total'); + table.boolean('livemode'); + table.timestamps(true, true); + + }); + await create('charge_items', function (table) { + table.increments(); + table.integer('user_id').references('users.id'); + table.integer('service_instance_id').references('service_instances.id').onDelete('cascade'); + table.boolean('approved').defaultTo(false); + table.string('subscription_id'); + table.string('item_id'); + table.float('amount'); + table.string('currency').defaultTo('usd'); + table.string('description'); + table.bigInteger('period_start'); + table.bigInteger('period_end'); + table.timestamps(true, true); + + }) + await create('user_invoice_lines', function (table) { + table.increments(); + table.integer('invoice_id').references('user_invoices.id').onDelete('cascade'); + table.string('line_item_id'); + table.float('amount'); + table.string('currency'); + table.string('description'); + table.boolean('proration'); + table.integer('quantity'); + table.string('type'); + table.boolean('livemode'); + table.timestamps(true, true); + + }); + await create('transactions', function (table) { + table.increments(); + table.integer('invoice_id').references('user_invoices.id').onDelete('cascade'); + table.integer('user_id').references('users.id'); + table.string('charge_id'); + table.string('invoice'); + table.float('amount'); + table.boolean('refunded'); + table.float('amount_refunded'); + table.jsonb('refunds'); + table.boolean('captured'); + table.string('currency'); + table.string('dispute'); + table.boolean('paid'); + table.string('description'); + table.string('failure_code'); + table.string('failure_message'); + table.string('statement_descriptor'); + table.string('status'); + table.boolean('livemode'); + table.timestamps(true, true); + + }); + await create('user_upcoming_invoice', function (table) { + table.increments(); + table.integer('user_id').references('users.id').onDelete('cascade'); + table.bigInteger('next_payment'); + table.jsonb('invoice_json'); + table.timestamps(true, true); + console.log("Created 'user_upcoming_invoice' table."); + + }); + await create('password_reset_request', function (table) { + table.increments(); + table.integer('user_id').references('users.id').onDelete('cascade'); + table.string('hash'); + table.timestamps(true, true); + }); + + await create('service_instance_seats', function (table) { + table.increments(); + table.integer('user_id').references('users.id').notNullable().onDelete('cascade'); + table.integer('service_instance_id').notNullable().references("service_instances.id").onDelete("cascade"); + table.unique(["user_id", "service_instance_id"]); + table.string("type").notNullable().defaultTo("seat"); + table.timestamps(true, true); + }); + console.log("***** All Tables successfully created *****"); }; -module.exports = function*(database){ - yield call(buildTables, database); +module.exports = function* (database) { + yield call(buildTables, database); }; \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.10.0.js b/plugins/database/migrations/versions/0.10.0.js new file mode 100644 index 00000000..f67cc9e4 --- /dev/null +++ b/plugins/database/migrations/versions/0.10.0.js @@ -0,0 +1,99 @@ +module.exports = { + + + up: async function (knex) { + let ServiceTemplate = require("../../../../models/base/entity")("service_templates", [], "id", knex); + + await knex.schema.createTable("tiers", table => { + table.increments(); + table.string("name").notNullable(); + table.specificType('features', 'text[]').defaultTo("{}"); + table.integer('service_template_id').notNullable().references('service_templates.id').onDelete("cascade"); + table.unique(['service_template_id', "name"]); + table.timestamps(true, true); + }); + await knex.schema.createTable("payment_structure_templates", table => { + table.increments(); + table.integer('tier_id').references('tiers.id').onDelete('cascade');; + table.integer('trial_period_days'); + table.bigInteger('amount'); + table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); + table.string('currency').defaultTo('usd'); + table.string('interval'); + table.integer('interval_count').defaultTo(1); + table.boolean('subscription_prorate').defaultTo(true); + table.string('statement_descriptor'); + table.jsonb('split_configuration'); + table.timestamps(true, true); + }); + + let templates = await ServiceTemplate.find(); + let tiers = templates.map(template => { + return { + name: template.data.name + "-tier", + service_template_id: template.data.id + } + }); + + let createdTiers = await knex("tiers").insert(tiers).returning("*") || []; + let templateMap = templates.reduce((acc, template) => { + acc[template.data.id] = template.data; + return acc; + }, {}); + let paymentTemplates = createdTiers.map(tier => { + let template = templateMap[tier.service_template_id]; + return { + amount: template.amount, + trial_period_days: template.trial_period_days, + currency: template.currency, + interval: template.interval, + interval_count: template.interval_count, + subscription_prorate: template.subscription_prorate, + statement_descriptor: template.statement_descriptor, + split_configuration: template.split_configuration, + tier_id: tier.id, + type: template.type + } + }); + let createdPayments = await knex("payment_structure_templates").insert(paymentTemplates); + await knex.schema.alterTable("service_templates", table => { + table.dropColumns("description", "type", "overhead", "details", "amount", "currency", "interval", "interval_count", "split_configuration", "statement_descriptor", "trial_period_days", "subscription_prorate") + }); + await knex.schema.alterTable("service_instances", table => { + table.integer('payment_structure_template_id').references('payment_structure_templates.id'); + }); + return await knex; + }, + + down: async function (knex) { + let paymentStructures = await knex("payment_structure_templates").select(); + let tiers = await knex("tiers").select(); + await knex.schema.alterTable("service_templates", table => { + table.integer('trial_period_days'); + table.float('amount'); + table.string('currency').defaultTo('usd'); + table.string('interval'); + table.string('description'); + table.text('details', 'longtext'); + table.integer('interval_count').defaultTo(1); + table.boolean('subscription_prorate').defaultTo(true); + table.string('statement_descriptor'); + table.float('overhead'); + table.jsonb('split_configuration'); + table.enu('type', ['subscription', 'one_time', 'custom', "split"]).defaultTo('subscription'); + + }); + await knex.schema.alterTable("service_instances", table => { + table.dropColumns('payment_structure_template_id'); + }); + for (let struct of paymentStructures) { + let service_template_id = tiers.find(tier => tier.id === struct.tier_id).service_template_id; + delete struct.id; + delete struct.tier_id; + await knex("service_templates").update(struct).where("id", service_template_id); + } + await knex.schema.dropTable("payment_structure_templates"); + await knex.schema.dropTable("tiers"); + + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.10.43.js b/plugins/database/migrations/versions/0.10.43.js new file mode 100644 index 00000000..17607b1c --- /dev/null +++ b/plugins/database/migrations/versions/0.10.43.js @@ -0,0 +1,24 @@ +module.exports = { + + + up: async function (knex) { + let permission = await knex("user_permissions").where("permission_name", "post_service_instances_id_change_properties"); + if(permission.length === 0){ + let permission_id = (await knex("user_permissions").returning("id").insert({"permission_name" : "post_service_instances_id_change_properties"}))[0]; + let rolesToPermission = [ + {role_id : 1, permission_id}, + {role_id : 2, permission_id}, + {role_id : 3, permission_id} + ] + let r2p = await knex("roles_to_permissions").insert(rolesToPermission); + }else{ + console.log("permission already present!"); + } + return await knex; + }, + + down: async function (knex) { + return await knex; + + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.0.js b/plugins/database/migrations/versions/0.11.0.js new file mode 100644 index 00000000..3f8ef7e4 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.0.js @@ -0,0 +1,30 @@ +module.exports = { + + + up: async function (knex) { + await knex.schema.createTable("service_instance_seats", table => { + table.increments(); + table.integer('user_id').references('users.id').notNullable().onDelete('cascade'); + table.integer('service_instance_id').notNullable().references("service_instances.id").onDelete("cascade"); + table.unique(["user_id", "service_instance_id"]); + table.string("type").notNullable().defaultTo("seat"); + table.timestamps(true, true); + }); + await knex.schema.alterTable("users", table => { + table.string('google_user_id').unique(); + }); + + + return await knex; + }, + + down: async function (knex) { + await knex.schema.alterTable("users", table => { + table.dropColumns("google_user_id"); + }); + await knex.schema.dropTable("service_instance_seats"); + + return await knex; + + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.101.js b/plugins/database/migrations/versions/0.11.101.js new file mode 100644 index 00000000..5e349b57 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.101.js @@ -0,0 +1,16 @@ +module.exports = { + + + up: async function (knex) { + await knex.schema.raw(` + ALTER TABLE "service_instances" + DROP CONSTRAINT "service_instances_status_check", + ADD CONSTRAINT "service_instances_status_check" + CHECK (status IN ('running', 'requested', 'in_progress', 'waiting_cancellation', 'missing_payment', 'cancelled', 'completed', 'cancellation_pending'))`); + + return await knex; + }, + + down: async function (knex) { + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.104.js b/plugins/database/migrations/versions/0.11.104.js new file mode 100644 index 00000000..c78033b2 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.104.js @@ -0,0 +1,566 @@ +module.exports = { + + + up: async function (knex) { + + var registrationUserEmail = { + name: "registration_user", + event_name: "service_instance_requested_by_user", + message: `
+ +
Powered by
+
`, + subject: "Welcome to [[_company_name]]", + description: "Sent to users when they sign up", + model: "service-instance", + send_email: false, + send_to_owner: true + }; + let newEmails = [ + + { + name: "new_invoice", + event_name: "new_invoice", + message: `
+ +
+ Powered by + + +
+
`, + subject: "Thank you for the payment", + description: "Sent to users when a new invoice is generated", + model: "invoice", + send_email: false, + send_to_owner: true + }, + { + name: "resubscribe_notification_admin", + event_name: "service_instance_resubscribed", + message: `
+ +
Powered by
+
`, + subject: "Account has resubscribed to [[_company_name]]!", + description: "Sent to admins when a user resubscribed", + model: "service-instance", + send_email: false, + send_to_owner: false + }, + { + name: "resubscribe_notification_user", + event_name: "service_instance_resubscribed", + message: `
+ +
Powered by
+
`, + subject: "We are happy to see you back!", + description: "Sent to users when they resubscribe", + model: "service-instance", + send_email: false, + send_to_owner: true + }, + { + name: "service_cancellation_goodbye", + event_name: "service_instance_cancellation_requested", + message: `
+ +
Powered by
+
`, + subject: "We're sad to let you go", + description: "Sent to a user after they cancel their subscription", + model: "service-instance-cancellation", + send_email: false + }, + { + name: "registration_enterprise_user", + event_name: "service_instance_custom_requested_by_user", + message: `
+ +
Powered by
+
`, + subject: "Pricing request received", + description: "Sent to customer when an enterprise service is requested", + model: "service-instance", + send_email: false, + send_to_owner: true + }, + { + name: "registration_enterprise_admin", + event_name: "service_instance_custom_requested_by_user", + message: `
+ +
Powered by
+
`, + subject: "New pricing request", + description: "Sent to admins when an enterprise service is requested", + model: "service-instance", + send_email: true, + send_to_owner: false + }, + { + name: "service_instance_plan_change_user", + event_name: "service_instance_plan_change", + message: `
+ +
Powered by
+
`, + subject: "Your [[_company_name]] plan has changed", + description: "Sent to users when a payment plan has been changed", + model: "service-instance", + send_email: false, + send_to_owner: true + + }, + { + name: "service_instance_plan_change_admin", + event_name: "service_instance_plan_change", + message: `
+ +
Powered by
+
`, + subject: "[[references.users.email]] has changed their plan", + description: "Sent to admins when a service payment plan has been changed", + model: "service-instance", + send_email: false, + send_to_owner: false + }, + { + name: "trial_expiration", + event_name: "service_instance_trial_expired", + message: `
+ +
Powered by
+
`, + subject: "Your free trial has expired", + description: "Sent when a free trial has ended", + model: "service-instance", + send_email: false, + send_to_owner: true + } + ]; + let emails = [ + + { + name: "password_reset", + event_name: "password_reset_request_created", + message: `
+ +
Powered by
+
`, + subject: "Password Reset", + description: "Sent when a user requests a password reset", + model: "user", + send_email: true + }, + { + name: "registration_admin", + event_name: "service_instance_requested_by_user", + message: `
+ +
Powered by
+
`, + subject: "New signup for [[_company_name]]!", + description: "Sent to admins when a new user has signed up", + model: "service-instance", + send_email: true, + send_to_owner: false + }, + { + name: "payment_failure", + event_name: "payment_failure", + message: `
+ +
Powered by
+
`, + subject: "Oh no, your payment failed", + description: "Sent when a payment has failed to go through. It notifies the user to update their payment method", + model: "user", + send_email: true + }, + {name:"invitation", + event_name:"user_invited", + message:`
+ +
Powered by
+
`, + subject:"Invitation", + description:"Sent when a user is invited to they system by an admin", + model:"user", + send_email:true + } + ]; + + let regUser = await knex("notification_templates").where("name", "registration_user"); + if(regUser.length > 0){ + emails.push(registrationUserEmail); + }else{ + newEmails.push(registrationUserEmail); + } + for(let email of emails){ + await knex("notification_templates").where("name", email.name).update(email) + } + + await knex("notification_templates").where("name", "service_cancellation_submitted").update({ + name: "service_cancellation", + event_name: "service_instance_cancellation_requested", + message: `
+ +
Powered by
+
`, + subject: "User just cancelled a subscription", + description: "Sent when a service cancellation has been requested by a user", + model: "service-instance", + send_email: false, + send_to_owner: false + }); + + let updated = await knex("notification_templates").where("name", "service_cancellation"); + + let newRecords = await knex("notification_templates").returning('*').insert(newEmails); + + let admin = await knex("notification_templates_to_roles").returning("id").insert([{ + notification_template_id: newRecords[1].id, + role_id: 1 + + }, + { + notification_template_id: updated[0].id, + role_id: 1 + }, + { + notification_template_id: newRecords[5].id, + role_id: 1 + }, + { + notification_template_id: newRecords[7].id, + role_id: 1 + }]) + var templateNamesToDelete = ["request_service_instance_admin", "request_service_instance_user", "request_service_instance_new_user", "service_requires_payment_approval", "service_instance_update", "instance_cancellation_rejected", "instance_cancellation_approved", "user_suspension"]; + let toDelete = (await knex("notification_templates").returning("*").whereIn("name", templateNamesToDelete)).map(template => template.id); + await knex("notification_templates_to_roles").whereIn("notification_template_id", toDelete).delete(); + await knex("notification_templates").whereIn("name", templateNamesToDelete).delete(); + return await knex; + }, + + down: async function (knex) { + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.18.js b/plugins/database/migrations/versions/0.11.18.js new file mode 100644 index 00000000..ca3fe388 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.18.js @@ -0,0 +1,635 @@ +module.exports = { + + up: async function (knex) { + await knex("notification_templates").where({name: "invitation"}).update({ + subject: "Invitation", + message: ` + + + + +
+
+ + + This is preheader text. Some clients will show this text as a preview. + + + + +
+ + +
+

Hi there,

+

You have been invited, click below to finish your account.

+ + + + + + +
+ + + + + + +
Complete Registration
+
+
+
+
` + }); + + await knex("notification_templates").where({name: "password_reset"}).update({ + message: ` + + + + +
+
+ + + Password Reset Request + + + + +
+ + +
+

Hi there,

+

You have requested a password reset, click below to set a new password.

+ + + + + + +
+ + + + + + +
Reset Password
+
+
+
+
`, + subject: "Password Reset" + }); + return await knex; + }, + + down: async function (knex) { + + return await knex; + + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.81.js b/plugins/database/migrations/versions/0.11.81.js new file mode 100644 index 00000000..82deb633 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.81.js @@ -0,0 +1,22 @@ +module.exports = { + + + up: async function (knex) { + + await knex.schema.alterTable("users", table => { + table.string('google_refresh_token'); + }); + + + return await knex; + }, + + down: async function (knex) { + await knex.schema.alterTable("users", table => { + table.dropColumns("google_refresh_token"); + }); + + return await knex; + + } +} \ No newline at end of file diff --git a/plugins/database/migrations/versions/0.11.91.js b/plugins/database/migrations/versions/0.11.91.js new file mode 100644 index 00000000..21aac5b0 --- /dev/null +++ b/plugins/database/migrations/versions/0.11.91.js @@ -0,0 +1,22 @@ +module.exports = { + + + up: async function (knex) { + await knex.schema.raw(` + ALTER TABLE "service_instances" + DROP CONSTRAINT "service_instances_status_check", + ADD CONSTRAINT "service_instances_status_check" + CHECK (status IN ('running', 'requested', 'in_progress', 'waiting_cancellation', 'missing_payment', 'cancelled', 'completed', 'cancellation_pending'))`); + + return await knex; + }, + + down: async function (knex) { + await knex.schema.raw(` + ALTER TABLE "service_instances" + DROP CONSTRAINT "service_instances_status_check", + ADD CONSTRAINT "service_instances_status_check" + CHECK (status IN ('running', 'requested', 'in_progress', 'waiting_cancellation', 'missing_payment', 'cancelled', 'completed'))`); + return knex; +} +} \ No newline at end of file diff --git a/plugins/database/populate.js b/plugins/database/populate.js index 7ed128aa..1f552b01 100644 --- a/plugins/database/populate.js +++ b/plugins/database/populate.js @@ -144,9 +144,7 @@ module.exports = function (database, initConfig) { {"option": "company_email", "value": initConfig.company_email}, {"option": "hostname", "value": initConfig.hostname} ]; - SystemOption.batchUpdate(options, function (result) { - return resolve(result); - }) + return resolve(SystemOption.batchUpdate(options)); }); }).then(options => { return createAdmin(initConfig) diff --git a/plugins/database/tests/model-paths.json b/plugins/database/tests/model-paths.json new file mode 100644 index 00000000..d0172abb --- /dev/null +++ b/plugins/database/tests/model-paths.json @@ -0,0 +1,3388 @@ +{ + "/users": { + "get": { + "summary": "Get users", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "get_users", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of users", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/users" + } + } + } + } + } + }, + "/users/search": { + "get": { + "summary": "Get users", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "get_users_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredusers", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/users" + } + } + } + } + } + }, + "/users/{id}": { + "get": { + "summary": "Get users by id", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "get_users_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "users id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "users with id", + "schema": { + "$ref": "#/definitions/users" + } + } + } + }, + "put": { + "summary": "Update users", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "put_users_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "users id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/users" + } + } + ], + "responses": { + "200": { + "description": "users with id", + "schema": { + "$ref": "#/definitions/users" + } + } + } + }, + "delete": { + "summary": "Delete users by id", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_users_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "users id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "users that was deleted", + "schema": { + "$ref": "#/definitions/users" + } + } + } + } + }, + "/users/own": { + "get": { + "summary": "Get requester's users", + "tags": [ + "users" + ], + "produces": [ + "application/json" + ], + "operationId": "get_users_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of users, owned by requester", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/users" + } + } + } + } + } + }, + "/event-logs": { + "get": { + "summary": "Get event_logs", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "get_event_logs", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of event_logs", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/event_logs" + } + } + } + } + }, + "post": { + "summary": "Create new event_logs", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "post_event_logs", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "event_logs to create", + "required": true, + "schema": { + "$ref": "#/definitions/event_logs" + } + } + ], + "responses": { + "200": { + "description": "event_logs with id", + "schema": { + "$ref": "#/definitions/event_logs" + } + } + } + } + }, + "/event-logs/search": { + "get": { + "summary": "Get event_logs", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "get_event_logs_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredevent_logs", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/event_logs" + } + } + } + } + } + }, + "/event-logs/{id}": { + "get": { + "summary": "Get event_logs by id", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "get_event_logs_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "event_logs id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "event_logs with id", + "schema": { + "$ref": "#/definitions/event_logs" + } + } + } + }, + "put": { + "summary": "Update event_logs", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "put_event_logs_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "event_logs id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/event_logs" + } + } + ], + "responses": { + "200": { + "description": "event_logs with id", + "schema": { + "$ref": "#/definitions/event_logs" + } + } + } + }, + "delete": { + "summary": "Delete event_logs by id", + "tags": [ + "event-logs" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_event_logs_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "event_logs id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "event_logs that was deleted", + "schema": { + "$ref": "#/definitions/event_logs" + } + } + } + } + }, + "/funds": { + "get": { + "summary": "Get funds", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "get_funds", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of funds", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/funds" + } + } + } + } + }, + "post": { + "summary": "Create new funds", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "post_funds", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "funds to create", + "required": true, + "schema": { + "$ref": "#/definitions/funds" + } + } + ], + "responses": { + "200": { + "description": "funds with id", + "schema": { + "$ref": "#/definitions/funds" + } + } + } + } + }, + "/funds/search": { + "get": { + "summary": "Get funds", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "get_funds_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredfunds", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/funds" + } + } + } + } + } + }, + "/funds/{id}": { + "get": { + "summary": "Get funds by id", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "get_funds_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "funds id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "funds with id", + "schema": { + "$ref": "#/definitions/funds" + } + } + } + }, + "put": { + "summary": "Update funds", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "put_funds_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "funds id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/funds" + } + } + ], + "responses": { + "200": { + "description": "funds with id", + "schema": { + "$ref": "#/definitions/funds" + } + } + } + } + }, + "/funds/own": { + "get": { + "summary": "Get requester's funds", + "tags": [ + "funds" + ], + "produces": [ + "application/json" + ], + "operationId": "get_funds_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of funds, owned by requester", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/funds" + } + } + } + } + } + }, + "/invoices": { + "get": { + "summary": "Get invoices", + "tags": [ + "invoices" + ], + "produces": [ + "application/json" + ], + "operationId": "get_invoices", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of invoices", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/invoices" + } + } + } + } + } + }, + "/invoices/search": { + "get": { + "summary": "Get invoices", + "tags": [ + "invoices" + ], + "produces": [ + "application/json" + ], + "operationId": "get_invoices_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredinvoices", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/invoices" + } + } + } + } + } + }, + "/invoices/{id}": { + "get": { + "summary": "Get invoices by id", + "tags": [ + "invoices" + ], + "produces": [ + "application/json" + ], + "operationId": "get_invoices_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "invoices id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "invoices with id", + "schema": { + "$ref": "#/definitions/invoices" + } + } + } + } + }, + "/invoices/own": { + "get": { + "summary": "Get requester's invoices", + "tags": [ + "invoices" + ], + "produces": [ + "application/json" + ], + "operationId": "get_invoices_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of invoices, owned by requester", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/invoices" + } + } + } + } + } + }, + "/notification-templates": { + "get": { + "summary": "Get notification_templates", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notification_templates", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of notification_templates", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/notification_templates" + } + } + } + } + }, + "post": { + "summary": "Create new notification_templates", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "post_notification_templates", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "notification_templates to create", + "required": true, + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + ], + "responses": { + "200": { + "description": "notification_templates with id", + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + } + } + }, + "/notification-templates/search": { + "get": { + "summary": "Get notification_templates", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notification_templates_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filterednotification_templates", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/notification_templates" + } + } + } + } + } + }, + "/notification-templates/{id}": { + "get": { + "summary": "Get notification_templates by id", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notification_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notification_templates id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "notification_templates with id", + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + } + }, + "put": { + "summary": "Update notification_templates", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "put_notification_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notification_templates id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + ], + "responses": { + "200": { + "description": "notification_templates with id", + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + } + }, + "delete": { + "summary": "Delete notification_templates by id", + "tags": [ + "notification-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_notification_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notification_templates id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "notification_templates that was deleted", + "schema": { + "$ref": "#/definitions/notification_templates" + } + } + } + } + }, + "/notifications": { + "get": { + "summary": "Get notifications", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notifications", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of notifications", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/notifications" + } + } + } + } + }, + "post": { + "summary": "Create new notifications", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "post_notifications", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "notifications to create", + "required": true, + "schema": { + "$ref": "#/definitions/notifications" + } + } + ], + "responses": { + "200": { + "description": "notifications with id", + "schema": { + "$ref": "#/definitions/notifications" + } + } + } + } + }, + "/notifications/search": { + "get": { + "summary": "Get notifications", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notifications_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filterednotifications", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/notifications" + } + } + } + } + } + }, + "/notifications/{id}": { + "get": { + "summary": "Get notifications by id", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notifications_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notifications id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "notifications with id", + "schema": { + "$ref": "#/definitions/notifications" + } + } + } + }, + "put": { + "summary": "Update notifications", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "put_notifications_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notifications id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/notifications" + } + } + ], + "responses": { + "200": { + "description": "notifications with id", + "schema": { + "$ref": "#/definitions/notifications" + } + } + } + }, + "delete": { + "summary": "Delete notifications by id", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_notifications_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "notifications id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "notifications that was deleted", + "schema": { + "$ref": "#/definitions/notifications" + } + } + } + } + }, + "/notifications/own": { + "get": { + "summary": "Get requester's notifications", + "tags": [ + "notifications" + ], + "produces": [ + "application/json" + ], + "operationId": "get_notifications_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of notifications, owned by requester", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/notifications" + } + } + } + } + } + }, + "/permissions": { + "get": { + "summary": "Get user_permissions", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "get_permissions", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of user_permissions", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/user_permissions" + } + } + } + } + }, + "post": { + "summary": "Create new user_permissions", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "post_permissions", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "user_permissions to create", + "required": true, + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + ], + "responses": { + "200": { + "description": "user_permissions with id", + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + } + } + }, + "/permissions/search": { + "get": { + "summary": "Get user_permissions", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "get_permissions_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filtereduser_permissions", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/user_permissions" + } + } + } + } + } + }, + "/permissions/{id}": { + "get": { + "summary": "Get user_permissions by id", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "get_permissions_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_permissions id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "user_permissions with id", + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + } + }, + "put": { + "summary": "Update user_permissions", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "put_permissions_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_permissions id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + ], + "responses": { + "200": { + "description": "user_permissions with id", + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + } + }, + "delete": { + "summary": "Delete user_permissions by id", + "tags": [ + "permissions" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_permissions_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_permissions id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "user_permissions that was deleted", + "schema": { + "$ref": "#/definitions/user_permissions" + } + } + } + } + }, + "/roles": { + "get": { + "summary": "Get user_roles", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "get_roles", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of user_roles", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/user_roles" + } + } + } + } + }, + "post": { + "summary": "Create new user_roles", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "post_roles", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "user_roles to create", + "required": true, + "schema": { + "$ref": "#/definitions/user_roles" + } + } + ], + "responses": { + "200": { + "description": "user_roles with id", + "schema": { + "$ref": "#/definitions/user_roles" + } + } + } + } + }, + "/roles/search": { + "get": { + "summary": "Get user_roles", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "get_roles_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filtereduser_roles", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/user_roles" + } + } + } + } + } + }, + "/roles/{id}": { + "get": { + "summary": "Get user_roles by id", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "get_roles_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_roles id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "user_roles with id", + "schema": { + "$ref": "#/definitions/user_roles" + } + } + } + }, + "put": { + "summary": "Update user_roles", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "put_roles_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_roles id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/user_roles" + } + } + ], + "responses": { + "200": { + "description": "user_roles with id", + "schema": { + "$ref": "#/definitions/user_roles" + } + } + } + }, + "delete": { + "summary": "Delete user_roles by id", + "tags": [ + "roles" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_roles_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "user_roles id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "user_roles that was deleted", + "schema": { + "$ref": "#/definitions/user_roles" + } + } + } + } + }, + "/service-categories": { + "get": { + "summary": "Get service_categories", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_categories", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_categories", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_categories" + } + } + } + } + }, + "post": { + "summary": "Create new service_categories", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_categories", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_categories to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_categories" + } + } + ], + "responses": { + "200": { + "description": "service_categories with id", + "schema": { + "$ref": "#/definitions/service_categories" + } + } + } + } + }, + "/service-categories/search": { + "get": { + "summary": "Get service_categories", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_categories_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_categories", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_categories" + } + } + } + } + } + }, + "/service-categories/{id}": { + "get": { + "summary": "Get service_categories by id", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_categories_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_categories id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_categories with id", + "schema": { + "$ref": "#/definitions/service_categories" + } + } + } + }, + "put": { + "summary": "Update service_categories", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_categories_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_categories id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_categories" + } + } + ], + "responses": { + "200": { + "description": "service_categories with id", + "schema": { + "$ref": "#/definitions/service_categories" + } + } + } + }, + "delete": { + "summary": "Delete service_categories by id", + "tags": [ + "service-categories" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_categories_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_categories id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_categories that was deleted", + "schema": { + "$ref": "#/definitions/service_categories" + } + } + } + } + }, + "/service-instance-cancellations": { + "get": { + "summary": "Get service_instance_cancellations", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_cancellations", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_instance_cancellations", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + } + }, + "post": { + "summary": "Create new service_instance_cancellations", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_instance_cancellations", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_instance_cancellations to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + ], + "responses": { + "200": { + "description": "service_instance_cancellations with id", + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + } + }, + "/service-instance-cancellations/search": { + "get": { + "summary": "Get service_instance_cancellations", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_cancellations_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_instance_cancellations", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + } + } + }, + "/service-instance-cancellations/{id}": { + "get": { + "summary": "Get service_instance_cancellations by id", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_cancellations_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_cancellations id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_cancellations with id", + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + }, + "put": { + "summary": "Update service_instance_cancellations", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_instance_cancellations_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_cancellations id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + ], + "responses": { + "200": { + "description": "service_instance_cancellations with id", + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + }, + "delete": { + "summary": "Delete service_instance_cancellations by id", + "tags": [ + "service-instance-cancellations" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_instance_cancellations_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_cancellations id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_cancellations that was deleted", + "schema": { + "$ref": "#/definitions/service_instance_cancellations" + } + } + } + } + }, + "/service-instance-messages": { + "get": { + "summary": "Get service_instance_messages", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_messages", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_instance_messages", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + } + }, + "post": { + "summary": "Create new service_instance_messages", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_instance_messages", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_instance_messages to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + ], + "responses": { + "200": { + "description": "service_instance_messages with id", + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + } + }, + "/service-instance-messages/search": { + "get": { + "summary": "Get service_instance_messages", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_messages_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_instance_messages", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + } + } + }, + "/service-instance-messages/{id}": { + "get": { + "summary": "Get service_instance_messages by id", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_messages_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_messages id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_messages with id", + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + }, + "put": { + "summary": "Update service_instance_messages", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_instance_messages_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_messages id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + ], + "responses": { + "200": { + "description": "service_instance_messages with id", + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + }, + "delete": { + "summary": "Delete service_instance_messages by id", + "tags": [ + "service-instance-messages" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_instance_messages_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_messages id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_messages that was deleted", + "schema": { + "$ref": "#/definitions/service_instance_messages" + } + } + } + } + }, + "/service-instance-properties": { + "get": { + "summary": "Get service_instance_properties", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_properties", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_instance_properties", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + } + }, + "post": { + "summary": "Create new service_instance_properties", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_instance_properties", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_instance_properties to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + ], + "responses": { + "200": { + "description": "service_instance_properties with id", + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + } + }, + "/service-instance-properties/search": { + "get": { + "summary": "Get service_instance_properties", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_properties_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_instance_properties", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + } + } + }, + "/service-instance-properties/{id}": { + "get": { + "summary": "Get service_instance_properties by id", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instance_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_properties id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_properties with id", + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + }, + "put": { + "summary": "Update service_instance_properties", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_instance_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_properties id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + ], + "responses": { + "200": { + "description": "service_instance_properties with id", + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + }, + "delete": { + "summary": "Delete service_instance_properties by id", + "tags": [ + "service-instance-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_instance_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instance_properties id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instance_properties that was deleted", + "schema": { + "$ref": "#/definitions/service_instance_properties" + } + } + } + } + }, + "/service-instances": { + "get": { + "summary": "Get service_instances", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instances", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_instances", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instances" + } + } + } + } + } + }, + "/service-instances/search": { + "get": { + "summary": "Get service_instances", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instances_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_instances", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instances" + } + } + } + } + } + }, + "/service-instances/{id}": { + "get": { + "summary": "Get service_instances by id", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instances_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instances id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instances with id", + "schema": { + "$ref": "#/definitions/service_instances" + } + } + } + }, + "put": { + "summary": "Update service_instances", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_instances_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instances id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_instances" + } + } + ], + "responses": { + "200": { + "description": "service_instances with id", + "schema": { + "$ref": "#/definitions/service_instances" + } + } + } + }, + "delete": { + "summary": "Delete service_instances by id", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_instances_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_instances id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_instances that was deleted", + "schema": { + "$ref": "#/definitions/service_instances" + } + } + } + } + }, + "/service-instances/own": { + "get": { + "summary": "Get requester's service_instances", + "tags": [ + "service-instances" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_instances_own", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_instances, owned by requester", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_instances" + } + } + } + } + } + }, + "/service-template-properties": { + "get": { + "summary": "Get service_template_properties", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_template_properties", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_template_properties", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_template_properties" + } + } + } + } + }, + "post": { + "summary": "Create new service_template_properties", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_template_properties", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_template_properties to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + ], + "responses": { + "200": { + "description": "service_template_properties with id", + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + } + } + }, + "/service-template-properties/search": { + "get": { + "summary": "Get service_template_properties", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_template_properties_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_template_properties", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_template_properties" + } + } + } + } + } + }, + "/service-template-properties/{id}": { + "get": { + "summary": "Get service_template_properties by id", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_template_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_template_properties id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_template_properties with id", + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + } + }, + "put": { + "summary": "Update service_template_properties", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_template_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_template_properties id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + ], + "responses": { + "200": { + "description": "service_template_properties with id", + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + } + }, + "delete": { + "summary": "Delete service_template_properties by id", + "tags": [ + "service-template-properties" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_template_properties_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_template_properties id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_template_properties that was deleted", + "schema": { + "$ref": "#/definitions/service_template_properties" + } + } + } + } + }, + "/service-templates": { + "get": { + "summary": "Get service_templates", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_templates", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of service_templates", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_templates" + } + } + } + } + }, + "post": { + "summary": "Create new service_templates", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "post_service_templates", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "service_templates to create", + "required": true, + "schema": { + "$ref": "#/definitions/service_templates" + } + } + ], + "responses": { + "200": { + "description": "service_templates with id", + "schema": { + "$ref": "#/definitions/service_templates" + } + } + } + } + }, + "/service-templates/search": { + "get": { + "summary": "Get service_templates", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_templates_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredservice_templates", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/service_templates" + } + } + } + } + } + }, + "/service-templates/{id}": { + "get": { + "summary": "Get service_templates by id", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "get_service_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_templates id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_templates with id", + "schema": { + "$ref": "#/definitions/service_templates" + } + } + } + }, + "put": { + "summary": "Update service_templates", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "put_service_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_templates id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/service_templates" + } + } + ], + "responses": { + "200": { + "description": "service_templates with id", + "schema": { + "$ref": "#/definitions/service_templates" + } + } + } + }, + "delete": { + "summary": "Delete service_templates by id", + "tags": [ + "service-templates" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_service_templates_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "service_templates id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "service_templates that was deleted", + "schema": { + "$ref": "#/definitions/service_templates" + } + } + } + } + }, + "/webhooks": { + "get": { + "summary": "Get webhooks", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "get_webhooks", + "security": [ + { + "internalApiKey": [] + } + ], + "responses": { + "200": { + "description": "An array of webhooks", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/webhooks" + } + } + } + } + }, + "post": { + "summary": "Create new webhooks", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "post_webhooks", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "data", + "in": "body", + "description": "webhooks to create", + "required": true, + "schema": { + "$ref": "#/definitions/webhooks" + } + } + ], + "responses": { + "200": { + "description": "webhooks with id", + "schema": { + "$ref": "#/definitions/webhooks" + } + } + } + } + }, + "/webhooks/search": { + "get": { + "summary": "Get webhooks", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "get_webhooks_search", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "key", + "in": "query", + "description": "Attribute to search by", + "required": true, + "type": "string" + }, + { + "name": "value", + "in": "query", + "description": "Value to search for", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "An array of filteredwebhooks", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/webhooks" + } + } + } + } + } + }, + "/webhooks/{id}": { + "get": { + "summary": "Get webhooks by id", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "get_webhooks_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "webhooks id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "webhooks with id", + "schema": { + "$ref": "#/definitions/webhooks" + } + } + } + }, + "put": { + "summary": "Update webhooks", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "put_webhooks_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "webhooks id", + "required": true, + "type": "number", + "format": "double" + }, + { + "name": "data", + "in": "body", + "description": "Data to update", + "required": true, + "schema": { + "$ref": "#/definitions/webhooks" + } + } + ], + "responses": { + "200": { + "description": "webhooks with id", + "schema": { + "$ref": "#/definitions/webhooks" + } + } + } + }, + "delete": { + "summary": "Delete webhooks by id", + "tags": [ + "webhooks" + ], + "produces": [ + "application/json" + ], + "operationId": "delete_webhooks_id", + "security": [ + { + "internalApiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "webhooks id", + "required": true, + "type": "number", + "format": "double" + } + ], + "responses": { + "200": { + "description": "webhooks that was deleted", + "schema": { + "$ref": "#/definitions/webhooks" + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/database/tests/refresh_version.js b/plugins/database/tests/refresh_version.js index 07d780d8..48c3c2fc 100644 --- a/plugins/database/tests/refresh_version.js +++ b/plugins/database/tests/refresh_version.js @@ -3,5 +3,9 @@ require('dotenv').config({path: require("path").join(__dirname, '../../../env/.e let knex = require("../../../config/db"); -//require("../migrations/versions/0.9.0").down(knex); -require("../migrations/versions/0.9.0").up(knex); \ No newline at end of file +// require("../migrations/versions/0.9.0").down(knex); +try { + require("../migrations/versions/0.10.0").down(knex).catch(error => console.log(error)); +}catch(e){ + console.error(e); +} \ No newline at end of file diff --git a/plugins/database/tests/swagger.json b/plugins/database/tests/swagger.json new file mode 100644 index 00000000..2d0ad92c --- /dev/null +++ b/plugins/database/tests/swagger.json @@ -0,0 +1 @@ +{"charge_items":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"service_instance_id":{"type":"integer"},"approved":{"type":"boolean"},"subscription_id":{"maxLength":255,"type":"string"},"item_id":{"maxLength":255,"type":"string"},"amount":{"format":"float","type":"number"},"currency":{"maxLength":255,"type":"string"},"description":{"maxLength":255,"type":"string"},"period_start":{"format":"int64","type":"integer"},"period_end":{"format":"int64","type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"event_logs":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"log_level":{"maxLength":255,"type":"string"},"log_type":{"maxLength":255,"type":"string"},"log":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"files":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"path":{"maxLength":255,"type":"string"},"size":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"mimetype":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"funds":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"flagged":{"type":"boolean"},"source":{"type":"object"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"invitations":{"type":"object","properties":{"id":{"type":"integer"},"token":{"maxLength":255,"type":"string"},"user_id":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"user_invoice_lines":{"type":"object","properties":{"id":{"type":"integer"},"invoice_id":{"type":"integer"},"line_item_id":{"maxLength":255,"type":"string"},"amount":{"format":"float","type":"number"},"currency":{"maxLength":255,"type":"string"},"description":{"maxLength":255,"type":"string"},"proration":{"type":"boolean"},"quantity":{"type":"integer"},"type":{"maxLength":255,"type":"string"},"livemode":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"notification_templates":{"type":"object","properties":{"id":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"event_name":{"maxLength":255,"type":"string"},"message":{"type":"string"},"subject":{"maxLength":255,"type":"string"},"description":{"maxLength":255,"type":"string"},"model":{"maxLength":255,"type":"string"},"additional_recipients":{"items":{"type":"string","format":"email"},"type":"array"},"send_email":{"type":"boolean"},"send_to_owner":{"type":"boolean"},"create_notification":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"notifications":{"type":"object","properties":{"id":{"type":"integer"},"source_id":{"maxLength":255,"type":"string"},"message":{"type":"string"},"type":{"maxLength":255,"type":"string"},"user_id":{"type":"integer"},"subject":{"maxLength":255,"type":"string"},"affected_versions":{"maxLength":255,"type":"string"},"read":{"type":"boolean"},"email_delivered":{"type":"boolean"},"email_read":{"type":"boolean"},"created_at":{"type":"string"}}},"password_reset_request":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"hash":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"user_permissions":{"type":"object","properties":{"id":{"type":"integer"},"permission_name":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"user_roles":{"type":"object","properties":{"id":{"type":"integer"},"role_name":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"service_categories":{"type":"object","properties":{"id":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"description":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"service_instances":{"type":"object","properties":{"id":{"type":"integer"},"service_id":{"type":"integer"},"user_id":{"type":"integer"},"requested_by":{"type":"integer"},"payment_plan":{"type":"object"},"name":{"maxLength":255,"type":"string"},"description":{"type":"string"},"subscription_id":{"maxLength":255,"type":"string"},"subscribed_at":{"format":"int64","type":"integer"},"trial_end":{"format":"int64","type":"integer"},"status":{"type":"string"},"type":{"type":"string"},"split_configuration":{"type":"object"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"references":{"type":"object","properties":{"service_instance_properties":{"type":"array","items":[{"$ref":"#/definitions/service_instance_properties"}]},"service_instance_messages":{"type":"array","items":[{"$ref":"#/definitions/service_instance_messages"}]},"charge_items":{"type":"array","items":[{"$ref":"#/definitions/charge_items"}]},"service_instance_cancellations":{"type":"array","items":[{"$ref":"#/definitions/service_instance_cancellations"}]},"users":{"type":"array","items":[{"$ref":"#/definitions/users"}]}}}}},"service_instance_cancellations":{"type":"object","properties":{"id":{"type":"integer"},"service_instance_id":{"type":"integer"},"user_id":{"type":"integer"},"status":{"type":"string"},"fulfilled_by":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"service_instance_messages":{"type":"object","properties":{"id":{"type":"integer"},"service_instance_id":{"type":"integer"},"user_id":{"type":"integer"},"message":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"references":{"type":"object","properties":{"users":{"type":"array","items":[{"$ref":"#/definitions/users"}]}}}}},"service_instance_properties":{"type":"object","properties":{"id":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"type":{"maxLength":255,"type":"string"},"data":{"type":"object"},"config":{"type":"object"},"prop_class":{"maxLength":255,"type":"string"},"prop_label":{"maxLength":255,"type":"string"},"prop_description":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"parent_id":{"type":"integer"},"private":{"type":"boolean"},"prompt_user":{"type":"boolean"},"required":{"type":"boolean"}}},"service_template_properties":{"type":"object","properties":{"id":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"type":{"maxLength":255,"type":"string"},"data":{"type":"object"},"config":{"type":"object"},"prop_class":{"maxLength":255,"type":"string"},"prop_label":{"maxLength":255,"type":"string"},"prop_description":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"parent_id":{"type":"integer"},"private":{"type":"boolean"},"prompt_user":{"type":"boolean"},"required":{"type":"boolean"}}},"service_templates":{"type":"object","properties":{"id":{"type":"integer"},"category_id":{"type":"integer"},"created_by":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"description":{"maxLength":255,"type":"string"},"details":{"type":"string"},"published":{"type":"boolean"},"statement_descriptor":{"maxLength":255,"type":"string"},"trial_period_days":{"type":"integer"},"amount":{"format":"float","type":"number"},"overhead":{"format":"float","type":"number"},"currency":{"maxLength":255,"type":"string"},"interval":{"maxLength":255,"type":"string"},"interval_count":{"type":"integer"},"type":{"type":"string"},"subscription_prorate":{"type":"boolean"},"split_configuration":{"type":"object"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"references":{"type":"object","properties":{"service_template_properties":{"type":"array","items":[{"$ref":"#/definitions/service_template_properties"}]},"service_categories":{"type":"array","items":[{"$ref":"#/definitions/service_categories"}]},"users":{"type":"array","items":[{"$ref":"#/definitions/users"}]}}}},"required":["name"]},"system_options":{"type":"object","properties":{"option":{"maxLength":255,"type":"string"},"value":{"maxLength":255,"type":"string"},"public":{"type":"boolean"},"type":{"maxLength":255,"type":"string"},"data_type":{"maxLength":255,"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["option"]},"transactions":{"type":"object","properties":{"id":{"type":"integer"},"invoice_id":{"type":"integer"},"user_id":{"type":"integer"},"charge_id":{"maxLength":255,"type":"string"},"invoice":{"maxLength":255,"type":"string"},"amount":{"format":"float","type":"number"},"refunded":{"type":"boolean"},"amount_refunded":{"format":"float","type":"number"},"refunds":{"type":"object"},"captured":{"type":"boolean"},"currency":{"maxLength":255,"type":"string"},"dispute":{"maxLength":255,"type":"string"},"paid":{"type":"boolean"},"description":{"maxLength":255,"type":"string"},"failure_code":{"maxLength":255,"type":"string"},"failure_message":{"maxLength":255,"type":"string"},"statement_descriptor":{"maxLength":255,"type":"string"},"status":{"maxLength":255,"type":"string"},"livemode":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"users":{"type":"object","properties":{"id":{"type":"integer"},"role_id":{"type":"integer"},"name":{"maxLength":255,"type":"string"},"email":{"maxLength":255,"type":"string"},"password":{"format":"password","maxLength":255,"type":"string"},"provider":{"maxLength":255,"type":"string"},"status":{"type":"string"},"customer_id":{"maxLength":255,"type":"string"},"phone":{"maxLength":255,"type":"string"},"last_login":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"references":{"type":"object","properties":{"user_roles":{"type":"array","items":[{"$ref":"#/definitions/user_roles"}]},"funds":{"type":"array","items":[{"$ref":"#/definitions/funds"}]}}}},"required":["email"]},"webhooks":{"type":"object","properties":{"id":{"type":"integer"},"endpoint_url":{"maxLength":255,"type":"string"},"health":{"maxLength":255,"type":"string"},"async_lifecycle":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["endpoint_url"]}} \ No newline at end of file diff --git a/plugins/hosted-page-manager/default.handlebars b/plugins/hosted-page-manager/default.handlebars new file mode 100644 index 00000000..0fb1de44 --- /dev/null +++ b/plugins/hosted-page-manager/default.handlebars @@ -0,0 +1,46 @@ + + + + + +
Bad link, click + to have a new access link emailed to you +
+ + + + \ No newline at end of file diff --git a/plugins/hosted-page-manager/main.js b/plugins/hosted-page-manager/main.js new file mode 100644 index 00000000..8d8f75db --- /dev/null +++ b/plugins/hosted-page-manager/main.js @@ -0,0 +1,165 @@ +let { call, put, all, select, fork, spawn, take } = require("redux-saga/effects"); +let consume = require("pluginbot/effects/consume"); +let mustache = require("mustache"); +let fs = require('fs'); +let jsonwebtoken = require("jsonwebtoken") +let join = require("path").join; +const EXP = 24; //hours before link expires +function* run(config, provide, channels) { + let database = yield consume(channels.database); + let store = require("../../config/redux/store"); + yield call(database.createTableIfNotExist, "embed_configurations", function (table) { + table.text('config'); + table.string("name"); + console.log("Created 'embed_configurations' table."); + }); + + yield call(database.createTableIfNotExist, "embed_access_tokens", function (table) { + table.string('token'); + table.timestamp('expiration'); + table.integer("user_id").references('users.id').onDelete('cascade'); + console.log("Created 'embed_access_tokens' table."); + }); + + function createToken(userId) { + return new Promise(async resolve => { + require('crypto').randomBytes(20, async function (err, buffer) { + let token = buffer.toString("hex"); + await database("embed_access_tokens").insert({ + user_id: userId, + token, + expiration: new Date(new Date().getTime() + 60 * 60 * EXP * 1000) + }); + resolve(token); + }) + }); + } + let router = yield consume(channels.pageRouter); + async function validateToken(token, userId) { + let entry = (await database("embed_access_tokens").where({ + token, + user_id: userId + }))[0]; + if (!entry) { + throw "No Token Found" + } + if (new Date(entry.expiration) < new Date()) { + throw "Token Expired" + } + return true; + } + async function sendLink(req, res) { + try { + let userId = req.params.userId; + let user = (await database("users").where({ id: userId }))[0] + if (!user) { + return res.status(400).json({ error: "User doesn't exist" }); + } + + let token = await createToken(userId); + + let mailer = require("../../lib/mailer"); + + mailer(user.email, `Access to billing account with ${store.getState().options.company_name} was requested, go here to access your billing settings - this link will only work for ${EXP} hours`, "Billing Dashboard Access"); + res.status(200).json({ message: "Link sent" }) + } catch (e) { + console.error(e); + res.status(500).json({ error: e }); + } + } + + function createLink(userId, token) { + return `https://${store.getState().options.hostname}/page/billing?user=${userId}&token=${token}`; + } + + async function generateJWT(req, res) { + let { userId, token } = req.params; + try { + if (await validateToken(token, userId)) { + let token = jsonwebtoken.sign({ uid: userId }, process.env.SECRET_KEY, { expiresIn: '3h' }); + res.json({ token }); + } + } catch (e) { + res.status(400).json({ error: e }); + } + } + let routeDefinition = [ + { + endpoint: "/auth/link/:userId/generate", + method: "post", + middleware: [sendLink], + permissions: [], + description: "Generate and email a new link to userId" + + }, + { + endpoint: "/auth/link/:userId/:token/jwt", + method: "post", + middleware: [generateJWT], + permissions: [], + description: "Generate a new JWT from link token" + } + ] + let embedAccessManager = { + createToken, + createLink + } + yield provide({ routeDefinition, embedAccessManager }); + while (true) { + let { path, name, needsToken } = yield consume(channels.hostedPage); + + database("embed_configurations").where("name", name).then(async config => { + if (config.length === 0) { + await database("embed_configurations").insert({ + name + }); + } + }); + + router.get("/" + name, async function (req, res) { + try { + let jwt = null; + if (needsToken) { + let { user, token } = req.query; + try { + if (await validateToken(token, user)) { + jwt = jsonwebtoken.sign({ uid: user }, process.env.SECRET_KEY, { expiresIn: '3h' }); + } + } catch (e) { + console.error("bad token", e); + fs.readFile(join(__dirname, "./default.handlebars"), "utf8", async function (err, data) { + res.send(mustache.render(data)) + }); + return; + } + + } + fs.readFile(path, "utf8", async function (err, data) { + let embedConfiguration = (await database("embed_configurations").returning("*").where("name", name))[0].config || "{}"; + let url = "https://" + store.getState().options.hostname; + try{ + let rendered = mustache.render(data, { + dbConfig: "var dbConfig = " + embedConfiguration, + query: req.query, + generatedConfig: `var genConfig = { + selector: document.getElementById('servicebot-hosted-embeddable'), + url: "${url}", + token: "${jwt}" + }` + }); + res.send(rendered); + }catch(e){ + console.error(e); + } + }); + } catch (e) { + console.error(e); + res.status(500).json({ error: e }); + } + }); + } + + + +} +module.exports = { run }; \ No newline at end of file diff --git a/plugins/hosted-page-manager/package.json b/plugins/hosted-page-manager/package.json new file mode 100644 index 00000000..97adad34 --- /dev/null +++ b/plugins/hosted-page-manager/package.json @@ -0,0 +1,14 @@ +{ + "name": "hosted-page-manager", + "version": "0.0.1", + "dependencies": { + + }, + "pluginbot" : { + "server" : { + "main" : "main.js", + "consumes" : ["database", "pageRouter", "hostedPage"] + } + } + } + \ No newline at end of file diff --git a/plugins/initial-state/package.json b/plugins/initial-state/package.json new file mode 100644 index 00000000..c0772fe7 --- /dev/null +++ b/plugins/initial-state/package.json @@ -0,0 +1,13 @@ +{ + "name": "initial-state", + "version": "0.0.1", + "dependencies": { + + }, + "pluginbot" : { + "server" : { + "main" : "server.js", + "consumes" : ["configurationManager"] + } + } +} diff --git a/plugins/initial-state/server.js b/plugins/initial-state/server.js new file mode 100644 index 00000000..e215d2a0 --- /dev/null +++ b/plugins/initial-state/server.js @@ -0,0 +1,24 @@ +let {call, put, all, select, fork, spawn, take} = require("redux-saga/effects"); +let consume = require("pluginbot/effects/consume"); +let sagaMiddleware = require("../../middleware/express-saga-middleware"); + +function* run(config, provide, channels) { + let configurationManager = yield consume(channels.configurationManager); + let middleware = function*(req, res, next){ + let publicConfigurations = yield call(configurationManager.getConfigurations, true); + }; + middleware = yield call(sagaMiddleware, middleware); + + let routeDefinition = { + endpoint : "/initial-state", + method : "get", + middleware : [middleware], + permissions : [], + description : "Get initial state" + + } + yield provide(routeDefinition); + +} + +module.exports = {run}; \ No newline at end of file diff --git a/plugins/payment-manager/main.js b/plugins/payment-manager/main.js index b97565fc..9b05ecbe 100644 --- a/plugins/payment-manager/main.js +++ b/plugins/payment-manager/main.js @@ -8,6 +8,8 @@ function* run(config, provide, channels) { let database = yield consume(channels.database); yield call(scheduleTrials); yield call(scheduleSplits); + yield call(scheduleCancellations); + //process split payments //todo: reduce duplicate code - this chunk is in a bunch of places :( @@ -128,7 +130,10 @@ function trialExpiration(instance) { let fund = await Fund.findOne("user_id", currentInstance.get("user_id")); if (!fund.data) { - console.log("TRIAL EXPIRED AND NO FUNDS, UNSUBSCRIBE!"); + console.log("TRIAL EXPIRED AND NO FUNDS, UNSUBSCRIBE! FOR INSTANCE " + instance.id ); + instance = await instance.attachReferences(); + require("../../config/redux/store").dispatchEvent("service_instance_trial_expired", instance); + instance.unsubscribe() } else { console.log("funds have been added, no unsubscribe needed"); @@ -138,7 +143,17 @@ function trialExpiration(instance) { } } } - +async function scheduleCancellationForInstance(instance){ + console.log("Scheduling cancellation for " + instance.data.id); + return await instance.scheduleCancellation(); +} +function* scheduleCancellations(){ + let ServiceInstance = require("../../models/service-instance"); + let instances = yield call(ServiceInstance.find, {status : "cancellation_pending"}); + for(let instance of instances){ + yield call(scheduleCancellationForInstance, instance) + } +} function* scheduleSplits() { let ServiceInstance = require("../../models/service-instance"); let Fund = require('../../models/fund'); diff --git a/plugins/service-lifecycle/main.js b/plugins/service-lifecycle/main.js index 89c83e4f..42a61ed2 100644 --- a/plugins/service-lifecycle/main.js +++ b/plugins/service-lifecycle/main.js @@ -13,8 +13,12 @@ function* run(config, provide, channels) { pre_reactivate : [], post_reactivate : [], pre_property_change : [], - post_property_change : [] - + post_property_change : [], + pre_payment_structure_change: [], + post_payment_structure_change: [], + post_seat_created: [], + post_seat_deleted: [], + post_cancellation_pending: [] } @@ -94,8 +98,55 @@ function* run(config, provide, channels) { } return result; + }, + prePaymentStructureChange : async function({instance, payment_structure_template}){ + let result = {} + for(let hook of lifecycles.pre_payment_structure_change){ + let hookresult = await hook.run({instance, payment_structure_template}); + result = {...result, ...hookresult}; + } + return result; + + }, + postPaymentStructureChange : async function({instance}){ + let result = {} + for(let hook of lifecycles.post_payment_structure_change){ + let hookresult = await hook.run({instance}); + result = {...result, ...hookresult}; + } + return result; + + }, + postSeatCreated : async function({seat}){ + let result = {} + for(let hook of lifecycles.post_seat_created){ + let hookresult = await hook.run({seat}); + result = {...result, ...hookresult}; + } + return result; + + }, + postSeatDeleted : async function({seat}){ + let result = {} + for(let hook of lifecycles.post_seat_deleted){ + let hookresult = await hook.run({seat}); + result = {...result, ...hookresult}; + } + return result; + }, + postCancellationPending : async function({instance, end_date}){ + let result = {} + for(let hook of lifecycles.post_cancellation_pending){ + let hookresult = await hook.run({instance, end_date}); + result = {...result, ...hookresult}; + } + return result; } + + + + }; yield provide({lifecycleManager}) diff --git a/plugins/setup/app.js b/plugins/setup/app.js index b7ebc240..f27842b3 100644 --- a/plugins/setup/app.js +++ b/plugins/setup/app.js @@ -165,7 +165,7 @@ module.exports = function* (appConfig, initialConfig, dbConfig, app) { let configBuilder = require("pluginbot/config"); let clientPlugins = Object.keys((await configBuilder.buildClientConfig(CONFIG_PATH)).plugins); - response.render("main", {bundle: appConfig.bundle_path, plugins: clientPlugins}); + response.render("main", {vendor: appConfig.vendor_path, bundle: appConfig.bundle_path, plugins: clientPlugins}); }); return () => { diff --git a/plugins/stripe/api/import.js b/plugins/stripe/api/import.js index e7dce35f..ab9495fb 100644 --- a/plugins/stripe/api/import.js +++ b/plugins/stripe/api/import.js @@ -9,7 +9,8 @@ let ServiceCategory = require('../../../models/service-category'); let Invoice = require('../../../models/invoice'); let dispatchEvent = require("../../../config/redux/store").dispatchEvent; let stripe = require('../../../config/stripe'); - +let Tier = require('../../../models/tier'); +let PaymentStructureTemplate = require('../../../models/payment-structure-template'); module.exports = function(knex) { @@ -59,24 +60,29 @@ module.exports = function(knex) { return promiseServiceCategory().then(function (category) { return new Promise(function (resolve, reject) { - stripe().connection.plans.list(req_params, function (err, plans) { + stripe().connection.plans.list(req_params, async function (err, plans) { if(!err) { - Promise.all(plans.data.map(function (plan) { - return importServiceTemplate(category, plan).catch(function (err) { - console.log(err); - return Promise.resolve(true); - });; - })).then(function () { - // Check for more, and recursively call importStripePlans - if (plans.has_more) { - let last_plan = plans.data[plans.data.length - 1].id; - console.log(`Parsed all plans until Plan ID ${last_plan}`); - return setTimeout(resolve,1000,importStripePlans(last_plan)); - } else { - console.log(`All plans have been imported.`); - return resolve(true); - } - }); + for(let plan of plans.data){ + await importServiceTemplate(category, plan).catch(err => console.error("error importing template", err)); + } + // Promise.all(plans.data.map(function (plan) { + // return importServiceTemplate(category, plan).catch(function (err) { + // console.log(err); + // return Promise.resolve(true); + // });; + // } + // ) + // ).then(function () { + // Check for more, and recursively call importStripePlans + if (plans.has_more) { + let last_plan = plans.data[plans.data.length - 1].id; + console.log(`Parsed all plans until Plan ID ${last_plan}`); + return setTimeout(resolve,1000,importStripePlans(last_plan)); + } else { + console.log(`All plans have been imported.`); + return resolve(true); + } + } else { console.log(err); return resolve(true); @@ -97,24 +103,21 @@ module.exports = function(knex) { if (last_id !== null) { req_params['starting_after'] = last_id; } return new Promise(function (resolve, reject) { - stripe().connection.subscriptions.list(req_params, function (err, subscriptions) { + stripe().connection.subscriptions.list(req_params, async function (err, subscriptions) { if(!err) { - Promise.all(subscriptions.data.map(function (subscription) { - return importServiceInstance(subscription).catch(function (err) { - console.log(err); - return Promise.resolve(true); - }); - })).then(function () { - // Check for more, and recursively call importStripePlans - if (subscriptions.has_more) { - let last_subscription = subscriptions["data"][subscriptions["data"].length - 1].id; - console.log(`Parsed all subscriptions until Plan ID ${last_subscription}`); - return setTimeout(resolve,1000,importStripeSubscriptions(last_subscription)); - } else { - console.log(`All subscriptions have been imported.`); - return resolve(true); - } - }); + for(let subscription of subscriptions.data){ + await importServiceInstance(subscription).catch(err => {console.error(err)}) + } + + // Check for more, and recursively call importStripePlans + if (subscriptions.has_more) { + let last_subscription = subscriptions["data"][subscriptions["data"].length - 1].id; + console.log(`Parsed all subscriptions until Plan ID ${last_subscription}`); + return setTimeout(resolve,1000,importStripeSubscriptions(last_subscription)); + } else { + console.log(`All subscriptions have been imported.`); + return resolve(true); + } } else { return reject('Cannot make the API call to retrieve Plans.'); } @@ -204,7 +207,7 @@ module.exports = function(knex) { let importServiceTemplate = function (category, plan) { return new Promise(function (resolve, reject) { - ServiceTemplate.findOne('name', plan.id, function (template) { + ServiceTemplate.findOne('name', plan.name || plan.nickname || plan.id, function (template) { if(template.data) { return resolve(template); } else { @@ -212,20 +215,33 @@ module.exports = function(knex) { } }) }).then(function (template) { - return new Promise(function (resolve, reject) { + return new Promise( async function (resolve, reject) { if(!template) { let newPlan = Object.assign({}, plan); delete newPlan.id; - newPlan.category_id = category.data.id; - newPlan.created_by = 1; - newPlan.description = plan.name || plan.nickname || "Imported from Stripe"; - newPlan.name = plan.name || plan.nickname || plan.id; - let template = new ServiceTemplate(newPlan); - template.create((err, template) => { - if(err){ - console.error(err); - } - return resolve(template); }); + let newTemplate = {}; + newTemplate.category_id = category.data.id; + newTemplate.created_by = 1; + newTemplate.description = plan.name || plan.nickname || "Imported from Stripe"; + newTemplate.name = plan.name || plan.nickname || plan.id; + newTemplate.published = true; + try { + let template = await ServiceTemplate.createPromise(newTemplate); + let newTier = await Tier.createPromise({ + service_template_id: template.id, + name: template.name + "-Tier" + }); + let newPaymentStructure = await PaymentStructureTemplate.createPromise({ + trial_period_days: 0, + ...newPlan, + tier_id: newTier.id, + type: "subscription" + }); + resolve({template, newTier, newPaymentStructure}); + } catch (e) { + console.error("error while creating template", e); + reject(e); + } } else { return resolve(template); } @@ -248,7 +264,7 @@ module.exports = function(knex) { }); }); }; - + let importServiceInstance = function (subscription) { return new Promise(function (resolve, reject) { //Make sure service does not already exist @@ -291,13 +307,19 @@ module.exports = function(knex) { }); }); }).then(function (service) { - return new Promise(function (resolve, reject) { - ServiceTemplate.findOne('name', service.payment_plan.id, function (template) { - if(template.data) { - service.service_id = template.data.id; - } - return resolve(service); - }); + return new Promise(async function (resolve, reject) { + let plan = service.payment_plan; + let template = (await ServiceTemplate.find({'name': plan.name || plan.nickname || plan.id}, true))[0]; + if(template && template.data) { + let paymentStructureTemplate = (await PaymentStructureTemplate.find({'tier_id': template.data.references.tiers[0].id}))[0]; + service.service_id = template.data.id; + service.payment_structure_template_id = paymentStructureTemplate.data.id; + }else{ + let {template, newTier, newPaymentStructure} = await importServiceTemplate("Uncategorized", plan); + service.service_id = template.data.id; + service.payment_structure_template_id = newPaymentStructure.data.id; + } + return resolve(service); }); }).then(function (service) { return new Promise(function (resolve, reject) { @@ -348,10 +370,10 @@ module.exports = function(knex) { }; return { - endpoint : "/stripe/import", - method : "post", - middleware : [importMiddleware], - permissions : ["can_administrate"], - description : "Imports data from stripe" + endpoint : "/stripe/import", + method : "post", + middleware : [importMiddleware], + permissions : ["can_administrate"], + description : "Imports data from stripe" }; }; \ No newline at end of file diff --git a/plugins/stripe/api/webhook.js b/plugins/stripe/api/webhook.js index ab3c7f69..2d3a8518 100644 --- a/plugins/stripe/api/webhook.js +++ b/plugins/stripe/api/webhook.js @@ -7,7 +7,7 @@ let User = require('../../../models/user'); let ServiceInstance = require('../../../models/service-instance'); let Invoice = require('../../../models/invoice'); -module.exports = function(knex) { +module.exports = function (knex) { let stripe = require('../../../config/stripe'); let store = require("../../../config/redux/store"); @@ -15,23 +15,23 @@ module.exports = function(knex) { * This function will retrieve an event from Stripe using the event id to validate post request * @param event_id - ID of the event coming from Stripe */ - let validateStripeEvent = function (event_id, callback){ - stripe().connection.events.retrieve(event_id, function(err, event) { + let validateStripeEvent = function (event_id, callback) { + stripe().connection.events.retrieve(event_id, function (err, event) { callback(err, event); }); }; let invoiceCreatedEvent = function (event, callback) { User.findOne('customer_id', event.data.object.customer, function (user) { - if(user.data) { + if (user.data) { Invoice.findOne('invoice_id', event.data.object.id, function (invoice) { - if(!invoice.data) { + if (!invoice.data) { Invoice.insertInvoice(event.data.object, user).then(function (result) { - Logger.log(event.id,'Invoice Created - Webhook from Stripe. Insert new Invoice.'); + Logger.log(event.id, 'Invoice Created - Webhook from Stripe. Insert new Invoice.'); callback(result); }).catch(function (err) { console.log(err); - Logger.log(event.id,'FAILED => Invoice Creation - Webhook from Stripe. Insert new Invoice.'); + Logger.log(event.id, 'FAILED => Invoice Creation - Webhook from Stripe. Insert new Invoice.'); callback(err); }); } else { @@ -46,13 +46,13 @@ module.exports = function(knex) { let invoiceUpdatedEvent = function (event, callback) { Invoice.findOne('invoice_id', event.data.object.id, function (invoice) { - if(invoice.data) { + if (invoice.data) { invoice.sync(event.data.object).then(function (result) { - Logger.log(event.id,'Invoice Updated - Webhook from Stripe. Invoice Updated.'); + Logger.log(event.id, 'Invoice Updated - Webhook from Stripe. Invoice Updated.'); callback(result); }).catch(function (err) { console.log(err); - Logger.log(event.id,'FAILED => Invoice Updated - Webhook from Stripe. Invoice Updated.'); + Logger.log(event.id, 'FAILED => Invoice Updated - Webhook from Stripe. Invoice Updated.'); callback(err); }); } else { @@ -61,19 +61,25 @@ module.exports = function(knex) { }); }; - let invoiceFailedEvent = function (event, callback) { + let invoiceFailedEvent = function (event, callbackFinal) { async.series([ function (callback) { - User.findOne('customer_id', event.data.object.customer, function (user) { + User.findOne('customer_id', event.data.object.customer, async function (user) { + let instance = (await ServiceInstance.find({ subscription_id: event.data.object.subscription }))[0]; + if (!event.data.object.next_payment_attempt) { + console.log("No more payment attempts"); + await instance.unsubscribe(); + } user.data.status = 'flagged'; user.update(function (err, result) { + callbackFinal(null, instance); callback(err, result); }); }); }, function (callback) { invoiceUpdatedEvent(event, function (result) { - callback(null, result); + // callback(null, result); }); } ]); @@ -81,12 +87,12 @@ module.exports = function(knex) { let customerDeletedEvent = function (event, callback) { User.findOne('customer_id', event.data.object.id, function (user) { - if(user.data) { + if (user.data) { user.purgeData(false, function (result) { user.data.status = 'suspended'; user.data.customer_id = null; user.update(function (err, result) { - Logger.log(event.id,'Customer deleted - Webhook from Stripe. Set user activate to false.'); + Logger.log(event.id, 'Customer deleted - Webhook from Stripe. Set user activate to false.'); callback(result); }); }); @@ -97,12 +103,12 @@ module.exports = function(knex) { } let subscriptionDeletedEvent = function (event, callback) { - ServiceInstance.findOne('subscription_id', event.data.object.id, function(service) { - if(service.data) { + ServiceInstance.findOne('subscription_id', event.data.object.id, function (service) { + if (service.data) { service.data.status = 'cancelled'; service.data.subscription_id = null; service.update(function (err, result) { - Logger.log(event.id,'Subscription deleted - Webhook from Stripe.'); + Logger.log(event.id, 'Subscription deleted - Webhook from Stripe.'); callback(result); }); } else { @@ -122,7 +128,7 @@ module.exports = function(knex) { // invoice.updated [Sync the invoice] // ping - let webhook = function(req, res, next){ + let webhook = function (req, res, next) { let event_id = req.body.id; async.waterfall([ function (callback) { @@ -134,11 +140,11 @@ module.exports = function(knex) { } }); }, - function (event, callback){ - if(event) { + function (event, callback) { + if (event) { //Check if the database has not processed this event before - Logger.findOne('event_id', event.id, function(found_event) { - if(!found_event.data){ + Logger.findOne('event_id', event.id, function (found_event) { + if (!found_event.data) { callback(null, true, event); } else { res.status(200).send('Event already processed'); @@ -148,20 +154,20 @@ module.exports = function(knex) { } }, function (valid, event, callback) { - if(valid) { + if (valid) { switch (event.type) { case 'customer.deleted': - customerDeletedEvent (event, function (result) { + customerDeletedEvent(event, function (result) { console.log(result); }); break; case 'customer.subscription.deleted': - subscriptionDeletedEvent (event, function (result) { + subscriptionDeletedEvent(event, function (result) { console.log(result); }); break; case 'invoice.created': - invoiceCreatedEvent (event, function (result) { + invoiceCreatedEvent(event, function (result) { console.log(result); }); break; @@ -171,9 +177,16 @@ module.exports = function(knex) { }); break; case 'invoice.payment_failed': - invoiceFailedEvent(event, function (user) { - console.log(user); - store.dispatchEvent("payment_failure", user); + invoiceFailedEvent(req.body, function (err, instance) { + let accessManager = store.getState(true).pluginbot.services.embedAccessManager + if (accessManager) { + accessManager = accessManager[0]; + accessManager.createToken(instance.data.user_id).then(token => { + instance.data.billing_settings_url = accessManager.createLink(instance.data.user_id, token); + store.dispatchEvent("payment_failure", instance); + }); + } + }); break; default: @@ -187,11 +200,11 @@ module.exports = function(knex) { }; return { - endpoint : "/stripe/webhook", - method : "post", - middleware : [webhook], - permissions : [], - description : "Stripe Webhook" + endpoint: "/stripe/webhook", + method: "post", + middleware: [webhook], + permissions: [], + description: "Stripe Webhook" }; } \ No newline at end of file diff --git a/plugins/stripe/stripe.js b/plugins/stripe/stripe.js index 4091dff7..7b4c0745 100644 --- a/plugins/stripe/stripe.js +++ b/plugins/stripe/stripe.js @@ -21,25 +21,31 @@ let run = function* (config, provide, services) { yield provide({routeDefinition}); - - //Update customer invoices every hour - setInterval(async () => { + let updateCustomers = async () => { + console.log("Updating customers"); + const delay = time => new Promise(res=>setTimeout(()=>res(),time)); let User = require("../../models/user"); let Invoice = require("../../models/invoice"); let users = (await User.find()); - users.map(user => { - //Fetch all invoices - Invoice.fetchUserInvoices(user).then(function (updated_invoices) { - console.log(`Invoices Updated for user: ${user.data.email}`); + await delay(50000); + for(let user of users){ + await Invoice.fetchUserInvoices(user).then(function (updated_invoices) { + // console.log(`Invoices Updated for user: ${user.data.email}`); }).catch(function (err) { - console.log(`Invoice Skipped for user: ${user.data.email}`); + // console.log(`Invoice Skipped for user: ${user.data.email}`); console.log(err); }); + await delay(200) Invoice.fetchUpcomingInvoice(user, function (upcoming_invoice) { - console.log(`Upcoming Invoice Updated for user: ${user.data.email}`); + // console.log(`Upcoming Invoice Updated for user: ${user.data.email}`); }); - }) - }, 3600000); + + } + console.log("Fetching invoices done"); + }; + //Update customer invoices every hour + setInterval(updateCustomers, 18000000); + updateCustomers(); }; module.exports = {run}; \ No newline at end of file diff --git a/plugins/system-options/routes.js b/plugins/system-options/routes.js index f81c5281..1c6c7aed 100644 --- a/plugins/system-options/routes.js +++ b/plugins/system-options/routes.js @@ -11,9 +11,8 @@ module.exports = function*(configurationManager){ function* updatePublic(req, res, next){ let updates = yield call(configurationManager.updateConfigurations, req.body, true); - //todo: why is this so stupid let reduced = updates.reduce((settings, setting)=>{ - settings[setting[0].option] = setting[0].value; + settings[setting.option] = setting.value; return settings; }, {}); yield call([res, "json"], reduced); diff --git a/plugins/updates/updates.js b/plugins/updates/updates.js index 1d6ae99a..41681aba 100644 --- a/plugins/updates/updates.js +++ b/plugins/updates/updates.js @@ -13,7 +13,6 @@ let run = function* (config, provide, services) { let salt = process.env.INSTANCE_SALT // let hash = require("bcryptjs").hashSync(salt, 10).toString("hex"); let checkMaster = async function () { - console.log("CHECKIN WITH BIG PAPA FOR BIG ANNOUNCEMENTS") let version = process.env.npm_package_version; let data = await analytics.getAnalyticsData(); diff --git a/plugins/webhooks/main.js b/plugins/webhooks/main.js index 6b5a505e..6cd1bcd1 100644 --- a/plugins/webhooks/main.js +++ b/plugins/webhooks/main.js @@ -32,14 +32,12 @@ function* run(config, provide, channels) { let eventPayload = JSON.stringify({event_name : eventName, event_data : parsedEvent}); let hmac = generateHmac(eventPayload, process.env.SECRET_KEY); let webhookRequest = fetch(webhook.endpoint_url, {method: "POST", body: eventPayload, headers: {...headers, "X-Servicebot-Signature" : hmac}}) - .then(response => { + .then(async response => { if (!response.ok) { console.error("error making webhook request", response.statusText); } - db("webhooks").where("id", webhook.id).update({health: response.statusText}).then(result => { - - }) - return response + let statusText = (response.status >= 200 && response.status <= 299) ? "OK" : response.statusText; + await db("webhooks").where("id", webhook.id).update({health: statusText}); }) .catch(error => { let health = error.errno || error @@ -94,7 +92,28 @@ function* run(config, provide, channels) { { stage: "post_property_change", run: sendToWebhooks("post_property_change") - } + }, + { + stage: "pre_payment_structure_change", + run: sendToWebhooks("pre_payment_structure_change") + }, + { + stage: "post_payment_structure_change", + run: sendToWebhooks("post_payment_structure_change") + }, + { + stage: "post_seat_created", + run: sendToWebhooks("post_seat_created") + }, + { + stage: "post_seat_deleted", + run: sendToWebhooks("post_seat_deleted") + }, + { + stage: "post_cancellation_pending", + run: sendToWebhooks("post_cancellation_pending") + }, + ]; diff --git a/plugins/webhooks/view/form.jsx b/plugins/webhooks/view/form.jsx index 09049b0c..d0775423 100644 --- a/plugins/webhooks/view/form.jsx +++ b/plugins/webhooks/view/form.jsx @@ -1,7 +1,5 @@ import React from 'react'; -import Fetcher from "../../../views/components/utilities/fetcher.jsx" -import ServiceBotBaseForm from "../../../views/components/elements/forms/servicebot-base-form.jsx"; -import {inputField} from "../../../views/components/elements/forms/servicebot-base-field.jsx"; +import {Fetcher, ServicebotBaseForm, inputField} from "servicebot-base-form"; import Alerts from '../../../views/components/elements/alerts.jsx'; import {required, url} from 'redux-form-validators' import {Field,} from 'redux-form' @@ -11,7 +9,8 @@ import Jumbotron from '../../../views/components/layouts/jumbotron.jsx'; import Collapsible from 'react-collapsible'; import '../stylesheets/webhooks.css'; import cookie from "react-cookie"; - +import ContentTitle from "../../../views/components/layouts/content-title.jsx"; +import Content from "../../../views/components/layouts/content.jsx"; function ManagementEmbed(props) { let server; @@ -144,11 +143,13 @@ function WebhookForm(props) { {/**/} - - - - -
+
+ + + + +
+
@@ -168,7 +169,7 @@ function WebhookModal(props) {
-
@@ -386,144 +367,119 @@ Servicebot.init({ }) ` } - let formEmbed = (
- Paste the generated HTML on the page you want to embed a request form. You can find more detailed documentation here - -
{formHTML}
-
) return (
- -
-

Embed

- Servicebot has embeddable forms which can facilitate actions such as subscribing, adding a credit card, cancelling, and resubscribing - {this.state.showManagementEmbed ?
- - -
: -
- -
} - {this.state.showFormEmbed ?
{formEmbed} - -
: -
- -
} - -

Webhooks

- Servicebot can send webhook events that notify your application any time an event happens. - This is especially useful for events—like new customer subscription or trial expiration—that - your SaaS product needs to know about. You can integrate your SaaS with Servicebot by listening - to API calls sent from your Servicebot instance to your SaaS product. - -
- - -
- -
-
-
Webhook events information
-
+
+ +
+

Webhooks

+
+
+ +

Add endpoints

+
+
+ Servicebot can send webhook events that notify your application or third-party system any time an event happens. + Use it for events, like new customer subscription or trial expiration, that + your SaaS needs to know about. +
+
+
+ + +
+
+ +
+

Webhook events information

+ +
{!this.state.showEventsInfo ? - - : - - } + : + } +
+ {this.state.showEventsInfo && +
+
+

The webhook system can notify your SaaS application if any of the following events + occour: See documentation for payload + information

+
    +
  • Pre-subscription: This event happens right after the customer subscribes to + your service, prior to the subscription request completion. +
  • +
  • Post-subscription: This event happens after the subscription has been + successfully completed. +
  • +
  • Pre-trial expiration: This event happens right after the trial expires, prior + to any expiration processes. +
  • +
  • Post-trial expiration: This event happens after the trial expiration has been + completed. +
  • +
  • Pre-reactivation: This event happens right after the reactivation event + happens, prior to any reactivation processes. +
  • +
  • Post-reactivation: This event happens after eactivation event has been + completed. +
  • +
+
-
- {this.state.showEventsInfo && -
-

The webhook system can notify your SaaS application if any of the following events - occour:

- See documentation for payload - information -
    -
  • Pre-subscription: This event happens right after the customer subscribes to - your service, prior to the subscription request completion. -
  • -
  • Post-subscription: This event happens after the subscription has been - successfully completed. -
  • -
  • Pre-trial expiration: This event happens right after the trial expires, prior - to any expiration processes. -
  • -
  • Post-trial expiration: This event happens after the trial expiration has been - completed. -
  • -
  • Pre-reactivation: This event happens right after the reactivation event - happens, prior to any reactivation processes. -
  • -
  • Post-reactivation: This event happens after eactivation event has been - completed. -
  • -
-
- } -
-
- {hooks.map((hook, index) => { - //Set health check - let health = {hook.health}; - if (!hook.health) { - health = Test Endpoints; - } else if (hook.health === 'OK') { - health = ; - } - //Set Type - let type = Asynchronous; - if (hook.async_lifecycle === false) { - type = Synchronous; } - return ( -
-
{hook.endpoint_url}
-
-
- {type} - {health} -
-
- - -
+
+ +
+

Manage Webhooks

+
+
+
+ {hooks.map((hook, index) => { + //Set health check + let health = {hook.health}; + if (!hook.health) { + health = Test Endpoints; + } else if (hook.health === 'OK') { + health = ; + } + //Set Type + let type = Asynchronous; + if (hook.async_lifecycle === false) { + type = Synchronous; + } + return ( +
+ {hook.endpoint_url}{type}{health} +
+ + +
+
+ ) + })}
- ) - })} +
+ +
+ {endpointModals()} -
- {endpointModals()} +
@@ -533,7 +489,7 @@ Servicebot.init({ let RouteDefinition = { - component: Webhooks, name: "Integrations", path: "/webhooks", isVisible: function (user) { + component: Webhooks, navType: "settings", name: "Webhook Settings", path: "/webhooks", isVisible: function (user) { //todo: this is dirty, need to do permission based... return user.role_id === 1 } diff --git a/public/assets/SB_Icon_Menu/Billing.png b/public/assets/SB_Icon_Menu/Billing.png new file mode 100644 index 00000000..f6c437f1 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Billing.png differ diff --git a/public/assets/SB_Icon_Menu/Help.png b/public/assets/SB_Icon_Menu/Help.png new file mode 100644 index 00000000..0c4d1e90 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Help.png differ diff --git a/public/assets/SB_Icon_Menu/Home.png b/public/assets/SB_Icon_Menu/Home.png new file mode 100644 index 00000000..01c6db00 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Home.png differ diff --git a/public/assets/SB_Icon_Menu/Integrations.png b/public/assets/SB_Icon_Menu/Integrations.png new file mode 100644 index 00000000..b4019368 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Integrations.png differ diff --git a/public/assets/SB_Icon_Menu/Manage.png b/public/assets/SB_Icon_Menu/Manage.png new file mode 100644 index 00000000..a7681d7a Binary files /dev/null and b/public/assets/SB_Icon_Menu/Manage.png differ diff --git a/public/assets/SB_Icon_Menu/Settings.png b/public/assets/SB_Icon_Menu/Settings.png new file mode 100644 index 00000000..42e68de9 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Settings.png differ diff --git a/public/assets/SB_Icon_Menu/Subscriptions.png b/public/assets/SB_Icon_Menu/Subscriptions.png new file mode 100644 index 00000000..9b004c16 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Subscriptions.png differ diff --git a/public/assets/SB_Icon_Menu/Users.png b/public/assets/SB_Icon_Menu/Users.png new file mode 100644 index 00000000..0d9bf774 Binary files /dev/null and b/public/assets/SB_Icon_Menu/Users.png differ diff --git a/public/assets/email-templates/footer-logo.png b/public/assets/email-templates/footer-logo.png new file mode 100644 index 00000000..e2e3c12b Binary files /dev/null and b/public/assets/email-templates/footer-logo.png differ diff --git a/public/assets/embed/billing.svg b/public/assets/embed/billing.svg new file mode 100644 index 00000000..2185f2ac --- /dev/null +++ b/public/assets/embed/billing.svg @@ -0,0 +1,22 @@ + + + + SB/Icon/EmbedPage/Billing + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/embed/checkout.svg b/public/assets/embed/checkout.svg new file mode 100644 index 00000000..1ebb3671 --- /dev/null +++ b/public/assets/embed/checkout.svg @@ -0,0 +1,21 @@ + + + + SB/Icon/EmbedPage/Checkout + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/embed/embed-intro-default.png b/public/assets/embed/embed-intro-default.png new file mode 100644 index 00000000..97c3634e Binary files /dev/null and b/public/assets/embed/embed-intro-default.png differ diff --git a/public/assets/embed/login.svg b/public/assets/embed/login.svg new file mode 100644 index 00000000..23aafa6d --- /dev/null +++ b/public/assets/embed/login.svg @@ -0,0 +1,14 @@ + + + + SB/Icon/EmbedPage/Login + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/public/assets/embed/pricing.svg b/public/assets/embed/pricing.svg new file mode 100644 index 00000000..cd45b2f6 --- /dev/null +++ b/public/assets/embed/pricing.svg @@ -0,0 +1,46 @@ + + + + SB/Icon/EmbedPage/Pricing + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/favicons/sbcon.png b/public/assets/favicons/sbcon.png new file mode 100644 index 00000000..6db39495 Binary files /dev/null and b/public/assets/favicons/sbcon.png differ diff --git a/public/assets/favicons/servicebotfavicon.ico b/public/assets/favicons/servicebotfavicon.ico new file mode 100644 index 00000000..fc0535ed Binary files /dev/null and b/public/assets/favicons/servicebotfavicon.ico differ diff --git a/public/assets/icons/trash.svg b/public/assets/icons/trash.svg new file mode 100644 index 00000000..f24d55bf --- /dev/null +++ b/public/assets/icons/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/tier-icons/tier-1-icon.png b/public/assets/tier-icons/tier-1-icon.png new file mode 100644 index 00000000..5ae8832a Binary files /dev/null and b/public/assets/tier-icons/tier-1-icon.png differ diff --git a/public/assets/tier-icons/tier-2-icon.png b/public/assets/tier-icons/tier-2-icon.png new file mode 100644 index 00000000..7268bdc0 Binary files /dev/null and b/public/assets/tier-icons/tier-2-icon.png differ diff --git a/public/assets/tier-icons/tier-3-icon.png b/public/assets/tier-icons/tier-3-icon.png new file mode 100644 index 00000000..881b7a4a Binary files /dev/null and b/public/assets/tier-icons/tier-3-icon.png differ diff --git a/public/assets/tier-icons/tier-4-icon.png b/public/assets/tier-icons/tier-4-icon.png new file mode 100644 index 00000000..4da59e8b Binary files /dev/null and b/public/assets/tier-icons/tier-4-icon.png differ diff --git a/public/assets/tier-icons/tier-5-icon.png b/public/assets/tier-icons/tier-5-icon.png new file mode 100644 index 00000000..77425254 Binary files /dev/null and b/public/assets/tier-icons/tier-5-icon.png differ diff --git a/public/css/build/bootstrap.min.css b/public/css/build/bootstrap.min.css new file mode 100644 index 00000000..ddbd5eb2 --- /dev/null +++ b/public/css/build/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:9954;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/public/css/build/font-awesome.min.css b/public/css/build/font-awesome.min.css new file mode 100644 index 00000000..540440ce --- /dev/null +++ b/public/css/build/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/public/css/font-awesome.css b/public/css/font-awesome.css new file mode 100644 index 00000000..38260c37 --- /dev/null +++ b/public/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/public/css/main.css b/public/css/main.css new file mode 100644 index 00000000..13926875 --- /dev/null +++ b/public/css/main.css @@ -0,0 +1,945 @@ +/* mixins */ +/* fonts */ +/* form */ +.icon.plus { + color: #000; + position: absolute; + margin-left: 3px; + margin-top: 10px; +} +.icon.plus:before { + content: ''; + position: absolute; + width: 15px; + height: 1px; + background-color: currentColor; +} +.icon.plus:after { + content: ''; + position: absolute; + width: 15px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} +.icon.close { + color: #000; + position: absolute; + margin-top: 0; + margin-left: 0; + width: 21px; + height: 21px; +} +.icon.close:before { + content: ''; + position: absolute; + top: 10px; + width: 21px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} +.icon.close:after { + content: ''; + position: absolute; + top: 10px; + width: 21px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +/* variables */ +/* font */ +/* gutters */ +/* layout */ +/* z-indexes */ +/* forms */ +/* _section font */ +._sub-heading { + color: #6F7F9F; + line-height: 22px; + font-size: 16px; + font-family: "Avenir", "Arial"; +} + +/* elements */ +.buttons { + padding: 6px 12px; + margin-bottom: 0; + font-size: 12px; + font-weight: 600; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.buttons.rounded { + border-radius: 50px; +} +.buttons._add, .buttons._primary { + font-size: 14px; + padding: 14px 24px; + background-color: #4C82FC; + color: #fff; + border-radius: 1px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.17); +} +.buttons._save, .buttons._success { + font-size: 14px; + padding: 14px 24px; + background-color: #1ABE98; + color: #fff; + border-radius: 1px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.17); +} +.buttons._right { + float: right; +} + +.clear { + display: block; + clear: both; +} + +/* component */ +.form-group.form-group-flex { + width: 100%; + flex-direction: column; +} +.form-group.form-group-flex .form-label-flex-md { + flex-basis: auto; +} + +label { + color: #6F7F9F; + font-size: 16px; + font-weight: normal; + line-height: 22px; + text-transform: uppercase; + font-family: "Open Sans", "Arial"; +} + +input, .form-control { + color: #000; + font-size: 16px; + font-weight: 300; + border: 1px solid #6F7F9F; + border-radius: 1px; + height: 42px; +} + +.form-help-text { + font-size: 0.89rem; + line-height: 1.2rem; + color: #6F7F9F; + margin-bottom: 16px; +} + +.tiers ._container { + overflow-y: scroll; +} +.tiers ._container ._tier-list { + display: flex; + flex-direction: row; + align-items: center; + max-width: 100%; + padding-left: 0; + margin-bottom: 27px; + overflow-y: visible; +} +.tiers ._container ._tier-list ._tier { + flex-shrink: 0; + height: 186px; + width: 312px; + border-radius: 3px; + background-color: #36476B; + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.28); + list-style: none; + margin-right: 16px; + overflow: hidden; + transition: all 0.3s; + display: flex; + flex-direction: column; +} +.tiers ._container ._tier-list ._tier:hover { + border: 3px solid #0CFFCD; + background-color: #36476B; + box-shadow: 0 0 4px 0 #4C82FC; + transition: all 0.3s; +} +.tiers ._container ._tier-list ._tier._selected { + border: 3px solid #0CFFCD; + background-color: #36476B; + box-shadow: 0 0 4px 0 #4C82FC; +} +.tiers ._container ._tier-list ._tier._selected ._tier-heading { + background-color: transparent; + box-shadow: none; +} +.tiers ._container ._tier-list ._tier ._tier-heading { + position: relative; + background-color: #6F7F9F; + color: #fff; + box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.13); +} +.tiers ._container ._tier-list ._tier ._tier-heading h2 { + color: #fff; + font-size: 16px; + text-transform: uppercase; + text-align: center; + padding: 16px 0; + margin: 0; +} +.tiers ._container ._tier-list ._tier ._tier-heading ._tier-delete { + position: absolute; + top: 17px; + right: 19px; + border: none; + background: transparent; + color: #fff; + position: absolute; + margin-top: 0; + margin-left: 0; + width: 21px; + height: 21px; +} +.tiers ._container ._tier-list ._tier ._tier-heading ._tier-delete:before { + content: ''; + position: absolute; + top: 10px; + width: 21px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} +.tiers ._container ._tier-list ._tier ._tier-heading ._tier-delete:after { + content: ''; + position: absolute; + top: 10px; + width: 21px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} +.tiers ._container ._tier-list ._tier ._tier-heading ._tier-delete:before { + width: 17px; + height: 4px; + top: 3px; + transform: rotate(-45deg) translate(-50%, -50%); +} +.tiers ._container ._tier-list ._tier ._tier-heading ._tier-delete:after { + width: 17px; + height: 4px; + top: 70%; + transform: rotate(45deg) translate(-62%, 0%); +} +.tiers ._container ._tier-list ._tier ._tier-preview { + flex-grow: 1; +} +.tiers ._container ._tier-list ._tier:first-child ._tier-preview { + background: url("/assets/tier-icons/tier-1-icon.png"); + background-repeat: no-repeat; + background-size: 25%; + background-position: center center; +} +.tiers ._container ._tier-list ._tier:nth-child(2) ._tier-preview { + background: url("/assets/tier-icons/tier-2-icon.png"); + background-repeat: no-repeat; + background-size: 25%; + background-position: center center; +} +.tiers ._container ._tier-list ._tier:nth-child(3) ._tier-preview { + background: url("/assets/tier-icons/tier-3-icon.png"); + background-repeat: no-repeat; + background-size: 25%; + background-position: center center; +} +.tiers ._container ._tier-list ._tier:nth-child(4) ._tier-preview { + background: url("/assets/tier-icons/tier-4-icon.png"); + background-repeat: no-repeat; + background-size: 25%; + background-position: center center; +} +.tiers ._container ._tier-list ._tier:nth-child(5) ._tier-preview { + background: url("/assets/tier-icons/tier-5-icon.png"); + background-repeat: no-repeat; + background-size: 25%; + background-position: center center; +} +.tiers ._container ._tier-list #_tier-add { + list-style: none; + width: 280px; + position: relative; +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button { + color: #fff; + position: absolute; + margin-left: 3px; + margin-top: 10px; + display: block; + background-color: #081C49; + border-radius: 50px; + margin-left: 43px; + margin-top: -20px; + padding: 24px; + transition: all 0.3s; +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button:before { + content: ''; + position: absolute; + width: 15px; + height: 1px; + background-color: currentColor; +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button:after { + content: ''; + position: absolute; + width: 15px; + height: 1px; + background-color: currentColor; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button:before { + left: 50%; + transform: translateX(-50%) rotate(90deg); +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button:after { + left: 50%; + transform: translateX(-50%); +} +.tiers ._container ._tier-list #_tier-add ._tier-add-button:hover { + background-color: #0CFFCD; + box-shadow: 0 0 4px 0 #4C82FC; + transition: all 0.3s; +} +.tiers ._tier-details { + border-radius: 1px; + background-color: #FFFFFF; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06); + padding: 26px 16px; +} +.tiers ._tier-details ._tier-name_name { + max-width: 50%; + min-width: 300px; +} +.tiers ._tier-details ._tier-name_type { + max-width: 50%; + min-width: 300px; +} +.tiers ._tier-details ._tier-name_billing_period { + max-width: 50%; + min-width: 300px; +} +.tiers ._tier-details .payment-structures .buttons._add { + float: right; +} +.tiers ._tier-details .payment-structures .buttons._add .icon { + color: #fff; + float: left; + display: block; + position: relative; + margin-right: 34px; + transform: translateY(-2px); +} +.tiers ._tier-details .payment-structures .buttons._add .icon:before, .tiers ._tier-details .payment-structures .buttons._add .icon:after { + height: 3px; +} +.tiers ._tier-details .payment-structures ._billing-options { + padding: 10px 0 20px; + display: flex; +} +.tiers ._tier-details .payment-structures ._billing-options ._count { + background: #081C49; + color: #fff; + padding: 5px; + height: 26px; + width: 26px; + display: inline-block; + line-height: 17px; + border-radius: 50px; + text-align: center; + margin-right: 12px; +} +.tiers ._tier-details .payment-structures ._billing-options ._sub-heading { + color: #6F7F9F; + line-height: 22px; + font-size: 16px; + font-family: "Avenir" "Arial"; +} +.tiers ._tier-details .payment-structures ._billing-options ._hr { + border-bottom: 1px solid #dedede; + flex-grow: 1; + margin: 0 20px; + transform: translateY(-14px); +} +.tiers ._tier-details .payment-structures ._billing-options ._billing-options-delete { + background: transparent; + border: none; + background-image: url(/assets/icons/trash.svg); + background-repeat: no-repeat; + background-size: contain; + width: 20px; +} +.tiers ._tier-details .payment-structures ._billing-options-fields { + max-width: 50%; + min-width: 300px; + display: flex; + flex-direction: row; + align-content: center; +} +.tiers ._tier-details .payment-structures ._billing-options-fields ._per { + color: #6F7F9F; + font-size: 16px; + font-weight: normal; + text-transform: uppercase; + line-height: 22px; + font-family: "Open Sans", "Arial"; + color: #6F7F9F; + display: block; + padding: 33px 22px 0px; +} +.tiers ._tier-details .form-group.form-group-flex { + width: 100%; + flex-direction: column; +} +.tiers ._tier-details .form-group.form-group-flex .form-label-flex-md { + flex-basis: auto; +} +.tiers ._tier-details label { + color: #6F7F9F; + font-size: 16px; + font-weight: normal; + line-height: 22px; + text-transform: uppercase; + font-family: "Open Sans", "Arial"; +} +.tiers ._tier-details input, .tiers ._tier-details .form-control { + color: #000; + font-size: 16px; + font-weight: 300; + border: 1px solid #6F7F9F; + border-radius: 1px; + height: 42px; +} + +/* font */ +/* gutters */ +/* layout */ +/* z-indexes */ +/* forms */ +.form-offering ._form-field-group { + max-width: 50%; + min-width: 300px; +} +.form-offering ._form-field-group._form-field-name_software_name label { + display: none; +} +.form-offering ._save { + float: right; + margin: 16px; + margin-right: 35px; +} + +/* Embeddable Page Styling */ +.embeddable-card { + display: flex; + flex-direction: column; + justify-content: space-evenly; + align-content: center; + align-items: center; + padding: 24px 24px 16px; + background-color: #FFFFFF; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); + border-radius: 3px; + margin: 0 auto 10px; + height: 144px; + width: 144px; + transition: all "" linear; +} +.embeddable-card:hover, .embeddable-card.selected { + transition: all "" linear; + cursor: pointer; + background-color: rgba(255, 255, 255, 0.61); + box-shadow: inset 0 0 3px 0 rgba(0, 0, 0, 0.14), 0 2px 4px 0 rgba(0, 0, 0, 0.1); +} +.embeddable-card:hover ._label, .embeddable-card.selected ._label { + transition: all "" linear; +} +.embeddable-card:first-of-type { + margin-top: 24px; +} +.embeddable-card ._icon { + min-width: 50px; + min-height: 50px; +} +.embeddable-card ._label { + color: #475981; + font-size: 14px; + font-family: "Open Sans", "Arial"; + color: #6F7F9F; + font-size: 12px; + transition: all "" linear; + display: block; + text-align: center; + letter-spacing: 0.86px; +} +.embeddable-card ._description { + color: #475981; + font-size: 14px; + font-family: "Open Sans", "Arial"; +} + +.embeddable-intro { + display: flex; + flex-direction: column; + justify-content: space-evenly; + align-items: center; + text-align: center; + min-height: 80vh; + max-width: 400px; + margin: auto; +} +.embeddable-intro ._content-image { + background-color: #F9FCFF; + border-radius: 390px; + padding: 60px; + height: 410px; +} +.embeddable-intro ._content-image img { + max-width: 100%; +} +.embeddable-intro ._content-text { + color: #475981; + font-size: 14px; + font-family: "Open Sans", "Arial"; +} + +#app-embeddables ._sidebar { + flex-basis: auto; +} +#app-embeddables ._sidebar ._sub-heading { + font-weight: 500; +} + +/* Embeddable Page - Checkout Page Embed */ +#plugin_embeddable-checkout #_section-3 ._embed-code-form { + display: flex; +} +#plugin_embeddable-checkout #_section-3 ._embed-code-form .form-group { + flex-basis: 30%; + margin-right: 16px; +} +#plugin_embeddable-checkout #_section-3 ._embed-code-form .form-group#_select-a-plan { + flex-grow: 1; +} +#plugin_embeddable-checkout #_section-3 ._embed-code-form .form-group:last-child { + margin-right: 0; +} + +/* layout components */ +.app-header { + position: fixed; + width: 100%; + display: flex; + justify-content: space-between; + height: 57px; + padding: 8px 26px; + background-color: #F7F8FA; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.23); + z-index: 9920; + /* end app-notification */ +} +.app-header .app-header-left, .app-header .app-header-right { + display: flex; + align-content: flex-end; +} +.app-header .app-header-right > * { + margin-left: 8px; +} +.app-header .app-logo { + height: 100%; + max-height: calc(57px - 20px); + margin-top: 1px; +} +.app-header .app-profile { + height: 100%; + max-width: 50px; +} +.app-header .app-profile img { + height: 100%; +} +.app-header .app-notification { + height: 100%; + width: 50px; + background: #475981; + border-radius: 50px; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} +.app-header .app-notification i { + color: #fff; +} +.app-header .app-notification .app-notification-list { + position: absolute; + width: 300px; + background: white; + right: 0; + top: 55px; + border-radius: 3px; + z-index: 999999; + font-size: 14px; + box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.06); +} +.app-header .app-notification .app-notification-list :before { + content: ''; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #ffffff; + margin: 0 0 15px 0; + position: absolute; + top: -5px; + right: 17px; +} +.app-header .app-notification .app-notification-list ul { + padding: 0; + margin: 0; +} +.app-header .app-notification .app-notification-list ul li { + list-style: none; + padding: 10px 20px 10px 32px; + line-height: 1.5em; + position: relative; +} +.app-header .app-notification .app-notification-list ul li :hover { + background: #f3f3f3; +} +.app-header .app-notification .app-notification-list ul li :first-child, .app-header .app-notification .app-notification-list ul li :last-child { + padding-top: 16px; +} +.app-header .app-notification .app-notification-list ul li.unread-message:before { + height: 8px; + width: 8px; + background: #dc3535; + position: absolute; + left: 12px; + margin-top: 1px; + top: 44%; + transform: translateY(-50%); + border-radius: 50px; + content: ''; +} +.app-header .app-notification .app-notification-list .app-notification-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.app-navigation { + position: fixed; + width: 280px; + padding-top: 57px; + background-color: #475981; + height: 100%; + z-index: 9910; +} +.app-navigation .app-links-container { + height: 100%; +} +.app-navigation .app-links-container ._main { + display: flex; + flex-direction: column; + justify-content: space-between; + align-content: space-between; + height: 100%; + overflow-y: auto; +} +.app-navigation .app-links-container ._main .app-links { + padding: 0; + margin: 0; + list-style: none; +} +.app-navigation .app-links-container ._main .app-links > li { + border-bottom: 1px solid #5C6A8B; +} +.app-navigation .app-links-container ._main .app-links li { + padding: 0; +} +.app-navigation .app-links-container ._main .app-links li a { + display: block; + width: 100%; + padding: 17px; + padding-left: 80px; + font-family: "Avenir", "Helvetica", sans-serif; + font-size: 16px; + font-weight: 500; + text-transform: uppercase; + color: #fff; + position: relative; + letter-spacing: 1px; +} +.app-navigation .app-links-container ._main .app-links li a:hover { + background: #374a75; +} +.app-navigation .app-links-container ._main .app-links li a.nav-link-parent .caret { + transition: all "" linear; + margin-left: 50px; + transform: scale(1.5) translateY(-1px); + border-top-color: #fff; +} +.app-navigation .app-links-container ._main .app-links li a.nav-link-parent ~ ul { + transition: all 130ms linear; + height: 0; + overflow: hidden; +} +.app-navigation .app-links-container ._main .app-links li a.active { + background-color: #081C49; + color: #fff; +} +.app-navigation .app-links-container ._main .app-links li a.active .caret { + transition: all "" linear; + transform: rotate(180deg) scale(1.6) translateY(1px); +} +.app-navigation .app-links-container ._main .app-links li a.active ~ ul { + transition: all 130ms linear; + height: 197px; + overflow: hidden; +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons { + position: absolute; +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons:before { + content: ''; + width: 28px; + height: 28px; + background-size: contain; + background-repeat: no-repeat; + position: absolute; + left: -46px; +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons.icon-home:before { + background-image: url("/assets/SB_Icon_Menu/Home.png"); +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons.icon-integrations:before { + background-image: url("/assets/SB_Icon_Menu/Integrations.png"); +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons.icon-manage:before { + background-image: url("/assets/SB_Icon_Menu/Manage.png"); +} +.app-navigation .app-links-container ._main .app-links li a .nav-icons.icon-settings:before { + background-image: url("/assets/SB_Icon_Menu/Settings.png"); +} +.app-navigation .app-links-container ._main .app-links li .app-dropdown { + padding: 0; +} +.app-navigation .app-links-container ._main .app-links li .app-dropdown li:last-child a { + padding-bottom: 17px; +} +.app-navigation .app-links-container ._main .app-links li .app-dropdown li a { + transition: all "" linear; + font-size: 14px; + font-weight: 500; + color: #fff; + text-transform: capitalize; + padding-top: 8px; + padding-bottom: 8px; +} +.app-navigation .app-links-container ._main .app-links li .app-dropdown li a.active, .app-navigation .app-links-container ._main .app-links li .app-dropdown li a:hover { + transition: all "" linear; + background-color: #4f6185; + color: #fff; +} + +.nav-footer { + padding-top: 32px; + padding-bottom: 16px; + text-align: center; + width: 100%; +} +.nav-footer .navvbar-badge { + padding: 0; +} +.nav-footer a { + font-size: 12px; + margin-bottom: 8px; + color: #90a3d0; + letter-spacing: 1px; +} + +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist .nav-link-parent { + font-size: 1.25em; + padding-left: 40px; + text-transform: capitalize; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist .nav-link-parent, .app-navigation .app-links-container ._main .app-links .nav-setup-checklist .nav-link-child { + background-color: #6F7F9F; + color: #fff; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist ._list { + background-color: #6F7F9F; + padding-bottom: 16px; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist ._list .nav-link-child { + padding: 8px 16px 8px 34px; + text-transform: none; + font-size: 0.9em; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist ._list .nav-link-child ._step-count { + color: #fff; + border: 2px solid currentColor; + border-radius: 50px; + width: 28px; + height: 28px; + font-size: 12px; + text-align: center; + display: inline-block; + margin-right: 20px; + padding-right: 1px; + padding-top: 1px; + line-height: 23px; + padding-right: 0; + margin-right: 8px; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist ._list .nav-link-child._completed { + opacity: 0.5; +} +.app-navigation .app-links-container ._main .app-links .nav-setup-checklist ._list .nav-link-child._completed ._step-count { + border-color: #fff; + background-color: #fff; + color: #475981; +} + +.app-dashboard .app-body { + padding-top: 57px; + padding-left: 280px; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid\9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + border-top-color: #081C49; +} + +/* todo: To be cleaned up */ +.app-dashboard .servicetron { + display: none !important; +} + +.app-dashboard .navvbar-badge { + margin-top: 0; + display: block; + float: none !important; + width: 100%; + text-align: center; +} + +/*** +===== APP LAYOUT ===== +***/ +.app-content ._title-container { + background: #fff; + border-bottom: 1px solid #B9BBCB; +} +.app-content ._title-container ._heading { + font-size: 1.2rem; + font-weight: normal; + color: #475981; + padding: 23px 27px 22px; + margin-bottom: 0; +} +.app-content ._content-container { + background: #fff; + display: flex; +} +.app-content ._content-container ._sidebar { + flex-basis: 30%; + flex-shrink: 0; + max-width: 300px; + padding: 24px; + background-color: #EBF3F9; +} +.app-content ._content-container ._content { + flex-grow: 1; + width: calc(100vw - 300px - 300px - 20px); +} +.app-content ._content-container ._content ._section { + background-color: #F6F8F9; + margin: 16px; + padding: 16px 24px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06); +} +.app-content ._content-container ._content ._section:first-child { + padding-top: 24px; +} +.app-content ._content-container ._content ._section .caret { + transition: all "" linear; + display: block; + float: right; + margin: 8px; +} +.app-content ._content-container ._content ._section > h3 { + color: #6F7F9F; + font-size: 16px; + font-weight: normal; + text-transform: uppercase; + line-height: 22px; + font-family: "Open Sans", "Arial"; + margin-bottom: 0; +} +.app-content ._content-container ._content ._section > h3 > .form-step-count { + border: 2px solid currentColor; + border-radius: 50px; + width: 28px; + height: 28px; + font-size: 12px; + text-align: center; + display: inline-block; + margin-right: 20px; + padding-right: 1px; + padding-top: 1px; +} +.app-content ._content-container ._content ._section ._indented { + padding-left: 48px; +} +.app-content ._content-container ._content ._section._active .caret { + transition: all "" linear; + transform: rotate(180deg); +} +.app-content ._content-container ._content ._section._active ._indented { + padding-top: 16px; + padding-bottom: 8px; +} + +img { + color: #475981; + font-size: 14px; + font-family: "Open Sans", "Arial"; + color: #6F7F9F; + font-size: 12px; +} + +/*# sourceMappingURL=main.css.map */ diff --git a/public/css/main.css.map b/public/css/main.css.map new file mode 100644 index 00000000..c28af101 --- /dev/null +++ b/public/css/main.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAAA,YAAY;AC6BZ,WAAW;AAaX,UAAU;ACYR,UAAO;EArDP,KAAK,EAsDiB,IAAI;EArD1B,QAAQ,EAAE,QAAQ;EAClB,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,IAAI;;AAEhB,iBAAS;EACP,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;;AAEhC,gBAAQ;EACN,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,aAAa;EAChC,SAAS,EAAE,aAAa;;AAqC1B,WAAO;EAhCL,KAAK,EAiCgB,IAAI;EAhCzB,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,CAAC;EACb,WAAW,EAAE,CAAC;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AACd,kBAAS;EACP,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,cAAc;EACjC,SAAS,EAAE,cAAc;;AAE3B,iBAAQ;EACN,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,aAAa;EAChC,SAAS,EAAE,aAAa;;;AF7C5B,eAAe;AGJf,UAAU;AAKV,aAAa;AAGb,YAAY;AAUZ,eAAe;AAKf,WAAW;ACvBX,mBAAmB;AAoBnB,aAAa;EALX,KAAK,ECec,OAAc;EDdjC,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,iBAAiB;;;AJThC,cAAc;AMTd,QAAQ;EACN,OAAO,EAAE,QAAQ;EACjB,aAAa,EAAE,CAAC;EAChB,SAAS,EAAE,IAAc;EACzB,WAAW,EAAE,GAAG;EAChB,WAAW,EAAE,UAAU;EACvB,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,MAAM;EACnB,cAAc,EAAE,MAAM;EACtB,YAAY,EAAE,YAAY;EAC1B,MAAM,EAAE,OAAO;EACf,WAAW,EAAE,IAAI;EACjB,gBAAgB,EAAE,IAAI;EACtB,MAAM,EAAE,qBAAqB;EAC7B,aAAa,EAAE,GAAG;;AAElB,gBAAS;EACP,aAAa,EAAE,IAAI;;AAGrB,gCAAkB;EAChB,SAAS,EHnBD,IAAI;EGoBZ,OAAO,EAAE,SAAS;EAClB,gBAAgB,EAAE,OAAO;EACzB,KAAK,EDPkB,IAAY;ECQnC,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,+BAA4B;;AAG1C,iCAAmB;EACjB,SAAS,EH5BD,IAAI;EG6BZ,OAAO,EAAE,SAAS;EAClB,gBAAgB,EAAE,OAAO;EACzB,KAAK,EDhBkB,IAAY;ECiBnC,aAAa,EAAE,GAAG;EAClB,UAAU,EAAE,+BAA4B;;AAG1C,eAAQ;EACN,KAAK,EAAE,KAAK;;;AAKhB,MAAM;EACJ,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;;;ANlCb,eAAe;ACiCb,2BAA4B;EAC1B,KAAK,EAAE,IAAI;EACX,cAAc,EM/CE,MAAM;;ANkDpB,+CAAmB;EACjB,UAAU,EAAE,IAAI;;;AAQtB,KAAK;EAED,KAAK,EI/BU,OAAc;EJqC/B,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,MAAM;EACnB,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,SAAS;EACzB,WAAW,EAAE,oBAAoB;;;AAInC,oBAAoB;EAClB,KAAK,EI3EK,IAAI;EJ4Ed,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,MAAM,EAAE,iBAAwB;EAChC,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,IAAI;;;AM7EhB,eAAe;EACb,SAAS,EAAE,OAAO;EAClB,WAAW,EAAE,MAAM;EACnB,KAAK,EFuBc,OAAc;EEtBjC,aAAa,EJFN,IAAI;;;AKJX,kBAAY;EACV,UAAU,EAAE,MAAM;;AAElB,8BAAY;EACV,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,WAAW,EAAE,MAAM;EACnB,SAAS,EAAE,IAAI;EACf,YAAY,EAAE,CAAC;EACf,aAAa,EAAE,IAAI;EACnB,UAAU,EAAE,OAAO;;AAEnB,qCAAO;EPGX,WAAW,EAAE,CAAC;EACd,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,KAAK;EACZ,aAAa,EAAE,GAAG;EAClB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,8BAA2B;EACvC,UAAU,EAAE,IAAI;EAChB,YAAY,EAAE,IAAI;EAClB,QAAQ,EAAE,MAAM;EORV,UAAU,EAAE,QAAQ;EACpB,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;;AAEtB,2CAAO;EACL,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,iBAAiB;EAC7B,UAAU,EAAE,QAAQ;;AAGtB,+CAAY;EACV,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,iBAAiB;;AAE7B,8DAAe;EACb,gBAAgB,EAAE,WAAW;EAC7B,UAAU,EAAE,IAAI;;AAIpB,oDAAe;EACb,QAAQ,EAAE,QAAQ;EAClB,gBAAgB,EHXL,OAAc;EGYzB,KAAK,EHzBY,IAAY;EG0B7B,UAAU,EAAE,6BAA6B;;AAEzC,uDAAG;EACD,KAAK,EH7BU,IAAY;EG8B3B,SAAS,EAAE,IAAI;EACf,cAAc,EAAE,SAAS;EACzB,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,MAAM;EACf,MAAM,EAAE,CAAC;;AAGX,kEAAc;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,WAAW;ENlC/B,KAAK,EGRkB,IAAY;EHSnC,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,CAAC;EACb,WAAW,EAAE,CAAC;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AACd,yEAAS;EACP,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,cAAc;EACjC,SAAS,EAAE,cAAc;;AAE3B,wEAAQ;EACN,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,aAAa;EAChC,SAAS,EAAE,aAAa;;AMahB,yEAAQ;EACN,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,GAAG,EAAE,GAAG;EACR,SAAS,EAAE,oCAAmC;;AAEhD,wEAAO;EACL,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,GAAG,EAAE,GAAG;EACR,SAAS,EAAE,iCAAiC;;AAKlD,oDAAc;EACZ,SAAS,EAAE,CAAC;;AAIZ,gEAAc;EACZ,UAAU,EAAE,yCAAS;EACrB,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,GAAG;EACpB,mBAAmB,EAAE,aAAa;;AAJpC,iEAAc;EACZ,UAAU,EAAE,yCAAS;EACrB,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,GAAG;EACpB,mBAAmB,EAAE,aAAa;;AAJpC,iEAAc;EACZ,UAAU,EAAE,yCAAS;EACrB,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,GAAG;EACpB,mBAAmB,EAAE,aAAa;;AAJpC,iEAAc;EACZ,UAAU,EAAE,yCAAS;EACrB,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,GAAG;EACpB,mBAAmB,EAAE,aAAa;;AAJpC,iEAAc;EACZ,UAAU,EAAE,yCAAS;EACrB,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,GAAG;EACpB,mBAAmB,EAAE,aAAa;;AAoBxC,yCAAW;EACT,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,KAAK;EACZ,QAAQ,EAAE,QAAQ;;AAElB,2DAAkB;EN9GxB,KAAK,EGgBoB,IAAY;EHfrC,QAAQ,EAAE,QAAQ;EAClB,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,IAAI;EM6GR,OAAO,EAAE,KAAK;EACd,gBAAgB,EHhGA,OAAgB;EGiGhC,aAAa,EAAE,IAAI;EACnB,WAAW,EAAE,IAAI;EACjB,UAAU,EAAE,KAAK;EACjB,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,QAAQ;;ANjH5B,kEAAS;EACP,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;;AAEhC,iEAAQ;EACN,OAAO,EAAE,EAAE;EACX,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,GAAG;EACX,gBAAgB,EAAE,YAAY;EAC9B,iBAAiB,EAAE,aAAa;EAChC,SAAS,EAAE,aAAa;;AMqGlB,kEAAQ;EACN,IAAI,EAAE,GAAG;EACT,SAAS,EAAE,8BAA8B;;AAE3C,iEAAO;EACL,IAAI,EAAE,GAAG;EACT,SAAS,EAAE,gBAAgB;;AAE7B,iEAAO;EACL,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,iBAAiB;EAC7B,UAAU,EAAE,QAAQ;;AAO9B,qBAAe;EACb,aAAa,EAAE,GAAG;EAClB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,+BAA+B;EAC3C,OAAO,EAAE,SAAS;;AAIlB,sCAAiB;EACf,SAAS,EAHc,GAAG;EAI1B,SAAS,EAHc,KAAK;;AAK9B,sCAAiB;EACf,SAAS,EAPc,GAAG;EAQ1B,SAAS,EAPc,KAAK;;AAS9B,gDAA2B;EACzB,SAAS,EAXc,GAAG;EAY1B,SAAS,EAXc,KAAK;;AAe5B,uDAAa;EACX,KAAK,EAAE,KAAK;;AAEZ,6DAAK;EACH,KAAK,EHpJY,IAAY;EGqJ7B,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,KAAK;EACd,QAAQ,EAAE,QAAQ;EAClB,YAAY,EAAE,IAAI;EAClB,SAAS,EAAE,gBAAgB;;AAE3B,yIAAiB;EACf,MAAM,EAAE,GAAG;;AAKjB,2DAAiB;EACf,OAAO,EAAE,WAAW;EACpB,OAAO,EAAE,IAAI;;AAEb,mEAAO;EACL,UAAU,EHrKM,OAAgB;EGsKhC,KAAK,EHvKY,IAAY;EGwK7B,OAAO,EAAE,GAAG;EACZ,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,YAAY;EACrB,WAAW,EAAE,IAAI;EACjB,aAAa,EAAE,IAAI;EACnB,UAAU,EAAE,MAAM;EAClB,YAAY,EAAE,IAAI;;AAGpB,yEAAa;EACX,KAAK,EAAE,OAAO;EACd,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,gBAAgB;;AAG/B,gEAAI;EACF,aAAa,EAAE,iBAAiB;EAChC,SAAS,EAAE,CAAC;EACZ,MAAM,EAAE,MAAM;EACd,SAAS,EAAE,iBAAiB;;AAG9B,oFAAwB;EACtB,UAAU,EAAE,WAAW;EACvB,MAAM,EAAE,IAAI;EACZ,gBAAgB,EAAE,4BAA4B;EAC9C,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,KAAK,EAAE,IAAI;;AAKf,kEAAwB;EACtB,SAAS,EA5EY,GAAG;EA6ExB,SAAS,EA5EY,KAAK;EA6E1B,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,aAAa,EAAE,MAAM;;AAErB,wEAAK;EPpMX,KAAK,EIDc,OAAc;EJEjC,SAAS,EG/BO,IAAI;EHgCpB,WAAW,EAAE,MAAM;EACnB,cAAc,EAAE,SAAS;EACzB,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,oBAAoB;EOiMzB,KAAK,EHvMM,OAAc;EGwMzB,OAAO,EAAE,KAAK;EACd,OAAO,EAAE,aAAa;;AP1L9B,iDAA4B;EAC1B,KAAK,EAAE,IAAI;EACX,cAAc,EO4LM,MAAM;;APzLxB,qEAAmB;EACjB,UAAU,EAAE,IAAI;;AAQtB,2BAAK;EAED,KAAK,EI/BU,OAAc;EJqC/B,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,MAAM;EACnB,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,SAAS;EACzB,WAAW,EAAE,oBAAoB;;AAInC,gEAAoB;EAClB,KAAK,EI3EK,IAAI;EJ4Ed,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,MAAM,EAAE,iBAAwB;EAChC,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,IAAI;;;AEjFhB,UAAU;AAKV,aAAa;AAGb,YAAY;AAUZ,eAAe;AAKf,WAAW;AMnBT,iCAAkB;EAChB,SAAS,ENmBO,GAAG;EMlBnB,SAAS,ENmBO,KAAK;;AMhBnB,sEAAK;EACH,OAAO,EAAE,IAAI;;AAMnB,qBAAM;EACJ,KAAK,EAAE,KAAK;EACZ,MAAM,ENZD,IAAI;EMaT,YAAY,EAAE,IAAI;;;ACnBtB,6BAA6B;AAG7B,gBAAiB;EACf,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,YAAY;EAC7B,aAAa,EAAE,MAAM;EACrB,WAAW,EAAE,MAAM;EACnB,OAAO,EAAE,cAAmC;EAC5C,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,8BAA2B;EACvC,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,WAAsB;EAC9B,MAAM,EAAE,KAAW;EACnB,KAAK,EAAE,KAAW;ETuEhB,UAAU,EAAE,aAAiB;;ASpE/B,iDAAmB;EToEjB,UAAU,EAAE,aAAiB;ESlE7B,MAAM,EAAE,OAAO;EACf,gBAAgB,EAAE,yBAAsB;EACxC,UAAU,EAAE,mEAA6D;;AAEzE,iEAAO;ET8DP,UAAU,EAAE,aAAiB;;ASzD/B,8BAAe;EACb,UAAU,EAAE,IAAa;;AAG3B,uBAAS;EACP,SAAS,EAAE,IAAI;EACf,UAAU,EAAE,IAAI;;AAGlB,wBAAU;ENlCV,KAAK,ECEW,OAAO;EDDvB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,oBAAoB;EAIjC,KAAK,ECoBc,OAAc;EDnBjC,SAAS,EAAE,IAAI;EH2Eb,UAAU,EAAE,aAAiB;ES7C7B,OAAO,EAAE,KAAK;EACd,UAAU,EAAE,MAAM;EAClB,cAAc,EAAE,MAAM;;AAGxB,8BAAgB;EN1ChB,KAAK,ECEW,OAAO;EDDvB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,oBAAoB;;;AM+CnC,iBAAiB;EACf,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,YAAY;EAC7B,WAAW,EAAE,MAAM;EACnB,UAAU,EAAE,MAAM;EAClB,UAAU,EAAE,IAAI;EAChB,SAAS,EAAE,KAAK;EAChB,MAAM,EAAE,IAAI;;AAEZ,iCAAe;EACb,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,KAAK;EACpB,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,KAAK;;AAEb,qCAAG;EACD,SAAS,EAAE,IAAI;;AAInB,gCAAc;ENtEd,KAAK,ECEW,OAAO;EDDvB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,oBAAoB;;;AM6EjC,0BAAS;EACP,UAAU,EAAE,IAAI;;AAEhB,wCAAa;EACX,WAAW,EAAE,GAAG;;;ACvFtB,2CAA2C;AAcvC,yDAAkB;EAChB,OAAO,EAAE,IAAI;;AAEb,qEAAY;EACV,UAAU,EAAE,GAAG;EACf,YAAY,ERbX,IAAI;;AQmBL,oFAAiB;EACf,SAAS,EAAE,CAAC;;AAGd,gFAAY;EACV,YAAY,EAAE,CAAC;;;AXXzB,uBAAuB;AYnBvB,WAAW;EACT,QAAQ,EAAE,KAAK;EACf,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,IAAI;EACb,eAAe,EAAE,aAAa;EAC9B,MAAM,ETIY,IAAI;ESHtB,OAAO,EAAE,QAAwB;EACjC,gBAAgB,EPJC,OAAO;EOKxB,UAAU,EAAE,+BAA4B;EACxC,OAAO,ETUM,IAAI;ESoGjB,0BAA0B;;AA5G1B,2DAAmC;EACjC,OAAO,EAAE,IAAI;EACb,aAAa,EAAE,QAAQ;;AAOvB,iCAAK;EACH,WAAW,EAAE,GAAW;;AAI5B,qBAAS;EACP,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,iBAAkC;EAC9C,UAAU,EAAE,GAAG;;AAGjB,wBAAY;EACV,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI;;AAEf,4BAAG;EACD,MAAM,EAAE,IAAI;;AAIhB,6BAAiB;EACf,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,UAAU,EPrCI,OAAO;EOsCrB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM;EACnB,eAAe,EAAE,MAAM;EACvB,QAAQ,EAAE,QAAQ;;AAElB,+BAAC;EACC,KAAK,EPlCgB,IAAY;;AOqCnC,oDAAuB;EACrB,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,KAAK;EACZ,UAAU,EAAE,KAAK;EACjB,KAAK,EAAE,CAAC;EACR,GAAG,EAAE,IAAI;EACT,aAAa,EAAE,GAAG;EAClB,OAAO,ETxCS,MAAM;ESyCtB,SAAS,EAAE,IAAI;EACf,UAAU,EAAE,+BAA+B;;AAE3C,4DAAO;EACL,OAAO,EAAE,EAAE;EACX,MAAM,EAAE,CAAC;EACT,WAAW,EAAE,qBAAqB;EAClC,YAAY,EAAE,qBAAqB;EACnC,aAAa,EAAE,iBAAiB;EAChC,MAAM,EAAE,UAAU;EAClB,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,IAAI;EACT,KAAK,EAAE,IAAI;;AAGb,uDAAG;EACD,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;;AAET,0DAAG;EACD,UAAU,EAAE,IAAI;EAChB,OAAO,EAAE,mBAAmB;EAC5B,WAAW,EAAE,KAAK;EAClB,QAAQ,EAAE,QAAQ;;AAElB,iEAAO;EACL,UAAU,EAAE,OAAO;;AAGrB,+IAAyB;EACvB,WAAW,ETtFd,IAAI;;ASyFH,gFAAwB;EACtB,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,OAAO;EACnB,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,IAAI;EACV,UAAU,EAAE,GAAG;EACf,GAAG,EAAE,GAAG;EACR,SAAS,EAAE,gBAAgB;EAC3B,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,EAAE;;AAKjB,+EAA0B;EACxB,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;;AAQpB,eAAe;EACb,QAAQ,EAAE,KAAK;EACf,KAAK,ETnHW,KAAK;ESoHrB,WAAW,ETrHO,IAAI;ESsHtB,gBAAgB,EPzHA,OAAO;EO0HvB,MAAM,EAAE,IAAI;EACZ,OAAO,ET7GK,IAAI;;AS+GhB,oCAAqB;EACnB,MAAM,EAAE,IAAI;;AAEZ,2CAAO;EACL,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,aAAa;EAC9B,aAAa,EAAE,aAAa;EAC5B,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,IAAI;;AAEhB,sDAAW;EACT,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,UAAU,EAAE,IAAI;;AAEhB,2DAAO;EACL,aAAa,EAAE,iBAAiB;;AAGlC,yDAAG;EACD,OAAO,EAAE,CAAC;;AAEV,2DAAE;EACA,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,IAAW;EACpB,YAAY,EAAE,IAAI;EAClB,WAAW,ET5JL,iCAAiC;ES6JvC,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,cAAc,EAAE,SAAS;EACzB,KAAK,EPlJU,IAAY;EOmJ3B,QAAQ,EAAE,QAAQ;EAClB,cAAc,EAAE,GAAG;;AAEnB,iEAAQ;EACN,UAAU,EAAE,OAAO;;AAKnB,kFAAO;EXvFjB,UAAU,EAAE,aAAiB;EWyFjB,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,2BAA2B;EACtC,gBAAgB,EPhKL,IAAY;;AOmKzB,gFAAO;EX9FjB,UAAU,EAAE,gBAAiB;EWgGjB,MAAM,EAAE,CAAC;EACT,QAAQ,EAAE,MAAM;;AAIpB,kEAAS;EACP,gBAAgB,EP1KJ,OAAgB;EO2K5B,KAAK,EP5KQ,IAAY;;AO8KzB,yEAAO;EXzGjB,UAAU,EAAE,aAAiB;EW2GjB,SAAS,EAAE,yCAAyC;;AAGtD,uEAAO;EX9GjB,UAAU,EAAE,gBAAiB;EWgHjB,MAAM,EAAE,KAAK;EACb,QAAQ,EAAE,MAAM;;AAIpB,sEAAW;EACT,QAAQ,EAAE,QAAQ;;AAElB,6EAAS;EACP,OAAO,EAAE,EAAE;EACX,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,eAAe,EAAE,OAAO;EACxB,iBAAiB,EAAE,SAAS;EAC5B,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,KAAK;;AAIX,uFAAS;EACP,gBAAgB,EAAE,oCAAoC;;AAIxD,+FAAS;EACP,gBAAgB,EAAE,4CAA4C;;AAIhE,yFAAS;EACP,gBAAgB,EAAE,sCAAsC;;AAI1D,2FAAS;EACP,gBAAgB,EAAE,wCAAwC;;AAMlE,uEAAc;EACZ,OAAO,EAAE,CAAC;;AAIR,uFAAe;EACb,cAAc,EAAE,IAAI;;AAGtB,4EAAE;EXlKZ,UAAU,EAAE,aAAiB;EWoKjB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,GAAG;EAChB,KAAK,EP3OM,IAAY;EO4OvB,cAAc,EAAE,UAAU;EAC1B,WAAW,EAAE,GAAW;EACxB,cAAc,EAAE,GAAW;;AAE3B,uKAAkB;EX3K9B,UAAU,EAAE,aAAiB;EW6Kf,gBAAgB,EPhPT,OAAuB;EOiP9B,KAAK,EPnPI,IAAY;;;AO8PvC,WAAW;EACT,WAAW,EAAE,IAAW;EACxB,cAAc,ET3QP,IAAI;ES4QX,UAAU,EAAE,MAAM;EAClB,KAAK,EAAE,IAAI;;AAEX,0BAAc;EACZ,OAAO,EAAE,CAAC;;AAGZ,aAAC;EACC,SAAS,EAAE,IAAI;EACf,aAAa,EAAE,GAAW;EAC1B,KAAK,EAAE,OAAO;EACd,cAAc,EAAE,GAAG;;;AAQnB,4FAAgB;EACd,SAAS,EAAE,MAAM;EACjB,YAAY,EAAE,IAAa;EAC3B,cAAc,EAAE,UAAU;;AAG5B,yLAAkC;EAChC,gBAAgB,EP9QD,OAAc;EO+Q7B,KAAK,EP5RgB,IAAY;;AO+RnC,kFAAM;EACJ,gBAAgB,EPnRD,OAAc;EOoR7B,cAAc,ET5SX,IAAI;;AS8SP,kGAAgB;EACd,OAAO,EAAE,iBAAuC;EAChD,cAAc,EAAE,IAAI;EACpB,SAAS,EAAE,KAAK;;AAEhB,+GAAa;EACX,KAAK,EPzSY,IAAY;EJfrC,MAAM,EAAE,sBAAsB;EAC9B,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI;EACf,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,IAAI;EAClB,aAAa,EAAE,GAAG;EAClB,WAAW,EAAE,GAAG;EWiTR,WAAW,EAAE,IAAI;EACjB,aAAa,EAAE,CAAC;EAChB,YAAY,EAAE,GAAW;;AAG3B,6GAAa;EACX,OAAO,EAAE,GAAG;;AAEZ,0HAAa;EACX,YAAY,EPpTG,IAAY;EOqT3B,gBAAgB,EPrTD,IAAY;EOsT3B,KAAK,EPjUC,OAAO;;;AOkVzB,wBAAwB;EACtB,WAAW,EThVO,IAAI;ESiVtB,YAAY,EThVI,KAAK;;;ASmVvB,MAAM;EACJ,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,WAAW,EAAE,GAAG;EAChB,cAAc,EAAE,MAAM;EACtB,UAAU,EAAE,UAAU;EACtB,UAAU,EAAE,WAAW;EACvB,YAAY,EAAE,qBAAqB;EACnC,WAAW,EAAE,qBAAqB;EAClC,gBAAgB,EPrVQ,OAAgB;;;AOwV1C,4BAA4B;AAC5B,2BAA2B;EACzB,OAAO,EAAE,eAAe;;;AAE1B,6BAA8B;EAC5B,UAAU,EAAE,CAAC;EACb,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,eAAe;EACtB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,MAAM;;;ACnXpB;;IAEI;AAIF,8BAAiB;EACf,UAAU,ERUa,IAAY;EQTnC,aAAa,EAAE,iBAAuC;;AAEtD,wCAAS;EAEP,SAAS,EAAE,MAAM;EACjB,WAAW,EAAE,MAAM;EACnB,KAAK,ERRO,OAAO;EQSnB,OAAO,EAAE,cAAc;EACvB,aAAa,EAAE,CAAC;;AAMpB,gCAAoB;EAClB,UAAU,ERNa,IAAY;EQOnC,OAAO,EAAE,IAAI;;AAEb,0CAAU;EACR,UAAU,EAAE,GAAG;EACf,WAAW,EAAE,CAAC;EACd,SAAS,EAAE,KAAK;EAChB,OAAO,EAAE,IAAa;EACtB,gBAAgB,ER3BE,OAAO;;AQ8B3B,0CAAU;EACR,SAAS,EAAE,CAAC;EACZ,KAAK,EAAE,kCAAkC;;AAEzC,oDAAS;EAEP,gBAAgB,ERtCC,OAAO;EQuCxB,MAAM,EVnCL,IAAI;EUoCL,OAAO,EAAE,SAAqB;EAC9B,UAAU,EAAE,+BAA4B;;AAExC,gEAAa;EACX,WAAW,EAAE,IAAa;;AAG5B,2DAAM;EZqCV,UAAU,EAAE,aAAiB;EYnCvB,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,GAAG;;AAGb,yDAAM;EZzBZ,KAAK,EIDc,OAAc;EJEjC,SAAS,EG/BO,IAAI;EHgCpB,WAAW,EAAE,MAAM;EACnB,cAAc,EAAE,SAAS;EACzB,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,oBAAoB;EYsBzB,aAAa,EAAE,CAAC;;AAEhB,4EAAoB;EZ1D5B,MAAM,EAAE,sBAAsB;EAC9B,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI;EACf,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,IAAI;EAClB,aAAa,EAAE,GAAG;EAClB,WAAW,EAAE,GAAG;;AYsDV,+DAAa;EACX,YAAY,EAAE,IAAW;;AAKzB,mEAAM;EZeZ,UAAU,EAAE,aAAiB;EYbrB,SAAS,EAAE,cAAc;;AAG3B,uEAAW;EACT,WAAW,EVvEd,IAAI;EUwED,cAAc,EAAE,GAAW;;;AbvDvC,GAAG;EInBD,KAAK,ECEW,OAAO;EDDvB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,oBAAoB;EAIjC,KAAK,ECoBc,OAAc;EDnBjC,SAAS,EAAE,IAAI", +"sources": ["../scss/main.scss","../scss/_mixins.scss","../scss/css-icons.scss","../scss/variables.scss","../scss/text.scss","../scss/colors.scss","../scss/buttons.scss","../scss/_component-forms.scss","../scss/_component-tier.scss","../scss/_component-forms-offering.scss","../scss/_component-embeddables.scss","../scss/_component-embeddables-checkout.scss","../scss/_layout-nav.scss","../scss/_layout-content.scss"], +"names": [], +"file": "main.css" +} diff --git a/public/fonts/FontAwesome.otf b/public/fonts/FontAwesome.otf new file mode 100644 index 00000000..401ec0f3 Binary files /dev/null and b/public/fonts/FontAwesome.otf differ diff --git a/public/fonts/fontawesome-webfont.eot b/public/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/public/fonts/fontawesome-webfont.eot differ diff --git a/public/fonts/fontawesome-webfont.svg b/public/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/public/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/fonts/fontawesome-webfont.ttf b/public/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/public/fonts/fontawesome-webfont.ttf differ diff --git a/public/fonts/fontawesome-webfont.woff b/public/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/public/fonts/fontawesome-webfont.woff differ diff --git a/public/fonts/fontawesome-webfont.woff2 b/public/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/public/fonts/fontawesome-webfont.woff2 differ diff --git a/public/js/bootstrap-3.3.7-dist/css/bootstrap.css b/public/js/bootstrap-3.3.7-dist/css/bootstrap.css index 6167622c..ebc3b730 100644 --- a/public/js/bootstrap-3.3.7-dist/css/bootstrap.css +++ b/public/js/bootstrap-3.3.7-dist/css/bootstrap.css @@ -5872,7 +5872,7 @@ button.close { right: 0; bottom: 0; left: 0; - z-index: 1050; + z-index: 9954; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; diff --git a/public/js/bootstrap-3.3.7-dist/css/bootstrap.css.map b/public/js/bootstrap-3.3.7-dist/css/bootstrap.css.map index f010c82d..df3ff448 100644 --- a/public/js/bootstrap-3.3.7-dist/css/bootstrap.css.map +++ b/public/js/bootstrap-3.3.7-dist/css/bootstrap.css.map @@ -1 +1 @@ -{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;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ukDH;AexkDC;EACE,oBAAA;Cf0kDH;Ae3kDC;EACE,WAAA;Cf6kDH;Ae9kDC;EACE,oBAAA;CfglDH;AejlDC;EACE,mBAAA;CfmlDH;Ae/kDC;EACE,YAAA;CfilDH;AejmDC;EACE,WAAA;CfmmDH;AepmDC;EACE,mBAAA;CfsmDH;AevmDC;EACE,mBAAA;CfymDH;Ae1mDC;EACE,UAAA;Cf4mDH;Ae7mDC;EACE,mBAAA;Cf+mDH;AehnDC;EACE,mBAAA;CfknDH;AennDC;EACE,UAAA;CfqnDH;AetnDC;EACE,mBAAA;CfwnDH;AeznDC;EACE,mBAAA;Cf2nDH;Ae5nDC;EACE,UAAA;Cf8nDH;Ae/nDC;EACE,mBAAA;CfioDH;AeloDC;EACE,kBAAA;CfooDH;AehoDC;EACE,WAAA;CfkoDH;AepnDC;EACE,kBAAA;CfsnDH;AevnDC;EACE,0BAAA;CfynDH;Ae1nDC;EACE,0BAAA;Cf4nDH;Ae7nDC;EACE,iBAAA;Cf+nDH;AehoDC;EACE,0BAAA;CfkoDH;AenoDC;EACE,0BAAA;CfqoDH;AetoDC;EACE,iBAAA;CfwoDH;AezoDC;EACE,0BAAA;Cf2oDH;Ae5oDC;EACE,0BAAA;Cf8oDH;Ae/oDC;EACE,iBAAA;CfipDH;AelpDC;EACE,0BAAA;CfopDH;AerpDC;EACE,yBAAA;CfupDH;AexpDC;EACE,gBAAA;Cf0pDH;Aa1pDD;EElCI;IACE,YAAA;Gf+rDH;EexrDD;IACE,YAAA;Gf0rDD;Ee3rDD;IACE,oBAAA;Gf6rDD;Ee9rDD;IACE,oBAAA;GfgsDD;EejsDD;IACE,WAAA;GfmsDD;EepsDD;IACE,oBAAA;GfssDD;EevsDD;IACE,oBAAA;GfysDD;Ee1sDD;IACE,WAAA;Gf4sDD;Ee7sDD;IACE,oBAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,WAAA;GfqtDD;EettDD;IACE,oBAAA;GfwtDD;EeztDD;IACE,mBAAA;Gf2tDD;Ee7sDD;IACE,YAAA;Gf+sDD;EehtDD;IACE,oBAAA;GfktDD;EentDD;IACE,oBAAA;GfqtDD;EettDD;IACE,WAAA;GfwtDD;EeztDD;IACE,oBAAA;Gf2tDD;Ee5tDD;IACE,oBAAA;Gf8tDD;Ee/tDD;IACE,WAAA;GfiuDD;EeluDD;IACE,oBAAA;GfouDD;EeruDD;IACE,oBAAA;GfuuDD;EexuDD;IACE,WAAA;Gf0uDD;Ee3uDD;IACE,oBAAA;Gf6uDD;Ee9uDD;IACE,mBAAA;GfgvDD;Ee5uDD;IACE,YAAA;Gf8uDD;Ee9vDD;IACE,WAAA;GfgwDD;EejwDD;IACE,mBAAA;GfmwDD;EepwDD;IACE,mBAAA;GfswDD;EevwDD;IACE,UAAA;GfywDD;Ee1wDD;IACE,mBAAA;Gf4wDD;Ee7wDD;IACE,mBAAA;Gf+wDD;EehxDD;IACE,UAAA;GfkxDD;EenxDD;IACE,mBAAA;GfqxDD;EetxDD;IACE,mBAAA;GfwxDD;EezxDD;IACE,UAAA;Gf2xDD;Ee5xDD;IACE,mBAAA;Gf8xDD;Ee/xDD;IACE,kBAAA;GfiyDD;Ee7xDD;IACE,WAAA;Gf+xDD;EejxDD;IACE,kBAAA;GfmxDD;EepxDD;IACE,0BAAA;GfsxDD;EevxDD;IACE,0BAAA;GfyxDD;Ee1xDD;IACE,iBAAA;Gf4xDD;Ee7xDD;IACE,0BAAA;Gf+xDD;EehyDD;IACE,0BAAA;GfkyDD;EenyDD;IACE,iBAAA;GfqyDD;EetyDD;IACE,0BAAA;GfwyDD;EezyDD;IACE,0BAAA;Gf2yDD;Ee5yDD;IACE,iBAAA;Gf8yDD;Ee/yDD;IACE,0BAAA;GfizDD;EelzDD;IACE,yBAAA;GfozDD;EerzDD;IACE,gBAAA;GfuzDD;CACF;Aa/yDD;EE3CI;IACE,YAAA;Gf61DH;Eet1DD;IACE,YAAA;Gfw1DD;Eez1DD;IACE,oBAAA;Gf21DD;Ee51DD;IACE,oBAAA;Gf81DD;Ee/1DD;IACE,WAAA;Gfi2DD;Eel2DD;IACE,oBAAA;Gfo2DD;Eer2DD;IACE,oBAAA;Gfu2DD;Eex2DD;IACE,WAAA;Gf02DD;Ee32DD;IACE,oBAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,WAAA;Gfm3DD;Eep3DD;IACE,oBAAA;Gfs3DD;Eev3DD;IACE,mBAAA;Gfy3DD;Ee32DD;IACE,YAAA;Gf62DD;Ee92DD;IACE,oBAAA;Gfg3DD;Eej3DD;IACE,oBAAA;Gfm3DD;Eep3DD;IACE,WAAA;Gfs3DD;Eev3DD;IACE,oBAAA;Gfy3DD;Ee13DD;IACE,oBAAA;Gf43DD;Ee73DD;IACE,WAAA;Gf+3DD;Eeh4DD;IACE,oBAAA;Gfk4DD;Een4DD;IACE,oBAAA;Gfq4DD;Eet4DD;IACE,WAAA;Gfw4DD;Eez4DD;IACE,oBAAA;Gf24DD;Ee54DD;IACE,mBAAA;Gf84DD;Ee14DD;IACE,YAAA;Gf44DD;Ee55DD;IACE,WAAA;Gf85DD;Ee/5DD;IACE,mBAAA;Gfi6DD;Eel6DD;IACE,mBAAA;Gfo6DD;Eer6DD;IACE,UAAA;Gfu6DD;Eex6DD;IACE,mBAAA;Gf06DD;Ee36DD;IACE,mBAAA;Gf66DD;Ee96DD;IACE,UAAA;Gfg7DD;Eej7DD;IACE,mBAAA;Gfm7DD;Eep7DD;IACE,mBAAA;Gfs7DD;Eev7DD;IACE,UAAA;Gfy7DD;Ee17DD;IACE,mBAAA;Gf47DD;Ee77DD;IACE,kBAAA;Gf+7DD;Ee37DD;IACE,WAAA;Gf67DD;Ee/6DD;IACE,kBAAA;Gfi7DD;Eel7DD;IACE,0BAAA;Gfo7DD;Eer7DD;IACE,0BAAA;Gfu7DD;Eex7DD;IACE,iBAAA;Gf07DD;Ee37DD;IACE,0BAAA;Gf67DD;Ee97DD;IACE,0BAAA;Gfg8DD;Eej8DD;IACE,iBAAA;Gfm8DD;Eep8DD;IACE,0BAAA;Gfs8DD;Eev8DD;IACE,0BAAA;Gfy8DD;Ee18DD;IACE,iBAAA;Gf48DD;Ee78DD;IACE,0BAAA;Gf+8DD;Eeh9DD;IACE,yBAAA;Gfk9DD;Een9DD;IACE,gBAAA;Gfq9DD;CACF;Aa18DD;EE9CI;IACE,YAAA;Gf2/DH;Eep/DD;IACE,YAAA;Gfs/DD;Eev/DD;IACE,oBAAA;Gfy/DD;Ee1/DD;IACE,oBAAA;Gf4/DD;Ee7/DD;IACE,WAAA;Gf+/DD;EehgED;IACE,oBAAA;GfkgED;EengED;IACE,oBAAA;GfqgED;EetgED;IACE,WAAA;GfwgED;EezgED;IACE,oBAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,WAAA;GfihED;EelhED;IACE,oBAAA;GfohED;EerhED;IACE,mBAAA;GfuhED;EezgED;IACE,YAAA;Gf2gED;Ee5gED;IACE,oBAAA;Gf8gED;Ee/gED;IACE,oBAAA;GfihED;EelhED;IACE,WAAA;GfohED;EerhED;IACE,oBAAA;GfuhED;EexhED;IACE,oBAAA;Gf0hED;Ee3hED;IACE,WAAA;Gf6hED;Ee9hED;IACE,oBAAA;GfgiED;EejiED;IACE,oBAAA;GfmiED;EepiED;IACE,WAAA;GfsiED;EeviED;IACE,oBAAA;GfyiED;Ee1iED;IACE,mBAAA;Gf4iED;EexiED;IACE,YAAA;Gf0iED;Ee1jED;IACE,WAAA;Gf4jED;Ee7jED;IACE,mBAAA;Gf+jED;EehkED;IACE,mBAAA;GfkkED;EenkED;IACE,UAAA;GfqkED;EetkED;IACE,mBAAA;GfwkED;EezkED;IACE,mBAAA;Gf2kED;Ee5kED;IACE,UAAA;Gf8kED;Ee/kED;IACE,mBAAA;GfilED;EellED;IACE,mBAAA;GfolED;EerlED;IACE,UAAA;GfulED;EexlED;IACE,mBAAA;Gf0lED;Ee3lED;IACE,kBAAA;Gf6lED;EezlED;IACE,WAAA;Gf2lED;Ee7kED;IACE,kBAAA;Gf+kED;EehlED;IACE,0BAAA;GfklED;EenlED;IACE,0BAAA;GfqlED;EetlED;IACE,iBAAA;GfwlED;EezlED;IACE,0BAAA;Gf2lED;Ee5lED;IACE,0BAAA;Gf8lED;Ee/lED;IACE,iBAAA;GfimED;EelmED;IACE,0BAAA;GfomED;EermED;IACE,0BAAA;GfumED;EexmED;IACE,iBAAA;Gf0mED;Ee3mED;IACE,0BAAA;Gf6mED;Ee9mED;IACE,yBAAA;GfgnED;EejnED;IACE,gBAAA;GfmnED;CACF;AgBvrED;EACE,8BAAA;ChByrED;AgBvrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChByrED;AgBvrED;EACE,iBAAA;ChByrED;AgBnrED;EACE,YAAA;EACA,gBAAA;EACA,oBAAA;ChBqrED;AgBxrED;;;;;;EAWQ,aAAA;EACA,wBAAA;EACA,oBAAA;EACA,2BAAA;ChBqrEP;AgBnsED;EAoBI,uBAAA;EACA,8BAAA;ChBkrEH;AgBvsED;;;;;;EA8BQ,cAAA;ChBirEP;AgB/sED;EAoCI,2BAAA;ChB8qEH;AgBltED;EAyCI,uBAAA;ChB4qEH;AgBrqED;;;;;;EAOQ,aAAA;ChBsqEP;AgB3pED;EACE,uBAAA;ChB6pED;AgB9pED;;;;;;EAQQ,uBAAA;ChB8pEP;AgBtqED;;EAeM,yBAAA;ChB2pEL;AgBjpED;EAEI,0BAAA;ChBkpEH;AgBzoED;EAEI,0BAAA;ChB0oEH;AgBjoED;EACE,iBAAA;EACA,YAAA;EACA,sBAAA;ChBmoED;AgB9nEG;;EACE,iBAAA;EACA,YAAA;EACA,oBAAA;ChBioEL;AiB7wEC;;;;;;;;;;;;EAOI,0BAAA;CjBoxEL;AiB9wEC;;;;;EAMI,0BAAA;CjB+wEL;AiBlyEC;;;;;;;;;;;;EAOI,0BAAA;CjByyEL;AiBnyEC;;;;;EAMI,0BAAA;CjBoyEL;AiBvzEC;;;;;;;;;;;;EAOI,0BAAA;CjB8zEL;AiBxzEC;;;;;EAMI,0BAAA;CjByzEL;AiB50EC;;;;;;;;;;;;EAOI,0BAAA;CjBm1EL;AiB70EC;;;;;EAMI,0BAAA;CjB80EL;AiBj2EC;;;;;;;;;;;;EAOI,0BAAA;CjBw2EL;AiBl2EC;;;;;EAMI,0BAAA;CjBm2EL;AgBjtED;EACE,iBAAA;EACA,kBAAA;ChBmtED;AgBtpED;EACA;IA3DI,YAAA;IACA,oBAAA;IACA,mBAAA;IACA,6CAAA;IACA,uBAAA;GhBotED;EgB7pEH;IAnDM,iBAAA;GhBmtEH;EgBhqEH;;;;;;IA1CY,oBAAA;GhBktET;EgBxqEH;IAlCM,UAAA;GhB6sEH;EgB3qEH;;;;;;IAzBY,eAAA;GhB4sET;EgBnrEH;;;;;;IArBY,gBAAA;GhBgtET;EgB3rEH;;;;IARY,iBAAA;GhBysET;CACF;AkBn6ED;EACE,WAAA;EACA,UAAA;EACA,UAAA;EAIA,aAAA;ClBk6ED;AkB/5ED;EACE,eAAA;EACA,YAAA;EACA,WAAA;EACA,oBAAA;EACA,gBAAA;EACA,qBAAA;EACA,eAAA;EACA,UAAA;EACA,iCAAA;ClBi6ED;AkB95ED;EACE,sBAAA;EACA,gBAAA;EACA,mBAAA;EACA,kBAAA;ClBg6ED;AkBr5ED;Eb4BE,+BAAA;EACG,4BAAA;EACK,uBAAA;CL43ET;AkBr5ED;;EAEE,gBAAA;EACA,mBAAA;EACA,oBAAA;ClBu5ED;AkBp5ED;EACE,eAAA;ClBs5ED;AkBl5ED;EACE,eAAA;EACA,YAAA;ClBo5ED;AkBh5ED;;EAEE,aAAA;ClBk5ED;AkB94ED;;;EZrEE,2CAAA;EACA,qBAAA;CNw9ED;AkB74ED;EACE,eAAA;EACA,iBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;ClB+4ED;AkBr3ED;EACE,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;EbxDA,yDAAA;EACQ,iDAAA;EAyHR,uFAAA;EACK,0EAAA;EACG,uEAAA;CLwzET;AmBh8EC;EACE,sBAAA;EACA,WAAA;EdUF,uFAAA;EACQ,+EAAA;CLy7ET;AKx5EC;EACE,YAAA;EACA,WAAA;CL05EH;AKx5EC;EAA0B,YAAA;CL25E3B;AK15EC;EAAgC,YAAA;CL65EjC;AkBj4EC;EACE,UAAA;EACA,8BAAA;ClBm4EH;AkB33EC;;;EAGE,0BAAA;EACA,WAAA;ClB63EH;AkB13EC;;EAEE,oBAAA;ClB43EH;AkBx3EC;EACE,aAAA;ClB03EH;AkB92ED;EACE,yBAAA;ClBg3ED;AkBx0ED;EAtBI;;;;IACE,kBAAA;GlBo2EH;EkBj2EC;;;;;;;;IAEE,kBAAA;GlBy2EH;EkBt2EC;;;;;;;;IAEE,kBAAA;GlB82EH;CACF;AkBp2ED;EACE,oBAAA;ClBs2ED;AkB91ED;;EAEE,mBAAA;EACA,eAAA;EACA,iBAAA;EACA,oBAAA;ClBg2ED;AkBr2ED;;EAQI,iBAAA;EACA,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,gBAAA;ClBi2EH;AkB91ED;;;;EAIE,mBAAA;EACA,mBAAA;EACA,mBAAA;ClBg2ED;AkB71ED;;EAEE,iBAAA;ClB+1ED;AkB31ED;;EAEE,mBAAA;EACA,sBAAA;EACA,mBAAA;EACA,iBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;ClB61ED;AkB31ED;;EAEE,cAAA;EACA,kBAAA;ClB61ED;AkBp1EC;;;;;;EAGE,oBAAA;ClBy1EH;AkBn1EC;;;;EAEE,oBAAA;ClBu1EH;AkBj1EC;;;;EAGI,oBAAA;ClBo1EL;AkBz0ED;EAEE,iBAAA;EACA,oBAAA;EAEA,iBAAA;EACA,iBAAA;ClBy0ED;AkBv0EC;;EAEE,gBAAA;EACA,iBAAA;ClBy0EH;AkB5zED;ECnQE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnBkkFD;AmBhkFC;EACE,aAAA;EACA,kBAAA;CnBkkFH;AmB/jFC;;EAEE,aAAA;CnBikFH;AkBx0ED;EAEI,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;ClBy0EH;AkB/0ED;EASI,aAAA;EACA,kBAAA;ClBy0EH;AkBn1ED;;EAcI,aAAA;ClBy0EH;AkBv1ED;EAiBI,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;ClBy0EH;AkBr0ED;EC/RE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBumFD;AmBrmFC;EACE,aAAA;EACA,kBAAA;CnBumFH;AmBpmFC;;EAEE,aAAA;CnBsmFH;AkBj1ED;EAEI,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ClBk1EH;AkBx1ED;EASI,aAAA;EACA,kBAAA;ClBk1EH;AkB51ED;;EAcI,aAAA;ClBk1EH;AkBh2ED;EAiBI,aAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;ClBk1EH;AkBz0ED;EAEE,mBAAA;ClB00ED;AkB50ED;EAMI,sBAAA;ClBy0EH;AkBr0ED;EACE,mBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,mBAAA;EACA,qBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBr0ED;;;EAGE,YAAA;EACA,aAAA;EACA,kBAAA;ClBu0ED;AkBn0ED;;;;;;;;;;EC1ZI,eAAA;CnByuFH;AkB/0ED;ECtZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CL0rFT;AmBxuFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL+rFT;AkBz1ED;EC5YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBwuFH;AkB91ED;ECtYI,eAAA;CnBuuFH;AkB91ED;;;;;;;;;;EC7ZI,eAAA;CnBuwFH;AkB12ED;ECzZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLwtFT;AmBtwFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL6tFT;AkBp3ED;EC/YI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBswFH;AkBz3ED;ECzYI,eAAA;CnBqwFH;AkBz3ED;;;;;;;;;;EChaI,eAAA;CnBqyFH;AkBr4ED;EC5ZI,sBAAA;Ed+CF,yDAAA;EACQ,iDAAA;CLsvFT;AmBpyFG;EACE,sBAAA;Ed4CJ,0EAAA;EACQ,kEAAA;CL2vFT;AkB/4ED;EClZI,eAAA;EACA,sBAAA;EACA,0BAAA;CnBoyFH;AkBp5ED;EC5YI,eAAA;CnBmyFH;AkBh5EC;EACE,UAAA;ClBk5EH;AkBh5EC;EACE,OAAA;ClBk5EH;AkBx4ED;EACE,eAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;ClB04ED;AkBvzED;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBy3EH;EkBrvEH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBu3EH;EkB1vEH;IAxHM,sBAAA;GlBq3EH;EkB7vEH;IApHM,sBAAA;IACA,uBAAA;GlBo3EH;EkBjwEH;;;IA9GQ,YAAA;GlBo3EL;EkBtwEH;IAxGM,YAAA;GlBi3EH;EkBzwEH;IApGM,iBAAA;IACA,uBAAA;GlBg3EH;EkB7wEH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB62EH;EkBpxEH;;IAtFQ,gBAAA;GlB82EL;EkBxxEH;;IAjFM,mBAAA;IACA,eAAA;GlB62EH;EkB7xEH;IA3EM,OAAA;GlB22EH;CACF;AkBj2ED;;;;EASI,cAAA;EACA,iBAAA;EACA,iBAAA;ClB81EH;AkBz2ED;;EAiBI,iBAAA;ClB41EH;AkB72ED;EJthBE,mBAAA;EACA,oBAAA;Cds4FD;AkB10EC;EAyBF;IAnCM,kBAAA;IACA,iBAAA;IACA,iBAAA;GlBw1EH;CACF;AkBx3ED;EAwCI,YAAA;ClBm1EH;AkBr0EC;EAUF;IAdQ,kBAAA;IACA,gBAAA;GlB60EL;CACF;AkBn0EC;EAEF;IANQ,iBAAA;IACA,gBAAA;GlB20EL;CACF;AoBp6FD;EACE,sBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,uBAAA;EACA,+BAAA;MAAA,2BAAA;EACA,gBAAA;EACA,uBAAA;EACA,8BAAA;EACA,oBAAA;EC0CA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,mBAAA;EhB+JA,0BAAA;EACG,uBAAA;EACC,sBAAA;EACI,kBAAA;CL+tFT;AoBv6FG;;;;;;EdnBF,2CAAA;EACA,qBAAA;CNk8FD;AoB16FC;;;EAGE,YAAA;EACA,sBAAA;CpB46FH;AoBz6FC;;EAEE,WAAA;EACA,uBAAA;Ef2BF,yDAAA;EACQ,iDAAA;CLi5FT;AoBz6FC;;;EAGE,oBAAA;EE7CF,cAAA;EAGA,0BAAA;EjB8DA,yBAAA;EACQ,iBAAA;CL05FT;AoBz6FG;;EAEE,qBAAA;CpB26FL;AoBl6FD;EC3DE,YAAA;EACA,uBAAA;EACA,mBAAA;CrBg+FD;AqB99FC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBg+FP;AqB99FG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBs+FT;AqBn+FC;;;EAGE,uBAAA;CrBq+FH;AqBh+FG;;;;;;;;;EAGE,uBAAA;EACI,mBAAA;CrBw+FT;AoBv9FD;ECZI,YAAA;EACA,uBAAA;CrBs+FH;AoBx9FD;EC9DE,YAAA;EACA,0BAAA;EACA,sBAAA;CrByhGD;AqBvhGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrByhGP;AqBvhGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB+hGT;AqB5hGC;;;EAGE,uBAAA;CrB8hGH;AqBzhGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBiiGT;AoB7gGD;ECfI,eAAA;EACA,uBAAA;CrB+hGH;AoB7gGD;EClEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBklGD;AqBhlGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBklGP;AqBhlGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBwlGT;AqBrlGC;;;EAGE,uBAAA;CrBulGH;AqBllGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB0lGT;AoBlkGD;ECnBI,eAAA;EACA,uBAAA;CrBwlGH;AoBlkGD;ECtEE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB2oGD;AqBzoGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB2oGP;AqBzoGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBipGT;AqB9oGC;;;EAGE,uBAAA;CrBgpGH;AqB3oGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBmpGT;AoBvnGD;ECvBI,eAAA;EACA,uBAAA;CrBipGH;AoBvnGD;EC1EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrBosGD;AqBlsGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBosGP;AqBlsGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB0sGT;AqBvsGC;;;EAGE,uBAAA;CrBysGH;AqBpsGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrB4sGT;AoB5qGD;EC3BI,eAAA;EACA,uBAAA;CrB0sGH;AoB5qGD;EC9EE,YAAA;EACA,0BAAA;EACA,sBAAA;CrB6vGD;AqB3vGC;;EAEE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;EACE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGC;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrB6vGP;AqB3vGG;;;;;;;;;EAGE,YAAA;EACA,0BAAA;EACI,sBAAA;CrBmwGT;AqBhwGC;;;EAGE,uBAAA;CrBkwGH;AqB7vGG;;;;;;;;;EAGE,0BAAA;EACI,sBAAA;CrBqwGT;AoBjuGD;EC/BI,eAAA;EACA,uBAAA;CrBmwGH;AoB5tGD;EACE,eAAA;EACA,oBAAA;EACA,iBAAA;CpB8tGD;AoB5tGC;;;;;EAKE,8BAAA;EfnCF,yBAAA;EACQ,iBAAA;CLkwGT;AoB7tGC;;;;EAIE,0BAAA;CpB+tGH;AoB7tGC;;EAEE,eAAA;EACA,2BAAA;EACA,8BAAA;CpB+tGH;AoB3tGG;;;;EAEE,eAAA;EACA,sBAAA;CpB+tGL;AoBttGD;;ECxEE,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CrBkyGD;AoBztGD;;EC5EE,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrByyGD;AoB5tGD;;EChFE,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CrBgzGD;AoB3tGD;EACE,eAAA;EACA,YAAA;CpB6tGD;AoBztGD;EACE,gBAAA;CpB2tGD;AoBptGC;;;EACE,YAAA;CpBwtGH;AuBl3GD;EACE,WAAA;ElBoLA,yCAAA;EACK,oCAAA;EACG,iCAAA;CLisGT;AuBr3GC;EACE,WAAA;CvBu3GH;AuBn3GD;EACE,cAAA;CvBq3GD;AuBn3GC;EAAY,eAAA;CvBs3Gb;AuBr3GC;EAAY,mBAAA;CvBw3Gb;AuBv3GC;EAAY,yBAAA;CvB03Gb;AuBv3GD;EACE,mBAAA;EACA,UAAA;EACA,iBAAA;ElBuKA,gDAAA;EACQ,2CAAA;KAAA,wCAAA;EAOR,mCAAA;EACQ,8BAAA;KAAA,2BAAA;EAGR,yCAAA;EACQ,oCAAA;KAAA,iCAAA;CL2sGT;AwBr5GD;EACE,sBAAA;EACA,SAAA;EACA,UAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,yBAAA;EACA,oCAAA;EACA,mCAAA;CxBu5GD;AwBn5GD;;EAEE,mBAAA;CxBq5GD;AwBj5GD;EACE,WAAA;CxBm5GD;AwB/4GD;EACE,mBAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,iBAAA;EACA,uBAAA;EACA,uBAAA;EACA,sCAAA;EACA,mBAAA;EnBsBA,oDAAA;EACQ,4CAAA;EmBrBR,qCAAA;UAAA,6BAAA;CxBk5GD;AwB74GC;EACE,SAAA;EACA,WAAA;CxB+4GH;AwBx6GD;ECzBE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBo8GD;AwB96GD;EAmCI,eAAA;EACA,kBAAA;EACA,YAAA;EACA,oBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxB84GH;AwBx4GC;;EAEE,sBAAA;EACA,eAAA;EACA,0BAAA;CxB04GH;AwBp4GC;;;EAGE,YAAA;EACA,sBAAA;EACA,WAAA;EACA,0BAAA;CxBs4GH;AwB73GC;;;EAGE,eAAA;CxB+3GH;AwB33GC;;EAEE,sBAAA;EACA,8BAAA;EACA,uBAAA;EE3GF,oEAAA;EF6GE,oBAAA;CxB63GH;AwBx3GD;EAGI,eAAA;CxBw3GH;AwB33GD;EAQI,WAAA;CxBs3GH;AwB92GD;EACE,WAAA;EACA,SAAA;CxBg3GD;AwBx2GD;EACE,QAAA;EACA,YAAA;CxB02GD;AwBt2GD;EACE,eAAA;EACA,kBAAA;EACA,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,oBAAA;CxBw2GD;AwBp2GD;EACE,gBAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,aAAA;CxBs2GD;AwBl2GD;EACE,SAAA;EACA,WAAA;CxBo2GD;AwB51GD;;EAII,cAAA;EACA,0BAAA;EACA,4BAAA;EACA,YAAA;CxB41GH;AwBn2GD;;EAWI,UAAA;EACA,aAAA;EACA,mBAAA;CxB41GH;AwBv0GD;EAXE;IApEA,WAAA;IACA,SAAA;GxB05GC;EwBv1GD;IA1DA,QAAA;IACA,YAAA;GxBo5GC;CACF;A2BpiHD;;EAEE,mBAAA;EACA,sBAAA;EACA,uBAAA;C3BsiHD;A2B1iHD;;EAMI,mBAAA;EACA,YAAA;C3BwiHH;A2BtiHG;;;;;;;;EAIE,WAAA;C3B4iHL;A2BtiHD;;;;EAKI,kBAAA;C3BuiHH;A2BliHD;EACE,kBAAA;C3BoiHD;A2BriHD;;;EAOI,YAAA;C3BmiHH;A2B1iHD;;;EAYI,iBAAA;C3BmiHH;A2B/hHD;EACE,iBAAA;C3BiiHD;A2B7hHD;EACE,eAAA;C3B+hHD;A2B9hHC;EClDA,8BAAA;EACG,2BAAA;C5BmlHJ;A2B7hHD;;EC/CE,6BAAA;EACG,0BAAA;C5BglHJ;A2B5hHD;EACE,YAAA;C3B8hHD;A2B5hHD;EACE,iBAAA;C3B8hHD;A2B5hHD;;ECnEE,8BAAA;EACG,2BAAA;C5BmmHJ;A2B3hHD;ECjEE,6BAAA;EACG,0BAAA;C5B+lHJ;A2B1hHD;;EAEE,WAAA;C3B4hHD;A2B3gHD;EACE,kBAAA;EACA,mBAAA;C3B6gHD;A2B3gHD;EACE,mBAAA;EACA,oBAAA;C3B6gHD;A2BxgHD;EtB/CE,yDAAA;EACQ,iDAAA;CL0jHT;A2BxgHC;EtBnDA,yBAAA;EACQ,iBAAA;CL8jHT;A2BrgHD;EACE,eAAA;C3BugHD;A2BpgHD;EACE,wBAAA;EACA,uBAAA;C3BsgHD;A2BngHD;EACE,wBAAA;C3BqgHD;A2B9/GD;;;EAII,eAAA;EACA,YAAA;EACA,YAAA;EACA,gBAAA;C3B+/GH;A2BtgHD;EAcM,YAAA;C3B2/GL;A2BzgHD;;;;EAsBI,iBAAA;EACA,eAAA;C3By/GH;A2Bp/GC;EACE,iBAAA;C3Bs/GH;A2Bp/GC;EC3KA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5B4pHF;A2Bt/GC;EC/KA,2BAAA;EACC,0BAAA;EAOD,gCAAA;EACC,+BAAA;C5BkqHF;A2Bv/GD;EACE,iBAAA;C3By/GD;A2Bv/GD;;EC/KE,8BAAA;EACC,6BAAA;C5B0qHF;A2Bt/GD;EC7LE,2BAAA;EACC,0BAAA;C5BsrHF;A2Bl/GD;EACE,eAAA;EACA,YAAA;EACA,oBAAA;EACA,0BAAA;C3Bo/GD;A2Bx/GD;;EAOI,YAAA;EACA,oBAAA;EACA,UAAA;C3Bq/GH;A2B9/GD;EAYI,YAAA;C3Bq/GH;A2BjgHD;EAgBI,WAAA;C3Bo/GH;A2Bn+GD;;;;EAKM,mBAAA;EACA,uBAAA;EACA,qBAAA;C3Bo+GL;A6B9sHD;EACE,mBAAA;EACA,eAAA;EACA,0BAAA;C7BgtHD;A6B7sHC;EACE,YAAA;EACA,gBAAA;EACA,iBAAA;C7B+sHH;A6BxtHD;EAeI,mBAAA;EACA,WAAA;EAKA,YAAA;EAEA,YAAA;EACA,iBAAA;C7BusHH;A6BrsHG;EACE,WAAA;C7BusHL;A6B7rHD;;;EV0BE,aAAA;EACA,mBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;CnBwqHD;AmBtqHC;;;EACE,aAAA;EACA,kBAAA;CnB0qHH;AmBvqHC;;;;;;EAEE,aAAA;CnB6qHH;A6B/sHD;;;EVqBE,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;CnB+rHD;AmB7rHC;;;EACE,aAAA;EACA,kBAAA;CnBisHH;AmB9rHC;;;;;;EAEE,aAAA;CnBosHH;A6B7tHD;;;EAGE,oBAAA;C7B+tHD;A6B7tHC;;;EACE,iBAAA;C7BiuHH;A6B7tHD;;EAEE,UAAA;EACA,oBAAA;EACA,uBAAA;C7B+tHD;A6B1tHD;EACE,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,eAAA;EACA,eAAA;EACA,mBAAA;EACA,0BAAA;EACA,uBAAA;EACA,mBAAA;C7B4tHD;A6BztHC;EACE,kBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6BztHC;EACE,mBAAA;EACA,gBAAA;EACA,mBAAA;C7B2tHH;A6B/uHD;;EA0BI,cAAA;C7BytHH;A6BptHD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;C5Bi0HJ;A6BrtHD;EACE,gBAAA;C7ButHD;A6BrtHD;;;;;;;EDxGE,6BAAA;EACG,0BAAA;C5Bs0HJ;A6BttHD;EACE,eAAA;C7BwtHD;A6BntHD;EACE,mBAAA;EAGA,aAAA;EACA,oBAAA;C7BmtHD;A6BxtHD;EAUI,mBAAA;C7BitHH;A6B3tHD;EAYM,kBAAA;C7BktHL;A6B/sHG;;;EAGE,WAAA;C7BitHL;A6B5sHC;;EAGI,mBAAA;C7B6sHL;A6B1sHC;;EAGI,WAAA;EACA,kBAAA;C7B2sHL;A8B12HD;EACE,iBAAA;EACA,gBAAA;EACA,iBAAA;C9B42HD;A8B/2HD;EAOI,mBAAA;EACA,eAAA;C9B22HH;A8Bn3HD;EAWM,mBAAA;EACA,eAAA;EACA,mBAAA;C9B22HL;A8B12HK;;EAEE,sBAAA;EACA,0BAAA;C9B42HP;A8Bv2HG;EACE,eAAA;C9By2HL;A8Bv2HK;;EAEE,eAAA;EACA,sBAAA;EACA,8BAAA;EACA,oBAAA;C9By2HP;A8Bl2HG;;;EAGE,0BAAA;EACA,sBAAA;C9Bo2HL;A8B74HD;ELHE,YAAA;EACA,cAAA;EACA,iBAAA;EACA,0BAAA;CzBm5HD;A8Bn5HD;EA0DI,gBAAA;C9B41HH;A8Bn1HD;EACE,8BAAA;C9Bq1HD;A8Bt1HD;EAGI,YAAA;EAEA,oBAAA;C9Bq1HH;A8B11HD;EASM,kBAAA;EACA,wBAAA;EACA,8BAAA;EACA,2BAAA;C9Bo1HL;A8Bn1HK;EACE,mCAAA;C9Bq1HP;A8B/0HK;;;EAGE,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,iCAAA;EACA,gBAAA;C9Bi1HP;A8B50HC;EAqDA,YAAA;EA8BA,iBAAA;C9B6vHD;A8Bh1HC;EAwDE,YAAA;C9B2xHH;A8Bn1HC;EA0DI,mBAAA;EACA,mBAAA;C9B4xHL;A8Bv1HC;EAgEE,UAAA;EACA,WAAA;C9B0xHH;A8B9wHD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9ByxHH;E8BztHH;IA9DQ,iBAAA;G9B0xHL;CACF;A8Bp2HC;EAuFE,gBAAA;EACA,mBAAA;C9BgxHH;A8Bx2HC;;;EA8FE,uBAAA;C9B+wHH;A8BjwHD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9B8wHH;E8B3uHH;;;IA9BM,0BAAA;G9B8wHH;CACF;A8B/2HD;EAEI,YAAA;C9Bg3HH;A8Bl3HD;EAMM,mBAAA;C9B+2HL;A8Br3HD;EASM,iBAAA;C9B+2HL;A8B12HK;;;EAGE,YAAA;EACA,0BAAA;C9B42HP;A8Bp2HD;EAEI,YAAA;C9Bq2HH;A8Bv2HD;EAIM,gBAAA;EACA,eAAA;C9Bs2HL;A8B11HD;EACE,YAAA;C9B41HD;A8B71HD;EAII,YAAA;C9B41HH;A8Bh2HD;EAMM,mBAAA;EACA,mBAAA;C9B61HL;A8Bp2HD;EAYI,UAAA;EACA,WAAA;C9B21HH;A8B/0HD;EA0DA;IAjEM,oBAAA;IACA,UAAA;G9B01HH;E8B1xHH;IA9DQ,iBAAA;G9B21HL;CACF;A8Bn1HD;EACE,iBAAA;C9Bq1HD;A8Bt1HD;EAKI,gBAAA;EACA,mBAAA;C9Bo1HH;A8B11HD;;;EAYI,uBAAA;C9Bm1HH;A8Br0HD;EA2BA;IApCM,8BAAA;IACA,2BAAA;G9Bk1HH;E8B/yHH;;;IA9BM,0BAAA;G9Bk1HH;CACF;A8Bz0HD;EAEI,cAAA;C9B00HH;A8B50HD;EAKI,eAAA;C9B00HH;A8Bj0HD;EAEE,iBAAA;EF3OA,2BAAA;EACC,0BAAA;C5B8iIF;A+BxiID;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;EACA,8BAAA;C/B0iID;A+BliID;EA8nBA;IAhoBI,mBAAA;G/BwiID;CACF;A+BzhID;EAgnBA;IAlnBI,YAAA;G/B+hID;CACF;A+BjhID;EACE,oBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,2DAAA;UAAA,mDAAA;EAEA,kCAAA;C/BkhID;A+BhhIC;EACE,iBAAA;C/BkhIH;A+Bt/HD;EA6jBA;IArlBI,YAAA;IACA,cAAA;IACA,yBAAA;YAAA,iBAAA;G/BkhID;E+BhhIC;IACE,0BAAA;IACA,wBAAA;IACA,kBAAA;IACA,6BAAA;G/BkhIH;E+B/gIC;IACE,oBAAA;G/BihIH;E+B5gIC;;;IAGE,gBAAA;IACA,iBAAA;G/B8gIH;CACF;A+B1gID;;EAGI,kBAAA;C/B2gIH;A+BtgIC;EAmjBF;;IArjBM,kBAAA;G/B6gIH;CACF;A+BpgID;;;;EAII,oBAAA;EACA,mBAAA;C/BsgIH;A+BhgIC;EAgiBF;;;;IAniBM,gBAAA;IACA,eAAA;G/B0gIH;CACF;A+B9/HD;EACE,cAAA;EACA,sBAAA;C/BggID;A+B3/HD;EA8gBA;IAhhBI,iBAAA;G/BigID;CACF;A+B7/HD;;EAEE,gBAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;C/B+/HD;A+Bz/HD;EAggBA;;IAlgBI,iBAAA;G/BggID;CACF;A+B9/HD;EACE,OAAA;EACA,sBAAA;C/BggID;A+B9/HD;EACE,UAAA;EACA,iBAAA;EACA,sBAAA;C/BggID;A+B1/HD;EACE,YAAA;EACA,mBAAA;EACA,gBAAA;EACA,kBAAA;EACA,aAAA;C/B4/HD;A+B1/HC;;EAEE,sBAAA;C/B4/HH;A+BrgID;EAaI,eAAA;C/B2/HH;A+Bl/HD;EALI;;IAEE,mBAAA;G/B0/HH;CACF;A+Bh/HD;EACE,mBAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;EC9LA,gBAAA;EACA,mBAAA;ED+LA,8BAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;C/Bm/HD;A+B/+HC;EACE,WAAA;C/Bi/HH;A+B//HD;EAmBI,eAAA;EACA,YAAA;EACA,YAAA;EACA,mBAAA;C/B++HH;A+BrgID;EAyBI,gBAAA;C/B++HH;A+Bz+HD;EAqbA;IAvbI,cAAA;G/B++HD;CACF;A+Bt+HD;EACE,oBAAA;C/Bw+HD;A+Bz+HD;EAII,kBAAA;EACA,qBAAA;EACA,kBAAA;C/Bw+HH;A+B58HC;EA2YF;IAjaM,iBAAA;IACA,YAAA;IACA,YAAA;IACA,cAAA;IACA,8BAAA;IACA,UAAA;IACA,yBAAA;YAAA,iBAAA;G/Bs+HH;E+B3kHH;;IAxZQ,2BAAA;G/Bu+HL;E+B/kHH;IArZQ,kBAAA;G/Bu+HL;E+Bt+HK;;IAEE,uBAAA;G/Bw+HP;CACF;A+Bt9HD;EA+XA;IA1YI,YAAA;IACA,UAAA;G/Bq+HD;E+B5lHH;IAtYM,YAAA;G/Bq+HH;E+B/lHH;IApYQ,kBAAA;IACA,qBAAA;G/Bs+HL;CACF;A+B39HD;EACE,mBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kCAAA;EACA,qCAAA;E1B9NA,6FAAA;EACQ,qFAAA;E2B/DR,gBAAA;EACA,mBAAA;ChC4vID;AkBtuHD;EAwEA;IAtIM,sBAAA;IACA,iBAAA;IACA,uBAAA;GlBwyHH;EkBpqHH;IA/HM,sBAAA;IACA,YAAA;IACA,uBAAA;GlBsyHH;EkBzqHH;IAxHM,sBAAA;GlBoyHH;EkB5qHH;IApHM,sBAAA;IACA,uBAAA;GlBmyHH;EkBhrHH;;;IA9GQ,YAAA;GlBmyHL;EkBrrHH;IAxGM,YAAA;GlBgyHH;EkBxrHH;IApGM,iBAAA;IACA,uBAAA;GlB+xHH;EkB5rHH;;IA5FM,sBAAA;IACA,cAAA;IACA,iBAAA;IACA,uBAAA;GlB4xHH;EkBnsHH;;IAtFQ,gBAAA;GlB6xHL;EkBvsHH;;IAjFM,mBAAA;IACA,eAAA;GlB4xHH;EkB5sHH;IA3EM,OAAA;GlB0xHH;CACF;A+BpgIC;EAmWF;IAzWM,mBAAA;G/B8gIH;E+B5gIG;IACE,iBAAA;G/B8gIL;CACF;A+B7/HD;EAoVA;IA5VI,YAAA;IACA,UAAA;IACA,eAAA;IACA,gBAAA;IACA,eAAA;IACA,kBAAA;I1BzPF,yBAAA;IACQ,iBAAA;GLmwIP;CACF;A+BngID;EACE,cAAA;EHpUA,2BAAA;EACC,0BAAA;C5B00IF;A+BngID;EACE,iBAAA;EHzUA,6BAAA;EACC,4BAAA;EAOD,8BAAA;EACC,6BAAA;C5By0IF;A+B//HD;EChVE,gBAAA;EACA,mBAAA;ChCk1ID;A+BhgIC;ECnVA,iBAAA;EACA,oBAAA;ChCs1ID;A+BjgIC;ECtVA,iBAAA;EACA,oBAAA;ChC01ID;A+B3/HD;EChWE,iBAAA;EACA,oBAAA;ChC81ID;A+Bv/HD;EAsSA;IA1SI,YAAA;IACA,kBAAA;IACA,mBAAA;G/B+/HD;CACF;A+Bl+HD;EAhBE;IExWA,uBAAA;GjC81IC;E+Br/HD;IE5WA,wBAAA;IF8WE,oBAAA;G/Bu/HD;E+Bz/HD;IAKI,gBAAA;G/Bu/HH;CACF;A+B9+HD;EACE,0BAAA;EACA,sBAAA;C/Bg/HD;A+Bl/HD;EAKI,YAAA;C/Bg/HH;A+B/+HG;;EAEE,eAAA;EACA,8BAAA;C/Bi/HL;A+B1/HD;EAcI,YAAA;C/B++HH;A+B7/HD;EAmBM,YAAA;C/B6+HL;A+B3+HK;;EAEE,YAAA;EACA,8BAAA;C/B6+HP;A+Bz+HK;;;EAGE,YAAA;EACA,0BAAA;C/B2+HP;A+Bv+HK;;;EAGE,YAAA;EACA,8BAAA;C/By+HP;A+BjhID;EA8CI,mBAAA;C/Bs+HH;A+Br+HG;;EAEE,uBAAA;C/Bu+HL;A+BxhID;EAoDM,uBAAA;C/Bu+HL;A+B3hID;;EA0DI,sBAAA;C/Bq+HH;A+B99HK;;;EAGE,0BAAA;EACA,YAAA;C/Bg+HP;A+B/7HC;EAoKF;IA7LU,YAAA;G/B49HP;E+B39HO;;IAEE,YAAA;IACA,8BAAA;G/B69HT;E+Bz9HO;;;IAGE,YAAA;IACA,0BAAA;G/B29HT;E+Bv9HO;;;IAGE,YAAA;IACA,8BAAA;G/By9HT;CACF;A+B3jID;EA8GI,YAAA;C/Bg9HH;A+B/8HG;EACE,YAAA;C/Bi9HL;A+BjkID;EAqHI,YAAA;C/B+8HH;A+B98HG;;EAEE,YAAA;C/Bg9HL;A+B58HK;;;;EAEE,YAAA;C/Bg9HP;A+Bx8HD;EACE,uBAAA;EACA,sBAAA;C/B08HD;A+B58HD;EAKI,eAAA;C/B08HH;A+Bz8HG;;EAEE,YAAA;EACA,8BAAA;C/B28HL;A+Bp9HD;EAcI,eAAA;C/By8HH;A+Bv9HD;EAmBM,eAAA;C/Bu8HL;A+Br8HK;;EAEE,YAAA;EACA,8BAAA;C/Bu8HP;A+Bn8HK;;;EAGE,YAAA;EACA,0BAAA;C/Bq8HP;A+Bj8HK;;;EAGE,YAAA;EACA,8BAAA;C/Bm8HP;A+B3+HD;EA+CI,mBAAA;C/B+7HH;A+B97HG;;EAEE,uBAAA;C/Bg8HL;A+Bl/HD;EAqDM,uBAAA;C/Bg8HL;A+Br/HD;;EA2DI,sBAAA;C/B87HH;A+Bx7HK;;;EAGE,0BAAA;EACA,YAAA;C/B07HP;A+Bn5HC;EAwBF;IAvDU,sBAAA;G/Bs7HP;E+B/3HH;IApDU,0BAAA;G/Bs7HP;E+Bl4HH;IAjDU,eAAA;G/Bs7HP;E+Br7HO;;IAEE,YAAA;IACA,8BAAA;G/Bu7HT;E+Bn7HO;;;IAGE,YAAA;IACA,0BAAA;G/Bq7HT;E+Bj7HO;;;IAGE,YAAA;IACA,8BAAA;G/Bm7HT;CACF;A+B3hID;EA+GI,eAAA;C/B+6HH;A+B96HG;EACE,YAAA;C/Bg7HL;A+BjiID;EAsHI,eAAA;C/B86HH;A+B76HG;;EAEE,YAAA;C/B+6HL;A+B36HK;;;;EAEE,YAAA;C/B+6HP;AkCzjJD;EACE,kBAAA;EACA,oBAAA;EACA,iBAAA;EACA,0BAAA;EACA,mBAAA;ClC2jJD;AkChkJD;EAQI,sBAAA;ClC2jJH;AkCnkJD;EAWM,kBAAA;EACA,eAAA;EACA,YAAA;ClC2jJL;AkCxkJD;EAkBI,eAAA;ClCyjJH;AmC7kJD;EACE,sBAAA;EACA,gBAAA;EACA,eAAA;EACA,mBAAA;CnC+kJD;AmCnlJD;EAOI,gBAAA;CnC+kJH;AmCtlJD;;EAUM,mBAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,sBAAA;EACA,eAAA;EACA,uBAAA;EACA,uBAAA;EACA,kBAAA;CnCglJL;AmC9kJG;;EAGI,eAAA;EPXN,+BAAA;EACG,4BAAA;C5B2lJJ;AmC7kJG;;EPvBF,gCAAA;EACG,6BAAA;C5BwmJJ;AmCxkJG;;;;EAEE,WAAA;EACA,eAAA;EACA,0BAAA;EACA,mBAAA;CnC4kJL;AmCtkJG;;;;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;EACA,gBAAA;CnC2kJL;AmCloJD;;;;;;EAkEM,eAAA;EACA,uBAAA;EACA,mBAAA;EACA,oBAAA;CnCwkJL;AmC/jJD;;EC3EM,mBAAA;EACA,gBAAA;EACA,uBAAA;CpC8oJL;AoC5oJG;;ERKF,+BAAA;EACG,4BAAA;C5B2oJJ;AoC3oJG;;ERTF,gCAAA;EACG,6BAAA;C5BwpJJ;AmC1kJD;;EChFM,kBAAA;EACA,gBAAA;EACA,iBAAA;CpC8pJL;AoC5pJG;;ERKF,+BAAA;EACG,4BAAA;C5B2pJJ;AoC3pJG;;ERTF,gCAAA;EACG,6BAAA;C5BwqJJ;AqC3qJD;EACE,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,mBAAA;CrC6qJD;AqCjrJD;EAOI,gBAAA;CrC6qJH;AqCprJD;;EAUM,sBAAA;EACA,kBAAA;EACA,uBAAA;EACA,uBAAA;EACA,oBAAA;CrC8qJL;AqC5rJD;;EAmBM,sBAAA;EACA,0BAAA;CrC6qJL;AqCjsJD;;EA2BM,aAAA;CrC0qJL;AqCrsJD;;EAkCM,YAAA;CrCuqJL;AqCzsJD;;;;EA2CM,eAAA;EACA,uBAAA;EACA,oBAAA;CrCoqJL;AsCltJD;EACE,gBAAA;EACA,wBAAA;EACA,eAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,mBAAA;EACA,oBAAA;EACA,yBAAA;EACA,qBAAA;CtCotJD;AsChtJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CtCktJL;AsC7sJC;EACE,cAAA;CtC+sJH;AsC3sJC;EACE,mBAAA;EACA,UAAA;CtC6sJH;AsCtsJD;ECtCE,0BAAA;CvC+uJD;AuC5uJG;;EAEE,0BAAA;CvC8uJL;AsCzsJD;EC1CE,0BAAA;CvCsvJD;AuCnvJG;;EAEE,0BAAA;CvCqvJL;AsC5sJD;EC9CE,0BAAA;CvC6vJD;AuC1vJG;;EAEE,0BAAA;CvC4vJL;AsC/sJD;EClDE,0BAAA;CvCowJD;AuCjwJG;;EAEE,0BAAA;CvCmwJL;AsCltJD;ECtDE,0BAAA;CvC2wJD;AuCxwJG;;EAEE,0BAAA;CvC0wJL;AsCrtJD;EC1DE,0BAAA;CvCkxJD;AuC/wJG;;EAEE,0BAAA;CvCixJL;AwCnxJD;EACE,sBAAA;EACA,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,eAAA;EACA,uBAAA;EACA,oBAAA;EACA,mBAAA;EACA,0BAAA;EACA,oBAAA;CxCqxJD;AwClxJC;EACE,cAAA;CxCoxJH;AwChxJC;EACE,mBAAA;EACA,UAAA;CxCkxJH;AwC/wJC;;EAEE,OAAA;EACA,iBAAA;CxCixJH;AwC5wJG;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;CxC8wJL;AwCzwJC;;EAEE,eAAA;EACA,uBAAA;CxC2wJH;AwCxwJC;EACE,aAAA;CxC0wJH;AwCvwJC;EACE,kBAAA;CxCywJH;AwCtwJC;EACE,iBAAA;CxCwwJH;AyCl0JD;EACE,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,eAAA;EACA,0BAAA;CzCo0JD;AyCz0JD;;EASI,eAAA;CzCo0JH;AyC70JD;EAaI,oBAAA;EACA,gBAAA;EACA,iBAAA;CzCm0JH;AyCl1JD;EAmBI,0BAAA;CzCk0JH;AyC/zJC;;EAEE,mBAAA;EACA,mBAAA;EACA,oBAAA;CzCi0JH;AyC31JD;EA8BI,gBAAA;CzCg0JH;AyC9yJD;EACA;IAfI,kBAAA;IACA,qBAAA;GzCg0JD;EyC9zJC;;IAEE,mBAAA;IACA,oBAAA;GzCg0JH;EyCvzJH;;IAJM,gBAAA;GzC+zJH;CACF;A0C52JD;EACE,eAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;EACA,uBAAA;EACA,mBAAA;ErCiLA,4CAAA;EACK,uCAAA;EACG,oCAAA;CL8rJT;A0Cx3JD;;EAaI,kBAAA;EACA,mBAAA;C1C+2JH;A0C32JC;;;EAGE,sBAAA;C1C62JH;A0Cl4JD;EA0BI,aAAA;EACA,eAAA;C1C22JH;A2Cp4JD;EACE,cAAA;EACA,oBAAA;EACA,8BAAA;EACA,mBAAA;C3Cs4JD;A2C14JD;EAQI,cAAA;EAEA,eAAA;C3Co4JH;A2C94JD;EAeI,kBAAA;C3Ck4JH;A2Cj5JD;;EAqBI,iBAAA;C3Cg4JH;A2Cr5JD;EAyBI,gBAAA;C3C+3JH;A2Cv3JD;;EAEE,oBAAA;C3Cy3JD;A2C33JD;;EAMI,mBAAA;EACA,UAAA;EACA,aAAA;EACA,eAAA;C3Cy3JH;A2Cj3JD;ECvDE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C26JD;A2Ct3JD;EClDI,0BAAA;C5C26JH;A2Cz3JD;EC/CI,eAAA;C5C26JH;A2Cx3JD;EC3DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Cs7JD;A2C73JD;ECtDI,0BAAA;C5Cs7JH;A2Ch4JD;ECnDI,eAAA;C5Cs7JH;A2C/3JD;EC/DE,0BAAA;EACA,sBAAA;EACA,eAAA;C5Ci8JD;A2Cp4JD;EC1DI,0BAAA;C5Ci8JH;A2Cv4JD;ECvDI,eAAA;C5Ci8JH;A2Ct4JD;ECnEE,0BAAA;EACA,sBAAA;EACA,eAAA;C5C48JD;A2C34JD;EC9DI,0BAAA;C5C48JH;A2C94JD;EC3DI,eAAA;C5C48JH;A6C98JD;EACE;IAAQ,4BAAA;G7Ci9JP;E6Ch9JD;IAAQ,yBAAA;G7Cm9JP;CACF;A6Ch9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6Cx9JD;EACE;IAAQ,4BAAA;G7Cm9JP;E6Cl9JD;IAAQ,yBAAA;G7Cq9JP;CACF;A6C98JD;EACE,iBAAA;EACA,aAAA;EACA,oBAAA;EACA,0BAAA;EACA,mBAAA;ExCsCA,uDAAA;EACQ,+CAAA;CL26JT;A6C78JD;EACE,YAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,YAAA;EACA,mBAAA;EACA,0BAAA;ExCyBA,uDAAA;EACQ,+CAAA;EAyHR,oCAAA;EACK,+BAAA;EACG,4BAAA;CL+zJT;A6C18JD;;ECCI,8MAAA;EACA,yMAAA;EACA,sMAAA;EDAF,mCAAA;UAAA,2BAAA;C7C88JD;A6Cv8JD;;ExC5CE,2DAAA;EACK,sDAAA;EACG,mDAAA;CLu/JT;A6Cp8JD;EErEE,0BAAA;C/C4gKD;A+CzgKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C49JH;A6Cx8JD;EEzEE,0BAAA;C/CohKD;A+CjhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co+JH;A6C58JD;EE7EE,0BAAA;C/C4hKD;A+CzhKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9C4+JH;A6Ch9JD;EEjFE,0BAAA;C/CoiKD;A+CjiKC;EDgDE,8MAAA;EACA,yMAAA;EACA,sMAAA;C9Co/JH;AgD5iKD;EAEE,iBAAA;ChD6iKD;AgD3iKC;EACE,cAAA;ChD6iKH;AgDziKD;;EAEE,QAAA;EACA,iBAAA;ChD2iKD;AgDxiKD;EACE,eAAA;ChD0iKD;AgDviKD;EACE,eAAA;ChDyiKD;AgDtiKC;EACE,gBAAA;ChDwiKH;AgDpiKD;;EAEE,mBAAA;ChDsiKD;AgDniKD;;EAEE,oBAAA;ChDqiKD;AgDliKD;;;EAGE,oBAAA;EACA,oBAAA;ChDoiKD;AgDjiKD;EACE,uBAAA;ChDmiKD;AgDhiKD;EACE,uBAAA;ChDkiKD;AgD9hKD;EACE,cAAA;EACA,mBAAA;ChDgiKD;AgD1hKD;EACE,gBAAA;EACA,iBAAA;ChD4hKD;AiDnlKD;EAEE,oBAAA;EACA,gBAAA;CjDolKD;AiD5kKD;EACE,mBAAA;EACA,eAAA;EACA,mBAAA;EAEA,oBAAA;EACA,uBAAA;EACA,uBAAA;CjD6kKD;AiD1kKC;ErB3BA,6BAAA;EACC,4BAAA;C5BwmKF;AiD3kKC;EACE,iBAAA;ErBvBF,gCAAA;EACC,+BAAA;C5BqmKF;AiDpkKD;;EAEE,YAAA;CjDskKD;AiDxkKD;;EAKI,YAAA;CjDukKH;AiDnkKC;;;;EAEE,sBAAA;EACA,YAAA;EACA,0BAAA;CjDukKH;AiDnkKD;EACE,YAAA;EACA,iBAAA;CjDqkKD;AiDhkKC;;;EAGE,0BAAA;EACA,eAAA;EACA,oBAAA;CjDkkKH;AiDvkKC;;;EASI,eAAA;CjDmkKL;AiD5kKC;;;EAYI,eAAA;CjDqkKL;AiDhkKC;;;EAGE,WAAA;EACA,YAAA;EACA,0BAAA;EACA,sBAAA;CjDkkKH;AiDxkKC;;;;;;;;;EAYI,eAAA;CjDukKL;AiDnlKC;;;EAeI,eAAA;CjDykKL;AkD3qKC;EACE,eAAA;EACA,0BAAA;ClD6qKH;AkD3qKG;;EAEE,eAAA;ClD6qKL;AkD/qKG;;EAKI,eAAA;ClD8qKP;AkD3qKK;;;;EAEE,eAAA;EACA,0BAAA;ClD+qKP;AkD7qKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDkrKP;AkDxsKC;EACE,eAAA;EACA,0BAAA;ClD0sKH;AkDxsKG;;EAEE,eAAA;ClD0sKL;AkD5sKG;;EAKI,eAAA;ClD2sKP;AkDxsKK;;;;EAEE,eAAA;EACA,0BAAA;ClD4sKP;AkD1sKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD+sKP;AkDruKC;EACE,eAAA;EACA,0BAAA;ClDuuKH;AkDruKG;;EAEE,eAAA;ClDuuKL;AkDzuKG;;EAKI,eAAA;ClDwuKP;AkDruKK;;;;EAEE,eAAA;EACA,0BAAA;ClDyuKP;AkDvuKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClD4uKP;AkDlwKC;EACE,eAAA;EACA,0BAAA;ClDowKH;AkDlwKG;;EAEE,eAAA;ClDowKL;AkDtwKG;;EAKI,eAAA;ClDqwKP;AkDlwKK;;;;EAEE,eAAA;EACA,0BAAA;ClDswKP;AkDpwKK;;;;;;EAGE,YAAA;EACA,0BAAA;EACA,sBAAA;ClDywKP;AiDxqKD;EACE,cAAA;EACA,mBAAA;CjD0qKD;AiDxqKD;EACE,iBAAA;EACA,iBAAA;CjD0qKD;AmDpyKD;EACE,oBAAA;EACA,uBAAA;EACA,8BAAA;EACA,mBAAA;E9C0DA,kDAAA;EACQ,0CAAA;CL6uKT;AmDnyKD;EACE,cAAA;CnDqyKD;AmDhyKD;EACE,mBAAA;EACA,qCAAA;EvBpBA,6BAAA;EACC,4BAAA;C5BuzKF;AmDtyKD;EAMI,eAAA;CnDmyKH;AmD9xKD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;CnDgyKD;AmDpyKD;;;;;EAWI,eAAA;CnDgyKH;AmD3xKD;EACE,mBAAA;EACA,0BAAA;EACA,2BAAA;EvBxCA,gCAAA;EACC,+BAAA;C5Bs0KF;AmDrxKD;;EAGI,iBAAA;CnDsxKH;AmDzxKD;;EAMM,oBAAA;EACA,iBAAA;CnDuxKL;AmDnxKG;;EAEI,cAAA;EvBvEN,6BAAA;EACC,4BAAA;C5B61KF;AmDjxKG;;EAEI,iBAAA;EvBvEN,gCAAA;EACC,+BAAA;C5B21KF;AmD1yKD;EvB1DE,2BAAA;EACC,0BAAA;C5Bu2KF;AmD7wKD;EAEI,oBAAA;CnD8wKH;AmD3wKD;EACE,oBAAA;CnD6wKD;AmDrwKD;;;EAII,iBAAA;CnDswKH;AmD1wKD;;;EAOM,mBAAA;EACA,oBAAA;CnDwwKL;AmDhxKD;;EvBzGE,6BAAA;EACC,4BAAA;C5B63KF;AmDrxKD;;;;EAmBQ,4BAAA;EACA,6BAAA;CnDwwKP;AmD5xKD;;;;;;;;EAwBU,4BAAA;CnD8wKT;AmDtyKD;;;;;;;;EA4BU,6BAAA;CnDoxKT;AmDhzKD;;EvBjGE,gCAAA;EACC,+BAAA;C5Bq5KF;AmDrzKD;;;;EAyCQ,+BAAA;EACA,gCAAA;CnDkxKP;AmD5zKD;;;;;;;;EA8CU,+BAAA;CnDwxKT;AmDt0KD;;;;;;;;EAkDU,gCAAA;CnD8xKT;AmDh1KD;;;;EA2DI,2BAAA;CnD2xKH;AmDt1KD;;EA+DI,cAAA;CnD2xKH;AmD11KD;;EAmEI,UAAA;CnD2xKH;AmD91KD;;;;;;;;;;;;EA0EU,eAAA;CnDkyKT;AmD52KD;;;;;;;;;;;;EA8EU,gBAAA;CnD4yKT;AmD13KD;;;;;;;;EAuFU,iBAAA;CnD6yKT;AmDp4KD;;;;;;;;EAgGU,iBAAA;CnD8yKT;AmD94KD;EAsGI,UAAA;EACA,iBAAA;CnD2yKH;AmDjyKD;EACE,oBAAA;CnDmyKD;AmDpyKD;EAKI,iBAAA;EACA,mBAAA;CnDkyKH;AmDxyKD;EASM,gBAAA;CnDkyKL;AmD3yKD;EAcI,iBAAA;CnDgyKH;AmD9yKD;;EAkBM,2BAAA;CnDgyKL;AmDlzKD;EAuBI,cAAA;CnD8xKH;AmDrzKD;EAyBM,8BAAA;CnD+xKL;AmDxxKD;EC1PE,mBAAA;CpDqhLD;AoDnhLC;EACE,eAAA;EACA,0BAAA;EACA,mBAAA;CpDqhLH;AoDxhLC;EAMI,uBAAA;CpDqhLL;AoD3hLC;EASI,eAAA;EACA,0BAAA;CpDqhLL;AoDlhLC;EAEI,0BAAA;CpDmhLL;AmDvyKD;EC7PE,sBAAA;CpDuiLD;AoDriLC;EACE,YAAA;EACA,0BAAA;EACA,sBAAA;CpDuiLH;AoD1iLC;EAMI,0BAAA;CpDuiLL;AoD7iLC;EASI,eAAA;EACA,uBAAA;CpDuiLL;AoDpiLC;EAEI,6BAAA;CpDqiLL;AmDtzKD;EChQE,sBAAA;CpDyjLD;AoDvjLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpDyjLH;AoD5jLC;EAMI,0BAAA;CpDyjLL;AoD/jLC;EASI,eAAA;EACA,0BAAA;CpDyjLL;AoDtjLC;EAEI,6BAAA;CpDujLL;AmDr0KD;ECnQE,sBAAA;CpD2kLD;AoDzkLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD2kLH;AoD9kLC;EAMI,0BAAA;CpD2kLL;AoDjlLC;EASI,eAAA;EACA,0BAAA;CpD2kLL;AoDxkLC;EAEI,6BAAA;CpDykLL;AmDp1KD;ECtQE,sBAAA;CpD6lLD;AoD3lLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD6lLH;AoDhmLC;EAMI,0BAAA;CpD6lLL;AoDnmLC;EASI,eAAA;EACA,0BAAA;CpD6lLL;AoD1lLC;EAEI,6BAAA;CpD2lLL;AmDn2KD;ECzQE,sBAAA;CpD+mLD;AoD7mLC;EACE,eAAA;EACA,0BAAA;EACA,sBAAA;CpD+mLH;AoDlnLC;EAMI,0BAAA;CpD+mLL;AoDrnLC;EASI,eAAA;EACA,0BAAA;CpD+mLL;AoD5mLC;EAEI,6BAAA;CpD6mLL;AqD7nLD;EACE,mBAAA;EACA,eAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;CrD+nLD;AqDpoLD;;;;;EAYI,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;CrD+nLH;AqD1nLD;EACE,uBAAA;CrD4nLD;AqDxnLD;EACE,oBAAA;CrD0nLD;AsDrpLD;EACE,iBAAA;EACA,cAAA;EACA,oBAAA;EACA,0BAAA;EACA,0BAAA;EACA,mBAAA;EjDwDA,wDAAA;EACQ,gDAAA;CLgmLT;AsD/pLD;EASI,mBAAA;EACA,kCAAA;CtDypLH;AsDppLD;EACE,cAAA;EACA,mBAAA;CtDspLD;AsDppLD;EACE,aAAA;EACA,mBAAA;CtDspLD;AuD5qLD;EACE,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,eAAA;EACA,YAAA;EACA,0BAAA;EjCRA,aAAA;EAGA,0BAAA;CtBqrLD;AuD7qLC;;EAEE,YAAA;EACA,sBAAA;EACA,gBAAA;EjCfF,aAAA;EAGA,0BAAA;CtB6rLD;AuDzqLC;EACE,WAAA;EACA,gBAAA;EACA,wBAAA;EACA,UAAA;EACA,yBAAA;CvD2qLH;AwDhsLD;EACE,iBAAA;CxDksLD;AwD9rLD;EACE,cAAA;EACA,iBAAA;EACA,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,kCAAA;EAIA,WAAA;CxD6rLD;AwD1rLC;EnD+GA,sCAAA;EACI,kCAAA;EACC,iCAAA;EACG,8BAAA;EAkER,oDAAA;EAEK,0CAAA;EACG,oCAAA;CL6gLT;AwDhsLC;EnD2GA,mCAAA;EACI,+BAAA;EACC,8BAAA;EACG,2BAAA;CLwlLT;AwDpsLD;EACE,mBAAA;EACA,iBAAA;CxDssLD;AwDlsLD;EACE,mBAAA;EACA,YAAA;EACA,aAAA;CxDosLD;AwDhsLD;EACE,mBAAA;EACA,uBAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EnDaA,iDAAA;EACQ,yCAAA;EmDZR,qCAAA;UAAA,6BAAA;EAEA,WAAA;CxDksLD;AwD9rLD;EACE,gBAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,uBAAA;CxDgsLD;AwD9rLC;ElCrEA,WAAA;EAGA,yBAAA;CtBowLD;AwDjsLC;ElCtEA,aAAA;EAGA,0BAAA;CtBwwLD;AwDhsLD;EACE,cAAA;EACA,iCAAA;CxDksLD;AwD9rLD;EACE,iBAAA;CxDgsLD;AwD5rLD;EACE,UAAA;EACA,wBAAA;CxD8rLD;AwDzrLD;EACE,mBAAA;EACA,cAAA;CxD2rLD;AwDvrLD;EACE,cAAA;EACA,kBAAA;EACA,8BAAA;CxDyrLD;AwD5rLD;EAQI,iBAAA;EACA,iBAAA;CxDurLH;AwDhsLD;EAaI,kBAAA;CxDsrLH;AwDnsLD;EAiBI,eAAA;CxDqrLH;AwDhrLD;EACE,mBAAA;EACA,aAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;CxDkrLD;AwDhqLD;EAZE;IACE,aAAA;IACA,kBAAA;GxD+qLD;EwD7qLD;InDvEA,kDAAA;IACQ,0CAAA;GLuvLP;EwD5qLD;IAAY,aAAA;GxD+qLX;CACF;AwD1qLD;EAFE;IAAY,aAAA;GxDgrLX;CACF;AyD/zLD;EACE,mBAAA;EACA,cAAA;EACA,eAAA;ECRA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;EDHA,gBAAA;EnCVA,WAAA;EAGA,yBAAA;CtBs1LD;AyD30LC;EnCdA,aAAA;EAGA,0BAAA;CtB01LD;AyD90LC;EAAW,iBAAA;EAAmB,eAAA;CzDk1L/B;AyDj1LC;EAAW,iBAAA;EAAmB,eAAA;CzDq1L/B;AyDp1LC;EAAW,gBAAA;EAAmB,eAAA;CzDw1L/B;AyDv1LC;EAAW,kBAAA;EAAmB,eAAA;CzD21L/B;AyDv1LD;EACE,iBAAA;EACA,iBAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,mBAAA;CzDy1LD;AyDr1LD;EACE,mBAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;CzDu1LD;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,UAAA;EACA,UAAA;EACA,oBAAA;EACA,wBAAA;EACA,uBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,QAAA;EACA,iBAAA;EACA,4BAAA;EACA,yBAAA;CzDq1LH;AyDn1LC;EACE,SAAA;EACA,SAAA;EACA,iBAAA;EACA,4BAAA;EACA,wBAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,kBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,WAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;AyDn1LC;EACE,OAAA;EACA,UAAA;EACA,iBAAA;EACA,wBAAA;EACA,0BAAA;CzDq1LH;A2Dl7LD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,cAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EDXA,4DAAA;EAEA,mBAAA;EACA,oBAAA;EACA,uBAAA;EACA,iBAAA;EACA,wBAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;ECAA,gBAAA;EAEA,uBAAA;EACA,qCAAA;UAAA,6BAAA;EACA,uBAAA;EACA,qCAAA;EACA,mBAAA;EtD8CA,kDAAA;EACQ,0CAAA;CLk5LT;A2D77LC;EAAY,kBAAA;C3Dg8Lb;A2D/7LC;EAAY,kBAAA;C3Dk8Lb;A2Dj8LC;EAAY,iBAAA;C3Do8Lb;A2Dn8LC;EAAY,mBAAA;C3Ds8Lb;A2Dn8LD;EACE,UAAA;EACA,kBAAA;EACA,gBAAA;EACA,0BAAA;EACA,iCAAA;EACA,2BAAA;C3Dq8LD;A2Dl8LD;EACE,kBAAA;C3Do8LD;A2D57LC;;EAEE,mBAAA;EACA,eAAA;EACA,SAAA;EACA,UAAA;EACA,0BAAA;EACA,oBAAA;C3D87LH;A2D37LD;EACE,mBAAA;C3D67LD;A2D37LD;EACE,mBAAA;EACA,YAAA;C3D67LD;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,0BAAA;EACA,sCAAA;EACA,cAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,YAAA;EACA,mBAAA;EACA,uBAAA;EACA,uBAAA;C3D47LL;A2Dz7LC;EACE,SAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,4BAAA;EACA,wCAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,UAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;C3D47LL;A2Dz7LC;EACE,UAAA;EACA,mBAAA;EACA,oBAAA;EACA,6BAAA;EACA,yCAAA;EACA,WAAA;C3D27LH;A2D17LG;EACE,aAAA;EACA,SAAA;EACA,mBAAA;EACA,oBAAA;EACA,0BAAA;C3D47LL;A2Dx7LC;EACE,SAAA;EACA,aAAA;EACA,kBAAA;EACA,sBAAA;EACA,2BAAA;EACA,uCAAA;C3D07LH;A2Dz7LG;EACE,aAAA;EACA,WAAA;EACA,sBAAA;EACA,wBAAA;EACA,cAAA;C3D27LL;A4DpjMD;EACE,mBAAA;C5DsjMD;A4DnjMD;EACE,mBAAA;EACA,iBAAA;EACA,YAAA;C5DqjMD;A4DxjMD;EAMI,cAAA;EACA,mBAAA;EvD6KF,0CAAA;EACK,qCAAA;EACG,kCAAA;CLy4LT;A4D/jMD;;EAcM,eAAA;C5DqjML;A4D3hMC;EA4NF;IvD3DE,uDAAA;IAEK,6CAAA;IACG,uCAAA;IA7JR,oCAAA;IAEQ,4BAAA;IA+GR,4BAAA;IAEQ,oBAAA;GL86LP;E4DzjMG;;IvDmHJ,2CAAA;IACQ,mCAAA;IuDjHF,QAAA;G5D4jML;E4D1jMG;;IvD8GJ,4CAAA;IACQ,oCAAA;IuD5GF,QAAA;G5D6jML;E4D3jMG;;;IvDyGJ,wCAAA;IACQ,gCAAA;IuDtGF,QAAA;G5D8jML;CACF;A4DpmMD;;;EA6CI,eAAA;C5D4jMH;A4DzmMD;EAiDI,QAAA;C5D2jMH;A4D5mMD;;EAsDI,mBAAA;EACA,OAAA;EACA,YAAA;C5D0jMH;A4DlnMD;EA4DI,WAAA;C5DyjMH;A4DrnMD;EA+DI,YAAA;C5DyjMH;A4DxnMD;;EAmEI,QAAA;C5DyjMH;A4D5nMD;EAuEI,YAAA;C5DwjMH;A4D/nMD;EA0EI,WAAA;C5DwjMH;A4DhjMD;EACE,mBAAA;EACA,OAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EtC9FA,aAAA;EAGA,0BAAA;EsC6FA,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;EACA,mCAAA;C5DmjMD;A4D9iMC;EdnGE,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9CopMH;A4DljMC;EACE,WAAA;EACA,SAAA;EdxGA,mGAAA;EACA,8FAAA;EACA,qHAAA;EAAA,+FAAA;EACA,4BAAA;EACA,uHAAA;C9C6pMH;A4DpjMC;;EAEE,WAAA;EACA,YAAA;EACA,sBAAA;EtCvHF,aAAA;EAGA,0BAAA;CtB4qMD;A4DtlMD;;;;EAuCI,mBAAA;EACA,SAAA;EACA,kBAAA;EACA,WAAA;EACA,sBAAA;C5DqjMH;A4DhmMD;;EA+CI,UAAA;EACA,mBAAA;C5DqjMH;A4DrmMD;;EAoDI,WAAA;EACA,oBAAA;C5DqjMH;A4D1mMD;;EAyDI,YAAA;EACA,aAAA;EACA,eAAA;EACA,mBAAA;C5DqjMH;A4DhjMG;EACE,iBAAA;C5DkjML;A4D9iMG;EACE,iBAAA;C5DgjML;A4DtiMD;EACE,mBAAA;EACA,aAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,mBAAA;C5DwiMD;A4DjjMD;EAYI,sBAAA;EACA,YAAA;EACA,aAAA;EACA,YAAA;EACA,oBAAA;EACA,uBAAA;EACA,oBAAA;EACA,gBAAA;EAWA,0BAAA;EACA,mCAAA;C5D8hMH;A4D7jMD;EAkCI,UAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;C5D8hMH;A4DvhMD;EACE,mBAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,kBAAA;EACA,qBAAA;EACA,YAAA;EACA,mBAAA;EACA,0CAAA;C5DyhMD;A4DxhMC;EACE,kBAAA;C5D0hMH;A4Dj/LD;EAhCE;;;;IAKI,YAAA;IACA,aAAA;IACA,kBAAA;IACA,gBAAA;G5DmhMH;E4D3hMD;;IAYI,mBAAA;G5DmhMH;E4D/hMD;;IAgBI,oBAAA;G5DmhMH;E4D9gMD;IACE,UAAA;IACA,WAAA;IACA,qBAAA;G5DghMD;E4D5gMD;IACE,aAAA;G5D8gMD;CACF;A6D7wMC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,aAAA;EACA,eAAA;C7D6yMH;A6D3yMC;;;;;;;;;;;;;;;;EACE,YAAA;C7D4zMH;AiCp0MD;E6BRE,eAAA;EACA,kBAAA;EACA,mBAAA;C9D+0MD;AiCt0MD;EACE,wBAAA;CjCw0MD;AiCt0MD;EACE,uBAAA;CjCw0MD;AiCh0MD;EACE,yBAAA;CjCk0MD;AiCh0MD;EACE,0BAAA;CjCk0MD;AiCh0MD;EACE,mBAAA;CjCk0MD;AiCh0MD;E8BzBE,YAAA;EACA,mBAAA;EACA,kBAAA;EACA,8BAAA;EACA,UAAA;C/D41MD;AiC9zMD;EACE,yBAAA;CjCg0MD;AiCzzMD;EACE,gBAAA;CjC2zMD;AgE51MD;EACE,oBAAA;ChE81MD;AgEx1MD;;;;ECdE,yBAAA;CjE42MD;AgEv1MD;;;;;;;;;;;;EAYE,yBAAA;ChEy1MD;AgEl1MD;EA6IA;IC7LE,0BAAA;GjEs4MC;EiEr4MD;IAAU,0BAAA;GjEw4MT;EiEv4MD;IAAU,8BAAA;GjE04MT;EiEz4MD;;IACU,+BAAA;GjE44MT;CACF;AgE51MD;EAwIA;IA1II,0BAAA;GhEk2MD;CACF;AgE51MD;EAmIA;IArII,2BAAA;GhEk2MD;CACF;AgE51MD;EA8HA;IAhII,iCAAA;GhEk2MD;CACF;AgE31MD;EAwHA;IC7LE,0BAAA;GjEo6MC;EiEn6MD;IAAU,0BAAA;GjEs6MT;EiEr6MD;IAAU,8BAAA;GjEw6MT;EiEv6MD;;IACU,+BAAA;GjE06MT;CACF;AgEr2MD;EAmHA;IArHI,0BAAA;GhE22MD;CACF;AgEr2MD;EA8GA;IAhHI,2BAAA;GhE22MD;CACF;AgEr2MD;EAyGA;IA3GI,iCAAA;GhE22MD;CACF;AgEp2MD;EAmGA;IC7LE,0BAAA;GjEk8MC;EiEj8MD;IAAU,0BAAA;GjEo8MT;EiEn8MD;IAAU,8BAAA;GjEs8MT;EiEr8MD;;IACU,+BAAA;GjEw8MT;CACF;AgE92MD;EA8FA;IAhGI,0BAAA;GhEo3MD;CACF;AgE92MD;EAyFA;IA3FI,2BAAA;GhEo3MD;CACF;AgE92MD;EAoFA;IAtFI,iCAAA;GhEo3MD;CACF;AgE72MD;EA8EA;IC7LE,0BAAA;GjEg+MC;EiE/9MD;IAAU,0BAAA;GjEk+MT;EiEj+MD;IAAU,8BAAA;GjEo+MT;EiEn+MD;;IACU,+BAAA;GjEs+MT;CACF;AgEv3MD;EAyEA;IA3EI,0BAAA;GhE63MD;CACF;AgEv3MD;EAoEA;IAtEI,2BAAA;GhE63MD;CACF;AgEv3MD;EA+DA;IAjEI,iCAAA;GhE63MD;CACF;AgEt3MD;EAyDA;ICrLE,yBAAA;GjEs/MC;CACF;AgEt3MD;EAoDA;ICrLE,yBAAA;GjE2/MC;CACF;AgEt3MD;EA+CA;ICrLE,yBAAA;GjEggNC;CACF;AgEt3MD;EA0CA;ICrLE,yBAAA;GjEqgNC;CACF;AgEn3MD;ECnJE,yBAAA;CjEygND;AgEh3MD;EA4BA;IC7LE,0BAAA;GjEqhNC;EiEphND;IAAU,0BAAA;GjEuhNT;EiEthND;IAAU,8BAAA;GjEyhNT;EiExhND;;IACU,+BAAA;GjE2hNT;CACF;AgE93MD;EACE,yBAAA;ChEg4MD;AgE33MD;EAqBA;IAvBI,0BAAA;GhEi4MD;CACF;AgE/3MD;EACE,yBAAA;ChEi4MD;AgE53MD;EAcA;IAhBI,2BAAA;GhEk4MD;CACF;AgEh4MD;EACE,yBAAA;ChEk4MD;AgE73MD;EAOA;IATI,iCAAA;GhEm4MD;CACF;AgE53MD;EACA;ICrLE,yBAAA;GjEojNC;CACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on