From 4deb7c3270d6ac8ee62260d465bc249bce8f3727 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Fri, 27 Oct 2017 17:53:04 +0900 Subject: [PATCH] Adopt dotnet core editorconfig, big reformating --- .editorconfig | 149 + BTCPayServer.Tests/BTCPayServerTester.cs | 224 +- BTCPayServer.Tests/CustomerHttpServer.cs | 116 +- BTCPayServer.Tests/Logging/Logs.cs | 142 +- BTCPayServer.Tests/Mocks/UrlHelperMock.cs | 58 +- BTCPayServer.Tests/ProcessLauncher.cs | 188 +- .../Properties/launchSettings.json | 10 +- BTCPayServer.Tests/ServerTester.cs | 376 +- BTCPayServer.Tests/TestAccount.cs | 134 +- BTCPayServer.Tests/UnitTest1.cs | 626 +- BTCPayServer.Tests/UnitTestPeusa.cs | 62 +- BTCPayServer.Tests/Utils.cs | 94 +- BTCPayServer/Authentication/BitIdentity.cs | 38 +- BTCPayServer/Authentication/BitToken.cs | 76 +- .../Authentication/PairingCodeEntity.cs | 84 +- .../Authentication/TokenRepository.cs | 348 +- BTCPayServer/BitpayHttpException.cs | 22 +- .../Configuration/BTCPayServerOptions.cs | 104 +- .../Configuration/BTCPayServerRuntime.cs | 164 +- BTCPayServer/Configuration/ConfigException.cs | 12 +- .../Configuration/ConfigurationExtensions.cs | 80 +- .../Configuration/DefaultConfiguration.cs | 146 +- .../Configuration/NetworkInformation.cs | 174 +- .../Controllers/AccessTokenController.cs | 136 +- BTCPayServer/Controllers/AccountController.cs | 896 +- .../Controllers/CallbackController.cs | 170 +- .../Controllers/InvoiceController.API.cs | 210 +- .../InvoiceController.PaymentProtocol.cs | 100 +- .../Controllers/InvoiceController.UI.cs | 544 +- BTCPayServer/Controllers/InvoiceController.cs | 216 +- BTCPayServer/Controllers/ManageController.cs | 1024 +- .../Controllers/PaymentRequestActionResult.cs | 60 +- BTCPayServer/Controllers/RateController.cs | 50 +- BTCPayServer/Controllers/ServerController.cs | 146 +- BTCPayServer/Controllers/StoresController.cs | 728 +- BTCPayServer/Data/AddressInvoiceData.cs | 38 +- BTCPayServer/Data/ApplicationDbContext.cs | 198 +- .../Data/ApplicationDbContextFactory.cs | 70 +- .../Data/HistoricalAddressInvoiceData.cs | 34 +- BTCPayServer/Data/InvoiceData.cs | 120 +- BTCPayServer/Data/PairedSINData.cs | 56 +- BTCPayServer/Data/PairingCodeData.cs | 78 +- BTCPayServer/Data/PaymentData.cs | 38 +- BTCPayServer/Data/PendingInvoiceData.cs | 10 +- BTCPayServer/Data/RefundData.cs | 34 +- BTCPayServer/Data/SettingData.cs | 18 +- BTCPayServer/Data/StoreData.cs | 110 +- BTCPayServer/Data/UserStore.cs | 48 +- BTCPayServer/Extensions.cs | 84 +- .../Filters/OnlyMediaTypeAttribute.cs | 114 +- .../Filters/XFrameOptionsAttribute.cs | 46 +- BTCPayServer/Hosting/BTCPayServerServices.cs | 326 +- BTCPayServer/Hosting/BTCpayMiddleware.cs | 166 +- BTCPayServer/Hosting/Startup.cs | 206 +- BTCPayServer/Logging/ConsoleLogger.cs | 664 +- BTCPayServer/Logging/Logs.cs | 78 +- .../20171012020112_PendingInvoices.cs | 84 +- .../LoginWithRecoveryCodeViewModel.cs | 8 +- BTCPayServer/Models/ApplicationUser.cs | 20 +- BTCPayServer/Models/BitpayErrorsModel.cs | 56 +- BTCPayServer/Models/ConfirmModel.cs | 26 +- BTCPayServer/Models/DataWrapper.cs | 54 +- BTCPayServer/Models/GetTokensResponse.cs | 74 +- BTCPayServer/Models/InvoiceResponse.cs | 388 +- .../InvoicingModels/CreateInvoiceModel.cs | 80 +- .../InvoicingModels/InvoiceDetailsModel.cs | 256 +- .../Models/InvoicingModels/InvoicesModel.cs | 90 +- .../Models/InvoicingModels/PaymentModel.cs | 50 +- .../InvoicingModels/UpdateCustomerModel.cs | 14 +- .../EnableAuthenticatorViewModel.cs | 16 +- .../Models/ManageViewModels/IndexViewModel.cs | 32 +- .../ServerViewModels/EmailsViewModel.cs | 30 +- .../Models/ServerViewModels/UsersViewModel.cs | 40 +- .../StoreViewModels/CreateStoreViewModel.cs | 16 +- .../Models/StoreViewModels/PairingModel.cs | 78 +- .../Models/StoreViewModels/StoreViewModel.cs | 80 +- .../Models/StoreViewModels/StoresViewModel.cs | 56 +- .../Models/StoreViewModels/TokensViewModel.cs | 120 +- BTCPayServer/Models/TokenRequest.cs | 142 +- BTCPayServer/Program.cs | 108 +- BTCPayServer/Roles.cs | 2 +- .../Services/BTCPayServerEnvironment.cs | 58 +- .../Services/Fees/FixedFeeProvider.cs | 30 +- BTCPayServer/Services/Fees/IFeeProvider.cs | 8 +- .../Services/Fees/NBxplorerFeeProvider.cs | 52 +- .../Services/Invoices/InvoiceEntity.cs | 610 +- .../Invoices/InvoiceNotificationManager.cs | 182 +- .../Services/Invoices/InvoiceRepository.cs | 796 +- .../Services/Invoices/InvoiceWatcher.cs | 614 +- BTCPayServer/Services/Mails/EmailSender.cs | 58 +- BTCPayServer/Services/Mails/EmailSettings.cs | 80 +- BTCPayServer/Services/PoliciesSettings.cs | 10 +- .../Services/Rates/BitpayRateProvider.cs | 50 +- .../Services/Rates/CachedRateProvider.cs | 82 +- .../Services/Rates/CoinAverageRateProvider.cs | 190 +- .../Services/Rates/CurrencyNameTable.cs | 136 +- BTCPayServer/Services/Rates/IRateProvider.cs | 44 +- .../Services/Rates/MockRateProvider.cs | 48 +- .../Rates/RateUnavailableException.cs | 22 +- BTCPayServer/Services/SettingsRepository.cs | 96 +- .../Services/Stores/StoreRepository.cs | 178 +- BTCPayServer/Services/Wallets/BTCPayWallet.cs | 82 +- .../DerivationStrategyValidatorAttribute.cs | 44 +- BTCPayServer/Validations/EmailValidator.cs | 20 +- BTCPayServer/Validations/PubKeyValidator.cs | 38 +- .../Views/Account/ConfirmEmail.cshtml | 18 +- BTCPayServer/Views/Account/Login.cshtml | 158 +- .../Views/Account/LoginWith2fa.cshtml | 90 +- BTCPayServer/Views/Account/Register.cshtml | 76 +- BTCPayServer/Views/Home/Home.cshtml | 220 +- BTCPayServer/Views/Invoice/Checkout.cshtml | 2 +- .../Views/Invoice/CreateInvoice.cshtml | 112 +- BTCPayServer/Views/Invoice/Invoice.cshtml | 354 +- .../Views/Invoice/ListInvoices.cshtml | 118 +- BTCPayServer/Views/Manage/Disable2fa.cshtml | 32 +- .../Views/Manage/EnableAuthenticator.cshtml | 88 +- .../Views/Manage/ExternalLogins.cshtml | 14 +- .../Views/Manage/GenerateRecoveryCodes.cshtml | 8 +- BTCPayServer/Views/Manage/Index.cshtml | 62 +- BTCPayServer/Views/Manage/ManageNavPages.cs | 8 +- .../Views/Manage/ResetAuthenticator.cshtml | 6 +- BTCPayServer/Views/Manage/SetPassword.cshtml | 4 +- .../Manage/TwoFactorAuthentication.cshtml | 14 +- BTCPayServer/Views/Manage/_Nav.cshtml | 2 +- BTCPayServer/Views/Manage/_ViewStart.cshtml | 4 +- BTCPayServer/Views/Server/Emails.cshtml | 94 +- BTCPayServer/Views/Server/ListUsers.cshtml | 35 +- BTCPayServer/Views/Server/Policies.cshtml | 32 +- BTCPayServer/Views/Server/ServerNavPages.cs | 40 +- BTCPayServer/Views/Server/_Nav.cshtml | 6 +- BTCPayServer/Views/Server/_ViewStart.cshtml | 4 +- BTCPayServer/Views/Shared/Confirm.cshtml | 36 +- BTCPayServer/Views/Shared/Error.cshtml | 2 +- BTCPayServer/Views/Shared/_Layout.cshtml | 140 +- BTCPayServer/Views/Shared/_NavLayout.cshtml | 48 +- .../Views/Shared/_StatusMessage.cshtml | 2 +- BTCPayServer/Views/Stores/CreateStore.cshtml | 52 +- BTCPayServer/Views/Stores/CreateToken.cshtml | 99 +- BTCPayServer/Views/Stores/ListStores.cshtml | 89 +- BTCPayServer/Views/Stores/ListTokens.cshtml | 53 +- .../Views/Stores/RequestPairing.cshtml | 76 +- BTCPayServer/Views/Stores/StoreNavPages.cs | 28 +- BTCPayServer/Views/Stores/UpdateStore.cshtml | 212 +- BTCPayServer/Views/Stores/_Nav.cshtml | 2 +- BTCPayServer/Views/Stores/_ViewStart.cshtml | 2 +- BTCPayServer/ZipUtils.cs | 44 +- BTCPayServer/wwwroot/css/bootstrap-theme.css | 1042 +- .../wwwroot/css/bootstrap-theme.css.map | 9 +- .../wwwroot/css/bootstrap-theme.min.css | 479 +- .../wwwroot/css/bootstrap-theme.min.css.map | 8 +- BTCPayServer/wwwroot/css/creative.min.css | 449 +- BTCPayServer/wwwroot/css/css.css | 350 +- BTCPayServer/wwwroot/css/normalizer.css | 13410 +++++----- BTCPayServer/wwwroot/css/site.min.css | 29 +- BTCPayServer/wwwroot/js/creative.js | 130 +- BTCPayServer/wwwroot/js/vue-qrcode.js | 2778 ++- BTCPayServer/wwwroot/js/vue-qrcode.js.map | 10 +- BTCPayServer/wwwroot/js/vue.js | 20763 ++++++++-------- .../vendor/bootstrap/css/bootstrap-grid.css | 2006 +- .../bootstrap/css/bootstrap-grid.min.css | 1559 +- .../vendor/bootstrap/css/bootstrap-reboot.css | 284 +- .../bootstrap/css/bootstrap-reboot.min.css | 293 +- .../vendor/bootstrap/css/bootstrap.css | 12196 ++++----- .../vendor/bootstrap/css/bootstrap.min.css | 8593 ++++++- .../wwwroot/vendor/bootstrap/js/bootstrap.js | 7370 +++--- .../vendor/font-awesome/css/font-awesome.css | 2287 +- .../font-awesome/css/font-awesome.min.css | 2927 ++- .../vendor/font-awesome/less/animated.less | 42 +- .../font-awesome/less/bordered-pulled.less | 42 +- .../vendor/font-awesome/less/core.less | 13 +- .../vendor/font-awesome/less/fixed-width.less | 4 +- .../vendor/font-awesome/less/icons.less | 3374 ++- .../vendor/font-awesome/less/larger.less | 26 +- .../vendor/font-awesome/less/list.less | 29 +- .../vendor/font-awesome/less/mixins.less | 63 +- .../vendor/font-awesome/less/path.less | 16 +- .../font-awesome/less/rotated-flipped.less | 25 +- .../font-awesome/less/screen-reader.less | 9 +- .../vendor/font-awesome/less/stacked.less | 36 +- .../vendor/font-awesome/less/variables.less | 14 +- .../vendor/font-awesome/scss/_animated.scss | 42 +- .../font-awesome/scss/_bordered-pulled.scss | 42 +- .../vendor/font-awesome/scss/_core.scss | 13 +- .../font-awesome/scss/_fixed-width.scss | 4 +- .../vendor/font-awesome/scss/_icons.scss | 3374 ++- .../vendor/font-awesome/scss/_larger.scss | 26 +- .../vendor/font-awesome/scss/_list.scss | 29 +- .../vendor/font-awesome/scss/_mixins.scss | 63 +- .../vendor/font-awesome/scss/_path.scss | 16 +- .../font-awesome/scss/_rotated-flipped.scss | 25 +- .../font-awesome/scss/_screen-reader.scss | 9 +- .../vendor/font-awesome/scss/_stacked.scss | 36 +- .../vendor/font-awesome/scss/_variables.scss | 14 +- .../jquery.easing.compatibility.js | 99 +- .../vendor/jquery-easing/jquery.easing.js | 302 +- .../magnific-popup/jquery.magnific-popup.js | 3607 +-- .../vendor/magnific-popup/magnific-popup.css | 632 +- BTCPayServer/wwwroot/vendor/popper/popper.js | 4719 ++-- .../vendor/scrollreveal/scrollreveal.js | 1598 +- 199 files changed, 66960 insertions(+), 46532 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..3a1882a26 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,149 @@ +# editorconfig.org + +# top-most EditorConfig file +root = true + +# Default settings: +# A newline ending every file +# Use 4 spaces as indentation +[*] +insert_final_newline = true +indent_style = space +indent_size = 4 + +[project.json] +indent_size = 2 + +# C# files +[*.cs] +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_within_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left + +# avoid this. unless absolutely necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# only use var when it's obvious what the variable type is +csharp_style_var_for_built_in_types = false:none +csharp_style_var_when_type_is_apparent = false:none +csharp_style_var_elsewhere = false:suggestion + +# use language keywords instead of BCL types +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# name all constant fields using PascalCase +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style + +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const + +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +# internal and private fields should be _camelCase +dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion +dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style + +dotnet_naming_symbols.private_internal_fields.applicable_kinds = field +dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal + +dotnet_naming_style.camel_case_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case + +# Code style defaults +dotnet_sort_system_directives_first = true +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion + +# Expression-bodied members +csharp_style_expression_bodied_methods = false:none +csharp_style_expression_bodied_constructors = false:none +csharp_style_expression_bodied_operators = false:none +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# C++ Files +[*.{cpp,h,in}] +curly_bracket_next_line = true +indent_brace_style = Allman + +# Xml project files +[*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] +indent_size = 2 + +# Xml build files +[*.builds] +indent_size = 2 + +# Xml files +[*.{xml,stylecop,resx,ruleset}] +indent_size = 2 + +# Xml config files +[*.{props,targets,config,nuspec}] +indent_size = 2 + +# Shell scripts +[*.sh] +end_of_line = lf +[*.{cmd, bat}] +end_of_line = crlf \ No newline at end of file diff --git a/BTCPayServer.Tests/BTCPayServerTester.cs b/BTCPayServer.Tests/BTCPayServerTester.cs index 1fd51566e..bc07d8d92 100644 --- a/BTCPayServer.Tests/BTCPayServerTester.cs +++ b/BTCPayServer.Tests/BTCPayServerTester.cs @@ -30,133 +30,133 @@ using Xunit; namespace BTCPayServer.Tests { - public class BTCPayServerTester : IDisposable - { - private string _Directory; + public class BTCPayServerTester : IDisposable + { + private string _Directory; - public BTCPayServerTester(string scope) - { - this._Directory = scope ?? throw new ArgumentNullException(nameof(scope)); - } + public BTCPayServerTester(string scope) + { + this._Directory = scope ?? throw new ArgumentNullException(nameof(scope)); + } - public Uri NBXplorerUri - { - get; set; - } - public string CookieFile - { - get; set; - } - public Uri ServerUri - { - get; - set; - } + public Uri NBXplorerUri + { + get; set; + } + public string CookieFile + { + get; set; + } + public Uri ServerUri + { + get; + set; + } - public ExtKey HDPrivateKey - { - get; set; - } + public ExtKey HDPrivateKey + { + get; set; + } - public string Postgres - { - get; set; - } + public string Postgres + { + get; set; + } - IWebHost _Host; - public int Port - { - get; set; - } + IWebHost _Host; + public int Port + { + get; set; + } - public void Start() - { - if(!Directory.Exists(_Directory)) - Directory.CreateDirectory(_Directory); + public void Start() + { + if (!Directory.Exists(_Directory)) + Directory.CreateDirectory(_Directory); - HDPrivateKey = new ExtKey(); - StringBuilder config = new StringBuilder(); - config.AppendLine($"regtest=1"); - config.AppendLine($"port={Port}"); - config.AppendLine($"explorer.url={NBXplorerUri.AbsoluteUri}"); - config.AppendLine($"explorer.cookiefile={CookieFile}"); - config.AppendLine($"hdpubkey={HDPrivateKey.Neuter().ToString(Network.RegTest)}"); - if(Postgres != null) - config.AppendLine($"postgres=" + Postgres); - File.WriteAllText(Path.Combine(_Directory, "settings.config"), config.ToString()); + HDPrivateKey = new ExtKey(); + StringBuilder config = new StringBuilder(); + config.AppendLine($"regtest=1"); + config.AppendLine($"port={Port}"); + config.AppendLine($"explorer.url={NBXplorerUri.AbsoluteUri}"); + config.AppendLine($"explorer.cookiefile={CookieFile}"); + config.AppendLine($"hdpubkey={HDPrivateKey.Neuter().ToString(Network.RegTest)}"); + if (Postgres != null) + config.AppendLine($"postgres=" + Postgres); + File.WriteAllText(Path.Combine(_Directory, "settings.config"), config.ToString()); - ServerUri = new Uri("http://" + HostName + ":" + Port + "/"); + ServerUri = new Uri("http://" + HostName + ":" + Port + "/"); - var conf = new DefaultConfiguration() { Logger = Logs.LogProvider.CreateLogger("Console") }.CreateConfiguration(new[] { "--datadir", _Directory }); + var conf = new DefaultConfiguration() { Logger = Logs.LogProvider.CreateLogger("Console") }.CreateConfiguration(new[] { "--datadir", _Directory }); - _Host = new WebHostBuilder() - .UseConfiguration(conf) - .ConfigureServices(s => - { - s.AddSingleton(new MockRateProvider(new Rate("USD", 5000m))); - s.AddLogging(l => - { - l.SetMinimumLevel(LogLevel.Information) - .AddFilter("Microsoft", LogLevel.Error) - .AddFilter("Hangfire", LogLevel.Error) - .AddProvider(Logs.LogProvider); - }); - }) - .UseKestrel() - .UseStartup() - .Build(); - _Host.Start(); - Runtime = (BTCPayServerRuntime)_Host.Services.GetService(typeof(BTCPayServerRuntime)); - var watcher = (InvoiceWatcher)_Host.Services.GetService(typeof(InvoiceWatcher)); - watcher.PollInterval = TimeSpan.FromMilliseconds(500); - } + _Host = new WebHostBuilder() + .UseConfiguration(conf) + .ConfigureServices(s => + { + s.AddSingleton(new MockRateProvider(new Rate("USD", 5000m))); + s.AddLogging(l => + { + l.SetMinimumLevel(LogLevel.Information) + .AddFilter("Microsoft", LogLevel.Error) + .AddFilter("Hangfire", LogLevel.Error) + .AddProvider(Logs.LogProvider); + }); + }) + .UseKestrel() + .UseStartup() + .Build(); + _Host.Start(); + Runtime = (BTCPayServerRuntime)_Host.Services.GetService(typeof(BTCPayServerRuntime)); + var watcher = (InvoiceWatcher)_Host.Services.GetService(typeof(InvoiceWatcher)); + watcher.PollInterval = TimeSpan.FromMilliseconds(500); + } - public BTCPayServerRuntime Runtime - { - get; set; - } - public string HostName - { - get; - internal set; - } + public BTCPayServerRuntime Runtime + { + get; set; + } + public string HostName + { + get; + internal set; + } - public T GetService() - { - return _Host.Services.GetRequiredService(); - } + public T GetService() + { + return _Host.Services.GetRequiredService(); + } - public T GetController(string userId = null) where T : Controller - { - var context = new DefaultHttpContext(); - context.Request.Host = new HostString("127.0.0.1"); - context.Request.Scheme = "http"; - context.Request.Protocol = "http"; - if(userId != null) - { - context.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, userId) })); - } - var scope = (IServiceScopeFactory)_Host.Services.GetService(typeof(IServiceScopeFactory)); - var provider = scope.CreateScope().ServiceProvider; - context.RequestServices = provider; + public T GetController(string userId = null) where T : Controller + { + var context = new DefaultHttpContext(); + context.Request.Host = new HostString("127.0.0.1"); + context.Request.Scheme = "http"; + context.Request.Protocol = "http"; + if (userId != null) + { + context.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, userId) })); + } + var scope = (IServiceScopeFactory)_Host.Services.GetService(typeof(IServiceScopeFactory)); + var provider = scope.CreateScope().ServiceProvider; + context.RequestServices = provider; - var httpAccessor = provider.GetRequiredService(); - httpAccessor.HttpContext = context; + var httpAccessor = provider.GetRequiredService(); + httpAccessor.HttpContext = context; - var controller = (T)ActivatorUtilities.CreateInstance(provider, typeof(T)); + var controller = (T)ActivatorUtilities.CreateInstance(provider, typeof(T)); - controller.Url = new UrlHelperMock(new Uri($"http://{HostName}:{Port}/")); - controller.ControllerContext = new ControllerContext() - { - HttpContext = context - }; - return controller; - } + controller.Url = new UrlHelperMock(new Uri($"http://{HostName}:{Port}/")); + controller.ControllerContext = new ControllerContext() + { + HttpContext = context + }; + return controller; + } - public void Dispose() - { - if(_Host != null) - _Host.Dispose(); - } - } + public void Dispose() + { + if (_Host != null) + _Host.Dispose(); + } + } } diff --git a/BTCPayServer.Tests/CustomerHttpServer.cs b/BTCPayServer.Tests/CustomerHttpServer.cs index 4bbdf2883..24f73c8ef 100644 --- a/BTCPayServer.Tests/CustomerHttpServer.cs +++ b/BTCPayServer.Tests/CustomerHttpServer.cs @@ -11,65 +11,65 @@ using Microsoft.AspNetCore.Hosting.Server.Features; namespace BTCPayServer.Tests { - public class CustomServer : IDisposable - { - TaskCompletionSource _Evt = null; - IWebHost _Host = null; - CancellationTokenSource _Closed = new CancellationTokenSource(); - public CustomServer() - { - var port = Utils.FreeTcpPort(); - _Host = new WebHostBuilder() - .Configure(app => - { - app.Run(req => - { - while(_Act == null) - { - Thread.Sleep(10); - _Closed.Token.ThrowIfCancellationRequested(); - } - _Act(req); - _Act = null; - _Evt.TrySetResult(true); - req.Response.StatusCode = 200; - return Task.CompletedTask; - }); - }) - .UseKestrel() - .UseUrls("http://127.0.0.1:" + port) - .Build(); - _Host.Start(); - } + public class CustomServer : IDisposable + { + TaskCompletionSource _Evt = null; + IWebHost _Host = null; + CancellationTokenSource _Closed = new CancellationTokenSource(); + public CustomServer() + { + var port = Utils.FreeTcpPort(); + _Host = new WebHostBuilder() + .Configure(app => + { + app.Run(req => + { + while (_Act == null) + { + Thread.Sleep(10); + _Closed.Token.ThrowIfCancellationRequested(); + } + _Act(req); + _Act = null; + _Evt.TrySetResult(true); + req.Response.StatusCode = 200; + return Task.CompletedTask; + }); + }) + .UseKestrel() + .UseUrls("http://127.0.0.1:" + port) + .Build(); + _Host.Start(); + } - public Uri GetUri() - { - return new Uri(_Host.ServerFeatures.Get().Addresses.First()); - } + public Uri GetUri() + { + return new Uri(_Host.ServerFeatures.Get().Addresses.First()); + } - Action _Act; - public void ProcessNextRequest(Action act) - { - var source = new TaskCompletionSource(); - CancellationTokenSource cancellation = new CancellationTokenSource(20000); - cancellation.Token.Register(() => source.TrySetCanceled()); - source = new TaskCompletionSource(); - _Evt = source; - _Act = act; - try - { - _Evt.Task.GetAwaiter().GetResult(); - } - catch(TaskCanceledException) - { - throw new Xunit.Sdk.XunitException("Callback to the webserver was expected, check if the callback url is accessible from internet"); - } - } + Action _Act; + public void ProcessNextRequest(Action act) + { + var source = new TaskCompletionSource(); + CancellationTokenSource cancellation = new CancellationTokenSource(20000); + cancellation.Token.Register(() => source.TrySetCanceled()); + source = new TaskCompletionSource(); + _Evt = source; + _Act = act; + try + { + _Evt.Task.GetAwaiter().GetResult(); + } + catch (TaskCanceledException) + { + throw new Xunit.Sdk.XunitException("Callback to the webserver was expected, check if the callback url is accessible from internet"); + } + } - public void Dispose() - { - _Closed.Cancel(); - _Host.Dispose(); - } - } + public void Dispose() + { + _Closed.Cancel(); + _Host.Dispose(); + } + } } diff --git a/BTCPayServer.Tests/Logging/Logs.cs b/BTCPayServer.Tests/Logging/Logs.cs index 13c727c47..e47eb7239 100644 --- a/BTCPayServer.Tests/Logging/Logs.cs +++ b/BTCPayServer.Tests/Logging/Logs.cs @@ -6,84 +6,84 @@ using Xunit.Abstractions; namespace BTCPayServer.Tests.Logging { - public interface ILog - { - void LogInformation(string msg); - } + public interface ILog + { + void LogInformation(string msg); + } - public class XUnitLogProvider : ILoggerProvider - { - ITestOutputHelper _Helper; - public XUnitLogProvider(ITestOutputHelper helper) - { - _Helper = helper; - } - public ILogger CreateLogger(string categoryName) - { - return new XUnitLog(_Helper) { Name = categoryName }; - } + public class XUnitLogProvider : ILoggerProvider + { + ITestOutputHelper _Helper; + public XUnitLogProvider(ITestOutputHelper helper) + { + _Helper = helper; + } + public ILogger CreateLogger(string categoryName) + { + return new XUnitLog(_Helper) { Name = categoryName }; + } - public void Dispose() - { - - } - } - public class XUnitLog : ILog, ILogger, IDisposable - { - ITestOutputHelper _Helper; - public XUnitLog(ITestOutputHelper helper) - { - _Helper = helper; - } + public void Dispose() + { - public string Name - { - get; set; - } + } + } + public class XUnitLog : ILog, ILogger, IDisposable + { + ITestOutputHelper _Helper; + public XUnitLog(ITestOutputHelper helper) + { + _Helper = helper; + } - public IDisposable BeginScope(TState state) - { - return this; - } + public string Name + { + get; set; + } - public void Dispose() - { + public IDisposable BeginScope(TState state) + { + return this; + } - } + public void Dispose() + { - public bool IsEnabled(LogLevel logLevel) - { - return true; - } + } - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - StringBuilder builder = new StringBuilder(); - builder.Append(formatter(state, exception)); - if(exception != null) - { - builder.AppendLine(); - builder.Append(exception.ToString()); - } - LogInformation(builder.ToString()); - } + public bool IsEnabled(LogLevel logLevel) + { + return true; + } - public void LogInformation(string msg) - { - if(msg != null) - _Helper.WriteLine(Name + ": " + msg); - } - } - public class Logs - { - public static ILog Tester - { - get; set; - } - public static XUnitLogProvider LogProvider - { - get; - set; - } - } + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + StringBuilder builder = new StringBuilder(); + builder.Append(formatter(state, exception)); + if (exception != null) + { + builder.AppendLine(); + builder.Append(exception.ToString()); + } + LogInformation(builder.ToString()); + } + + public void LogInformation(string msg) + { + if (msg != null) + _Helper.WriteLine(Name + ": " + msg); + } + } + public class Logs + { + public static ILog Tester + { + get; set; + } + public static XUnitLogProvider LogProvider + { + get; + set; + } + } } diff --git a/BTCPayServer.Tests/Mocks/UrlHelperMock.cs b/BTCPayServer.Tests/Mocks/UrlHelperMock.cs index 1fa3c4ddd..86fbab83c 100644 --- a/BTCPayServer.Tests/Mocks/UrlHelperMock.cs +++ b/BTCPayServer.Tests/Mocks/UrlHelperMock.cs @@ -6,38 +6,38 @@ using Microsoft.AspNetCore.Mvc.Routing; namespace BTCPayServer.Tests.Mocks { - public class UrlHelperMock : IUrlHelper - { - Uri _BaseUrl; - public UrlHelperMock(Uri baseUrl) - { - _BaseUrl = baseUrl; - } - public ActionContext ActionContext => throw new NotImplementedException(); + public class UrlHelperMock : IUrlHelper + { + Uri _BaseUrl; + public UrlHelperMock(Uri baseUrl) + { + _BaseUrl = baseUrl; + } + public ActionContext ActionContext => throw new NotImplementedException(); - public string Action(UrlActionContext actionContext) - { - return $"{_BaseUrl}mock"; - } + public string Action(UrlActionContext actionContext) + { + return $"{_BaseUrl}mock"; + } - public string Content(string contentPath) - { - return $"{_BaseUrl}{contentPath}"; - } + public string Content(string contentPath) + { + return $"{_BaseUrl}{contentPath}"; + } - public bool IsLocalUrl(string url) - { - return false; - } + public bool IsLocalUrl(string url) + { + return false; + } - public string Link(string routeName, object values) - { - return _BaseUrl.AbsoluteUri; - } + public string Link(string routeName, object values) + { + return _BaseUrl.AbsoluteUri; + } - public string RouteUrl(UrlRouteContext routeContext) - { - return _BaseUrl.AbsoluteUri; - } - } + public string RouteUrl(UrlRouteContext routeContext) + { + return _BaseUrl.AbsoluteUri; + } + } } diff --git a/BTCPayServer.Tests/ProcessLauncher.cs b/BTCPayServer.Tests/ProcessLauncher.cs index 45ced578a..f6673e148 100644 --- a/BTCPayServer.Tests/ProcessLauncher.cs +++ b/BTCPayServer.Tests/ProcessLauncher.cs @@ -8,105 +8,105 @@ using Xunit; namespace BTCPayServer.Tests { - public class ProcessLauncher - { - string _CurrentDirectory; - public string CurrentDirectory - { - get - { - return _CurrentDirectory; - } - } - public ProcessLauncher() - { - _CurrentDirectory = Directory.GetCurrentDirectory(); - } - public bool GoTo(string[] directories, bool createIfNotExists = false) - { - var original = _CurrentDirectory; - foreach(var dir in directories) - { - var newDirectory = Path.Combine(_CurrentDirectory, dir); - if(!Directory.Exists(newDirectory)) - { - if(createIfNotExists) - Directory.CreateDirectory(newDirectory); - else - { - _CurrentDirectory = original; - return false; - } - } - _CurrentDirectory = newDirectory; - } - return true; - } + public class ProcessLauncher + { + string _CurrentDirectory; + public string CurrentDirectory + { + get + { + return _CurrentDirectory; + } + } + public ProcessLauncher() + { + _CurrentDirectory = Directory.GetCurrentDirectory(); + } + public bool GoTo(string[] directories, bool createIfNotExists = false) + { + var original = _CurrentDirectory; + foreach (var dir in directories) + { + var newDirectory = Path.Combine(_CurrentDirectory, dir); + if (!Directory.Exists(newDirectory)) + { + if (createIfNotExists) + Directory.CreateDirectory(newDirectory); + else + { + _CurrentDirectory = original; + return false; + } + } + _CurrentDirectory = newDirectory; + } + return true; + } - Stack _Directories = new Stack(); - public void PushDirectory() - { - _Directories.Push(_CurrentDirectory); - } + Stack _Directories = new Stack(); + public void PushDirectory() + { + _Directories.Push(_CurrentDirectory); + } - public void PopDirectory() - { - _CurrentDirectory = _Directories.Pop(); - } + public void PopDirectory() + { + _CurrentDirectory = _Directories.Pop(); + } - public bool GoTo(string directory, bool createIfNotExists = false) - { - return GoTo(new[] { directory }, createIfNotExists); - } + public bool GoTo(string directory, bool createIfNotExists = false) + { + return GoTo(new[] { directory }, createIfNotExists); + } - public void Run(string processName, string args) - { - Start(processName, args).WaitForExit(); - } + public void Run(string processName, string args) + { + Start(processName, args).WaitForExit(); + } - public Process Start(string processName, string args) - { - Logs.Tester.LogInformation($"Running [{processName} {args}] from {_CurrentDirectory}"); - StringBuilder builder = new StringBuilder(); - var process = new Process() - { - StartInfo = new ProcessStartInfo - { - WorkingDirectory = _CurrentDirectory, - FileName = processName, - Arguments = args, - RedirectStandardOutput = true, - RedirectStandardError = true - } - }; - try - { - process.OutputDataReceived += (s, e) => - { - Logs.Tester.LogInformation(e.Data); - }; - process.ErrorDataReceived += (s, e) => - { - Logs.Tester.LogInformation(e.Data); - }; - process.Start(); - process.BeginErrorReadLine(); - process.BeginOutputReadLine(); - } - catch(Exception ex) { throw new Exception($"You need to install {processName} for this test (info : {ex.Message})"); } - return process; - } + public Process Start(string processName, string args) + { + Logs.Tester.LogInformation($"Running [{processName} {args}] from {_CurrentDirectory}"); + StringBuilder builder = new StringBuilder(); + var process = new Process() + { + StartInfo = new ProcessStartInfo + { + WorkingDirectory = _CurrentDirectory, + FileName = processName, + Arguments = args, + RedirectStandardOutput = true, + RedirectStandardError = true + } + }; + try + { + process.OutputDataReceived += (s, e) => + { + Logs.Tester.LogInformation(e.Data); + }; + process.ErrorDataReceived += (s, e) => + { + Logs.Tester.LogInformation(e.Data); + }; + process.Start(); + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + } + catch (Exception ex) { throw new Exception($"You need to install {processName} for this test (info : {ex.Message})"); } + return process; + } - public void AssertExists(string file) - { - var path = Path.Combine(_CurrentDirectory, file); - Assert.True(File.Exists(path), $"The file {path} should exist"); - } + public void AssertExists(string file) + { + var path = Path.Combine(_CurrentDirectory, file); + Assert.True(File.Exists(path), $"The file {path} should exist"); + } - public bool Exists(string file) - { - var path = Path.Combine(_CurrentDirectory, file); - return File.Exists(path); - } - } + public bool Exists(string file) + { + var path = Path.Combine(_CurrentDirectory, file); + return File.Exists(path); + } + } } diff --git a/BTCPayServer.Tests/Properties/launchSettings.json b/BTCPayServer.Tests/Properties/launchSettings.json index 1c0aa7816..61c764ea8 100644 --- a/BTCPayServer.Tests/Properties/launchSettings.json +++ b/BTCPayServer.Tests/Properties/launchSettings.json @@ -1,7 +1,7 @@ { - "profiles": { - "BTCPayServer.Tests": { - "commandName": "Project" + "profiles": { + "BTCPayServer.Tests": { + "commandName": "Project" + } } - } -} \ No newline at end of file +} diff --git a/BTCPayServer.Tests/ServerTester.cs b/BTCPayServer.Tests/ServerTester.cs index 2f78a5383..6f8994655 100644 --- a/BTCPayServer.Tests/ServerTester.cs +++ b/BTCPayServer.Tests/ServerTester.cs @@ -19,218 +19,218 @@ using System.Threading; namespace BTCPayServer.Tests { - public class ServerTester : IDisposable - { - public static ServerTester Create([CallerMemberNameAttribute]string scope = null) - { - return new ServerTester(scope); - } + public class ServerTester : IDisposable + { + public static ServerTester Create([CallerMemberNameAttribute]string scope = null) + { + return new ServerTester(scope); + } - string _Directory; - public ServerTester(string scope) - { - _Directory = scope; - } + string _Directory; + public ServerTester(string scope) + { + _Directory = scope; + } - public bool Dockerized - { - get; set; - } + public bool Dockerized + { + get; set; + } - public void Start() - { - if(Directory.Exists(_Directory)) - Utils.DeleteDirectory(_Directory); - if(!Directory.Exists(_Directory)) - Directory.CreateDirectory(_Directory); + public void Start() + { + if (Directory.Exists(_Directory)) + Utils.DeleteDirectory(_Directory); + if (!Directory.Exists(_Directory)) + Directory.CreateDirectory(_Directory); - FakeCallback = bool.Parse(GetEnvironment("TESTS_FAKECALLBACK", "true")); - ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_RPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), Network); - ExplorerClient = new ExplorerClient(Network, new Uri(GetEnvironment("TESTS_NBXPLORERURL", "http://127.0.0.1:32838/"))); - PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay")) - { - NBXplorerUri = ExplorerClient.Address, - Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver") - }; - PayTester.Port = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString())); - PayTester.HostName = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1"); - PayTester.Start(); - } + FakeCallback = bool.Parse(GetEnvironment("TESTS_FAKECALLBACK", "true")); + ExplorerNode = new RPCClient(RPCCredentialString.Parse(GetEnvironment("TESTS_RPCCONNECTION", "server=http://127.0.0.1:43782;ceiwHEbqWI83:DwubwWsoo3")), Network); + ExplorerClient = new ExplorerClient(Network, new Uri(GetEnvironment("TESTS_NBXPLORERURL", "http://127.0.0.1:32838/"))); + PayTester = new BTCPayServerTester(Path.Combine(_Directory, "pay")) + { + NBXplorerUri = ExplorerClient.Address, + Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver") + }; + PayTester.Port = int.Parse(GetEnvironment("TESTS_PORT", Utils.FreeTcpPort().ToString())); + PayTester.HostName = GetEnvironment("TESTS_HOSTNAME", "127.0.0.1"); + PayTester.Start(); + } - private string GetEnvironment(string variable, string defaultValue) - { - var var = Environment.GetEnvironmentVariable(variable); - return String.IsNullOrEmpty(var) ? defaultValue : var; - } + private string GetEnvironment(string variable, string defaultValue) + { + var var = Environment.GetEnvironmentVariable(variable); + return String.IsNullOrEmpty(var) ? defaultValue : var; + } - public TestAccount NewAccount() - { - return new TestAccount(this); - } + public TestAccount NewAccount() + { + return new TestAccount(this); + } - public bool FakeCallback - { - get; - set; - } - public RPCClient ExplorerNode - { - get; set; - } + public bool FakeCallback + { + get; + set; + } + public RPCClient ExplorerNode + { + get; set; + } - public ExplorerClient ExplorerClient - { - get; set; - } + public ExplorerClient ExplorerClient + { + get; set; + } - HttpClient _Http = new HttpClient(); + HttpClient _Http = new HttpClient(); - class MockHttpRequest : HttpRequest - { - Uri serverUri; - public MockHttpRequest(Uri serverUri) - { - this.serverUri = serverUri; - } - public override HttpContext HttpContext => throw new NotImplementedException(); + class MockHttpRequest : HttpRequest + { + Uri serverUri; + public MockHttpRequest(Uri serverUri) + { + this.serverUri = serverUri; + } + public override HttpContext HttpContext => throw new NotImplementedException(); - public override string Method - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override string Scheme - { - get => serverUri.Scheme; - set => throw new NotImplementedException(); - } - public override bool IsHttps - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override HostString Host - { - get => new HostString(serverUri.Host, serverUri.Port); - set => throw new NotImplementedException(); - } - public override PathString PathBase - { - get => ""; - set => throw new NotImplementedException(); - } - public override PathString Path - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override QueryString QueryString - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override IQueryCollection Query - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override string Protocol - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } + public override string Method + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override string Scheme + { + get => serverUri.Scheme; + set => throw new NotImplementedException(); + } + public override bool IsHttps + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override HostString Host + { + get => new HostString(serverUri.Host, serverUri.Port); + set => throw new NotImplementedException(); + } + public override PathString PathBase + { + get => ""; + set => throw new NotImplementedException(); + } + public override PathString Path + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override QueryString QueryString + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override IQueryCollection Query + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override string Protocol + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } - public override IHeaderDictionary Headers => throw new NotImplementedException(); + public override IHeaderDictionary Headers => throw new NotImplementedException(); - public override IRequestCookieCollection Cookies - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override long? ContentLength - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override string ContentType - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override Stream Body - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } + public override IRequestCookieCollection Cookies + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override long? ContentLength + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override string ContentType + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } + public override Stream Body + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } - public override bool HasFormContentType => throw new NotImplementedException(); + public override bool HasFormContentType => throw new NotImplementedException(); - public override IFormCollection Form - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } + public override IFormCollection Form + { + get => throw new NotImplementedException(); + set => throw new NotImplementedException(); + } - public override Task ReadFormAsync(CancellationToken cancellationToken = default(CancellationToken)) - { - throw new NotImplementedException(); - } - } + public override Task ReadFormAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + throw new NotImplementedException(); + } + } - /// - /// Simulating callback from NBXplorer. NBXplorer can't reach the host during tests as it is not running on localhost. - /// - /// - public void SimulateCallback(BitcoinAddress address = null) - { - if(!FakeCallback) //The callback of NBXplorer should work - return; + /// + /// Simulating callback from NBXplorer. NBXplorer can't reach the host during tests as it is not running on localhost. + /// + /// + public void SimulateCallback(BitcoinAddress address = null) + { + if (!FakeCallback) //The callback of NBXplorer should work + return; - var req = new MockHttpRequest(PayTester.ServerUri); - var controller = PayTester.GetController(); - if(address != null) - { + var req = new MockHttpRequest(PayTester.ServerUri); + var controller = PayTester.GetController(); + if (address != null) + { - var match = new TransactionMatch(); - match.Outputs.Add(new KeyPathInformation() { ScriptPubKey = address.ScriptPubKey }); - var content = new StringContent(new NBXplorer.Serializer(Network).ToString(match), new UTF8Encoding(false), "application/json"); - var uri = controller.GetCallbackUriAsync(req).GetAwaiter().GetResult(); + var match = new TransactionMatch(); + match.Outputs.Add(new KeyPathInformation() { ScriptPubKey = address.ScriptPubKey }); + var content = new StringContent(new NBXplorer.Serializer(Network).ToString(match), new UTF8Encoding(false), "application/json"); + var uri = controller.GetCallbackUriAsync(req).GetAwaiter().GetResult(); - HttpRequestMessage message = new HttpRequestMessage(); - message.Method = HttpMethod.Post; - message.RequestUri = uri; - message.Content = content; + HttpRequestMessage message = new HttpRequestMessage(); + message.Method = HttpMethod.Post; + message.RequestUri = uri; + message.Content = content; - _Http.SendAsync(message).GetAwaiter().GetResult(); - } - else - { - - var uri = controller.GetCallbackBlockUriAsync(req).GetAwaiter().GetResult(); - HttpRequestMessage message = new HttpRequestMessage(); - message.Method = HttpMethod.Post; - message.RequestUri = uri; - _Http.SendAsync(message).GetAwaiter().GetResult(); - } - } + _Http.SendAsync(message).GetAwaiter().GetResult(); + } + else + { + + var uri = controller.GetCallbackBlockUriAsync(req).GetAwaiter().GetResult(); + HttpRequestMessage message = new HttpRequestMessage(); + message.Method = HttpMethod.Post; + message.RequestUri = uri; + _Http.SendAsync(message).GetAwaiter().GetResult(); + } + } - public BTCPayServerTester PayTester - { - get; set; - } + public BTCPayServerTester PayTester + { + get; set; + } - public Network Network - { - get; - set; - } = Network.RegTest; + public Network Network + { + get; + set; + } = Network.RegTest; - public void Dispose() - { - if(PayTester != null) - PayTester.Dispose(); - } - } + public void Dispose() + { + if (PayTester != null) + PayTester.Dispose(); + } + } } diff --git a/BTCPayServer.Tests/TestAccount.cs b/BTCPayServer.Tests/TestAccount.cs index b22b19a0b..733096628 100644 --- a/BTCPayServer.Tests/TestAccount.cs +++ b/BTCPayServer.Tests/TestAccount.cs @@ -15,78 +15,78 @@ namespace BTCPayServer.Tests { public class TestAccount { - ServerTester parent; - public TestAccount(ServerTester parent) - { - this.parent = parent; - BitPay = new Bitpay(new Key(), parent.PayTester.ServerUri); - } + ServerTester parent; + public TestAccount(ServerTester parent) + { + this.parent = parent; + BitPay = new Bitpay(new Key(), parent.PayTester.ServerUri); + } - public void GrantAccess() - { - GrantAccessAsync().GetAwaiter().GetResult(); - } + public void GrantAccess() + { + GrantAccessAsync().GetAwaiter().GetResult(); + } - public void Register() - { - RegisterAsync().GetAwaiter().GetResult(); - } + public void Register() + { + RegisterAsync().GetAwaiter().GetResult(); + } - public BitcoinExtKey ExtKey - { - get; set; - } + public BitcoinExtKey ExtKey + { + get; set; + } - public async Task GrantAccessAsync() - { - await RegisterAsync(); - var store = await CreateStoreAsync(); - var pairingCode = BitPay.RequestClientAuthorization("test", Facade.Merchant); - Assert.IsType(await store.RequestPairing(pairingCode.ToString())); - await store.Pair(pairingCode.ToString(), StoreId); - } - public StoresController CreateStore() - { - return CreateStoreAsync().GetAwaiter().GetResult(); - } - public async Task CreateStoreAsync() - { - ExtKey = new ExtKey().GetWif(parent.Network); - var store = parent.PayTester.GetController(UserId); - await store.CreateStore(new CreateStoreViewModel() { Name = "Test Store" }); - StoreId = store.CreatedStoreId; - await store.UpdateStore(StoreId, new StoreViewModel() - { - DerivationScheme = ExtKey.Neuter().ToString() + "-[legacy]", - SpeedPolicy = SpeedPolicy.MediumSpeed - }, "Save"); - return store; - } + public async Task GrantAccessAsync() + { + await RegisterAsync(); + var store = await CreateStoreAsync(); + var pairingCode = BitPay.RequestClientAuthorization("test", Facade.Merchant); + Assert.IsType(await store.RequestPairing(pairingCode.ToString())); + await store.Pair(pairingCode.ToString(), StoreId); + } + public StoresController CreateStore() + { + return CreateStoreAsync().GetAwaiter().GetResult(); + } + public async Task CreateStoreAsync() + { + ExtKey = new ExtKey().GetWif(parent.Network); + var store = parent.PayTester.GetController(UserId); + await store.CreateStore(new CreateStoreViewModel() { Name = "Test Store" }); + StoreId = store.CreatedStoreId; + await store.UpdateStore(StoreId, new StoreViewModel() + { + DerivationScheme = ExtKey.Neuter().ToString() + "-[legacy]", + SpeedPolicy = SpeedPolicy.MediumSpeed + }, "Save"); + return store; + } - private async Task RegisterAsync() - { - var account = parent.PayTester.GetController(); - await account.Register(new RegisterViewModel() - { - Email = Guid.NewGuid() + "@toto.com", - ConfirmPassword = "Kitten0@", - Password = "Kitten0@", - }); - UserId = account.RegisteredUserId; - } + private async Task RegisterAsync() + { + var account = parent.PayTester.GetController(); + await account.Register(new RegisterViewModel() + { + Email = Guid.NewGuid() + "@toto.com", + ConfirmPassword = "Kitten0@", + Password = "Kitten0@", + }); + UserId = account.RegisteredUserId; + } - public Bitpay BitPay - { - get; set; - } - public string UserId - { - get; set; - } + public Bitpay BitPay + { + get; set; + } + public string UserId + { + get; set; + } - public string StoreId - { - get; set; - } - } + public string StoreId + { + get; set; + } + } } diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 2527384bb..d61ea15aa 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -25,369 +25,369 @@ using Microsoft.Extensions.Caching.Memory; namespace BTCPayServer.Tests { - public class UnitTest1 - { - public UnitTest1(ITestOutputHelper helper) - { - Logs.Tester = new XUnitLog(helper) { Name = "Tests" }; - Logs.LogProvider = new XUnitLogProvider(helper); - } + public class UnitTest1 + { + public UnitTest1(ITestOutputHelper helper) + { + Logs.Tester = new XUnitLog(helper) { Name = "Tests" }; + Logs.LogProvider = new XUnitLogProvider(helper); + } - [Fact] - public void CanCalculateCryptoDue() - { - var entity = new InvoiceEntity(); - entity.TxFee = Money.Coins(0.1m); - entity.Rate = 5000; - entity.Payments = new System.Collections.Generic.List(); - entity.ProductInformation = new ProductInformation() { Price = 5000 }; + [Fact] + public void CanCalculateCryptoDue() + { + var entity = new InvoiceEntity(); + entity.TxFee = Money.Coins(0.1m); + entity.Rate = 5000; + entity.Payments = new System.Collections.Generic.List(); + entity.ProductInformation = new ProductInformation() { Price = 5000 }; - Assert.Equal(Money.Coins(1.1m), entity.GetCryptoDue()); - Assert.Equal(Money.Coins(1.1m), entity.GetTotalCryptoDue()); + Assert.Equal(Money.Coins(1.1m), entity.GetCryptoDue()); + Assert.Equal(Money.Coins(1.1m), entity.GetTotalCryptoDue()); - entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.5m), new Key()) }); + entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.5m), new Key()) }); - //Since we need to spend one more txout, it should be 1.1 - 0,5 + 0.1 - Assert.Equal(Money.Coins(0.7m), entity.GetCryptoDue()); - Assert.Equal(Money.Coins(1.2m), entity.GetTotalCryptoDue()); + //Since we need to spend one more txout, it should be 1.1 - 0,5 + 0.1 + Assert.Equal(Money.Coins(0.7m), entity.GetCryptoDue()); + Assert.Equal(Money.Coins(1.2m), entity.GetTotalCryptoDue()); - entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.2m), new Key()) }); - Assert.Equal(Money.Coins(0.6m), entity.GetCryptoDue()); - Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); + entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.2m), new Key()) }); + Assert.Equal(Money.Coins(0.6m), entity.GetCryptoDue()); + Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); - entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.6m), new Key()) }); + entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.6m), new Key()) }); - Assert.Equal(Money.Zero, entity.GetCryptoDue()); - Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); + Assert.Equal(Money.Zero, entity.GetCryptoDue()); + Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); - entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.2m), new Key()) }); + entity.Payments.Add(new PaymentEntity() { Output = new TxOut(Money.Coins(0.2m), new Key()) }); - Assert.Equal(Money.Zero, entity.GetCryptoDue()); - Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); - } + Assert.Equal(Money.Zero, entity.GetCryptoDue()); + Assert.Equal(Money.Coins(1.3m), entity.GetTotalCryptoDue()); + } - [Fact] - public void CanPayUsingBIP70() - { - using(var tester = ServerTester.Create()) - { - tester.Start(); - var user = tester.NewAccount(); - user.GrantAccess(); - var invoice = user.BitPay.CreateInvoice(new Invoice() - { - Buyer = new Buyer() { email = "test@fwf.com" }, - Price = 5000.0, - Currency = "USD", - PosData = "posData", - OrderId = "orderId", - //RedirectURL = redirect + "redirect", - //NotificationURL = CallbackUri + "/notification", - ItemDesc = "Some description", - FullNotifications = true - }, Facade.Merchant); + [Fact] + public void CanPayUsingBIP70() + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + var user = tester.NewAccount(); + user.GrantAccess(); + var invoice = user.BitPay.CreateInvoice(new Invoice() + { + Buyer = new Buyer() { email = "test@fwf.com" }, + Price = 5000.0, + Currency = "USD", + PosData = "posData", + OrderId = "orderId", + //RedirectURL = redirect + "redirect", + //NotificationURL = CallbackUri + "/notification", + ItemDesc = "Some description", + FullNotifications = true + }, Facade.Merchant); - Assert.False(invoice.Refundable); + Assert.False(invoice.Refundable); - var url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP72); - var request = url.GetPaymentRequest(); - var payment = request.CreatePayment(); + var url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP72); + var request = url.GetPaymentRequest(); + var payment = request.CreatePayment(); - Transaction tx = new Transaction(); - tx.Outputs.AddRange(request.Details.Outputs.Select(o => new TxOut(o.Amount, o.Script))); - var cashCow = tester.ExplorerNode; - tx = cashCow.FundRawTransaction(tx).Transaction; - tx = cashCow.SignRawTransaction(tx); + Transaction tx = new Transaction(); + tx.Outputs.AddRange(request.Details.Outputs.Select(o => new TxOut(o.Amount, o.Script))); + var cashCow = tester.ExplorerNode; + tx = cashCow.FundRawTransaction(tx).Transaction; + tx = cashCow.SignRawTransaction(tx); - payment.Transactions.Add(tx); + payment.Transactions.Add(tx); - payment.RefundTo.Add(new PaymentOutput(Money.Coins(1.0m), new Key().ScriptPubKey)); - var ack = payment.SubmitPayment(); - Assert.NotNull(ack); + payment.RefundTo.Add(new PaymentOutput(Money.Coins(1.0m), new Key().ScriptPubKey)); + var ack = payment.SubmitPayment(); + Assert.NotNull(ack); - Eventually(() => - { - tester.SimulateCallback(url.Address); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("paid", localInvoice.Status); - Assert.True(localInvoice.Refundable); - }); - } - } + Eventually(() => + { + tester.SimulateCallback(url.Address); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("paid", localInvoice.Status); + Assert.True(localInvoice.Refundable); + }); + } + } - [Fact] - public void CanUseServerInitiatedPairingCode() - { - using(var tester = ServerTester.Create()) - { - tester.Start(); - var acc = tester.NewAccount(); - acc.Register(); - acc.CreateStore(); + [Fact] + public void CanUseServerInitiatedPairingCode() + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + var acc = tester.NewAccount(); + acc.Register(); + acc.CreateStore(); - var controller = tester.PayTester.GetController(acc.UserId); - var token = (RedirectToActionResult)controller.CreateToken(acc.StoreId, new Models.StoreViewModels.CreateTokenViewModel() - { - Facade = Facade.Merchant.ToString(), - Label = "bla", - PublicKey = null - }).GetAwaiter().GetResult(); + var controller = tester.PayTester.GetController(acc.UserId); + var token = (RedirectToActionResult)controller.CreateToken(acc.StoreId, new Models.StoreViewModels.CreateTokenViewModel() + { + Facade = Facade.Merchant.ToString(), + Label = "bla", + PublicKey = null + }).GetAwaiter().GetResult(); - var pairingCode = (string)token.RouteValues["pairingCode"]; + var pairingCode = (string)token.RouteValues["pairingCode"]; - acc.BitPay.AuthorizeClient(new PairingCode(pairingCode)).GetAwaiter().GetResult(); - Assert.True(acc.BitPay.TestAccess(Facade.Merchant)); - } - } + acc.BitPay.AuthorizeClient(new PairingCode(pairingCode)).GetAwaiter().GetResult(); + Assert.True(acc.BitPay.TestAccess(Facade.Merchant)); + } + } - [Fact] - public void CanSendIPN() - { - using(var callbackServer = new CustomServer()) - { - using(var tester = ServerTester.Create()) - { - tester.Start(); - var acc = tester.NewAccount(); - acc.GrantAccess(); - var invoice = acc.BitPay.CreateInvoice(new Invoice() - { - Price = 5.0, - Currency = "USD", - PosData = "posData", - OrderId = "orderId", - NotificationURL = callbackServer.GetUri().AbsoluteUri, - ItemDesc = "Some description", - FullNotifications = true - }); - BitcoinUrlBuilder url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP21); - tester.ExplorerNode.SendToAddress(url.Address, url.Amount); - Thread.Sleep(5000); - tester.SimulateCallback(url.Address); - callbackServer.ProcessNextRequest((ctx) => - { - var ipn = new StreamReader(ctx.Request.Body).ReadToEnd(); - JsonConvert.DeserializeObject(ipn); //can deserialize - }); - var invoice2 = acc.BitPay.GetInvoice(invoice.Id); - Assert.NotNull(invoice2); - } - } - } + [Fact] + public void CanSendIPN() + { + using (var callbackServer = new CustomServer()) + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + var acc = tester.NewAccount(); + acc.GrantAccess(); + var invoice = acc.BitPay.CreateInvoice(new Invoice() + { + Price = 5.0, + Currency = "USD", + PosData = "posData", + OrderId = "orderId", + NotificationURL = callbackServer.GetUri().AbsoluteUri, + ItemDesc = "Some description", + FullNotifications = true + }); + BitcoinUrlBuilder url = new BitcoinUrlBuilder(invoice.PaymentUrls.BIP21); + tester.ExplorerNode.SendToAddress(url.Address, url.Amount); + Thread.Sleep(5000); + tester.SimulateCallback(url.Address); + callbackServer.ProcessNextRequest((ctx) => + { + var ipn = new StreamReader(ctx.Request.Body).ReadToEnd(); + JsonConvert.DeserializeObject(ipn); //can deserialize + }); + var invoice2 = acc.BitPay.GetInvoice(invoice.Id); + Assert.NotNull(invoice2); + } + } + } - [Fact] - public void CantPairTwiceWithSamePubkey() - { - using(var tester = ServerTester.Create()) - { - tester.Start(); - var acc = tester.NewAccount(); - acc.Register(); - var store = acc.CreateStore(); - var pairingCode = acc.BitPay.RequestClientAuthorization("test", Facade.Merchant); - Assert.IsType(store.Pair(pairingCode.ToString(), acc.StoreId).GetAwaiter().GetResult()); + [Fact] + public void CantPairTwiceWithSamePubkey() + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + var acc = tester.NewAccount(); + acc.Register(); + var store = acc.CreateStore(); + var pairingCode = acc.BitPay.RequestClientAuthorization("test", Facade.Merchant); + Assert.IsType(store.Pair(pairingCode.ToString(), acc.StoreId).GetAwaiter().GetResult()); - pairingCode = acc.BitPay.RequestClientAuthorization("test1", Facade.Merchant); - var store2 = acc.CreateStore(); - store2.Pair(pairingCode.ToString(), store2.CreatedStoreId).GetAwaiter().GetResult(); - Assert.Contains(nameof(PairingResult.ReusedKey), store2.StatusMessage); - } - } + pairingCode = acc.BitPay.RequestClientAuthorization("test1", Facade.Merchant); + var store2 = acc.CreateStore(); + store2.Pair(pairingCode.ToString(), store2.CreatedStoreId).GetAwaiter().GetResult(); + Assert.Contains(nameof(PairingResult.ReusedKey), store2.StatusMessage); + } + } - [Fact] - public void InvoiceFlowThroughDifferentStatesCorrectly() - { - using(var tester = ServerTester.Create()) - { - tester.Start(); - var user = tester.NewAccount(); - Assert.False(user.BitPay.TestAccess(Facade.Merchant)); - user.GrantAccess(); - Assert.True(user.BitPay.TestAccess(Facade.Merchant)); - var invoice = user.BitPay.CreateInvoice(new Invoice() - { - Price = 5000.0, - Currency = "USD", - PosData = "posData", - OrderId = "orderId", - //RedirectURL = redirect + "redirect", - //NotificationURL = CallbackUri + "/notification", - ItemDesc = "Some description", - FullNotifications = true - }, Facade.Merchant); - var repo = tester.PayTester.GetService(); - var ctx = tester.PayTester.GetService().CreateContext(); - var textSearchResult = tester.PayTester.Runtime.InvoiceRepository.GetInvoices(new InvoiceQuery() - { - StoreId = user.StoreId, - TextSearch = invoice.OrderId - }).GetAwaiter().GetResult(); - Assert.Equal(1, textSearchResult.Length); - textSearchResult = tester.PayTester.Runtime.InvoiceRepository.GetInvoices(new InvoiceQuery() - { - StoreId = user.StoreId, - TextSearch = invoice.Id - }).GetAwaiter().GetResult(); + [Fact] + public void InvoiceFlowThroughDifferentStatesCorrectly() + { + using (var tester = ServerTester.Create()) + { + tester.Start(); + var user = tester.NewAccount(); + Assert.False(user.BitPay.TestAccess(Facade.Merchant)); + user.GrantAccess(); + Assert.True(user.BitPay.TestAccess(Facade.Merchant)); + var invoice = user.BitPay.CreateInvoice(new Invoice() + { + Price = 5000.0, + Currency = "USD", + PosData = "posData", + OrderId = "orderId", + //RedirectURL = redirect + "redirect", + //NotificationURL = CallbackUri + "/notification", + ItemDesc = "Some description", + FullNotifications = true + }, Facade.Merchant); + var repo = tester.PayTester.GetService(); + var ctx = tester.PayTester.GetService().CreateContext(); + var textSearchResult = tester.PayTester.Runtime.InvoiceRepository.GetInvoices(new InvoiceQuery() + { + StoreId = user.StoreId, + TextSearch = invoice.OrderId + }).GetAwaiter().GetResult(); + Assert.Equal(1, textSearchResult.Length); + textSearchResult = tester.PayTester.Runtime.InvoiceRepository.GetInvoices(new InvoiceQuery() + { + StoreId = user.StoreId, + TextSearch = invoice.Id + }).GetAwaiter().GetResult(); - Assert.Equal(1, textSearchResult.Length); + Assert.Equal(1, textSearchResult.Length); - invoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal(Money.Coins(0), invoice.BtcPaid); - Assert.Equal("new", invoice.Status); - Assert.Equal(false, (bool)((JValue)invoice.ExceptionStatus).Value); + invoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal(Money.Coins(0), invoice.BtcPaid); + Assert.Equal("new", invoice.Status); + Assert.Equal(false, (bool)((JValue)invoice.ExceptionStatus).Value); - Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime).Length); - Assert.Equal(0, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime + TimeSpan.FromDays(1)).Length); - Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5)).Length); - Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5), invoice.InvoiceTime.DateTime).Length); - Assert.Equal(0, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5), invoice.InvoiceTime.DateTime - TimeSpan.FromDays(1)).Length); + Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime).Length); + Assert.Equal(0, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime + TimeSpan.FromDays(1)).Length); + Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5)).Length); + Assert.Equal(1, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5), invoice.InvoiceTime.DateTime).Length); + Assert.Equal(0, user.BitPay.GetInvoices(invoice.InvoiceTime.DateTime - TimeSpan.FromDays(5), invoice.InvoiceTime.DateTime - TimeSpan.FromDays(1)).Length); - var firstPayment = Money.Coins(0.04m); + var firstPayment = Money.Coins(0.04m); - var txFee = Money.Zero; + var txFee = Money.Zero; - var rate = user.BitPay.GetRates(); + var rate = user.BitPay.GetRates(); - var cashCow = tester.ExplorerNode; + var cashCow = tester.ExplorerNode; - var invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); - var iii = ctx.AddressInvoices.ToArray(); - Assert.True(IsMapped(invoice, ctx)); - cashCow.SendToAddress(invoiceAddress, firstPayment); + var invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); + var iii = ctx.AddressInvoices.ToArray(); + Assert.True(IsMapped(invoice, ctx)); + cashCow.SendToAddress(invoiceAddress, firstPayment); - var invoiceEntity = repo.GetInvoice(null, invoice.Id, true).GetAwaiter().GetResult(); - Assert.Equal(1, invoiceEntity.HistoricalAddresses.Length); - Assert.Null(invoiceEntity.HistoricalAddresses[0].UnAssigned); + var invoiceEntity = repo.GetInvoice(null, invoice.Id, true).GetAwaiter().GetResult(); + Assert.Equal(1, invoiceEntity.HistoricalAddresses.Length); + Assert.Null(invoiceEntity.HistoricalAddresses[0].UnAssigned); - Money secondPayment = Money.Zero; + Money secondPayment = Money.Zero; - Eventually(() => - { - tester.SimulateCallback(invoiceAddress); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("new", localInvoice.Status); - Assert.Equal(firstPayment, localInvoice.BtcPaid); - txFee = localInvoice.BtcDue - invoice.BtcDue; - Assert.Equal("paidPartial", localInvoice.ExceptionStatus); - Assert.NotEqual(localInvoice.BitcoinAddress, invoice.BitcoinAddress); //New address - Assert.True(IsMapped(invoice, ctx)); - Assert.True(IsMapped(localInvoice, ctx)); + Eventually(() => + { + tester.SimulateCallback(invoiceAddress); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("new", localInvoice.Status); + Assert.Equal(firstPayment, localInvoice.BtcPaid); + txFee = localInvoice.BtcDue - invoice.BtcDue; + Assert.Equal("paidPartial", localInvoice.ExceptionStatus); + Assert.NotEqual(localInvoice.BitcoinAddress, invoice.BitcoinAddress); //New address + Assert.True(IsMapped(invoice, ctx)); + Assert.True(IsMapped(localInvoice, ctx)); - invoiceEntity = repo.GetInvoice(null, invoice.Id, true).GetAwaiter().GetResult(); - var historical1 = invoiceEntity.HistoricalAddresses.FirstOrDefault(h => h.Address == invoice.BitcoinAddress.ToString()); - Assert.NotNull(historical1.UnAssigned); - var historical2 = invoiceEntity.HistoricalAddresses.FirstOrDefault(h => h.Address == localInvoice.BitcoinAddress.ToString()); - Assert.Null(historical2.UnAssigned); - invoiceAddress = BitcoinAddress.Create(localInvoice.BitcoinAddress, cashCow.Network); - secondPayment = localInvoice.BtcDue; - }); + invoiceEntity = repo.GetInvoice(null, invoice.Id, true).GetAwaiter().GetResult(); + var historical1 = invoiceEntity.HistoricalAddresses.FirstOrDefault(h => h.Address == invoice.BitcoinAddress.ToString()); + Assert.NotNull(historical1.UnAssigned); + var historical2 = invoiceEntity.HistoricalAddresses.FirstOrDefault(h => h.Address == localInvoice.BitcoinAddress.ToString()); + Assert.Null(historical2.UnAssigned); + invoiceAddress = BitcoinAddress.Create(localInvoice.BitcoinAddress, cashCow.Network); + secondPayment = localInvoice.BtcDue; + }); - cashCow.SendToAddress(invoiceAddress, secondPayment); + cashCow.SendToAddress(invoiceAddress, secondPayment); - Eventually(() => - { - tester.SimulateCallback(invoiceAddress); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("paid", localInvoice.Status); - Assert.Equal(firstPayment + secondPayment, localInvoice.BtcPaid); - Assert.Equal(Money.Zero, localInvoice.BtcDue); - Assert.Equal(localInvoice.BitcoinAddress, invoiceAddress.ToString()); //no new address generated - Assert.True(IsMapped(localInvoice, ctx)); - Assert.Equal(false, (bool)((JValue)localInvoice.ExceptionStatus).Value); - }); + Eventually(() => + { + tester.SimulateCallback(invoiceAddress); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("paid", localInvoice.Status); + Assert.Equal(firstPayment + secondPayment, localInvoice.BtcPaid); + Assert.Equal(Money.Zero, localInvoice.BtcDue); + Assert.Equal(localInvoice.BitcoinAddress, invoiceAddress.ToString()); //no new address generated + Assert.True(IsMapped(localInvoice, ctx)); + Assert.Equal(false, (bool)((JValue)localInvoice.ExceptionStatus).Value); + }); - cashCow.Generate(1); //The user has medium speed settings, so 1 conf is enough to be confirmed + cashCow.Generate(1); //The user has medium speed settings, so 1 conf is enough to be confirmed - Eventually(() => - { - tester.SimulateCallback(); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("confirmed", localInvoice.Status); - }); + Eventually(() => + { + tester.SimulateCallback(); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("confirmed", localInvoice.Status); + }); - cashCow.Generate(5); //Now should be complete + cashCow.Generate(5); //Now should be complete - Eventually(() => - { - tester.SimulateCallback(); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("complete", localInvoice.Status); - }); + Eventually(() => + { + tester.SimulateCallback(); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("complete", localInvoice.Status); + }); - invoice = user.BitPay.CreateInvoice(new Invoice() - { - Price = 5000.0, - Currency = "USD", - PosData = "posData", - OrderId = "orderId", - //RedirectURL = redirect + "redirect", - //NotificationURL = CallbackUri + "/notification", - ItemDesc = "Some description", - FullNotifications = true - }, Facade.Merchant); - invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); + invoice = user.BitPay.CreateInvoice(new Invoice() + { + Price = 5000.0, + Currency = "USD", + PosData = "posData", + OrderId = "orderId", + //RedirectURL = redirect + "redirect", + //NotificationURL = CallbackUri + "/notification", + ItemDesc = "Some description", + FullNotifications = true + }, Facade.Merchant); + invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); - cashCow.SendToAddress(invoiceAddress, invoice.BtcDue + Money.Coins(1)); + cashCow.SendToAddress(invoiceAddress, invoice.BtcDue + Money.Coins(1)); - Eventually(() => - { - tester.SimulateCallback(invoiceAddress); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("paid", localInvoice.Status); - Assert.Equal(Money.Zero, localInvoice.BtcDue); - Assert.Equal("paidOver", (string)((JValue)localInvoice.ExceptionStatus).Value); - }); + Eventually(() => + { + tester.SimulateCallback(invoiceAddress); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("paid", localInvoice.Status); + Assert.Equal(Money.Zero, localInvoice.BtcDue); + Assert.Equal("paidOver", (string)((JValue)localInvoice.ExceptionStatus).Value); + }); - cashCow.Generate(1); + cashCow.Generate(1); - Eventually(() => - { - tester.SimulateCallback(); - var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); - Assert.Equal("confirmed", localInvoice.Status); - Assert.Equal(Money.Zero, localInvoice.BtcDue); - Assert.Equal("paidOver", (string)((JValue)localInvoice.ExceptionStatus).Value); - }); - } - } + Eventually(() => + { + tester.SimulateCallback(); + var localInvoice = user.BitPay.GetInvoice(invoice.Id, Facade.Merchant); + Assert.Equal("confirmed", localInvoice.Status); + Assert.Equal(Money.Zero, localInvoice.BtcDue); + Assert.Equal("paidOver", (string)((JValue)localInvoice.ExceptionStatus).Value); + }); + } + } - [Fact] - public void CheckRatesProvider() - { - var coinAverage = new CoinAverageRateProvider(); - var jpy = coinAverage.GetRateAsync("JPY").GetAwaiter().GetResult(); - var jpy2 = new BitpayRateProvider(new Bitpay(new Key(), new Uri("https://bitpay.com/"))).GetRateAsync("JPY").GetAwaiter().GetResult(); + [Fact] + public void CheckRatesProvider() + { + var coinAverage = new CoinAverageRateProvider(); + var jpy = coinAverage.GetRateAsync("JPY").GetAwaiter().GetResult(); + var jpy2 = new BitpayRateProvider(new Bitpay(new Key(), new Uri("https://bitpay.com/"))).GetRateAsync("JPY").GetAwaiter().GetResult(); - var cached = new CachedRateProvider(coinAverage, new MemoryCache(new MemoryCacheOptions() { ExpirationScanFrequency = TimeSpan.FromSeconds(1.0) })); - cached.CacheSpan = TimeSpan.FromSeconds(10); - var a = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); - var b = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); - //Manually check that cache get hit after 10 sec - var c = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); - } + var cached = new CachedRateProvider(coinAverage, new MemoryCache(new MemoryCacheOptions() { ExpirationScanFrequency = TimeSpan.FromSeconds(1.0) })); + cached.CacheSpan = TimeSpan.FromSeconds(10); + var a = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); + var b = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); + //Manually check that cache get hit after 10 sec + var c = cached.GetRateAsync("JPY").GetAwaiter().GetResult(); + } - private static bool IsMapped(Invoice invoice, ApplicationDbContext ctx) - { - var h = BitcoinAddress.Create(invoice.BitcoinAddress).ScriptPubKey.Hash.ToString(); - return ctx.AddressInvoices.FirstOrDefault(i => i.InvoiceDataId == invoice.Id && i.Address == h) != null; - } + private static bool IsMapped(Invoice invoice, ApplicationDbContext ctx) + { + var h = BitcoinAddress.Create(invoice.BitcoinAddress).ScriptPubKey.Hash.ToString(); + return ctx.AddressInvoices.FirstOrDefault(i => i.InvoiceDataId == invoice.Id && i.Address == h) != null; + } - private void Eventually(Action act) - { - CancellationTokenSource cts = new CancellationTokenSource(10000); - while(true) - { - try - { - act(); - break; - } - catch(XunitException) when(!cts.Token.IsCancellationRequested) - { - cts.Token.WaitHandle.WaitOne(500); - } - } - } - } + private void Eventually(Action act) + { + CancellationTokenSource cts = new CancellationTokenSource(10000); + while (true) + { + try + { + act(); + break; + } + catch (XunitException) when (!cts.Token.IsCancellationRequested) + { + cts.Token.WaitHandle.WaitOne(500); + } + } + } + } } diff --git a/BTCPayServer.Tests/UnitTestPeusa.cs b/BTCPayServer.Tests/UnitTestPeusa.cs index 363f0a3d5..83bcf4358 100644 --- a/BTCPayServer.Tests/UnitTestPeusa.cs +++ b/BTCPayServer.Tests/UnitTestPeusa.cs @@ -8,43 +8,43 @@ using Xunit; namespace BTCPayServer.Tests { - // Helper class for testing functionality and generating data needed during coding/debuging + // Helper class for testing functionality and generating data needed during coding/debuging public class UnitTestPeusa { - // Unit test that generates temorary checkout Bitpay page - // https://forkbitpay.slack.com/archives/C7M093Z55/p1508293682000217 - [Fact] - public void BitpayCheckout() - { - var key = new Key(Encoders.Hex.DecodeData("7b70a06f35562873e3dcb46005ed0fe78e1991ad906e56adaaafa40ba861e056")); - var url = new Uri("https://test.bitpay.com/"); - var btcpay = new Bitpay(key, url); - var invoice = btcpay.CreateInvoice(new Invoice() - { + // Unit test that generates temorary checkout Bitpay page + // https://forkbitpay.slack.com/archives/C7M093Z55/p1508293682000217 + [Fact] + public void BitpayCheckout() + { + var key = new Key(Encoders.Hex.DecodeData("7b70a06f35562873e3dcb46005ed0fe78e1991ad906e56adaaafa40ba861e056")); + var url = new Uri("https://test.bitpay.com/"); + var btcpay = new Bitpay(key, url); + var invoice = btcpay.CreateInvoice(new Invoice() + { - Price = 5.0, - Currency = "USD", - PosData = "posData", - OrderId = "cdfd8a5f-6928-4c3b-ba9b-ddf438029e73", - ItemDesc = "Hello from the otherside" - }, Facade.Merchant); + Price = 5.0, + Currency = "USD", + PosData = "posData", + OrderId = "cdfd8a5f-6928-4c3b-ba9b-ddf438029e73", + ItemDesc = "Hello from the otherside" + }, Facade.Merchant); - // go to invoice.Url - Console.WriteLine(invoice.Url); - } + // go to invoice.Url + Console.WriteLine(invoice.Url); + } - // Generating Extended public key to use on http://localhost:14142/stores/{storeId} - [Fact] - public void GeneratePubkey() - { - var network = Network.RegTest; + // Generating Extended public key to use on http://localhost:14142/stores/{storeId} + [Fact] + public void GeneratePubkey() + { + var network = Network.RegTest; - ExtKey masterKey = new ExtKey(); - Console.WriteLine("Master key : " + masterKey.ToString(network)); - ExtPubKey masterPubKey = masterKey.Neuter(); + ExtKey masterKey = new ExtKey(); + Console.WriteLine("Master key : " + masterKey.ToString(network)); + ExtPubKey masterPubKey = masterKey.Neuter(); - ExtPubKey pubkey = masterPubKey.Derive(0); - Console.WriteLine("PubKey " + 0 + " : " + pubkey.ToString(network)); - } + ExtPubKey pubkey = masterPubKey.Derive(0); + Console.WriteLine("PubKey " + 0 + " : " + pubkey.ToString(network)); + } } } diff --git a/BTCPayServer.Tests/Utils.cs b/BTCPayServer.Tests/Utils.cs index f16eca59d..6e23ba1a0 100644 --- a/BTCPayServer.Tests/Utils.cs +++ b/BTCPayServer.Tests/Utils.cs @@ -10,54 +10,54 @@ namespace BTCPayServer.Tests { public class Utils { - public static int FreeTcpPort() - { - TcpListener l = new TcpListener(IPAddress.Loopback, 0); - l.Start(); - int port = ((IPEndPoint)l.LocalEndpoint).Port; - l.Stop(); - return port; - } + public static int FreeTcpPort() + { + TcpListener l = new TcpListener(IPAddress.Loopback, 0); + l.Start(); + int port = ((IPEndPoint)l.LocalEndpoint).Port; + l.Stop(); + return port; + } - // http://stackoverflow.com/a/14933880/2061103 - public static void DeleteDirectory(string destinationDir) - { - const int magicDust = 10; - for(var gnomes = 1; gnomes <= magicDust; gnomes++) - { - try - { - Directory.Delete(destinationDir, true); - } - catch(DirectoryNotFoundException) - { - return; // good! - } - catch(IOException) - { - if(gnomes == magicDust) - throw; - // System.IO.IOException: The directory is not empty - System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes); + // http://stackoverflow.com/a/14933880/2061103 + public static void DeleteDirectory(string destinationDir) + { + const int magicDust = 10; + for (var gnomes = 1; gnomes <= magicDust; gnomes++) + { + try + { + Directory.Delete(destinationDir, true); + } + catch (DirectoryNotFoundException) + { + return; // good! + } + catch (IOException) + { + if (gnomes == magicDust) + throw; + // System.IO.IOException: The directory is not empty + System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes); - // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic - Thread.Sleep(100); - continue; - } - catch(UnauthorizedAccessException) - { - if(gnomes == magicDust) - throw; - // Wait, maybe another software make us authorized a little later - System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes); + // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic + Thread.Sleep(100); + continue; + } + catch (UnauthorizedAccessException) + { + if (gnomes == magicDust) + throw; + // Wait, maybe another software make us authorized a little later + System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes); - // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic - Thread.Sleep(100); - continue; - } - return; - } - // depending on your use case, consider throwing an exception here - } - } + // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic + Thread.Sleep(100); + continue; + } + return; + } + // depending on your use case, consider throwing an exception here + } + } } diff --git a/BTCPayServer/Authentication/BitIdentity.cs b/BTCPayServer/Authentication/BitIdentity.cs index db3f46e9d..1857b9161 100644 --- a/BTCPayServer/Authentication/BitIdentity.cs +++ b/BTCPayServer/Authentication/BitIdentity.cs @@ -9,27 +9,27 @@ namespace BTCPayServer.Authentication { public class BitIdentity : IIdentity { - public BitIdentity(PubKey key) - { - PubKey = key; - _Name = Encoders.Base58Check.EncodeData(Encoders.Hex.DecodeData("0f02" + key.Hash.ToString())); - SIN = NBitpayClient.Extensions.BitIdExtensions.GetBitIDSIN(key); - } - string _Name; + public BitIdentity(PubKey key) + { + PubKey = key; + _Name = Encoders.Base58Check.EncodeData(Encoders.Hex.DecodeData("0f02" + key.Hash.ToString())); + SIN = NBitpayClient.Extensions.BitIdExtensions.GetBitIDSIN(key); + } + string _Name; - public string SIN - { - get; - } - public PubKey PubKey - { - get; - } + public string SIN + { + get; + } + public PubKey PubKey + { + get; + } - public string AuthenticationType => "BitID"; + public string AuthenticationType => "BitID"; - public bool IsAuthenticated => true; + public bool IsAuthenticated => true; - public string Name => _Name; - } + public string Name => _Name; + } } diff --git a/BTCPayServer/Authentication/BitToken.cs b/BTCPayServer/Authentication/BitToken.cs index e933801db..d6a6ffd8d 100644 --- a/BTCPayServer/Authentication/BitToken.cs +++ b/BTCPayServer/Authentication/BitToken.cs @@ -8,43 +8,43 @@ namespace BTCPayServer.Authentication { public class BitTokenEntity { - public string Facade - { - get; set; - } - public string Value - { - get; set; - } - public string StoreId - { - get; set; - } - public string Label - { - get; set; - } - public DateTimeOffset PairingTime - { - get; set; - } - public string SIN - { - get; - set; - } + public string Facade + { + get; set; + } + public string Value + { + get; set; + } + public string StoreId + { + get; set; + } + public string Label + { + get; set; + } + public DateTimeOffset PairingTime + { + get; set; + } + public string SIN + { + get; + set; + } - public BitTokenEntity Clone(Facade facade) - { - return new BitTokenEntity() - { - Label = Label, - Facade = Facade, - StoreId = StoreId, - PairingTime = PairingTime, - SIN = SIN, - Value = Value - }; - } - } + public BitTokenEntity Clone(Facade facade) + { + return new BitTokenEntity() + { + Label = Label, + Facade = Facade, + StoreId = StoreId, + PairingTime = PairingTime, + SIN = SIN, + Value = Value + }; + } + } } diff --git a/BTCPayServer/Authentication/PairingCodeEntity.cs b/BTCPayServer/Authentication/PairingCodeEntity.cs index 0afbf8958..226dbd87b 100644 --- a/BTCPayServer/Authentication/PairingCodeEntity.cs +++ b/BTCPayServer/Authentication/PairingCodeEntity.cs @@ -4,47 +4,47 @@ using System.Text; namespace BTCPayServer.Authentication { - public class PairingCodeEntity - { - public string Id - { - get; - set; - } - public string Facade - { - get; - set; - } - public string Label - { - get; - set; - } - public string SIN - { - get; - set; - } - public DateTimeOffset CreatedTime - { - get; - set; - } - public DateTimeOffset Expiration - { - get; - set; - } - public string TokenValue - { - get; - set; - } + public class PairingCodeEntity + { + public string Id + { + get; + set; + } + public string Facade + { + get; + set; + } + public string Label + { + get; + set; + } + public string SIN + { + get; + set; + } + public DateTimeOffset CreatedTime + { + get; + set; + } + public DateTimeOffset Expiration + { + get; + set; + } + public string TokenValue + { + get; + set; + } - public bool IsExpired() - { - return DateTimeOffset.UtcNow > Expiration; - } - } + public bool IsExpired() + { + return DateTimeOffset.UtcNow > Expiration; + } + } } diff --git a/BTCPayServer/Authentication/TokenRepository.cs b/BTCPayServer/Authentication/TokenRepository.cs index d2a74d638..c9662cb31 100644 --- a/BTCPayServer/Authentication/TokenRepository.cs +++ b/BTCPayServer/Authentication/TokenRepository.cs @@ -13,196 +13,196 @@ using System.Linq; namespace BTCPayServer.Authentication { - public enum PairingResult - { - Partial, - Complete, - ReusedKey, - Expired - } + public enum PairingResult + { + Partial, + Complete, + ReusedKey, + Expired + } - public class TokenRepository - { - ApplicationDbContextFactory _Factory; - public TokenRepository(ApplicationDbContextFactory dbFactory) - { - if(dbFactory == null) - throw new ArgumentNullException(nameof(dbFactory)); - _Factory = dbFactory; - } + public class TokenRepository + { + ApplicationDbContextFactory _Factory; + public TokenRepository(ApplicationDbContextFactory dbFactory) + { + if (dbFactory == null) + throw new ArgumentNullException(nameof(dbFactory)); + _Factory = dbFactory; + } - public async Task GetTokens(string sin) - { - using(var ctx = _Factory.CreateContext()) - { - return (await ctx.PairedSINData - .Where(p => p.SIN == sin) - .ToListAsync()) - .Select(p => CreateTokenEntity(p)) - .ToArray(); - } - } + public async Task GetTokens(string sin) + { + using (var ctx = _Factory.CreateContext()) + { + return (await ctx.PairedSINData + .Where(p => p.SIN == sin) + .ToListAsync()) + .Select(p => CreateTokenEntity(p)) + .ToArray(); + } + } - private BitTokenEntity CreateTokenEntity(PairedSINData data) - { - return new BitTokenEntity() - { - Label = data.Label, - Facade = data.Facade, - Value = data.Id, - SIN = data.SIN, - PairingTime = data.PairingTime, - StoreId = data.StoreDataId - }; - } + private BitTokenEntity CreateTokenEntity(PairedSINData data) + { + return new BitTokenEntity() + { + Label = data.Label, + Facade = data.Facade, + Value = data.Id, + SIN = data.SIN, + PairingTime = data.PairingTime, + StoreId = data.StoreDataId + }; + } - public async Task CreatePairingCodeAsync() - { - string pairingCodeId = null; - while(true) - { - pairingCodeId = Encoders.Base58.EncodeData(RandomUtils.GetBytes(6)); - if(pairingCodeId.Length == 7) // woocommerce plugin check for exactly 7 digits - break; - } - using(var ctx = _Factory.CreateContext()) - { - var now = DateTime.UtcNow; - var expiration = DateTime.UtcNow + TimeSpan.FromMinutes(15); - await ctx.PairingCodes.AddAsync(new PairingCodeData() - { - Id = pairingCodeId, - DateCreated = now, - Expiration = expiration, - TokenValue = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)) - }); - await ctx.SaveChangesAsync(); - } - return pairingCodeId; - } + public async Task CreatePairingCodeAsync() + { + string pairingCodeId = null; + while (true) + { + pairingCodeId = Encoders.Base58.EncodeData(RandomUtils.GetBytes(6)); + if (pairingCodeId.Length == 7) // woocommerce plugin check for exactly 7 digits + break; + } + using (var ctx = _Factory.CreateContext()) + { + var now = DateTime.UtcNow; + var expiration = DateTime.UtcNow + TimeSpan.FromMinutes(15); + await ctx.PairingCodes.AddAsync(new PairingCodeData() + { + Id = pairingCodeId, + DateCreated = now, + Expiration = expiration, + TokenValue = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)) + }); + await ctx.SaveChangesAsync(); + } + return pairingCodeId; + } - public async Task UpdatePairingCode(PairingCodeEntity pairingCodeEntity) - { - using(var ctx = _Factory.CreateContext()) - { - var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeEntity.Id); - pairingCode.Label = pairingCodeEntity.Label; - pairingCode.Facade = pairingCodeEntity.Facade; - await ctx.SaveChangesAsync(); - return CreatePairingCodeEntity(pairingCode); - } - } + public async Task UpdatePairingCode(PairingCodeEntity pairingCodeEntity) + { + using (var ctx = _Factory.CreateContext()) + { + var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeEntity.Id); + pairingCode.Label = pairingCodeEntity.Label; + pairingCode.Facade = pairingCodeEntity.Facade; + await ctx.SaveChangesAsync(); + return CreatePairingCodeEntity(pairingCode); + } + } - public async Task PairWithStoreAsync(string pairingCodeId, string storeId) - { - using(var ctx = _Factory.CreateContext()) - { - var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeId); - if(pairingCode == null || pairingCode.Expiration < DateTimeOffset.UtcNow) - return PairingResult.Expired; - pairingCode.StoreDataId = storeId; - var result = await ActivateIfComplete(ctx, pairingCode); - await ctx.SaveChangesAsync(); - return result; - } - } + public async Task PairWithStoreAsync(string pairingCodeId, string storeId) + { + using (var ctx = _Factory.CreateContext()) + { + var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeId); + if (pairingCode == null || pairingCode.Expiration < DateTimeOffset.UtcNow) + return PairingResult.Expired; + pairingCode.StoreDataId = storeId; + var result = await ActivateIfComplete(ctx, pairingCode); + await ctx.SaveChangesAsync(); + return result; + } + } - public async Task PairWithSINAsync(string pairingCodeId, string sin) - { - using(var ctx = _Factory.CreateContext()) - { - var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeId); - if(pairingCode == null || pairingCode.Expiration < DateTimeOffset.UtcNow) - return PairingResult.Expired; - pairingCode.SIN = sin; - var result = await ActivateIfComplete(ctx, pairingCode); - await ctx.SaveChangesAsync(); - return result; - } - } + public async Task PairWithSINAsync(string pairingCodeId, string sin) + { + using (var ctx = _Factory.CreateContext()) + { + var pairingCode = await ctx.PairingCodes.FindAsync(pairingCodeId); + if (pairingCode == null || pairingCode.Expiration < DateTimeOffset.UtcNow) + return PairingResult.Expired; + pairingCode.SIN = sin; + var result = await ActivateIfComplete(ctx, pairingCode); + await ctx.SaveChangesAsync(); + return result; + } + } - private async Task ActivateIfComplete(ApplicationDbContext ctx, PairingCodeData pairingCode) - { - if(!string.IsNullOrEmpty(pairingCode.SIN) && !string.IsNullOrEmpty(pairingCode.StoreDataId)) - { - ctx.PairingCodes.Remove(pairingCode); + private async Task ActivateIfComplete(ApplicationDbContext ctx, PairingCodeData pairingCode) + { + if (!string.IsNullOrEmpty(pairingCode.SIN) && !string.IsNullOrEmpty(pairingCode.StoreDataId)) + { + ctx.PairingCodes.Remove(pairingCode); - // Can have concurrency issues... but no harm can be done - var alreadyUsed = await ctx.PairedSINData.Where(p => p.SIN == pairingCode.SIN && p.StoreDataId != pairingCode.StoreDataId).AnyAsync(); - if(alreadyUsed) - return PairingResult.ReusedKey; - await ctx.PairedSINData.AddAsync(new PairedSINData() - { - Id = pairingCode.TokenValue, - PairingTime = DateTime.UtcNow, - Facade = pairingCode.Facade, - Label = pairingCode.Label, - StoreDataId = pairingCode.StoreDataId, - SIN = pairingCode.SIN - }); - return PairingResult.Complete; - } - return PairingResult.Partial; - } + // Can have concurrency issues... but no harm can be done + var alreadyUsed = await ctx.PairedSINData.Where(p => p.SIN == pairingCode.SIN && p.StoreDataId != pairingCode.StoreDataId).AnyAsync(); + if (alreadyUsed) + return PairingResult.ReusedKey; + await ctx.PairedSINData.AddAsync(new PairedSINData() + { + Id = pairingCode.TokenValue, + PairingTime = DateTime.UtcNow, + Facade = pairingCode.Facade, + Label = pairingCode.Label, + StoreDataId = pairingCode.StoreDataId, + SIN = pairingCode.SIN + }); + return PairingResult.Complete; + } + return PairingResult.Partial; + } - public async Task GetTokensByStoreIdAsync(string storeId) - { - using(var ctx = _Factory.CreateContext()) - { - return (await ctx.PairedSINData.Where(p => p.StoreDataId == storeId).ToListAsync()) - .Select(c => CreateTokenEntity(c)) - .ToArray(); - } - } + public async Task GetTokensByStoreIdAsync(string storeId) + { + using (var ctx = _Factory.CreateContext()) + { + return (await ctx.PairedSINData.Where(p => p.StoreDataId == storeId).ToListAsync()) + .Select(c => CreateTokenEntity(c)) + .ToArray(); + } + } - public async Task GetPairingAsync(string pairingCode) - { - using(var ctx = _Factory.CreateContext()) - { - return CreatePairingCodeEntity(await ctx.PairingCodes.FindAsync(pairingCode)); - } - } + public async Task GetPairingAsync(string pairingCode) + { + using (var ctx = _Factory.CreateContext()) + { + return CreatePairingCodeEntity(await ctx.PairingCodes.FindAsync(pairingCode)); + } + } - private PairingCodeEntity CreatePairingCodeEntity(PairingCodeData data) - { - if(data == null) - return null; - return new PairingCodeEntity() - { - Facade = data.Facade, - Id = data.Id, - Label = data.Label, - Expiration = data.Expiration, - CreatedTime = data.DateCreated, - TokenValue = data.TokenValue, - SIN = data.SIN - }; - } + private PairingCodeEntity CreatePairingCodeEntity(PairingCodeData data) + { + if (data == null) + return null; + return new PairingCodeEntity() + { + Facade = data.Facade, + Id = data.Id, + Label = data.Label, + Expiration = data.Expiration, + CreatedTime = data.DateCreated, + TokenValue = data.TokenValue, + SIN = data.SIN + }; + } - public async Task DeleteToken(string tokenId) - { - using(var ctx = _Factory.CreateContext()) - { - var token = await ctx.PairedSINData.FindAsync(tokenId); - if(token == null) - return false; - ctx.PairedSINData.Remove(token); - await ctx.SaveChangesAsync(); - return true; - } - } + public async Task DeleteToken(string tokenId) + { + using (var ctx = _Factory.CreateContext()) + { + var token = await ctx.PairedSINData.FindAsync(tokenId); + if (token == null) + return false; + ctx.PairedSINData.Remove(token); + await ctx.SaveChangesAsync(); + return true; + } + } - public async Task GetToken(string tokenId) - { - using(var ctx = _Factory.CreateContext()) - { - var token = await ctx.PairedSINData.FindAsync(tokenId); - return CreateTokenEntity(token); - } - } + public async Task GetToken(string tokenId) + { + using (var ctx = _Factory.CreateContext()) + { + var token = await ctx.PairedSINData.FindAsync(tokenId); + return CreateTokenEntity(token); + } + } - } + } } diff --git a/BTCPayServer/BitpayHttpException.cs b/BTCPayServer/BitpayHttpException.cs index 7e4baa463..0474257fd 100644 --- a/BTCPayServer/BitpayHttpException.cs +++ b/BTCPayServer/BitpayHttpException.cs @@ -4,15 +4,15 @@ using System.Text; namespace BTCPayServer { - public class BitpayHttpException : Exception - { - public BitpayHttpException(int code, string message) : base(message) - { - StatusCode = code; - } - public int StatusCode - { - get; set; - } - } + public class BitpayHttpException : Exception + { + public BitpayHttpException(int code, string message) : base(message) + { + StatusCode = code; + } + public int StatusCode + { + get; set; + } + } } diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs index 2e0eb5e65..b2b917f24 100644 --- a/BTCPayServer/Configuration/BTCPayServerOptions.cs +++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs @@ -12,61 +12,61 @@ using Microsoft.Extensions.Configuration; namespace BTCPayServer.Configuration { - public class BTCPayServerOptions - { - public Network Network - { - get; set; - } - public Uri Explorer - { - get; set; - } + public class BTCPayServerOptions + { + public Network Network + { + get; set; + } + public Uri Explorer + { + get; set; + } - public string CookieFile - { - get; set; - } - public string ConfigurationFile - { - get; - private set; - } - public string DataDir - { - get; - private set; - } - public List Listen - { - get; - set; - } + public string CookieFile + { + get; set; + } + public string ConfigurationFile + { + get; + private set; + } + public string DataDir + { + get; + private set; + } + public List Listen + { + get; + set; + } - public void LoadArgs(IConfiguration conf) - { - var networkInfo = DefaultConfiguration.GetNetwork(conf); - Network = networkInfo?.Network; - if(Network == null) - throw new ConfigException("Invalid network"); + public void LoadArgs(IConfiguration conf) + { + var networkInfo = DefaultConfiguration.GetNetwork(conf); + Network = networkInfo?.Network; + if (Network == null) + throw new ConfigException("Invalid network"); - DataDir = conf.GetOrDefault("datadir", networkInfo.DefaultDataDirectory); - Logs.Configuration.LogInformation("Network: " + Network); + DataDir = conf.GetOrDefault("datadir", networkInfo.DefaultDataDirectory); + Logs.Configuration.LogInformation("Network: " + Network); - Explorer = conf.GetOrDefault("explorer.url", networkInfo.DefaultExplorerUrl); - CookieFile = conf.GetOrDefault("explorer.cookiefile", networkInfo.DefaultExplorerCookieFile); - RequireHttps = conf.GetOrDefault("requirehttps", false); - PostgresConnectionString = conf.GetOrDefault("postgres", null); - } + Explorer = conf.GetOrDefault("explorer.url", networkInfo.DefaultExplorerUrl); + CookieFile = conf.GetOrDefault("explorer.cookiefile", networkInfo.DefaultExplorerCookieFile); + RequireHttps = conf.GetOrDefault("requirehttps", false); + PostgresConnectionString = conf.GetOrDefault("postgres", null); + } - public bool RequireHttps - { - get; set; - } - public string PostgresConnectionString - { - get; - set; - } - } + public bool RequireHttps + { + get; set; + } + public string PostgresConnectionString + { + get; + set; + } + } } diff --git a/BTCPayServer/Configuration/BTCPayServerRuntime.cs b/BTCPayServer/Configuration/BTCPayServerRuntime.cs index 7ef6b61af..b238ca2e2 100644 --- a/BTCPayServer/Configuration/BTCPayServerRuntime.cs +++ b/BTCPayServer/Configuration/BTCPayServerRuntime.cs @@ -18,96 +18,96 @@ using BTCPayServer.Services.Wallets; namespace BTCPayServer.Configuration { - public class BTCPayServerRuntime : IDisposable - { - public ExplorerClient Explorer - { - get; - private set; - } + public class BTCPayServerRuntime : IDisposable + { + public ExplorerClient Explorer + { + get; + private set; + } - public void Configure(BTCPayServerOptions opts) - { - ConfigureAsync(opts).GetAwaiter().GetResult(); - } - public async Task ConfigureAsync(BTCPayServerOptions opts) - { - Network = opts.Network; - Explorer = new ExplorerClient(opts.Network, opts.Explorer); + public void Configure(BTCPayServerOptions opts) + { + ConfigureAsync(opts).GetAwaiter().GetResult(); + } + public async Task ConfigureAsync(BTCPayServerOptions opts) + { + Network = opts.Network; + Explorer = new ExplorerClient(opts.Network, opts.Explorer); - if(!Explorer.SetCookieAuth(opts.CookieFile)) - Explorer.SetNoAuth(); + if (!Explorer.SetCookieAuth(opts.CookieFile)) + Explorer.SetNoAuth(); - CancellationTokenSource cts = new CancellationTokenSource(30000); - try - { - Logs.Configuration.LogInformation("Trying to connect to explorer " + Explorer.Address.AbsoluteUri); - await Explorer.WaitServerStartedAsync(cts.Token).ConfigureAwait(false); - Logs.Configuration.LogInformation("Connection successfull"); - } - catch(Exception ex) - { - throw new ConfigException($"Could not connect to NBXplorer, {ex.Message}"); - } - DBreezeEngine db = new DBreezeEngine(CreateDBPath(opts, "TokensDB")); - _Resources.Add(db); + CancellationTokenSource cts = new CancellationTokenSource(30000); + try + { + Logs.Configuration.LogInformation("Trying to connect to explorer " + Explorer.Address.AbsoluteUri); + await Explorer.WaitServerStartedAsync(cts.Token).ConfigureAwait(false); + Logs.Configuration.LogInformation("Connection successfull"); + } + catch (Exception ex) + { + throw new ConfigException($"Could not connect to NBXplorer, {ex.Message}"); + } + DBreezeEngine db = new DBreezeEngine(CreateDBPath(opts, "TokensDB")); + _Resources.Add(db); - db = new DBreezeEngine(CreateDBPath(opts, "InvoiceDB")); - _Resources.Add(db); + db = new DBreezeEngine(CreateDBPath(opts, "InvoiceDB")); + _Resources.Add(db); - ApplicationDbContextFactory dbContext = null; - if(opts.PostgresConnectionString == null) - { - var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); - Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); - dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); - } - else - { - Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); - dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); - } - DBFactory = dbContext; - InvoiceRepository = new InvoiceRepository(dbContext, db, Network); - } + ApplicationDbContextFactory dbContext = null; + if (opts.PostgresConnectionString == null) + { + var connStr = "Data Source=" + Path.Combine(opts.DataDir, "sqllite.db"); + Logs.Configuration.LogInformation($"SQLite DB used ({connStr})"); + dbContext = new ApplicationDbContextFactory(DatabaseType.Sqlite, connStr); + } + else + { + Logs.Configuration.LogInformation($"Postgres DB used ({opts.PostgresConnectionString})"); + dbContext = new ApplicationDbContextFactory(DatabaseType.Postgres, opts.PostgresConnectionString); + } + DBFactory = dbContext; + InvoiceRepository = new InvoiceRepository(dbContext, db, Network); + } - private static string CreateDBPath(BTCPayServerOptions opts, string name) - { - var dbpath = Path.Combine(opts.DataDir, name); - if(!Directory.Exists(dbpath)) - Directory.CreateDirectory(dbpath); - return dbpath; - } + private static string CreateDBPath(BTCPayServerOptions opts, string name) + { + var dbpath = Path.Combine(opts.DataDir, name); + if (!Directory.Exists(dbpath)) + Directory.CreateDirectory(dbpath); + return dbpath; + } - List _Resources = new List(); + List _Resources = new List(); - public void Dispose() - { - lock(_Resources) - { - foreach(var r in _Resources) - { - r.Dispose(); - } - _Resources.Clear(); - } - } + public void Dispose() + { + lock (_Resources) + { + foreach (var r in _Resources) + { + r.Dispose(); + } + _Resources.Clear(); + } + } - public Network Network - { - get; - private set; - } - public InvoiceRepository InvoiceRepository - { - get; - set; - } - public ApplicationDbContextFactory DBFactory - { - get; - set; - } - } + public Network Network + { + get; + private set; + } + public InvoiceRepository InvoiceRepository + { + get; + set; + } + public ApplicationDbContextFactory DBFactory + { + get; + set; + } + } } diff --git a/BTCPayServer/Configuration/ConfigException.cs b/BTCPayServer/Configuration/ConfigException.cs index 116dc2c61..3a3869727 100644 --- a/BTCPayServer/Configuration/ConfigException.cs +++ b/BTCPayServer/Configuration/ConfigException.cs @@ -5,11 +5,11 @@ using System.Threading.Tasks; namespace BTCPayServer.Configuration { - public class ConfigException : Exception - { - public ConfigException(string message) : base(message) - { + public class ConfigException : Exception + { + public ConfigException(string message) : base(message) + { - } - } + } + } } diff --git a/BTCPayServer/Configuration/ConfigurationExtensions.cs b/BTCPayServer/Configuration/ConfigurationExtensions.cs index c509c0c27..0dbd725a9 100644 --- a/BTCPayServer/Configuration/ConfigurationExtensions.cs +++ b/BTCPayServer/Configuration/ConfigurationExtensions.cs @@ -9,44 +9,44 @@ using Microsoft.Extensions.Primitives; namespace BTCPayServer.Configuration { - public static class ConfigurationExtensions - { - public static T GetOrDefault(this IConfiguration configuration, string key, T defaultValue) - { - var str = configuration[key] ?? configuration[key.Replace(".", string.Empty)]; - if(str == null) - return defaultValue; - if(typeof(T) == typeof(bool)) - { - var trueValues = new[] { "1", "true" }; - var falseValues = new[] { "0", "false" }; - if(trueValues.Contains(str, StringComparer.OrdinalIgnoreCase)) - return (T)(object)true; - if(falseValues.Contains(str, StringComparer.OrdinalIgnoreCase)) - return (T)(object)false; - throw new FormatException(); - } - else if(typeof(T) == typeof(Uri)) - return (T)(object)new Uri(str, UriKind.Absolute); - else if(typeof(T) == typeof(string)) - return (T)(object)str; - else if(typeof(T) == typeof(IPEndPoint)) - { - var separator = str.LastIndexOf(":"); - if(separator == -1) - throw new FormatException(); - var ip = str.Substring(0, separator); - var port = str.Substring(separator + 1); - return (T)(object)new IPEndPoint(IPAddress.Parse(ip), int.Parse(port)); - } - else if(typeof(T) == typeof(int)) - { - return (T)(object)int.Parse(str, CultureInfo.InvariantCulture); - } - else - { - throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name); - } - } - } + public static class ConfigurationExtensions + { + public static T GetOrDefault(this IConfiguration configuration, string key, T defaultValue) + { + var str = configuration[key] ?? configuration[key.Replace(".", string.Empty)]; + if (str == null) + return defaultValue; + if (typeof(T) == typeof(bool)) + { + var trueValues = new[] { "1", "true" }; + var falseValues = new[] { "0", "false" }; + if (trueValues.Contains(str, StringComparer.OrdinalIgnoreCase)) + return (T)(object)true; + if (falseValues.Contains(str, StringComparer.OrdinalIgnoreCase)) + return (T)(object)false; + throw new FormatException(); + } + else if (typeof(T) == typeof(Uri)) + return (T)(object)new Uri(str, UriKind.Absolute); + else if (typeof(T) == typeof(string)) + return (T)(object)str; + else if (typeof(T) == typeof(IPEndPoint)) + { + var separator = str.LastIndexOf(":"); + if (separator == -1) + throw new FormatException(); + var ip = str.Substring(0, separator); + var port = str.Substring(separator + 1); + return (T)(object)new IPEndPoint(IPAddress.Parse(ip), int.Parse(port)); + } + else if (typeof(T) == typeof(int)) + { + return (T)(object)int.Parse(str, CultureInfo.InvariantCulture); + } + else + { + throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name); + } + } + } } diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index b041fbe40..e6d39db52 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -13,88 +13,88 @@ using CommandLine; namespace BTCPayServer.Configuration { - public class DefaultConfiguration : StandardConfiguration.DefaultConfiguration - { - protected override CommandLineApplication CreateCommandLineApplicationCore() - { - CommandLineApplication app = new CommandLineApplication(true) - { - FullName = "NBXplorer\r\nLightweight block explorer for tracking HD wallets", - Name = "NBXplorer" - }; - app.HelpOption("-? | -h | --help"); - app.Option("-n | --network", $"Set the network among ({NetworkInformation.ToStringAll()}) (default: {Network.Main.ToString()})", CommandOptionType.SingleValue); - app.Option("--testnet | -testnet", $"Use testnet", CommandOptionType.BoolValue); - app.Option("--regtest | -regtest", $"Use regtest", CommandOptionType.BoolValue); - app.Option("--requirehttps", $"Will redirect to https version of the website (default: false)", CommandOptionType.BoolValue); - app.Option("--postgres", $"Connection string to postgres database (default: sqlite is used)", CommandOptionType.SingleValue); - app.Option("--explorerurl", $"Url of the NBxplorer (default: : Default setting of NBXplorer for the network)", CommandOptionType.SingleValue); - app.Option("--explorercookiefile", $"Path to the cookie file (default: Default setting of NBXplorer for the network)", CommandOptionType.SingleValue); + public class DefaultConfiguration : StandardConfiguration.DefaultConfiguration + { + protected override CommandLineApplication CreateCommandLineApplicationCore() + { + CommandLineApplication app = new CommandLineApplication(true) + { + FullName = "NBXplorer\r\nLightweight block explorer for tracking HD wallets", + Name = "NBXplorer" + }; + app.HelpOption("-? | -h | --help"); + app.Option("-n | --network", $"Set the network among ({NetworkInformation.ToStringAll()}) (default: {Network.Main.ToString()})", CommandOptionType.SingleValue); + app.Option("--testnet | -testnet", $"Use testnet", CommandOptionType.BoolValue); + app.Option("--regtest | -regtest", $"Use regtest", CommandOptionType.BoolValue); + app.Option("--requirehttps", $"Will redirect to https version of the website (default: false)", CommandOptionType.BoolValue); + app.Option("--postgres", $"Connection string to postgres database (default: sqlite is used)", CommandOptionType.SingleValue); + app.Option("--explorerurl", $"Url of the NBxplorer (default: : Default setting of NBXplorer for the network)", CommandOptionType.SingleValue); + app.Option("--explorercookiefile", $"Path to the cookie file (default: Default setting of NBXplorer for the network)", CommandOptionType.SingleValue); - return app; - } + return app; + } - public override string EnvironmentVariablePrefix => "BTCPAY_"; + public override string EnvironmentVariablePrefix => "BTCPAY_"; - protected override string GetDefaultDataDir(IConfiguration conf) - { - return GetNetwork(conf).DefaultDataDirectory; - } + protected override string GetDefaultDataDir(IConfiguration conf) + { + return GetNetwork(conf).DefaultDataDirectory; + } - protected override string GetDefaultConfigurationFile(IConfiguration conf) - { - var network = GetNetwork(conf); - var dataDir = conf["datadir"]; - if(dataDir == null) - return network.DefaultConfigurationFile; - var fileName = Path.GetFileName(network.DefaultConfigurationFile); - return Path.Combine(dataDir, fileName); - } + protected override string GetDefaultConfigurationFile(IConfiguration conf) + { + var network = GetNetwork(conf); + var dataDir = conf["datadir"]; + if (dataDir == null) + return network.DefaultConfigurationFile; + var fileName = Path.GetFileName(network.DefaultConfigurationFile); + return Path.Combine(dataDir, fileName); + } - public static NetworkInformation GetNetwork(IConfiguration conf) - { - var network = conf.GetOrDefault("network", null); - if(network != null) - { - var info = NetworkInformation.GetNetworkByName(network); - if(info == null) - throw new ConfigException($"Invalid network name {network}"); - return info; - } + public static NetworkInformation GetNetwork(IConfiguration conf) + { + var network = conf.GetOrDefault("network", null); + if (network != null) + { + var info = NetworkInformation.GetNetworkByName(network); + if (info == null) + throw new ConfigException($"Invalid network name {network}"); + return info; + } - var net = conf.GetOrDefault("regtest", false) ? Network.RegTest : - conf.GetOrDefault("testnet", false) ? Network.TestNet : Network.Main; + var net = conf.GetOrDefault("regtest", false) ? Network.RegTest : + conf.GetOrDefault("testnet", false) ? Network.TestNet : Network.Main; - return NetworkInformation.GetNetworkByName(net.Name); - } + return NetworkInformation.GetNetworkByName(net.Name); + } - protected override string GetDefaultConfigurationFileTemplate(IConfiguration conf) - { - var network = GetNetwork(conf); - StringBuilder builder = new StringBuilder(); - builder.AppendLine("### Global settings ###"); - builder.AppendLine("#testnet=0"); - builder.AppendLine("#regtest=0"); - builder.AppendLine(); - builder.AppendLine("### Server settings ###"); - builder.AppendLine("#requirehttps=0"); - builder.AppendLine("#port=" + network.DefaultPort); - builder.AppendLine("#bind=127.0.0.1"); - builder.AppendLine(); - builder.AppendLine("### Database ###"); - builder.AppendLine("#postgres=User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;"); - builder.AppendLine(); - builder.AppendLine("### NBXplorer settings ###"); - builder.AppendLine("#explorer.url=" + network.DefaultExplorerUrl.AbsoluteUri); - builder.AppendLine("#explorer.cookiefile=" + network.DefaultExplorerCookieFile); - return builder.ToString(); - } + protected override string GetDefaultConfigurationFileTemplate(IConfiguration conf) + { + var network = GetNetwork(conf); + StringBuilder builder = new StringBuilder(); + builder.AppendLine("### Global settings ###"); + builder.AppendLine("#testnet=0"); + builder.AppendLine("#regtest=0"); + builder.AppendLine(); + builder.AppendLine("### Server settings ###"); + builder.AppendLine("#requirehttps=0"); + builder.AppendLine("#port=" + network.DefaultPort); + builder.AppendLine("#bind=127.0.0.1"); + builder.AppendLine(); + builder.AppendLine("### Database ###"); + builder.AppendLine("#postgres=User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;"); + builder.AppendLine(); + builder.AppendLine("### NBXplorer settings ###"); + builder.AppendLine("#explorer.url=" + network.DefaultExplorerUrl.AbsoluteUri); + builder.AppendLine("#explorer.cookiefile=" + network.DefaultExplorerCookieFile); + return builder.ToString(); + } - protected override IPEndPoint GetDefaultEndpoint(IConfiguration conf) - { - return new IPEndPoint(IPAddress.Parse("127.0.0.1"), GetNetwork(conf).DefaultPort); - } - } + protected override IPEndPoint GetDefaultEndpoint(IConfiguration conf) + { + return new IPEndPoint(IPAddress.Parse("127.0.0.1"), GetNetwork(conf).DefaultPort); + } + } } diff --git a/BTCPayServer/Configuration/NetworkInformation.cs b/BTCPayServer/Configuration/NetworkInformation.cs index 13f8bd5e6..7e6d591fd 100644 --- a/BTCPayServer/Configuration/NetworkInformation.cs +++ b/BTCPayServer/Configuration/NetworkInformation.cs @@ -8,96 +8,96 @@ using System.Threading.Tasks; namespace BTCPayServer.Configuration { - public class NetworkInformation - { - static NetworkInformation() - { - _Networks = new Dictionary(); - foreach(var network in Network.GetNetworks()) - { - NetworkInformation info = new NetworkInformation(); - info.DefaultDataDirectory = StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", network.Name); - info.DefaultConfigurationFile = Path.Combine(info.DefaultDataDirectory, "settings.config"); - info.DefaultExplorerCookieFile = Path.Combine(StandardConfiguration.DefaultDataDirectory.GetDirectory("NBXplorer", network.Name, false), ".cookie"); - info.Network = network; - info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24446", UriKind.Absolute); - info.DefaultPort = 23002; - _Networks.Add(network.Name, info); - if(network == Network.Main) - { - info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24444", UriKind.Absolute); - Main = info; - info.DefaultPort = 23000; - } - if(network == Network.TestNet) - { - info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24445", UriKind.Absolute); - info.DefaultPort = 23001; - } - } - } + public class NetworkInformation + { + static NetworkInformation() + { + _Networks = new Dictionary(); + foreach (var network in Network.GetNetworks()) + { + NetworkInformation info = new NetworkInformation(); + info.DefaultDataDirectory = StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", network.Name); + info.DefaultConfigurationFile = Path.Combine(info.DefaultDataDirectory, "settings.config"); + info.DefaultExplorerCookieFile = Path.Combine(StandardConfiguration.DefaultDataDirectory.GetDirectory("NBXplorer", network.Name, false), ".cookie"); + info.Network = network; + info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24446", UriKind.Absolute); + info.DefaultPort = 23002; + _Networks.Add(network.Name, info); + if (network == Network.Main) + { + info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24444", UriKind.Absolute); + Main = info; + info.DefaultPort = 23000; + } + if (network == Network.TestNet) + { + info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24445", UriKind.Absolute); + info.DefaultPort = 23001; + } + } + } - static Dictionary _Networks; - public static NetworkInformation GetNetworkByName(string name) - { - var value = _Networks.TryGet(name); - if(value != null) - return value; + static Dictionary _Networks; + public static NetworkInformation GetNetworkByName(string name) + { + var value = _Networks.TryGet(name); + if (value != null) + return value; - //Maybe alias ? - var network = Network.GetNetwork(name); - if(network != null) - { - value = _Networks.TryGet(network.Name); - if(value != null) - return value; - } - return null; - } + //Maybe alias ? + var network = Network.GetNetwork(name); + if (network != null) + { + value = _Networks.TryGet(network.Name); + if (value != null) + return value; + } + return null; + } - public static NetworkInformation Main - { - get; - set; - } - public Network Network - { - get; set; - } - public string DefaultConfigurationFile - { - get; - set; - } - public string DefaultDataDirectory - { - get; - set; - } - public Uri DefaultExplorerUrl - { - get; - internal set; - } - public int DefaultPort - { - get; - private set; - } - public string DefaultExplorerCookieFile - { - get; - internal set; - } + public static NetworkInformation Main + { + get; + set; + } + public Network Network + { + get; set; + } + public string DefaultConfigurationFile + { + get; + set; + } + public string DefaultDataDirectory + { + get; + set; + } + public Uri DefaultExplorerUrl + { + get; + internal set; + } + public int DefaultPort + { + get; + private set; + } + public string DefaultExplorerCookieFile + { + get; + internal set; + } - public override string ToString() - { - return Network.ToString(); - } + public override string ToString() + { + return Network.ToString(); + } - public static string ToStringAll() - { - return string.Join(", ", _Networks.Select(n => n.Key).ToArray()); - } - } + public static string ToStringAll() + { + return string.Join(", ", _Networks.Select(n => n.Key).ToArray()); + } + } } diff --git a/BTCPayServer/Controllers/AccessTokenController.cs b/BTCPayServer/Controllers/AccessTokenController.cs index 9d4d588b0..18726a78d 100644 --- a/BTCPayServer/Controllers/AccessTokenController.cs +++ b/BTCPayServer/Controllers/AccessTokenController.cs @@ -12,79 +12,79 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - public class AccessTokenController : Controller - { - TokenRepository _TokenRepository; - public AccessTokenController(TokenRepository tokenRepository) - { - _TokenRepository = tokenRepository ?? throw new ArgumentNullException(nameof(tokenRepository)); - } - [HttpGet] - [Route("tokens")] - public async Task Tokens() - { - var tokens = await _TokenRepository.GetTokens(this.GetBitIdentity().SIN); - return new GetTokensResponse(tokens); - } + public class AccessTokenController : Controller + { + TokenRepository _TokenRepository; + public AccessTokenController(TokenRepository tokenRepository) + { + _TokenRepository = tokenRepository ?? throw new ArgumentNullException(nameof(tokenRepository)); + } + [HttpGet] + [Route("tokens")] + public async Task Tokens() + { + var tokens = await _TokenRepository.GetTokens(this.GetBitIdentity().SIN); + return new GetTokensResponse(tokens); + } - [HttpPost] - [Route("tokens")] - public async Task>> Tokens([FromBody] TokenRequest request) - { - PairingCodeEntity pairingEntity = null; - if(string.IsNullOrEmpty(request.PairingCode)) - { - if(string.IsNullOrEmpty(request.Id) || !NBitpayClient.Extensions.BitIdExtensions.ValidateSIN(request.Id)) - throw new BitpayHttpException(400, "'id' property is required"); - if(string.IsNullOrEmpty(request.Facade)) - throw new BitpayHttpException(400, "'facade' property is required"); + [HttpPost] + [Route("tokens")] + public async Task>> Tokens([FromBody] TokenRequest request) + { + PairingCodeEntity pairingEntity = null; + if (string.IsNullOrEmpty(request.PairingCode)) + { + if (string.IsNullOrEmpty(request.Id) || !NBitpayClient.Extensions.BitIdExtensions.ValidateSIN(request.Id)) + throw new BitpayHttpException(400, "'id' property is required"); + if (string.IsNullOrEmpty(request.Facade)) + throw new BitpayHttpException(400, "'facade' property is required"); - var pairingCode = await _TokenRepository.CreatePairingCodeAsync(); - await _TokenRepository.PairWithSINAsync(pairingCode, request.Id); - pairingEntity = await _TokenRepository.UpdatePairingCode(new PairingCodeEntity() - { - Id = pairingCode, - Facade = request.Facade, - Label = request.Label - }); + var pairingCode = await _TokenRepository.CreatePairingCodeAsync(); + await _TokenRepository.PairWithSINAsync(pairingCode, request.Id); + pairingEntity = await _TokenRepository.UpdatePairingCode(new PairingCodeEntity() + { + Id = pairingCode, + Facade = request.Facade, + Label = request.Label + }); - } - else - { - var sin = this.GetBitIdentity(false)?.SIN ?? request.Id; - if(string.IsNullOrEmpty(request.Id) || !NBitpayClient.Extensions.BitIdExtensions.ValidateSIN(request.Id)) - throw new BitpayHttpException(400, "'id' property is required, alternatively, use BitId"); + } + else + { + var sin = this.GetBitIdentity(false)?.SIN ?? request.Id; + if (string.IsNullOrEmpty(request.Id) || !NBitpayClient.Extensions.BitIdExtensions.ValidateSIN(request.Id)) + throw new BitpayHttpException(400, "'id' property is required, alternatively, use BitId"); - pairingEntity = await _TokenRepository.GetPairingAsync(request.PairingCode); - if(pairingEntity == null) - throw new BitpayHttpException(404, "The specified pairingCode is not found"); - pairingEntity.SIN = sin; + pairingEntity = await _TokenRepository.GetPairingAsync(request.PairingCode); + if (pairingEntity == null) + throw new BitpayHttpException(404, "The specified pairingCode is not found"); + pairingEntity.SIN = sin; - if(string.IsNullOrEmpty(pairingEntity.Label) && !string.IsNullOrEmpty(request.Label)) - { - pairingEntity.Label = request.Label; - await _TokenRepository.UpdatePairingCode(pairingEntity); - } + if (string.IsNullOrEmpty(pairingEntity.Label) && !string.IsNullOrEmpty(request.Label)) + { + pairingEntity.Label = request.Label; + await _TokenRepository.UpdatePairingCode(pairingEntity); + } - var result = await _TokenRepository.PairWithSINAsync(request.PairingCode, sin); - if(result != PairingResult.Complete && result != PairingResult.Partial) - throw new BitpayHttpException(400, $"Error while pairing ({result})"); - - } + var result = await _TokenRepository.PairWithSINAsync(request.PairingCode, sin); + if (result != PairingResult.Complete && result != PairingResult.Partial) + throw new BitpayHttpException(400, $"Error while pairing ({result})"); - var pairingCodes = new List - { - new PairingCodeResponse() - { - PairingCode = pairingEntity.Id, - PairingExpiration = pairingEntity.Expiration, - DateCreated = pairingEntity.CreatedTime, - Facade = pairingEntity.Facade, - Token = pairingEntity.TokenValue, - Label = pairingEntity.Label - } - }; - return DataWrapper.Create(pairingCodes); - } - } + } + + var pairingCodes = new List + { + new PairingCodeResponse() + { + PairingCode = pairingEntity.Id, + PairingExpiration = pairingEntity.Expiration, + DateCreated = pairingEntity.CreatedTime, + Facade = pairingEntity.Facade, + Token = pairingEntity.TokenValue, + Label = pairingEntity.Label + } + }; + return DataWrapper.Create(pairingCodes); + } + } } diff --git a/BTCPayServer/Controllers/AccountController.cs b/BTCPayServer/Controllers/AccountController.cs index 176bc10ef..55237399d 100644 --- a/BTCPayServer/Controllers/AccountController.cs +++ b/BTCPayServer/Controllers/AccountController.cs @@ -18,503 +18,503 @@ using BTCPayServer.Services.Stores; namespace BTCPayServer.Controllers { - [Authorize] - [Route("[controller]/[action]")] - public class AccountController : Controller - { - private readonly UserManager _userManager; - private readonly SignInManager _signInManager; - private readonly IEmailSender _emailSender; - private readonly ILogger _logger; - StoreRepository storeRepository; - RoleManager _RoleManager; - SettingsRepository _SettingsRepository; + [Authorize] + [Route("[controller]/[action]")] + public class AccountController : Controller + { + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly IEmailSender _emailSender; + private readonly ILogger _logger; + StoreRepository storeRepository; + RoleManager _RoleManager; + SettingsRepository _SettingsRepository; - public AccountController( - UserManager userManager, - RoleManager roleManager, - StoreRepository storeRepository, - SignInManager signInManager, - IEmailSender emailSender, - SettingsRepository settingsRepository, - ILogger logger) - { - this.storeRepository = storeRepository; - _userManager = userManager; - _signInManager = signInManager; - _emailSender = emailSender; - _logger = logger; - _RoleManager = roleManager; - _SettingsRepository = settingsRepository; - } + public AccountController( + UserManager userManager, + RoleManager roleManager, + StoreRepository storeRepository, + SignInManager signInManager, + IEmailSender emailSender, + SettingsRepository settingsRepository, + ILogger logger) + { + this.storeRepository = storeRepository; + _userManager = userManager; + _signInManager = signInManager; + _emailSender = emailSender; + _logger = logger; + _RoleManager = roleManager; + _SettingsRepository = settingsRepository; + } - [TempData] - public string ErrorMessage - { - get; set; - } + [TempData] + public string ErrorMessage + { + get; set; + } - [HttpGet] - [AllowAnonymous] - public async Task Login(string returnUrl = null) - { - // Clear the existing external cookie to ensure a clean login process - await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); + [HttpGet] + [AllowAnonymous] + public async Task Login(string returnUrl = null) + { + // Clear the existing external cookie to ensure a clean login process + await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - ViewData["ReturnUrl"] = returnUrl; - return View(); - } + ViewData["ReturnUrl"] = returnUrl; + return View(); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task Login(LoginViewModel model, string returnUrl = null) - { - ViewData["ReturnUrl"] = returnUrl; - if(ModelState.IsValid) - { - // Require the user to have a confirmed email before they can log on. - var user = await _userManager.FindByEmailAsync(model.Email); - if(user != null) - { - if(user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user)) - { - ModelState.AddModelError(string.Empty, - "You must have a confirmed email to log in."); - return View(model); - } - } - // This doesn't count login failures towards account lockout - // To enable password failures to trigger account lockout, set lockoutOnFailure: true - var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); - if(result.Succeeded) - { - _logger.LogInformation("User logged in."); - return RedirectToLocal(returnUrl); - } - if(result.RequiresTwoFactor) - { - return RedirectToAction(nameof(LoginWith2fa), new - { - returnUrl, - model.RememberMe - }); - } - if(result.IsLockedOut) - { - _logger.LogWarning("User account locked out."); - return RedirectToAction(nameof(Lockout)); - } - else - { - ModelState.AddModelError(string.Empty, "Invalid login attempt."); - return View(model); - } - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Login(LoginViewModel model, string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + if (ModelState.IsValid) + { + // Require the user to have a confirmed email before they can log on. + var user = await _userManager.FindByEmailAsync(model.Email); + if (user != null) + { + if (user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user)) + { + ModelState.AddModelError(string.Empty, + "You must have a confirmed email to log in."); + return View(model); + } + } + // This doesn't count login failures towards account lockout + // To enable password failures to trigger account lockout, set lockoutOnFailure: true + var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); + if (result.Succeeded) + { + _logger.LogInformation("User logged in."); + return RedirectToLocal(returnUrl); + } + if (result.RequiresTwoFactor) + { + return RedirectToAction(nameof(LoginWith2fa), new + { + returnUrl, + model.RememberMe + }); + } + if (result.IsLockedOut) + { + _logger.LogWarning("User account locked out."); + return RedirectToAction(nameof(Lockout)); + } + else + { + ModelState.AddModelError(string.Empty, "Invalid login attempt."); + return View(model); + } + } - // If we got this far, something failed, redisplay form - return View(model); - } + // If we got this far, something failed, redisplay form + return View(model); + } - [HttpGet] - [AllowAnonymous] - public async Task LoginWith2fa(bool rememberMe, string returnUrl = null) - { - // Ensure the user has gone through the username & password screen first - var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + [HttpGet] + [AllowAnonymous] + public async Task LoginWith2fa(bool rememberMe, string returnUrl = null) + { + // Ensure the user has gone through the username & password screen first + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if(user == null) - { - throw new ApplicationException($"Unable to load two-factor authentication user."); - } + if (user == null) + { + throw new ApplicationException($"Unable to load two-factor authentication user."); + } - var model = new LoginWith2faViewModel { RememberMe = rememberMe }; - ViewData["ReturnUrl"] = returnUrl; + var model = new LoginWith2faViewModel { RememberMe = rememberMe }; + ViewData["ReturnUrl"] = returnUrl; - return View(model); - } + return View(model); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null) - { - if(!ModelState.IsValid) - { - return View(model); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null) + { + if (!ModelState.IsValid) + { + return View(model); + } - var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } - var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); + var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); - var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine); + var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine); - if(result.Succeeded) - { - _logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id); - return RedirectToLocal(returnUrl); - } - else if(result.IsLockedOut) - { - _logger.LogWarning("User with ID {UserId} account locked out.", user.Id); - return RedirectToAction(nameof(Lockout)); - } - else - { - _logger.LogWarning("Invalid authenticator code entered for user with ID {UserId}.", user.Id); - ModelState.AddModelError(string.Empty, "Invalid authenticator code."); - return View(); - } - } + if (result.Succeeded) + { + _logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id); + return RedirectToLocal(returnUrl); + } + else if (result.IsLockedOut) + { + _logger.LogWarning("User with ID {UserId} account locked out.", user.Id); + return RedirectToAction(nameof(Lockout)); + } + else + { + _logger.LogWarning("Invalid authenticator code entered for user with ID {UserId}.", user.Id); + ModelState.AddModelError(string.Empty, "Invalid authenticator code."); + return View(); + } + } - [HttpGet] - [AllowAnonymous] - public async Task LoginWithRecoveryCode(string returnUrl = null) - { - // Ensure the user has gone through the username & password screen first - var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if(user == null) - { - throw new ApplicationException($"Unable to load two-factor authentication user."); - } + [HttpGet] + [AllowAnonymous] + public async Task LoginWithRecoveryCode(string returnUrl = null) + { + // Ensure the user has gone through the username & password screen first + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + throw new ApplicationException($"Unable to load two-factor authentication user."); + } - ViewData["ReturnUrl"] = returnUrl; + ViewData["ReturnUrl"] = returnUrl; - return View(); - } + return View(); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task LoginWithRecoveryCode(LoginWithRecoveryCodeViewModel model, string returnUrl = null) - { - if(!ModelState.IsValid) - { - return View(model); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task LoginWithRecoveryCode(LoginWithRecoveryCodeViewModel model, string returnUrl = null) + { + if (!ModelState.IsValid) + { + return View(model); + } - var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if(user == null) - { - throw new ApplicationException($"Unable to load two-factor authentication user."); - } + var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); + if (user == null) + { + throw new ApplicationException($"Unable to load two-factor authentication user."); + } - var recoveryCode = model.RecoveryCode.Replace(" ", string.Empty); + var recoveryCode = model.RecoveryCode.Replace(" ", string.Empty); - var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode); + var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode); - if(result.Succeeded) - { - _logger.LogInformation("User with ID {UserId} logged in with a recovery code.", user.Id); - return RedirectToLocal(returnUrl); - } - if(result.IsLockedOut) - { - _logger.LogWarning("User with ID {UserId} account locked out.", user.Id); - return RedirectToAction(nameof(Lockout)); - } - else - { - _logger.LogWarning("Invalid recovery code entered for user with ID {UserId}", user.Id); - ModelState.AddModelError(string.Empty, "Invalid recovery code entered."); - return View(); - } - } + if (result.Succeeded) + { + _logger.LogInformation("User with ID {UserId} logged in with a recovery code.", user.Id); + return RedirectToLocal(returnUrl); + } + if (result.IsLockedOut) + { + _logger.LogWarning("User with ID {UserId} account locked out.", user.Id); + return RedirectToAction(nameof(Lockout)); + } + else + { + _logger.LogWarning("Invalid recovery code entered for user with ID {UserId}", user.Id); + ModelState.AddModelError(string.Empty, "Invalid recovery code entered."); + return View(); + } + } - [HttpGet] - [AllowAnonymous] - public IActionResult Lockout() - { - return View(); - } + [HttpGet] + [AllowAnonymous] + public IActionResult Lockout() + { + return View(); + } - [HttpGet] - [AllowAnonymous] - public IActionResult Register(string returnUrl = null) - { - ViewData["ReturnUrl"] = returnUrl; - return View(); - } + [HttpGet] + [AllowAnonymous] + public IActionResult Register(string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + return View(); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task Register(RegisterViewModel model, string returnUrl = null) - { - ViewData["ReturnUrl"] = returnUrl; - if(ModelState.IsValid) - { - var policies = await _SettingsRepository.GetSettingAsync() ?? new PoliciesSettings(); - var user = new ApplicationUser { UserName = model.Email, Email = model.Email, RequiresEmailConfirmation = policies.RequiresConfirmedEmail }; - var result = await _userManager.CreateAsync(user, model.Password); - if(result.Succeeded) - { - _logger.LogInformation("User created a new account with password."); + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Register(RegisterViewModel model, string returnUrl = null) + { + ViewData["ReturnUrl"] = returnUrl; + if (ModelState.IsValid) + { + var policies = await _SettingsRepository.GetSettingAsync() ?? new PoliciesSettings(); + var user = new ApplicationUser { UserName = model.Email, Email = model.Email, RequiresEmailConfirmation = policies.RequiresConfirmedEmail }; + var result = await _userManager.CreateAsync(user, model.Password); + if (result.Succeeded) + { + _logger.LogInformation("User created a new account with password."); - var admin = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin); - if(admin.Count == 0) - { - _logger.LogInformation("Admin created."); - await _RoleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin)); - await _userManager.AddToRoleAsync(user, Roles.ServerAdmin); - } + var admin = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin); + if (admin.Count == 0) + { + _logger.LogInformation("Admin created."); + await _RoleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin)); + await _userManager.AddToRoleAsync(user, Roles.ServerAdmin); + } - var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); - var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme); - RegisteredUserId = user.Id; - await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl); - _logger.LogInformation("User created a new account with password."); - if(!policies.RequiresConfirmedEmail) - { - await _signInManager.SignInAsync(user, isPersistent: false); - return RedirectToLocal(returnUrl); - } - else - { - TempData["StatusMessage"] = "Account created, please confirm your email"; - return View(); - } - } - AddErrors(result); - } + var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme); + RegisteredUserId = user.Id; + await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl); + _logger.LogInformation("User created a new account with password."); + if (!policies.RequiresConfirmedEmail) + { + await _signInManager.SignInAsync(user, isPersistent: false); + return RedirectToLocal(returnUrl); + } + else + { + TempData["StatusMessage"] = "Account created, please confirm your email"; + return View(); + } + } + AddErrors(result); + } - // If we got this far, something failed, redisplay form - return View(model); - } + // If we got this far, something failed, redisplay form + return View(model); + } - /// - /// Test property - /// - public string RegisteredUserId - { - get; set; - } + /// + /// Test property + /// + public string RegisteredUserId + { + get; set; + } - [HttpGet] - public async Task Logout() - { - await _signInManager.SignOutAsync(); - _logger.LogInformation("User logged out."); - return RedirectToAction(nameof(HomeController.Index), "Home"); - } + [HttpGet] + public async Task Logout() + { + await _signInManager.SignOutAsync(); + _logger.LogInformation("User logged out."); + return RedirectToAction(nameof(HomeController.Index), "Home"); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public IActionResult ExternalLogin(string provider, string returnUrl = null) - { - // Request a redirect to the external login provider. - var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new - { - returnUrl - }); - var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); - return Challenge(properties, provider); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public IActionResult ExternalLogin(string provider, string returnUrl = null) + { + // Request a redirect to the external login provider. + var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new + { + returnUrl + }); + var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); + return Challenge(properties, provider); + } - [HttpGet] - [AllowAnonymous] - public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null) - { - if(remoteError != null) - { - ErrorMessage = $"Error from external provider: {remoteError}"; - return RedirectToAction(nameof(Login)); - } - var info = await _signInManager.GetExternalLoginInfoAsync(); - if(info == null) - { - return RedirectToAction(nameof(Login)); - } + [HttpGet] + [AllowAnonymous] + public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null) + { + if (remoteError != null) + { + ErrorMessage = $"Error from external provider: {remoteError}"; + return RedirectToAction(nameof(Login)); + } + var info = await _signInManager.GetExternalLoginInfoAsync(); + if (info == null) + { + return RedirectToAction(nameof(Login)); + } - // Sign in the user with this external login provider if the user already has a login. - var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true); - if(result.Succeeded) - { - _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider); - return RedirectToLocal(returnUrl); - } - if(result.IsLockedOut) - { - return RedirectToAction(nameof(Lockout)); - } - else - { - // If the user does not have an account, then ask the user to create an account. - ViewData["ReturnUrl"] = returnUrl; - ViewData["LoginProvider"] = info.LoginProvider; - var email = info.Principal.FindFirstValue(ClaimTypes.Email); - return View("ExternalLogin", new ExternalLoginViewModel { Email = email }); - } - } + // Sign in the user with this external login provider if the user already has a login. + var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true); + if (result.Succeeded) + { + _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider); + return RedirectToLocal(returnUrl); + } + if (result.IsLockedOut) + { + return RedirectToAction(nameof(Lockout)); + } + else + { + // If the user does not have an account, then ask the user to create an account. + ViewData["ReturnUrl"] = returnUrl; + ViewData["LoginProvider"] = info.LoginProvider; + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + return View("ExternalLogin", new ExternalLoginViewModel { Email = email }); + } + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null) - { - if(ModelState.IsValid) - { - // Get the information about the user from the external login provider - var info = await _signInManager.GetExternalLoginInfoAsync(); - if(info == null) - { - throw new ApplicationException("Error loading external login information during confirmation."); - } - var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; - var result = await _userManager.CreateAsync(user); - if(result.Succeeded) - { - result = await _userManager.AddLoginAsync(user, info); - if(result.Succeeded) - { - await _signInManager.SignInAsync(user, isPersistent: false); - _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); - return RedirectToLocal(returnUrl); - } - } - AddErrors(result); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ExternalLoginConfirmation(ExternalLoginViewModel model, string returnUrl = null) + { + if (ModelState.IsValid) + { + // Get the information about the user from the external login provider + var info = await _signInManager.GetExternalLoginInfoAsync(); + if (info == null) + { + throw new ApplicationException("Error loading external login information during confirmation."); + } + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await _userManager.CreateAsync(user); + if (result.Succeeded) + { + result = await _userManager.AddLoginAsync(user, info); + if (result.Succeeded) + { + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); + return RedirectToLocal(returnUrl); + } + } + AddErrors(result); + } - ViewData["ReturnUrl"] = returnUrl; - return View(nameof(ExternalLogin), model); - } + ViewData["ReturnUrl"] = returnUrl; + return View(nameof(ExternalLogin), model); + } - [HttpGet] - [AllowAnonymous] - public async Task ConfirmEmail(string userId, string code) - { - if(userId == null || code == null) - { - return RedirectToAction(nameof(HomeController.Index), "Home"); - } - var user = await _userManager.FindByIdAsync(userId); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{userId}'."); - } - var result = await _userManager.ConfirmEmailAsync(user, code); - return View(result.Succeeded ? "ConfirmEmail" : "Error"); - } + [HttpGet] + [AllowAnonymous] + public async Task ConfirmEmail(string userId, string code) + { + if (userId == null || code == null) + { + return RedirectToAction(nameof(HomeController.Index), "Home"); + } + var user = await _userManager.FindByIdAsync(userId); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{userId}'."); + } + var result = await _userManager.ConfirmEmailAsync(user, code); + return View(result.Succeeded ? "ConfirmEmail" : "Error"); + } - [HttpGet] - [AllowAnonymous] - public IActionResult ForgotPassword() - { - return View(); - } + [HttpGet] + [AllowAnonymous] + public IActionResult ForgotPassword() + { + return View(); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ForgotPassword(ForgotPasswordViewModel model) - { - if(ModelState.IsValid) - { - var user = await _userManager.FindByEmailAsync(model.Email); - if(user == null || !(await _userManager.IsEmailConfirmedAsync(user))) - { - // Don't reveal that the user does not exist or is not confirmed - return RedirectToAction(nameof(ForgotPasswordConfirmation)); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ForgotPassword(ForgotPasswordViewModel model) + { + if (ModelState.IsValid) + { + var user = await _userManager.FindByEmailAsync(model.Email); + if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) + { + // Don't reveal that the user does not exist or is not confirmed + return RedirectToAction(nameof(ForgotPasswordConfirmation)); + } - // For more information on how to enable account confirmation and password reset please - // visit https://go.microsoft.com/fwlink/?LinkID=532713 - var code = await _userManager.GeneratePasswordResetTokenAsync(user); - var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme); - await _emailSender.SendEmailAsync(model.Email, "Reset Password", - $"Please reset your password by clicking here: link"); - return RedirectToAction(nameof(ForgotPasswordConfirmation)); - } + // For more information on how to enable account confirmation and password reset please + // visit https://go.microsoft.com/fwlink/?LinkID=532713 + var code = await _userManager.GeneratePasswordResetTokenAsync(user); + var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme); + await _emailSender.SendEmailAsync(model.Email, "Reset Password", + $"Please reset your password by clicking here: link"); + return RedirectToAction(nameof(ForgotPasswordConfirmation)); + } - // If we got this far, something failed, redisplay form - return View(model); - } + // If we got this far, something failed, redisplay form + return View(model); + } - [HttpGet] - [AllowAnonymous] - public IActionResult ForgotPasswordConfirmation() - { - return View(); - } + [HttpGet] + [AllowAnonymous] + public IActionResult ForgotPasswordConfirmation() + { + return View(); + } - [HttpGet] - [AllowAnonymous] - public IActionResult ResetPassword(string code = null) - { - if(code == null) - { - throw new ApplicationException("A code must be supplied for password reset."); - } - var model = new ResetPasswordViewModel { Code = code }; - return View(model); - } + [HttpGet] + [AllowAnonymous] + public IActionResult ResetPassword(string code = null) + { + if (code == null) + { + throw new ApplicationException("A code must be supplied for password reset."); + } + var model = new ResetPasswordViewModel { Code = code }; + return View(model); + } - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task ResetPassword(ResetPasswordViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - var user = await _userManager.FindByEmailAsync(model.Email); - if(user == null) - { - // Don't reveal that the user does not exist - return RedirectToAction(nameof(ResetPasswordConfirmation)); - } - var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password); - if(result.Succeeded) - { - return RedirectToAction(nameof(ResetPasswordConfirmation)); - } - AddErrors(result); - return View(); - } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task ResetPassword(ResetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + var user = await _userManager.FindByEmailAsync(model.Email); + if (user == null) + { + // Don't reveal that the user does not exist + return RedirectToAction(nameof(ResetPasswordConfirmation)); + } + var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password); + if (result.Succeeded) + { + return RedirectToAction(nameof(ResetPasswordConfirmation)); + } + AddErrors(result); + return View(); + } - [HttpGet] - [AllowAnonymous] - public IActionResult ResetPasswordConfirmation() - { - return View(); - } + [HttpGet] + [AllowAnonymous] + public IActionResult ResetPasswordConfirmation() + { + return View(); + } - [HttpGet] - public IActionResult AccessDenied() - { - return View(); - } + [HttpGet] + public IActionResult AccessDenied() + { + return View(); + } - #region Helpers + #region Helpers - private void AddErrors(IdentityResult result) - { - foreach(var error in result.Errors) - { - ModelState.AddModelError(string.Empty, error.Description); - } - } + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError(string.Empty, error.Description); + } + } - private IActionResult RedirectToLocal(string returnUrl) - { - if(Url.IsLocalUrl(returnUrl)) - { - return Redirect(returnUrl); - } - else - { - return RedirectToAction(nameof(HomeController.Index), "Home"); - } - } + private IActionResult RedirectToLocal(string returnUrl) + { + if (Url.IsLocalUrl(returnUrl)) + { + return Redirect(returnUrl); + } + else + { + return RedirectToAction(nameof(HomeController.Index), "Home"); + } + } - #endregion - } + #endregion + } } diff --git a/BTCPayServer/Controllers/CallbackController.cs b/BTCPayServer/Controllers/CallbackController.cs index b3455b73c..aeb96e28a 100644 --- a/BTCPayServer/Controllers/CallbackController.cs +++ b/BTCPayServer/Controllers/CallbackController.cs @@ -18,99 +18,99 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - public class CallbackController : Controller - { - public class CallbackSettings - { - public string Token - { - get; set; - } - } - SettingsRepository _Settings; - Network _Network; - InvoiceWatcher _Watcher; - ExplorerClient _Explorer; + public class CallbackController : Controller + { + public class CallbackSettings + { + public string Token + { + get; set; + } + } + SettingsRepository _Settings; + Network _Network; + InvoiceWatcher _Watcher; + ExplorerClient _Explorer; - public CallbackController(SettingsRepository repo, - ExplorerClient explorer, - InvoiceWatcher watcher, - Network network) - { - _Settings = repo; - _Network = network; - _Watcher = watcher; - _Explorer = explorer; - } + public CallbackController(SettingsRepository repo, + ExplorerClient explorer, + InvoiceWatcher watcher, + Network network) + { + _Settings = repo; + _Network = network; + _Watcher = watcher; + _Explorer = explorer; + } - [Route("callbacks/transactions")] - [HttpPost] - public async Task NewTransaction(string token) - { - await AssertToken(token); - Logs.PayServer.LogInformation("New transaction callback"); - //We don't want to register all the json converter at MVC level, so we parse here - var serializer = new NBXplorer.Serializer(_Network); - var content = await new StreamReader(Request.Body, new UTF8Encoding(false), false, 1024, true).ReadToEndAsync(); - var match = serializer.ToObject(content); + [Route("callbacks/transactions")] + [HttpPost] + public async Task NewTransaction(string token) + { + await AssertToken(token); + Logs.PayServer.LogInformation("New transaction callback"); + //We don't want to register all the json converter at MVC level, so we parse here + var serializer = new NBXplorer.Serializer(_Network); + var content = await new StreamReader(Request.Body, new UTF8Encoding(false), false, 1024, true).ReadToEndAsync(); + var match = serializer.ToObject(content); - foreach(var output in match.Outputs) - { - await _Watcher.NotifyReceived(output.ScriptPubKey); - } - } + foreach (var output in match.Outputs) + { + await _Watcher.NotifyReceived(output.ScriptPubKey); + } + } - [Route("callbacks/blocks")] - [HttpPost] - public async Task NewBlock(string token) - { - await AssertToken(token); - Logs.PayServer.LogInformation("New block callback"); - await _Watcher.NotifyBlock(); - } + [Route("callbacks/blocks")] + [HttpPost] + public async Task NewBlock(string token) + { + await AssertToken(token); + Logs.PayServer.LogInformation("New block callback"); + await _Watcher.NotifyBlock(); + } - private async Task AssertToken(string token) - { - var callback = await _Settings.GetSettingAsync(); - if(await GetToken() != token) - throw new BTCPayServer.BitpayHttpException(400, "invalid-callback-token"); - } + private async Task AssertToken(string token) + { + var callback = await _Settings.GetSettingAsync(); + if (await GetToken() != token) + throw new BTCPayServer.BitpayHttpException(400, "invalid-callback-token"); + } - public async Task GetCallbackUriAsync(HttpRequest request) - { - string token = await GetToken(); - return new Uri(request.GetAbsoluteRoot() + "/callbacks/transactions?token=" + token); - } + public async Task GetCallbackUriAsync(HttpRequest request) + { + string token = await GetToken(); + return new Uri(request.GetAbsoluteRoot() + "/callbacks/transactions?token=" + token); + } - public async Task RegisterCallbackUriAsync(DerivationStrategyBase derivationScheme, HttpRequest request) - { - var uri = await GetCallbackUriAsync(request); - await _Explorer.SubscribeToWalletAsync(uri, derivationScheme); - } + public async Task RegisterCallbackUriAsync(DerivationStrategyBase derivationScheme, HttpRequest request) + { + var uri = await GetCallbackUriAsync(request); + await _Explorer.SubscribeToWalletAsync(uri, derivationScheme); + } - private async Task GetToken() - { - var callback = await _Settings.GetSettingAsync(); - if(callback == null) - { - callback = new CallbackSettings() { Token = Guid.NewGuid().ToString() }; - await _Settings.UpdateSetting(callback); - } - var token = callback.Token; - return token; - } + private async Task GetToken() + { + var callback = await _Settings.GetSettingAsync(); + if (callback == null) + { + callback = new CallbackSettings() { Token = Guid.NewGuid().ToString() }; + await _Settings.UpdateSetting(callback); + } + var token = callback.Token; + return token; + } - public async Task GetCallbackBlockUriAsync(HttpRequest request) - { - string token = await GetToken(); - return new Uri(request.GetAbsoluteRoot() + "/callbacks/blocks?token=" + token); - } + public async Task GetCallbackBlockUriAsync(HttpRequest request) + { + string token = await GetToken(); + return new Uri(request.GetAbsoluteRoot() + "/callbacks/blocks?token=" + token); + } - public async Task RegisterCallbackBlockUriAsync(HttpRequest request) - { - var uri = await GetCallbackBlockUriAsync(request); - await _Explorer.SubscribeToBlocksAsync(uri); - return uri; - } - } + public async Task RegisterCallbackBlockUriAsync(HttpRequest request) + { + var uri = await GetCallbackBlockUriAsync(request); + await _Explorer.SubscribeToBlocksAsync(uri); + return uri; + } + } } diff --git a/BTCPayServer/Controllers/InvoiceController.API.cs b/BTCPayServer/Controllers/InvoiceController.API.cs index b5009f30b..9da44a58f 100644 --- a/BTCPayServer/Controllers/InvoiceController.API.cs +++ b/BTCPayServer/Controllers/InvoiceController.API.cs @@ -16,123 +16,123 @@ using BTCPayServer.Services.Stores; namespace BTCPayServer.Controllers { - [EnableCors("BitpayAPI")] - [BitpayAPIConstraint] - public class InvoiceControllerAPI : Controller + [EnableCors("BitpayAPI")] + [BitpayAPIConstraint] + public class InvoiceControllerAPI : Controller { - private InvoiceController _InvoiceController; - private InvoiceRepository _InvoiceRepository; - private TokenRepository _TokenRepository; - private StoreRepository _StoreRepository; + private InvoiceController _InvoiceController; + private InvoiceRepository _InvoiceRepository; + private TokenRepository _TokenRepository; + private StoreRepository _StoreRepository; - public InvoiceControllerAPI(InvoiceController invoiceController, - InvoiceRepository invoceRepository, - TokenRepository tokenRepository, - StoreRepository storeRepository) - { - this._InvoiceController = invoiceController; - this._InvoiceRepository = invoceRepository; - this._TokenRepository = tokenRepository; - this._StoreRepository = storeRepository; - } + public InvoiceControllerAPI(InvoiceController invoiceController, + InvoiceRepository invoceRepository, + TokenRepository tokenRepository, + StoreRepository storeRepository) + { + this._InvoiceController = invoiceController; + this._InvoiceRepository = invoceRepository; + this._TokenRepository = tokenRepository; + this._StoreRepository = storeRepository; + } - [HttpPost] - [Route("invoices")] - [MediaTypeConstraint("application/json")] - public async Task> CreateInvoice([FromBody] Invoice invoice) - { - var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, invoice.Token); - var store = await FindStore(bitToken); - return await _InvoiceController.CreateInvoiceCore(invoice, store, HttpContext.Request.GetAbsoluteRoot()); - } + [HttpPost] + [Route("invoices")] + [MediaTypeConstraint("application/json")] + public async Task> CreateInvoice([FromBody] Invoice invoice) + { + var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, invoice.Token); + var store = await FindStore(bitToken); + return await _InvoiceController.CreateInvoiceCore(invoice, store, HttpContext.Request.GetAbsoluteRoot()); + } - [HttpGet] - [Route("invoices/{id}")] - public async Task> GetInvoice(string id, string token) - { - var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, token); - var store = await FindStore(bitToken); - var invoice = await _InvoiceRepository.GetInvoice(store.Id, id); - if(invoice == null) - throw new BitpayHttpException(404, "Object not found"); + [HttpGet] + [Route("invoices/{id}")] + public async Task> GetInvoice(string id, string token) + { + var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, token); + var store = await FindStore(bitToken); + var invoice = await _InvoiceRepository.GetInvoice(store.Id, id); + if (invoice == null) + throw new BitpayHttpException(404, "Object not found"); - var resp = invoice.EntityToDTO(); - return new DataWrapper(resp); - } + var resp = invoice.EntityToDTO(); + return new DataWrapper(resp); + } - [HttpGet] - [Route("invoices")] - public async Task> GetInvoices( - string token, - DateTimeOffset? dateStart = null, - DateTimeOffset? dateEnd = null, - string orderId = null, - string itemCode = null, - string status = null, - int? limit = null, - int? offset = null) - { - if(dateEnd != null) - dateEnd = dateEnd.Value + TimeSpan.FromDays(1); //Should include the end day - var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, token); - var store = await FindStore(bitToken); - var query = new InvoiceQuery() - { - Count = limit, - Skip = offset, - EndDate = dateEnd, - StartDate = dateStart, - OrderId = orderId, - ItemCode = itemCode, - Status = status, - StoreId = store.Id - }; + [HttpGet] + [Route("invoices")] + public async Task> GetInvoices( + string token, + DateTimeOffset? dateStart = null, + DateTimeOffset? dateEnd = null, + string orderId = null, + string itemCode = null, + string status = null, + int? limit = null, + int? offset = null) + { + if (dateEnd != null) + dateEnd = dateEnd.Value + TimeSpan.FromDays(1); //Should include the end day + var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, token); + var store = await FindStore(bitToken); + var query = new InvoiceQuery() + { + Count = limit, + Skip = offset, + EndDate = dateEnd, + StartDate = dateStart, + OrderId = orderId, + ItemCode = itemCode, + Status = status, + StoreId = store.Id + }; - var entities = (await _InvoiceRepository.GetInvoices(query)) - .Select((o) => o.EntityToDTO()).ToArray(); + var entities = (await _InvoiceRepository.GetInvoices(query)) + .Select((o) => o.EntityToDTO()).ToArray(); - return DataWrapper.Create(entities); - } + return DataWrapper.Create(entities); + } - private async Task CheckTokenPermissionAsync(Facade facade, string expectedToken) - { - if(facade == null) - throw new ArgumentNullException(nameof(facade)); + private async Task CheckTokenPermissionAsync(Facade facade, string expectedToken) + { + if (facade == null) + throw new ArgumentNullException(nameof(facade)); - var actualTokens = (await _TokenRepository.GetTokens(this.GetBitIdentity().SIN)).ToArray(); - actualTokens = actualTokens.SelectMany(t => GetCompatibleTokens(t)).ToArray(); - - var actualToken = actualTokens.FirstOrDefault(a => a.Value.Equals(expectedToken, StringComparison.Ordinal)); - if(expectedToken == null || actualToken == null) - { - Logs.PayServer.LogDebug($"No token found for facade {facade} for SIN {this.GetBitIdentity().SIN}"); - throw new BitpayHttpException(401, $"This endpoint does not support the `{actualTokens.Select(a => a.Facade).Concat(new[] { "user" }).FirstOrDefault()}` facade"); - } - return actualToken; - } + var actualTokens = (await _TokenRepository.GetTokens(this.GetBitIdentity().SIN)).ToArray(); + actualTokens = actualTokens.SelectMany(t => GetCompatibleTokens(t)).ToArray(); - private IEnumerable GetCompatibleTokens(BitTokenEntity token) - { - if(token.Facade == Facade.Merchant.ToString()) - { - yield return token.Clone(Facade.User); - yield return token.Clone(Facade.PointOfSale); - } - if(token.Facade == Facade.PointOfSale.ToString()) - { - yield return token.Clone(Facade.User); - } - yield return token; - } + var actualToken = actualTokens.FirstOrDefault(a => a.Value.Equals(expectedToken, StringComparison.Ordinal)); + if (expectedToken == null || actualToken == null) + { + Logs.PayServer.LogDebug($"No token found for facade {facade} for SIN {this.GetBitIdentity().SIN}"); + throw new BitpayHttpException(401, $"This endpoint does not support the `{actualTokens.Select(a => a.Facade).Concat(new[] { "user" }).FirstOrDefault()}` facade"); + } + return actualToken; + } - private async Task FindStore(BitTokenEntity bitToken) - { - var store = await _StoreRepository.FindStore(bitToken.StoreId); - if(store == null) - throw new BitpayHttpException(401, "Unknown store"); - return store; - } + private IEnumerable GetCompatibleTokens(BitTokenEntity token) + { + if (token.Facade == Facade.Merchant.ToString()) + { + yield return token.Clone(Facade.User); + yield return token.Clone(Facade.PointOfSale); + } + if (token.Facade == Facade.PointOfSale.ToString()) + { + yield return token.Clone(Facade.User); + } + yield return token; + } - } + private async Task FindStore(BitTokenEntity bitToken) + { + var store = await _StoreRepository.FindStore(bitToken.StoreId); + if (store == null) + throw new BitpayHttpException(401, "Unknown store"); + return store; + } + + } } diff --git a/BTCPayServer/Controllers/InvoiceController.PaymentProtocol.cs b/BTCPayServer/Controllers/InvoiceController.PaymentProtocol.cs index 9e3c4f9da..e72934865 100644 --- a/BTCPayServer/Controllers/InvoiceController.PaymentProtocol.cs +++ b/BTCPayServer/Controllers/InvoiceController.PaymentProtocol.cs @@ -14,59 +14,59 @@ namespace BTCPayServer.Controllers { public partial class InvoiceController { - [HttpGet] - [Route("i/{invoiceId}")] - [AcceptMediaTypeConstraint("application/bitcoin-paymentrequest")] - public async Task GetInvoiceRequest(string invoiceId) - { - var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); - if(invoice == null || invoice.IsExpired()) - return NotFound(); + [HttpGet] + [Route("i/{invoiceId}")] + [AcceptMediaTypeConstraint("application/bitcoin-paymentrequest")] + public async Task GetInvoiceRequest(string invoiceId) + { + var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); + if (invoice == null || invoice.IsExpired()) + return NotFound(); - var dto = invoice.EntityToDTO(); - PaymentRequest request = new PaymentRequest - { - DetailsVersion = 1 - }; - request.Details.Expires = invoice.ExpirationTime; - request.Details.Memo = invoice.ProductInformation.ItemDesc; - request.Details.Network = _Network; - request.Details.Outputs.Add(new PaymentOutput() { Amount = dto.BTCDue, Script = BitcoinAddress.Create(dto.BitcoinAddress, _Network).ScriptPubKey }); - request.Details.MerchantData = Encoding.UTF8.GetBytes(invoice.Id); - request.Details.Time = DateTimeOffset.UtcNow; - request.Details.PaymentUrl = new Uri(invoice.ServerUrl.WithTrailingSlash() + ($"i/{invoice.Id}"), UriKind.Absolute); + var dto = invoice.EntityToDTO(); + PaymentRequest request = new PaymentRequest + { + DetailsVersion = 1 + }; + request.Details.Expires = invoice.ExpirationTime; + request.Details.Memo = invoice.ProductInformation.ItemDesc; + request.Details.Network = _Network; + request.Details.Outputs.Add(new PaymentOutput() { Amount = dto.BTCDue, Script = BitcoinAddress.Create(dto.BitcoinAddress, _Network).ScriptPubKey }); + request.Details.MerchantData = Encoding.UTF8.GetBytes(invoice.Id); + request.Details.Time = DateTimeOffset.UtcNow; + request.Details.PaymentUrl = new Uri(invoice.ServerUrl.WithTrailingSlash() + ($"i/{invoice.Id}"), UriKind.Absolute); - var store = await _StoreRepository.FindStore(invoice.StoreId); - if(store == null) - throw new BitpayHttpException(401, "Unknown store"); + var store = await _StoreRepository.FindStore(invoice.StoreId); + if (store == null) + throw new BitpayHttpException(401, "Unknown store"); - if(store.StoreCertificate != null) - { - try - { - request.Sign(store.StoreCertificate, PKIType.X509SHA256); - } - catch(Exception ex) - { - Logs.PayServer.LogWarning(ex, "Error while signing payment request"); - } - } + if (store.StoreCertificate != null) + { + try + { + request.Sign(store.StoreCertificate, PKIType.X509SHA256); + } + catch (Exception ex) + { + Logs.PayServer.LogWarning(ex, "Error while signing payment request"); + } + } - return new PaymentRequestActionResult(request); - } + return new PaymentRequestActionResult(request); + } - [HttpPost] - [Route("i/{invoiceId}", Order = 99)] - [MediaTypeConstraint("application/bitcoin-payment")] - public async Task PostPayment(string invoiceId) - { - var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); - if(invoice == null || invoice.IsExpired()) - return NotFound(); - var payment = PaymentMessage.Load(Request.Body); - var unused = _Wallet.BroadcastTransactionsAsync(payment.Transactions); - await _InvoiceRepository.AddRefundsAsync(invoiceId, payment.RefundTo.Select(p => new TxOut(p.Amount, p.Script)).ToArray()); - return new PaymentAckActionResult(payment.CreateACK(invoiceId + " is currently processing, thanks for your purchase...")); - } - } + [HttpPost] + [Route("i/{invoiceId}", Order = 99)] + [MediaTypeConstraint("application/bitcoin-payment")] + public async Task PostPayment(string invoiceId) + { + var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); + if (invoice == null || invoice.IsExpired()) + return NotFound(); + var payment = PaymentMessage.Load(Request.Body); + var unused = _Wallet.BroadcastTransactionsAsync(payment.Transactions); + await _InvoiceRepository.AddRefundsAsync(invoiceId, payment.RefundTo.Select(p => new TxOut(p.Amount, p.Script)).ToArray()); + return new PaymentAckActionResult(payment.CreateACK(invoiceId + " is currently processing, thanks for your purchase...")); + } + } } diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 822001869..bc3a21cb3 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -18,299 +18,299 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - public partial class InvoiceController - { + public partial class InvoiceController + { - [HttpPost] - [Route("invoices/{invoiceId}")] - public async Task Invoice(string invoiceId, string command) - { - if(command == "refresh") - { - await _Watcher.WatchAsync(invoiceId, true); - } - StatusMessage = "Invoice is state is being refreshed, please refresh the page soon..."; - return RedirectToAction(nameof(Invoice), new - { - invoiceId = invoiceId - }); - } + [HttpPost] + [Route("invoices/{invoiceId}")] + public async Task Invoice(string invoiceId, string command) + { + if (command == "refresh") + { + await _Watcher.WatchAsync(invoiceId, true); + } + StatusMessage = "Invoice is state is being refreshed, please refresh the page soon..."; + return RedirectToAction(nameof(Invoice), new + { + invoiceId = invoiceId + }); + } - [HttpGet] - [Route("invoices/{invoiceId}")] - public async Task Invoice(string invoiceId) - { - var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery() - { - UserId = GetUserId(), - InvoiceId = invoiceId - })).FirstOrDefault(); - if(invoice == null) - return NotFound(); + [HttpGet] + [Route("invoices/{invoiceId}")] + public async Task Invoice(string invoiceId) + { + var invoice = (await _InvoiceRepository.GetInvoices(new InvoiceQuery() + { + UserId = GetUserId(), + InvoiceId = invoiceId + })).FirstOrDefault(); + if (invoice == null) + return NotFound(); - var dto = invoice.EntityToDTO(); - var store = await _StoreRepository.FindStore(invoice.StoreId); - InvoiceDetailsModel model = new InvoiceDetailsModel() - { - StoreName = store.StoreName, - StoreLink = Url.Action(nameof(StoresController.UpdateStore), "Stores", new { storeId = store.Id }), - Id = invoice.Id, - Status = invoice.Status, - RefundEmail = invoice.RefundMail, - CreatedDate = invoice.InvoiceTime, - ExpirationDate = invoice.ExpirationTime, - OrderId = invoice.OrderId, - BuyerInformation = invoice.BuyerInformation, - Rate = invoice.Rate, - Fiat = dto.Price + " " + dto.Currency, - BTC = invoice.GetTotalCryptoDue().ToString() + " BTC", - BTCDue = invoice.GetCryptoDue().ToString() + " BTC", - BTCPaid = invoice.GetTotalPaid().ToString() + " BTC", - NetworkFee = invoice.GetNetworkFee().ToString() + " BTC", - NotificationUrl = invoice.NotificationURL, - ProductInformation = invoice.ProductInformation, - BitcoinAddress = invoice.DepositAddress, - PaymentUrl = dto.PaymentUrls.BIP72 - }; + var dto = invoice.EntityToDTO(); + var store = await _StoreRepository.FindStore(invoice.StoreId); + InvoiceDetailsModel model = new InvoiceDetailsModel() + { + StoreName = store.StoreName, + StoreLink = Url.Action(nameof(StoresController.UpdateStore), "Stores", new { storeId = store.Id }), + Id = invoice.Id, + Status = invoice.Status, + RefundEmail = invoice.RefundMail, + CreatedDate = invoice.InvoiceTime, + ExpirationDate = invoice.ExpirationTime, + OrderId = invoice.OrderId, + BuyerInformation = invoice.BuyerInformation, + Rate = invoice.Rate, + Fiat = dto.Price + " " + dto.Currency, + BTC = invoice.GetTotalCryptoDue().ToString() + " BTC", + BTCDue = invoice.GetCryptoDue().ToString() + " BTC", + BTCPaid = invoice.GetTotalPaid().ToString() + " BTC", + NetworkFee = invoice.GetNetworkFee().ToString() + " BTC", + NotificationUrl = invoice.NotificationURL, + ProductInformation = invoice.ProductInformation, + BitcoinAddress = invoice.DepositAddress, + PaymentUrl = dto.PaymentUrls.BIP72 + }; - var payments = invoice - .Payments - .Select(async payment => - { - var m = new InvoiceDetailsModel.Payment(); - m.DepositAddress = payment.Output.ScriptPubKey.GetDestinationAddress(_Network); - m.Confirmations = (await _Explorer.GetTransactionAsync(payment.Outpoint.Hash))?.Confirmations ?? 0; - m.TransactionId = payment.Outpoint.Hash.ToString(); - m.ReceivedTime = payment.ReceivedTime; - m.TransactionLink = _Network == Network.Main ? $"https://www.smartbit.com.au/tx/{m.TransactionId}" : $"https://testnet.smartbit.com.au/tx/{m.TransactionId}"; - return m; - }) - .ToArray(); - await Task.WhenAll(payments); - model.Payments = payments.Select(p => p.GetAwaiter().GetResult()).ToList(); - model.StatusMessage = StatusMessage; - return View(model); - } + var payments = invoice + .Payments + .Select(async payment => + { + var m = new InvoiceDetailsModel.Payment(); + m.DepositAddress = payment.Output.ScriptPubKey.GetDestinationAddress(_Network); + m.Confirmations = (await _Explorer.GetTransactionAsync(payment.Outpoint.Hash))?.Confirmations ?? 0; + m.TransactionId = payment.Outpoint.Hash.ToString(); + m.ReceivedTime = payment.ReceivedTime; + m.TransactionLink = _Network == Network.Main ? $"https://www.smartbit.com.au/tx/{m.TransactionId}" : $"https://testnet.smartbit.com.au/tx/{m.TransactionId}"; + return m; + }) + .ToArray(); + await Task.WhenAll(payments); + model.Payments = payments.Select(p => p.GetAwaiter().GetResult()).ToList(); + model.StatusMessage = StatusMessage; + return View(model); + } - static Dictionary _CurrencyProviders = new Dictionary(); - private IFormatProvider GetCurrencyProvider(string currency) - { - lock(_CurrencyProviders) - { - if(_CurrencyProviders.Count == 0) - { - foreach(var culture in CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture)) - { - try - { - _CurrencyProviders.TryAdd(new RegionInfo(culture.LCID).ISOCurrencySymbol, culture); - } - catch { } - } - } - return _CurrencyProviders.TryGet(currency); - } - } + static Dictionary _CurrencyProviders = new Dictionary(); + private IFormatProvider GetCurrencyProvider(string currency) + { + lock (_CurrencyProviders) + { + if (_CurrencyProviders.Count == 0) + { + foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture)) + { + try + { + _CurrencyProviders.TryAdd(new RegionInfo(culture.LCID).ISOCurrencySymbol, culture); + } + catch { } + } + } + return _CurrencyProviders.TryGet(currency); + } + } - [HttpGet] - [Route("i/{invoiceId}")] - [Route("invoice")] - [AcceptMediaTypeConstraint("application/bitcoin-paymentrequest", false)] - [XFrameOptionsAttribute(null)] - public async Task Checkout(string invoiceId, string id = null) - { - //Keep compatibility with Bitpay - invoiceId = invoiceId ?? id; - id = invoiceId; - //// + [HttpGet] + [Route("i/{invoiceId}")] + [Route("invoice")] + [AcceptMediaTypeConstraint("application/bitcoin-paymentrequest", false)] + [XFrameOptionsAttribute(null)] + public async Task Checkout(string invoiceId, string id = null) + { + //Keep compatibility with Bitpay + invoiceId = invoiceId ?? id; + id = invoiceId; + //// - var model = await GetInvoiceModel(invoiceId); - if (model == null) - return NotFound(); + var model = await GetInvoiceModel(invoiceId); + if (model == null) + return NotFound(); - return View(nameof(Checkout), model); - } + return View(nameof(Checkout), model); + } - private async Task GetInvoiceModel(string invoiceId) - { - var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); - if (invoice == null) - return null; - var store = await _StoreRepository.FindStore(invoice.StoreId); - var dto = invoice.EntityToDTO(); + private async Task GetInvoiceModel(string invoiceId) + { + var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); + if (invoice == null) + return null; + var store = await _StoreRepository.FindStore(invoice.StoreId); + var dto = invoice.EntityToDTO(); - var model = new PaymentModel() - { - ServerUrl = HttpContext.Request.GetAbsoluteRoot(), - OrderId = invoice.OrderId, - InvoiceId = invoice.Id, - BtcAddress = invoice.DepositAddress.ToString(), - BtcAmount = (invoice.GetTotalCryptoDue() - invoice.TxFee).ToString(), - BtcTotalDue = invoice.GetTotalCryptoDue().ToString(), - BtcDue = invoice.GetCryptoDue().ToString(), - CustomerEmail = invoice.RefundMail, - ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds), - MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds, - ItemDesc = invoice.ProductInformation.ItemDesc, - Rate = invoice.Rate.ToString("C", GetCurrencyProvider(invoice.ProductInformation.Currency)), - MerchantRefLink = invoice.RedirectURL ?? "/", - StoreName = store.StoreName, - TxFees = invoice.TxFee.ToString(), - InvoiceBitcoinUrl = dto.PaymentUrls.BIP72, - TxCount = invoice.GetTxCount(), - BtcPaid = invoice.GetTotalPaid().ToString(), - Status = invoice.Status - }; + var model = new PaymentModel() + { + ServerUrl = HttpContext.Request.GetAbsoluteRoot(), + OrderId = invoice.OrderId, + InvoiceId = invoice.Id, + BtcAddress = invoice.DepositAddress.ToString(), + BtcAmount = (invoice.GetTotalCryptoDue() - invoice.TxFee).ToString(), + BtcTotalDue = invoice.GetTotalCryptoDue().ToString(), + BtcDue = invoice.GetCryptoDue().ToString(), + CustomerEmail = invoice.RefundMail, + ExpirationSeconds = Math.Max(0, (int)(invoice.ExpirationTime - DateTimeOffset.UtcNow).TotalSeconds), + MaxTimeSeconds = (int)(invoice.ExpirationTime - invoice.InvoiceTime).TotalSeconds, + ItemDesc = invoice.ProductInformation.ItemDesc, + Rate = invoice.Rate.ToString("C", GetCurrencyProvider(invoice.ProductInformation.Currency)), + MerchantRefLink = invoice.RedirectURL ?? "/", + StoreName = store.StoreName, + TxFees = invoice.TxFee.ToString(), + InvoiceBitcoinUrl = dto.PaymentUrls.BIP72, + TxCount = invoice.GetTxCount(), + BtcPaid = invoice.GetTotalPaid().ToString(), + Status = invoice.Status + }; - var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); - model.TimeLeft = PrettyPrint(expiration); - return model; - } + var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds); + model.TimeLeft = PrettyPrint(expiration); + return model; + } - private string PrettyPrint(TimeSpan expiration) - { - StringBuilder builder = new StringBuilder(); - if(expiration.Days >= 1) - builder.Append(expiration.Days.ToString()); - if(expiration.Hours >= 1) - builder.Append(expiration.Hours.ToString("00")); - builder.Append($"{expiration.Minutes.ToString("00")}:{expiration.Seconds.ToString("00")}"); - return builder.ToString(); - } + private string PrettyPrint(TimeSpan expiration) + { + StringBuilder builder = new StringBuilder(); + if (expiration.Days >= 1) + builder.Append(expiration.Days.ToString()); + if (expiration.Hours >= 1) + builder.Append(expiration.Hours.ToString("00")); + builder.Append($"{expiration.Minutes.ToString("00")}:{expiration.Seconds.ToString("00")}"); + return builder.ToString(); + } - [HttpGet] - [Route("i/{invoiceId}/status")] - public async Task GetStatus(string invoiceId) - { - var model = await GetInvoiceModel(invoiceId); - if(model == null) - return NotFound(); - return Json(model); - } + [HttpGet] + [Route("i/{invoiceId}/status")] + public async Task GetStatus(string invoiceId) + { + var model = await GetInvoiceModel(invoiceId); + if (model == null) + return NotFound(); + return Json(model); + } - [HttpPost] - [Route("i/{invoiceId}/UpdateCustomer")] - public async Task UpdateCustomer(string invoiceId, [FromBody]UpdateCustomerModel data) - { - if(!ModelState.IsValid) - { - return BadRequest(ModelState); - } - await _InvoiceRepository.UpdateInvoice(invoiceId, data).ConfigureAwait(false); - return Ok(); - } + [HttpPost] + [Route("i/{invoiceId}/UpdateCustomer")] + public async Task UpdateCustomer(string invoiceId, [FromBody]UpdateCustomerModel data) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + await _InvoiceRepository.UpdateInvoice(invoiceId, data).ConfigureAwait(false); + return Ok(); + } - [HttpGet] - [Route("invoices")] - [Authorize(AuthenticationSchemes = "Identity.Application")] - [BitpayAPIConstraint(false)] - public async Task ListInvoices(string searchTerm = null, int skip = 0, int count = 20) - { - var model = new InvoicesModel(); - foreach(var invoice in await _InvoiceRepository.GetInvoices(new InvoiceQuery() - { - TextSearch = searchTerm, - Count = count, - Skip = skip, - UserId = GetUserId() - })) - { - model.SearchTerm = searchTerm; - model.Invoices.Add(new InvoiceModel() - { - Status = invoice.Status, - Date = invoice.InvoiceTime, - InvoiceId = invoice.Id, - AmountCurrency = $"{invoice.ProductInformation.Price.ToString(CultureInfo.InvariantCulture)} {invoice.ProductInformation.Currency}" - }); - } - model.Skip = skip; - model.Count = count; - model.StatusMessage = StatusMessage; - return View(model); - } + [HttpGet] + [Route("invoices")] + [Authorize(AuthenticationSchemes = "Identity.Application")] + [BitpayAPIConstraint(false)] + public async Task ListInvoices(string searchTerm = null, int skip = 0, int count = 20) + { + var model = new InvoicesModel(); + foreach (var invoice in await _InvoiceRepository.GetInvoices(new InvoiceQuery() + { + TextSearch = searchTerm, + Count = count, + Skip = skip, + UserId = GetUserId() + })) + { + model.SearchTerm = searchTerm; + model.Invoices.Add(new InvoiceModel() + { + Status = invoice.Status, + Date = invoice.InvoiceTime, + InvoiceId = invoice.Id, + AmountCurrency = $"{invoice.ProductInformation.Price.ToString(CultureInfo.InvariantCulture)} {invoice.ProductInformation.Currency}" + }); + } + model.Skip = skip; + model.Count = count; + model.StatusMessage = StatusMessage; + return View(model); + } - [HttpGet] - [Route("invoices/create")] - [Authorize(AuthenticationSchemes = "Identity.Application")] - [BitpayAPIConstraint(false)] - public async Task CreateInvoice() - { - var stores = await GetStores(GetUserId()); - if(stores.Count() == 0) - { - StatusMessage = "Error: You need to create at least one store before creating a transaction"; - return RedirectToAction(nameof(StoresController.ListStores), "Stores"); - } - return View(new CreateInvoiceModel() { Stores = stores }); - } + [HttpGet] + [Route("invoices/create")] + [Authorize(AuthenticationSchemes = "Identity.Application")] + [BitpayAPIConstraint(false)] + public async Task CreateInvoice() + { + var stores = await GetStores(GetUserId()); + if (stores.Count() == 0) + { + StatusMessage = "Error: You need to create at least one store before creating a transaction"; + return RedirectToAction(nameof(StoresController.ListStores), "Stores"); + } + return View(new CreateInvoiceModel() { Stores = stores }); + } - [HttpPost] - [Route("invoices/create")] - [Authorize(AuthenticationSchemes = "Identity.Application")] - [BitpayAPIConstraint(false)] - public async Task CreateInvoice(CreateInvoiceModel model) - { - if(!ModelState.IsValid) - { - model.Stores = await GetStores(GetUserId(), model.StoreId); - return View(model); - } - var store = await _StoreRepository.FindStore(model.StoreId, GetUserId()); - if(string.IsNullOrEmpty(store.DerivationStrategy)) - { - StatusMessage = "Error: You need to configure the derivation scheme in order to create an invoice"; - return RedirectToAction(nameof(StoresController.UpdateStore), "Stores", new - { - storeId = store.Id - }); - } - var result = await CreateInvoiceCore(new Invoice() - { - Price = model.Amount.Value, - Currency = "USD", - PosData = model.PosData, - OrderId = model.OrderId, - //RedirectURL = redirect + "redirect", - NotificationURL = model.NotificationUrl, - ItemDesc = model.ItemDesc, - FullNotifications = true, - BuyerEmail = model.BuyerEmail, - }, store, HttpContext.Request.GetAbsoluteRoot()); + [HttpPost] + [Route("invoices/create")] + [Authorize(AuthenticationSchemes = "Identity.Application")] + [BitpayAPIConstraint(false)] + public async Task CreateInvoice(CreateInvoiceModel model) + { + if (!ModelState.IsValid) + { + model.Stores = await GetStores(GetUserId(), model.StoreId); + return View(model); + } + var store = await _StoreRepository.FindStore(model.StoreId, GetUserId()); + if (string.IsNullOrEmpty(store.DerivationStrategy)) + { + StatusMessage = "Error: You need to configure the derivation scheme in order to create an invoice"; + return RedirectToAction(nameof(StoresController.UpdateStore), "Stores", new + { + storeId = store.Id + }); + } + var result = await CreateInvoiceCore(new Invoice() + { + Price = model.Amount.Value, + Currency = "USD", + PosData = model.PosData, + OrderId = model.OrderId, + //RedirectURL = redirect + "redirect", + NotificationURL = model.NotificationUrl, + ItemDesc = model.ItemDesc, + FullNotifications = true, + BuyerEmail = model.BuyerEmail, + }, store, HttpContext.Request.GetAbsoluteRoot()); - StatusMessage = $"Invoice {result.Data.Id} just created!"; - return RedirectToAction(nameof(ListInvoices)); - } + StatusMessage = $"Invoice {result.Data.Id} just created!"; + return RedirectToAction(nameof(ListInvoices)); + } - private async Task GetStores(string userId, string storeId = null) - { - return new SelectList(await _StoreRepository.GetStoresByUserId(userId), nameof(StoreData.Id), nameof(StoreData.StoreName), storeId); - } + private async Task GetStores(string userId, string storeId = null) + { + return new SelectList(await _StoreRepository.GetStoresByUserId(userId), nameof(StoreData.Id), nameof(StoreData.StoreName), storeId); + } - [HttpPost] - [Authorize(AuthenticationSchemes = "Identity.Application")] - [BitpayAPIConstraint(false)] - public IActionResult SearchInvoice(InvoicesModel invoices) - { - return RedirectToAction(nameof(ListInvoices), new - { - searchTerm = invoices.SearchTerm, - skip = invoices.Skip, - count = invoices.Count, - }); - } + [HttpPost] + [Authorize(AuthenticationSchemes = "Identity.Application")] + [BitpayAPIConstraint(false)] + public IActionResult SearchInvoice(InvoicesModel invoices) + { + return RedirectToAction(nameof(ListInvoices), new + { + searchTerm = invoices.SearchTerm, + skip = invoices.Skip, + count = invoices.Count, + }); + } - [TempData] - public string StatusMessage - { - get; - set; - } + [TempData] + public string StatusMessage + { + get; + set; + } - private string GetUserId() - { - return _UserManager.GetUserId(User); - } - } + private string GetUserId() + { + return _UserManager.GetUserId(User); + } + } } diff --git a/BTCPayServer/Controllers/InvoiceController.cs b/BTCPayServer/Controllers/InvoiceController.cs index 04c6651d7..6f0ea2db2 100644 --- a/BTCPayServer/Controllers/InvoiceController.cs +++ b/BTCPayServer/Controllers/InvoiceController.cs @@ -41,119 +41,119 @@ using NBXplorer; namespace BTCPayServer.Controllers { - public partial class InvoiceController : Controller - { - InvoiceRepository _InvoiceRepository; - BTCPayWallet _Wallet; - IRateProvider _RateProvider; - private InvoiceWatcher _Watcher; - StoreRepository _StoreRepository; - Network _Network; - UserManager _UserManager; - IFeeProvider _FeeProvider; - ExplorerClient _Explorer; + public partial class InvoiceController : Controller + { + InvoiceRepository _InvoiceRepository; + BTCPayWallet _Wallet; + IRateProvider _RateProvider; + private InvoiceWatcher _Watcher; + StoreRepository _StoreRepository; + Network _Network; + UserManager _UserManager; + IFeeProvider _FeeProvider; + ExplorerClient _Explorer; - public InvoiceController( - Network network, - InvoiceRepository invoiceRepository, - UserManager userManager, - BTCPayWallet wallet, - IRateProvider rateProvider, - StoreRepository storeRepository, - InvoiceWatcher watcher, - ExplorerClient explorerClient, - IFeeProvider feeProvider) - { - _Explorer = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient)); - _StoreRepository = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository)); - _Network = network ?? throw new ArgumentNullException(nameof(network)); - _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); - _Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); - _RateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); - _Watcher = watcher ?? throw new ArgumentNullException(nameof(watcher)); - _UserManager = userManager; - _FeeProvider = feeProvider ?? throw new ArgumentNullException(nameof(feeProvider)); - } + public InvoiceController( + Network network, + InvoiceRepository invoiceRepository, + UserManager userManager, + BTCPayWallet wallet, + IRateProvider rateProvider, + StoreRepository storeRepository, + InvoiceWatcher watcher, + ExplorerClient explorerClient, + IFeeProvider feeProvider) + { + _Explorer = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient)); + _StoreRepository = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository)); + _Network = network ?? throw new ArgumentNullException(nameof(network)); + _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); + _Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); + _RateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); + _Watcher = watcher ?? throw new ArgumentNullException(nameof(watcher)); + _UserManager = userManager; + _FeeProvider = feeProvider ?? throw new ArgumentNullException(nameof(feeProvider)); + } - internal async Task> CreateInvoiceCore(Invoice invoice, StoreData store, string serverUrl, double expiryMinutes = 15, double monitoringMinutes = 60) - { - //TODO: expiryMinutes (time before a new invoice can become paid) and monitoringMinutes (time before a paid invoice becomes invalid) should be configurable at store level - var derivationStrategy = store.DerivationStrategy; - var entity = new InvoiceEntity - { - InvoiceTime = DateTimeOffset.UtcNow, - DerivationStrategy = derivationStrategy ?? throw new BitpayHttpException(400, "This store has not configured the derivation strategy") - }; - Uri notificationUri = Uri.IsWellFormedUriString(invoice.NotificationURL, UriKind.Absolute) ? new Uri(invoice.NotificationURL, UriKind.Absolute) : null; - if(notificationUri == null || (notificationUri.Scheme != "http" && notificationUri.Scheme != "https")) //TODO: Filer non routable addresses ? - notificationUri = null; - EmailAddressAttribute emailValidator = new EmailAddressAttribute(); - entity.ExpirationTime = entity.InvoiceTime.AddMinutes(expiryMinutes); - entity.MonitoringExpiration = entity.InvoiceTime.AddMinutes(monitoringMinutes); - entity.OrderId = invoice.OrderId; - entity.ServerUrl = serverUrl; - entity.FullNotifications = invoice.FullNotifications; - entity.NotificationURL = notificationUri?.AbsoluteUri; - entity.BuyerInformation = Map(invoice); - //Another way of passing buyer info to support - FillBuyerInfo(invoice.Buyer, entity.BuyerInformation); - if(entity?.BuyerInformation?.BuyerEmail != null) - { - if(!EmailValidator.IsEmail(entity.BuyerInformation.BuyerEmail)) - throw new BitpayHttpException(400, "Invalid email"); - entity.RefundMail = entity.BuyerInformation.BuyerEmail; - } - entity.ProductInformation = Map(invoice); - entity.RedirectURL = invoice.RedirectURL ?? store.StoreWebsite; - entity.Status = "new"; - entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy); - entity.TxFee = store.GetStoreBlob(_Network).NetworkFeeDisabled ? Money.Zero : (await _FeeProvider.GetFeeRateAsync()).GetFee(100); // assume price for 100 bytes - entity.Rate = (double)await _RateProvider.GetRateAsync(invoice.Currency); - entity.PosData = invoice.PosData; - entity.DepositAddress = await _Wallet.ReserveAddressAsync(ParseDerivationStrategy(derivationStrategy)); + internal async Task> CreateInvoiceCore(Invoice invoice, StoreData store, string serverUrl, double expiryMinutes = 15, double monitoringMinutes = 60) + { + //TODO: expiryMinutes (time before a new invoice can become paid) and monitoringMinutes (time before a paid invoice becomes invalid) should be configurable at store level + var derivationStrategy = store.DerivationStrategy; + var entity = new InvoiceEntity + { + InvoiceTime = DateTimeOffset.UtcNow, + DerivationStrategy = derivationStrategy ?? throw new BitpayHttpException(400, "This store has not configured the derivation strategy") + }; + Uri notificationUri = Uri.IsWellFormedUriString(invoice.NotificationURL, UriKind.Absolute) ? new Uri(invoice.NotificationURL, UriKind.Absolute) : null; + if (notificationUri == null || (notificationUri.Scheme != "http" && notificationUri.Scheme != "https")) //TODO: Filer non routable addresses ? + notificationUri = null; + EmailAddressAttribute emailValidator = new EmailAddressAttribute(); + entity.ExpirationTime = entity.InvoiceTime.AddMinutes(expiryMinutes); + entity.MonitoringExpiration = entity.InvoiceTime.AddMinutes(monitoringMinutes); + entity.OrderId = invoice.OrderId; + entity.ServerUrl = serverUrl; + entity.FullNotifications = invoice.FullNotifications; + entity.NotificationURL = notificationUri?.AbsoluteUri; + entity.BuyerInformation = Map(invoice); + //Another way of passing buyer info to support + FillBuyerInfo(invoice.Buyer, entity.BuyerInformation); + if (entity?.BuyerInformation?.BuyerEmail != null) + { + if (!EmailValidator.IsEmail(entity.BuyerInformation.BuyerEmail)) + throw new BitpayHttpException(400, "Invalid email"); + entity.RefundMail = entity.BuyerInformation.BuyerEmail; + } + entity.ProductInformation = Map(invoice); + entity.RedirectURL = invoice.RedirectURL ?? store.StoreWebsite; + entity.Status = "new"; + entity.SpeedPolicy = ParseSpeedPolicy(invoice.TransactionSpeed, store.SpeedPolicy); + entity.TxFee = store.GetStoreBlob(_Network).NetworkFeeDisabled ? Money.Zero : (await _FeeProvider.GetFeeRateAsync()).GetFee(100); // assume price for 100 bytes + entity.Rate = (double)await _RateProvider.GetRateAsync(invoice.Currency); + entity.PosData = invoice.PosData; + entity.DepositAddress = await _Wallet.ReserveAddressAsync(ParseDerivationStrategy(derivationStrategy)); - entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity); - await _Watcher.WatchAsync(entity.Id); - var resp = entity.EntityToDTO(); - return new DataWrapper(resp) { Facade = "pos/invoice" }; - } + entity = await _InvoiceRepository.CreateInvoiceAsync(store.Id, entity); + await _Watcher.WatchAsync(entity.Id); + var resp = entity.EntityToDTO(); + return new DataWrapper(resp) { Facade = "pos/invoice" }; + } - private SpeedPolicy ParseSpeedPolicy(string transactionSpeed, SpeedPolicy defaultPolicy) - { - if(transactionSpeed == null) - return defaultPolicy; - var mappings = new Dictionary(); - mappings.Add("low", SpeedPolicy.LowSpeed); - mappings.Add("medium", SpeedPolicy.MediumSpeed); - mappings.Add("high", SpeedPolicy.HighSpeed); - if(!mappings.TryGetValue(transactionSpeed, out SpeedPolicy policy)) - policy = defaultPolicy; - return policy; - } + private SpeedPolicy ParseSpeedPolicy(string transactionSpeed, SpeedPolicy defaultPolicy) + { + if (transactionSpeed == null) + return defaultPolicy; + var mappings = new Dictionary(); + mappings.Add("low", SpeedPolicy.LowSpeed); + mappings.Add("medium", SpeedPolicy.MediumSpeed); + mappings.Add("high", SpeedPolicy.HighSpeed); + if (!mappings.TryGetValue(transactionSpeed, out SpeedPolicy policy)) + policy = defaultPolicy; + return policy; + } - private void FillBuyerInfo(Buyer buyer, BuyerInformation buyerInformation) - { - if(buyer == null) - return; - buyerInformation.BuyerAddress1 = buyerInformation.BuyerAddress1 ?? buyer.Address1; - buyerInformation.BuyerAddress2 = buyerInformation.BuyerAddress2 ?? buyer.Address2; - buyerInformation.BuyerCity = buyerInformation.BuyerCity ?? buyer.City; - buyerInformation.BuyerCountry = buyerInformation.BuyerCountry ?? buyer.country; - buyerInformation.BuyerEmail = buyerInformation.BuyerEmail ?? buyer.email; - buyerInformation.BuyerName = buyerInformation.BuyerName ?? buyer.Name; - buyerInformation.BuyerPhone = buyerInformation.BuyerPhone ?? buyer.phone; - buyerInformation.BuyerState = buyerInformation.BuyerState ?? buyer.State; - buyerInformation.BuyerZip = buyerInformation.BuyerZip ?? buyer.zip; - } + private void FillBuyerInfo(Buyer buyer, BuyerInformation buyerInformation) + { + if (buyer == null) + return; + buyerInformation.BuyerAddress1 = buyerInformation.BuyerAddress1 ?? buyer.Address1; + buyerInformation.BuyerAddress2 = buyerInformation.BuyerAddress2 ?? buyer.Address2; + buyerInformation.BuyerCity = buyerInformation.BuyerCity ?? buyer.City; + buyerInformation.BuyerCountry = buyerInformation.BuyerCountry ?? buyer.country; + buyerInformation.BuyerEmail = buyerInformation.BuyerEmail ?? buyer.email; + buyerInformation.BuyerName = buyerInformation.BuyerName ?? buyer.Name; + buyerInformation.BuyerPhone = buyerInformation.BuyerPhone ?? buyer.phone; + buyerInformation.BuyerState = buyerInformation.BuyerState ?? buyer.State; + buyerInformation.BuyerZip = buyerInformation.BuyerZip ?? buyer.zip; + } - private DerivationStrategyBase ParseDerivationStrategy(string derivationStrategy) - { - return new DerivationStrategyFactory(_Network).Parse(derivationStrategy); - } + private DerivationStrategyBase ParseDerivationStrategy(string derivationStrategy) + { + return new DerivationStrategyFactory(_Network).Parse(derivationStrategy); + } - private TDest Map(TFrom data) - { - return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(data)); - } - } + private TDest Map(TFrom data) + { + return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(data)); + } + } } diff --git a/BTCPayServer/Controllers/ManageController.cs b/BTCPayServer/Controllers/ManageController.cs index 94782cf7d..da7bb88b3 100644 --- a/BTCPayServer/Controllers/ManageController.cs +++ b/BTCPayServer/Controllers/ManageController.cs @@ -23,516 +23,516 @@ using BTCPayServer.Services.Mails; namespace BTCPayServer.Controllers { - [Authorize] - [Route("[controller]/[action]")] - public class ManageController : Controller - { - private readonly UserManager _userManager; - private readonly SignInManager _signInManager; - private readonly IEmailSender _emailSender; - private readonly ILogger _logger; - private readonly UrlEncoder _urlEncoder; - TokenRepository _TokenRepository; - private readonly BTCPayWallet _Wallet; - IHostingEnvironment _Env; - StoreRepository _StoreRepository; - - - private const string AuthenicatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; - - public ManageController( - UserManager userManager, - SignInManager signInManager, - IEmailSender emailSender, - ILogger logger, - UrlEncoder urlEncoder, - TokenRepository tokenRepository, - BTCPayWallet wallet, - StoreRepository storeRepository, - IHostingEnvironment env) - { - _userManager = userManager; - _signInManager = signInManager; - _emailSender = emailSender; - _logger = logger; - _urlEncoder = urlEncoder; - _TokenRepository = tokenRepository; - _Wallet = wallet; - _Env = env; - _StoreRepository = storeRepository; - } - - [TempData] - public string StatusMessage - { - get; set; - } - - [HttpGet] - public async Task Index() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var model = new IndexViewModel - { - Username = user.UserName, - Email = user.Email, - PhoneNumber = user.PhoneNumber, - IsEmailConfirmed = user.EmailConfirmed, - StatusMessage = StatusMessage - }; - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Index(IndexViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - - bool needUpdate = false; - - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var email = user.Email; - if(model.Email != email) - { - var setEmailResult = await _userManager.SetEmailAsync(user, model.Email); - if(!setEmailResult.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred setting email for user with ID '{user.Id}'."); - } - } - - var phoneNumber = user.PhoneNumber; - if(model.PhoneNumber != phoneNumber) - { - var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, model.PhoneNumber); - if(!setPhoneResult.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred setting phone number for user with ID '{user.Id}'."); - } - } - - if(needUpdate) - { - var result = await _userManager.UpdateAsync(user); - if(!result.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred updating user with ID '{user.Id}'."); - } - } - - StatusMessage = "Your profile has been updated"; - return RedirectToAction(nameof(Index)); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task SendVerificationEmail(IndexViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); - var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme); - var email = user.Email; - await _emailSender.SendEmailConfirmationAsync(email, callbackUrl); - - StatusMessage = "Verification email sent. Please check your email."; - return RedirectToAction(nameof(Index)); - } - - [HttpGet] - public async Task ChangePassword() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var hasPassword = await _userManager.HasPasswordAsync(user); - if(!hasPassword) - { - return RedirectToAction(nameof(SetPassword)); - } - - var model = new ChangePasswordViewModel { StatusMessage = StatusMessage }; - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task ChangePassword(ChangePasswordViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var changePasswordResult = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); - if(!changePasswordResult.Succeeded) - { - AddErrors(changePasswordResult); - return View(model); - } - - await _signInManager.SignInAsync(user, isPersistent: false); - _logger.LogInformation("User changed their password successfully."); - StatusMessage = "Your password has been changed."; - - return RedirectToAction(nameof(ChangePassword)); - } - - [HttpGet] - public async Task SetPassword() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var hasPassword = await _userManager.HasPasswordAsync(user); - - if(hasPassword) - { - return RedirectToAction(nameof(ChangePassword)); - } - - var model = new SetPasswordViewModel { StatusMessage = StatusMessage }; - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task SetPassword(SetPasswordViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var addPasswordResult = await _userManager.AddPasswordAsync(user, model.NewPassword); - if(!addPasswordResult.Succeeded) - { - AddErrors(addPasswordResult); - return View(model); - } - - await _signInManager.SignInAsync(user, isPersistent: false); - StatusMessage = "Your password has been set."; - - return RedirectToAction(nameof(SetPassword)); - } - - [HttpGet] - public async Task ExternalLogins() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var model = new ExternalLoginsViewModel { CurrentLogins = await _userManager.GetLoginsAsync(user) }; - model.OtherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()) - .Where(auth => model.CurrentLogins.All(ul => auth.Name != ul.LoginProvider)) - .ToList(); - model.ShowRemoveButton = await _userManager.HasPasswordAsync(user) || model.CurrentLogins.Count > 1; - model.StatusMessage = StatusMessage; - - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task LinkLogin(string provider) - { - // Clear the existing external cookie to ensure a clean login process - await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - - // Request a redirect to the external login provider to link a login for the current user - var redirectUrl = Url.Action(nameof(LinkLoginCallback)); - var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); - return new ChallengeResult(provider, properties); - } - - [HttpGet] - public async Task LinkLoginCallback() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var info = await _signInManager.GetExternalLoginInfoAsync(user.Id); - if(info == null) - { - throw new ApplicationException($"Unexpected error occurred loading external login info for user with ID '{user.Id}'."); - } - - var result = await _userManager.AddLoginAsync(user, info); - if(!result.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred adding external login for user with ID '{user.Id}'."); - } - - // Clear the existing external cookie to ensure a clean login process - await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - - StatusMessage = "The external login was added."; - return RedirectToAction(nameof(ExternalLogins)); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task RemoveLogin(RemoveLoginViewModel model) - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var result = await _userManager.RemoveLoginAsync(user, model.LoginProvider, model.ProviderKey); - if(!result.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred removing external login for user with ID '{user.Id}'."); - } - - await _signInManager.SignInAsync(user, isPersistent: false); - StatusMessage = "The external login was removed."; - return RedirectToAction(nameof(ExternalLogins)); - } - - [HttpGet] - public async Task TwoFactorAuthentication() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var model = new TwoFactorAuthenticationViewModel - { - HasAuthenticator = await _userManager.GetAuthenticatorKeyAsync(user) != null, - Is2faEnabled = user.TwoFactorEnabled, - RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user), - }; - - return View(model); - } - - [HttpGet] - public async Task Disable2faWarning() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - if(!user.TwoFactorEnabled) - { - throw new ApplicationException($"Unexpected error occured disabling 2FA for user with ID '{user.Id}'."); - } - - return View(nameof(Disable2fa)); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Disable2fa() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(user, false); - if(!disable2faResult.Succeeded) - { - throw new ApplicationException($"Unexpected error occured disabling 2FA for user with ID '{user.Id}'."); - } - - _logger.LogInformation("User with ID {UserId} has disabled 2fa.", user.Id); - return RedirectToAction(nameof(TwoFactorAuthentication)); - } - - [HttpGet] - public async Task EnableAuthenticator() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); - if(string.IsNullOrEmpty(unformattedKey)) - { - await _userManager.ResetAuthenticatorKeyAsync(user); - unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); - } - - var model = new EnableAuthenticatorViewModel - { - SharedKey = FormatKey(unformattedKey), - AuthenticatorUri = GenerateQrCodeUri(user.Email, unformattedKey) - }; - - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task EnableAuthenticator(EnableAuthenticatorViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - // Strip spaces and hypens - var verificationCode = model.Code.Replace(" ", string.Empty).Replace("-", string.Empty); - - var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync( - user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode); - - if(!is2faTokenValid) - { - ModelState.AddModelError("model.Code", "Verification code is invalid."); - return View(model); - } - - await _userManager.SetTwoFactorEnabledAsync(user, true); - _logger.LogInformation("User with ID {UserId} has enabled 2FA with an authenticator app.", user.Id); - return RedirectToAction(nameof(GenerateRecoveryCodes)); - } - - [HttpGet] - public IActionResult ResetAuthenticatorWarning() - { - return View(nameof(ResetAuthenticator)); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task ResetAuthenticator() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - await _userManager.SetTwoFactorEnabledAsync(user, false); - await _userManager.ResetAuthenticatorKeyAsync(user); - _logger.LogInformation("User with id '{UserId}' has reset their authentication app key.", user.Id); - - return RedirectToAction(nameof(EnableAuthenticator)); - } - - [HttpGet] - public async Task GenerateRecoveryCodes() - { - var user = await _userManager.GetUserAsync(User); - if(user == null) - { - throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); - } - - if(!user.TwoFactorEnabled) - { - throw new ApplicationException($"Cannot generate recovery codes for user with ID '{user.Id}' as they do not have 2FA enabled."); - } - - var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10); - var model = new GenerateRecoveryCodesViewModel { RecoveryCodes = recoveryCodes.ToArray() }; - - _logger.LogInformation("User with ID {UserId} has generated new 2FA recovery codes.", user.Id); - - return View(model); - } - - #region Helpers - - private void AddErrors(IdentityResult result) - { - foreach(var error in result.Errors) - { - ModelState.AddModelError(string.Empty, error.Description); - } - } - - private string FormatKey(string unformattedKey) - { - var result = new StringBuilder(); - int currentPosition = 0; - while(currentPosition + 4 < unformattedKey.Length) - { - result.Append(unformattedKey.Substring(currentPosition, 4)).Append(" "); - currentPosition += 4; - } - if(currentPosition < unformattedKey.Length) - { - result.Append(unformattedKey.Substring(currentPosition)); - } - - return result.ToString().ToLowerInvariant(); - } - - private string GenerateQrCodeUri(string email, string unformattedKey) - { - return string.Format( - AuthenicatorUriFormat, - _urlEncoder.Encode("BTCPayServer"), - _urlEncoder.Encode(email), - unformattedKey); - } - - #endregion - } + [Authorize] + [Route("[controller]/[action]")] + public class ManageController : Controller + { + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly IEmailSender _emailSender; + private readonly ILogger _logger; + private readonly UrlEncoder _urlEncoder; + TokenRepository _TokenRepository; + private readonly BTCPayWallet _Wallet; + IHostingEnvironment _Env; + StoreRepository _StoreRepository; + + + private const string AuthenicatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; + + public ManageController( + UserManager userManager, + SignInManager signInManager, + IEmailSender emailSender, + ILogger logger, + UrlEncoder urlEncoder, + TokenRepository tokenRepository, + BTCPayWallet wallet, + StoreRepository storeRepository, + IHostingEnvironment env) + { + _userManager = userManager; + _signInManager = signInManager; + _emailSender = emailSender; + _logger = logger; + _urlEncoder = urlEncoder; + _TokenRepository = tokenRepository; + _Wallet = wallet; + _Env = env; + _StoreRepository = storeRepository; + } + + [TempData] + public string StatusMessage + { + get; set; + } + + [HttpGet] + public async Task Index() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var model = new IndexViewModel + { + Username = user.UserName, + Email = user.Email, + PhoneNumber = user.PhoneNumber, + IsEmailConfirmed = user.EmailConfirmed, + StatusMessage = StatusMessage + }; + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Index(IndexViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + bool needUpdate = false; + + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var email = user.Email; + if (model.Email != email) + { + var setEmailResult = await _userManager.SetEmailAsync(user, model.Email); + if (!setEmailResult.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred setting email for user with ID '{user.Id}'."); + } + } + + var phoneNumber = user.PhoneNumber; + if (model.PhoneNumber != phoneNumber) + { + var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, model.PhoneNumber); + if (!setPhoneResult.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred setting phone number for user with ID '{user.Id}'."); + } + } + + if (needUpdate) + { + var result = await _userManager.UpdateAsync(user); + if (!result.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred updating user with ID '{user.Id}'."); + } + } + + StatusMessage = "Your profile has been updated"; + return RedirectToAction(nameof(Index)); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task SendVerificationEmail(IndexViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme); + var email = user.Email; + await _emailSender.SendEmailConfirmationAsync(email, callbackUrl); + + StatusMessage = "Verification email sent. Please check your email."; + return RedirectToAction(nameof(Index)); + } + + [HttpGet] + public async Task ChangePassword() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var hasPassword = await _userManager.HasPasswordAsync(user); + if (!hasPassword) + { + return RedirectToAction(nameof(SetPassword)); + } + + var model = new ChangePasswordViewModel { StatusMessage = StatusMessage }; + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ChangePassword(ChangePasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var changePasswordResult = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); + if (!changePasswordResult.Succeeded) + { + AddErrors(changePasswordResult); + return View(model); + } + + await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation("User changed their password successfully."); + StatusMessage = "Your password has been changed."; + + return RedirectToAction(nameof(ChangePassword)); + } + + [HttpGet] + public async Task SetPassword() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var hasPassword = await _userManager.HasPasswordAsync(user); + + if (hasPassword) + { + return RedirectToAction(nameof(ChangePassword)); + } + + var model = new SetPasswordViewModel { StatusMessage = StatusMessage }; + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task SetPassword(SetPasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var addPasswordResult = await _userManager.AddPasswordAsync(user, model.NewPassword); + if (!addPasswordResult.Succeeded) + { + AddErrors(addPasswordResult); + return View(model); + } + + await _signInManager.SignInAsync(user, isPersistent: false); + StatusMessage = "Your password has been set."; + + return RedirectToAction(nameof(SetPassword)); + } + + [HttpGet] + public async Task ExternalLogins() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var model = new ExternalLoginsViewModel { CurrentLogins = await _userManager.GetLoginsAsync(user) }; + model.OtherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()) + .Where(auth => model.CurrentLogins.All(ul => auth.Name != ul.LoginProvider)) + .ToList(); + model.ShowRemoveButton = await _userManager.HasPasswordAsync(user) || model.CurrentLogins.Count > 1; + model.StatusMessage = StatusMessage; + + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task LinkLogin(string provider) + { + // Clear the existing external cookie to ensure a clean login process + await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); + + // Request a redirect to the external login provider to link a login for the current user + var redirectUrl = Url.Action(nameof(LinkLoginCallback)); + var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); + return new ChallengeResult(provider, properties); + } + + [HttpGet] + public async Task LinkLoginCallback() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var info = await _signInManager.GetExternalLoginInfoAsync(user.Id); + if (info == null) + { + throw new ApplicationException($"Unexpected error occurred loading external login info for user with ID '{user.Id}'."); + } + + var result = await _userManager.AddLoginAsync(user, info); + if (!result.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred adding external login for user with ID '{user.Id}'."); + } + + // Clear the existing external cookie to ensure a clean login process + await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); + + StatusMessage = "The external login was added."; + return RedirectToAction(nameof(ExternalLogins)); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RemoveLogin(RemoveLoginViewModel model) + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var result = await _userManager.RemoveLoginAsync(user, model.LoginProvider, model.ProviderKey); + if (!result.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred removing external login for user with ID '{user.Id}'."); + } + + await _signInManager.SignInAsync(user, isPersistent: false); + StatusMessage = "The external login was removed."; + return RedirectToAction(nameof(ExternalLogins)); + } + + [HttpGet] + public async Task TwoFactorAuthentication() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var model = new TwoFactorAuthenticationViewModel + { + HasAuthenticator = await _userManager.GetAuthenticatorKeyAsync(user) != null, + Is2faEnabled = user.TwoFactorEnabled, + RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user), + }; + + return View(model); + } + + [HttpGet] + public async Task Disable2faWarning() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + if (!user.TwoFactorEnabled) + { + throw new ApplicationException($"Unexpected error occured disabling 2FA for user with ID '{user.Id}'."); + } + + return View(nameof(Disable2fa)); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Disable2fa() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(user, false); + if (!disable2faResult.Succeeded) + { + throw new ApplicationException($"Unexpected error occured disabling 2FA for user with ID '{user.Id}'."); + } + + _logger.LogInformation("User with ID {UserId} has disabled 2fa.", user.Id); + return RedirectToAction(nameof(TwoFactorAuthentication)); + } + + [HttpGet] + public async Task EnableAuthenticator() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); + if (string.IsNullOrEmpty(unformattedKey)) + { + await _userManager.ResetAuthenticatorKeyAsync(user); + unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user); + } + + var model = new EnableAuthenticatorViewModel + { + SharedKey = FormatKey(unformattedKey), + AuthenticatorUri = GenerateQrCodeUri(user.Email, unformattedKey) + }; + + return View(model); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task EnableAuthenticator(EnableAuthenticatorViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + // Strip spaces and hypens + var verificationCode = model.Code.Replace(" ", string.Empty).Replace("-", string.Empty); + + var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync( + user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode); + + if (!is2faTokenValid) + { + ModelState.AddModelError("model.Code", "Verification code is invalid."); + return View(model); + } + + await _userManager.SetTwoFactorEnabledAsync(user, true); + _logger.LogInformation("User with ID {UserId} has enabled 2FA with an authenticator app.", user.Id); + return RedirectToAction(nameof(GenerateRecoveryCodes)); + } + + [HttpGet] + public IActionResult ResetAuthenticatorWarning() + { + return View(nameof(ResetAuthenticator)); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ResetAuthenticator() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + await _userManager.SetTwoFactorEnabledAsync(user, false); + await _userManager.ResetAuthenticatorKeyAsync(user); + _logger.LogInformation("User with id '{UserId}' has reset their authentication app key.", user.Id); + + return RedirectToAction(nameof(EnableAuthenticator)); + } + + [HttpGet] + public async Task GenerateRecoveryCodes() + { + var user = await _userManager.GetUserAsync(User); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); + } + + if (!user.TwoFactorEnabled) + { + throw new ApplicationException($"Cannot generate recovery codes for user with ID '{user.Id}' as they do not have 2FA enabled."); + } + + var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10); + var model = new GenerateRecoveryCodesViewModel { RecoveryCodes = recoveryCodes.ToArray() }; + + _logger.LogInformation("User with ID {UserId} has generated new 2FA recovery codes.", user.Id); + + return View(model); + } + + #region Helpers + + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { + ModelState.AddModelError(string.Empty, error.Description); + } + } + + private string FormatKey(string unformattedKey) + { + var result = new StringBuilder(); + int currentPosition = 0; + while (currentPosition + 4 < unformattedKey.Length) + { + result.Append(unformattedKey.Substring(currentPosition, 4)).Append(" "); + currentPosition += 4; + } + if (currentPosition < unformattedKey.Length) + { + result.Append(unformattedKey.Substring(currentPosition)); + } + + return result.ToString().ToLowerInvariant(); + } + + private string GenerateQrCodeUri(string email, string unformattedKey) + { + return string.Format( + AuthenicatorUriFormat, + _urlEncoder.Encode("BTCPayServer"), + _urlEncoder.Encode(email), + unformattedKey); + } + + #endregion + } } diff --git a/BTCPayServer/Controllers/PaymentRequestActionResult.cs b/BTCPayServer/Controllers/PaymentRequestActionResult.cs index ccb0bb428..7964afa14 100644 --- a/BTCPayServer/Controllers/PaymentRequestActionResult.cs +++ b/BTCPayServer/Controllers/PaymentRequestActionResult.cs @@ -7,34 +7,34 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - public class PaymentRequestActionResult : IActionResult - { - PaymentRequest req; - public PaymentRequestActionResult(PaymentRequest req) - { - this.req = req; - } - public Task ExecuteResultAsync(ActionContext context) - { - context.HttpContext.Response.Headers["Content-Transfer-Encoding"] = "binary"; - context.HttpContext.Response.ContentType = "application/bitcoin-paymentrequest"; - req.WriteTo(context.HttpContext.Response.Body); - return Task.CompletedTask; - } - } - public class PaymentAckActionResult : IActionResult - { - PaymentACK req; - public PaymentAckActionResult(PaymentACK req) - { - this.req = req; - } - public Task ExecuteResultAsync(ActionContext context) - { - context.HttpContext.Response.Headers["Content-Transfer-Encoding"] = "binary"; - context.HttpContext.Response.ContentType = "application/bitcoin-paymentack"; - req.WriteTo(context.HttpContext.Response.Body); - return Task.CompletedTask; - } - } + public class PaymentRequestActionResult : IActionResult + { + PaymentRequest req; + public PaymentRequestActionResult(PaymentRequest req) + { + this.req = req; + } + public Task ExecuteResultAsync(ActionContext context) + { + context.HttpContext.Response.Headers["Content-Transfer-Encoding"] = "binary"; + context.HttpContext.Response.ContentType = "application/bitcoin-paymentrequest"; + req.WriteTo(context.HttpContext.Response.Body); + return Task.CompletedTask; + } + } + public class PaymentAckActionResult : IActionResult + { + PaymentACK req; + public PaymentAckActionResult(PaymentACK req) + { + this.req = req; + } + public Task ExecuteResultAsync(ActionContext context) + { + context.HttpContext.Response.Headers["Content-Transfer-Encoding"] = "binary"; + context.HttpContext.Response.ContentType = "application/bitcoin-paymentack"; + req.WriteTo(context.HttpContext.Response.Body); + return Task.CompletedTask; + } + } } diff --git a/BTCPayServer/Controllers/RateController.cs b/BTCPayServer/Controllers/RateController.cs index c5df858d7..c0515e886 100644 --- a/BTCPayServer/Controllers/RateController.cs +++ b/BTCPayServer/Controllers/RateController.cs @@ -10,31 +10,31 @@ using BTCPayServer.Services.Rates; namespace BTCPayServer.Controllers { - public class RateController : Controller - { - IRateProvider _RateProvider; - CurrencyNameTable _CurrencyNameTable; - public RateController(IRateProvider rateProvider, CurrencyNameTable currencyNameTable) - { - _RateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); - _CurrencyNameTable = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable)); - } + public class RateController : Controller + { + IRateProvider _RateProvider; + CurrencyNameTable _CurrencyNameTable; + public RateController(IRateProvider rateProvider, CurrencyNameTable currencyNameTable) + { + _RateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); + _CurrencyNameTable = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable)); + } - [Route("rates")] - [HttpGet] - [BitpayAPIConstraint] - public async Task> GetRates() - { - var allRates = (await _RateProvider.GetRatesAsync()); - return new DataWrapper - (allRates.Select(r => - new NBitpayClient.Rate() - { - Code = r.Currency, - Name = _CurrencyNameTable.GetCurrencyData(r.Currency)?.Name, - Value = r.Value - }).Where(n => n.Name != null).ToArray()); + [Route("rates")] + [HttpGet] + [BitpayAPIConstraint] + public async Task> GetRates() + { + var allRates = (await _RateProvider.GetRatesAsync()); + return new DataWrapper + (allRates.Select(r => + new NBitpayClient.Rate() + { + Code = r.Currency, + Name = _CurrencyNameTable.GetCurrencyData(r.Currency)?.Name, + Value = r.Value + }).Where(n => n.Name != null).ToArray()); - } - } + } + } } diff --git a/BTCPayServer/Controllers/ServerController.cs b/BTCPayServer/Controllers/ServerController.cs index b78cc1971..9e25033d9 100644 --- a/BTCPayServer/Controllers/ServerController.cs +++ b/BTCPayServer/Controllers/ServerController.cs @@ -16,82 +16,82 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - [Authorize(Roles = Roles.ServerAdmin)] - public class ServerController : Controller - { - private UserManager _UserManager; - SettingsRepository _SettingsRepository; + [Authorize(Roles = Roles.ServerAdmin)] + public class ServerController : Controller + { + private UserManager _UserManager; + SettingsRepository _SettingsRepository; - public ServerController(UserManager userManager, SettingsRepository settingsRepository) - { - _UserManager = userManager; - _SettingsRepository = settingsRepository; - } + public ServerController(UserManager userManager, SettingsRepository settingsRepository) + { + _UserManager = userManager; + _SettingsRepository = settingsRepository; + } - [Route("server/users")] - public IActionResult ListUsers() - { - var users = new UsersViewModel(); - users.Users - = _UserManager.Users.Select(u => new UsersViewModel.UserViewModel() - { - Name = u.UserName, - Email = u.Email - }).ToList(); - return View(users); - } + [Route("server/users")] + public IActionResult ListUsers() + { + var users = new UsersViewModel(); + users.Users + = _UserManager.Users.Select(u => new UsersViewModel.UserViewModel() + { + Name = u.UserName, + Email = u.Email + }).ToList(); + return View(users); + } - [Route("server/emails")] - public async Task Emails() - { - var data = (await _SettingsRepository.GetSettingAsync()) ?? new EmailSettings(); - return View(new EmailsViewModel() { Settings = data }); - } + [Route("server/emails")] + public async Task Emails() + { + var data = (await _SettingsRepository.GetSettingAsync()) ?? new EmailSettings(); + return View(new EmailsViewModel() { Settings = data }); + } - [Route("server/policies")] - public async Task Policies() - { - var data = (await _SettingsRepository.GetSettingAsync()) ?? new PoliciesSettings(); - return View(data); - } - [Route("server/policies")] - [HttpPost] - public async Task Policies(PoliciesSettings settings) - { - await _SettingsRepository.UpdateSetting(settings); - TempData["StatusMessage"] = "Policies upadated successfully"; - return View(settings); - } + [Route("server/policies")] + public async Task Policies() + { + var data = (await _SettingsRepository.GetSettingAsync()) ?? new PoliciesSettings(); + return View(data); + } + [Route("server/policies")] + [HttpPost] + public async Task Policies(PoliciesSettings settings) + { + await _SettingsRepository.UpdateSetting(settings); + TempData["StatusMessage"] = "Policies upadated successfully"; + return View(settings); + } - [Route("server/emails")] - [HttpPost] - public async Task Emails(EmailsViewModel model, string command) - { - if(command == "Test") - { - if(!ModelState.IsValid) - return View(model); - try - { - var client = model.Settings.CreateSmtpClient(); - await client.SendMailAsync(model.Settings.From, model.TestEmail, "BTCPay test", "BTCPay test"); - model.StatusMessage = "Email sent to " + model.TestEmail + ", please, verify you received it"; - } - catch(Exception ex) - { - model.StatusMessage = "Error: " + ex.Message; - } - return View(model); - } - else - { - ModelState.Remove(nameof(model.TestEmail)); - if(!ModelState.IsValid) - return View(model); - await _SettingsRepository.UpdateSetting(model.Settings); - model.StatusMessage = "Email settings saved"; - return View(model); - } - } - } + [Route("server/emails")] + [HttpPost] + public async Task Emails(EmailsViewModel model, string command) + { + if (command == "Test") + { + if (!ModelState.IsValid) + return View(model); + try + { + var client = model.Settings.CreateSmtpClient(); + await client.SendMailAsync(model.Settings.From, model.TestEmail, "BTCPay test", "BTCPay test"); + model.StatusMessage = "Email sent to " + model.TestEmail + ", please, verify you received it"; + } + catch (Exception ex) + { + model.StatusMessage = "Error: " + ex.Message; + } + return View(model); + } + else + { + ModelState.Remove(nameof(model.TestEmail)); + if (!ModelState.IsValid) + return View(model); + await _SettingsRepository.UpdateSetting(model.Settings); + model.StatusMessage = "Email settings saved"; + return View(model); + } + } + } } diff --git a/BTCPayServer/Controllers/StoresController.cs b/BTCPayServer/Controllers/StoresController.cs index 4254f0e7b..d1ff24cff 100644 --- a/BTCPayServer/Controllers/StoresController.cs +++ b/BTCPayServer/Controllers/StoresController.cs @@ -20,399 +20,399 @@ using System.Threading.Tasks; namespace BTCPayServer.Controllers { - [Route("stores")] - [Authorize(AuthenticationSchemes = "Identity.Application")] - [Authorize(Policy = "CanAccessStore")] - [AutoValidateAntiforgeryToken] - public class StoresController : Controller - { - public StoresController( - StoreRepository repo, - TokenRepository tokenRepo, - CallbackController callbackController, - UserManager userManager, - AccessTokenController tokenController, - BTCPayWallet wallet, - Network network, - IHostingEnvironment env) - { - _Repo = repo; - _TokenRepository = tokenRepo; - _UserManager = userManager; - _TokenController = tokenController; - _Wallet = wallet; - _Env = env; - _Network = network; - _CallbackController = callbackController; - } - Network _Network; - CallbackController _CallbackController; - BTCPayWallet _Wallet; - AccessTokenController _TokenController; - StoreRepository _Repo; - TokenRepository _TokenRepository; - UserManager _UserManager; - IHostingEnvironment _Env; + [Route("stores")] + [Authorize(AuthenticationSchemes = "Identity.Application")] + [Authorize(Policy = "CanAccessStore")] + [AutoValidateAntiforgeryToken] + public class StoresController : Controller + { + public StoresController( + StoreRepository repo, + TokenRepository tokenRepo, + CallbackController callbackController, + UserManager userManager, + AccessTokenController tokenController, + BTCPayWallet wallet, + Network network, + IHostingEnvironment env) + { + _Repo = repo; + _TokenRepository = tokenRepo; + _UserManager = userManager; + _TokenController = tokenController; + _Wallet = wallet; + _Env = env; + _Network = network; + _CallbackController = callbackController; + } + Network _Network; + CallbackController _CallbackController; + BTCPayWallet _Wallet; + AccessTokenController _TokenController; + StoreRepository _Repo; + TokenRepository _TokenRepository; + UserManager _UserManager; + IHostingEnvironment _Env; - [TempData] - public string StatusMessage - { - get; set; - } + [TempData] + public string StatusMessage + { + get; set; + } - [HttpGet] - [Route("create")] - public IActionResult CreateStore() - { - return View(); - } + [HttpGet] + [Route("create")] + public IActionResult CreateStore() + { + return View(); + } - [HttpPost] - [Route("create")] - public async Task CreateStore(CreateStoreViewModel vm) - { - if(!ModelState.IsValid) - { - return View(vm); - } - var store = await _Repo.CreateStore(GetUserId(), vm.Name); - CreatedStoreId = store.Id; - StatusMessage = "Store successfully created"; - return RedirectToAction(nameof(ListStores)); - } + [HttpPost] + [Route("create")] + public async Task CreateStore(CreateStoreViewModel vm) + { + if (!ModelState.IsValid) + { + return View(vm); + } + var store = await _Repo.CreateStore(GetUserId(), vm.Name); + CreatedStoreId = store.Id; + StatusMessage = "Store successfully created"; + return RedirectToAction(nameof(ListStores)); + } - public string CreatedStoreId - { - get; set; - } + public string CreatedStoreId + { + get; set; + } - [HttpGet] - public async Task ListStores() - { - StoresViewModel result = new StoresViewModel(); - result.StatusMessage = StatusMessage; - var stores = await _Repo.GetStoresByUserId(GetUserId()); - var balances = stores.Select(async s => string.IsNullOrEmpty(s.DerivationStrategy) ? Money.Zero : await _Wallet.GetBalance(ParseDerivationStrategy(s.DerivationStrategy))).ToArray(); + [HttpGet] + public async Task ListStores() + { + StoresViewModel result = new StoresViewModel(); + result.StatusMessage = StatusMessage; + var stores = await _Repo.GetStoresByUserId(GetUserId()); + var balances = stores.Select(async s => string.IsNullOrEmpty(s.DerivationStrategy) ? Money.Zero : await _Wallet.GetBalance(ParseDerivationStrategy(s.DerivationStrategy))).ToArray(); - for(int i = 0; i < stores.Length; i++) - { - var store = stores[i]; - result.Stores.Add(new StoresViewModel.StoreViewModel() - { - Id = store.Id, - Name = store.StoreName, - WebSite = store.StoreWebsite, - Balance = await balances[i] - }); - } - return View(result); - } + for (int i = 0; i < stores.Length; i++) + { + var store = stores[i]; + result.Stores.Add(new StoresViewModel.StoreViewModel() + { + Id = store.Id, + Name = store.StoreName, + WebSite = store.StoreWebsite, + Balance = await balances[i] + }); + } + return View(result); + } - [HttpGet] - [Route("{storeId}/delete")] - public async Task DeleteStore(string storeId) - { - var store = await _Repo.FindStore(storeId, GetUserId()); - if(store == null) - return NotFound(); - return View("Confirm", new ConfirmModel() - { - Title = "Delete store " + store.StoreName, - Description = "This store will still be accessible to users sharing it", - Action = "Delete" - }); - } + [HttpGet] + [Route("{storeId}/delete")] + public async Task DeleteStore(string storeId) + { + var store = await _Repo.FindStore(storeId, GetUserId()); + if (store == null) + return NotFound(); + return View("Confirm", new ConfirmModel() + { + Title = "Delete store " + store.StoreName, + Description = "This store will still be accessible to users sharing it", + Action = "Delete" + }); + } - [HttpPost] - [Route("{storeId}/delete")] - public async Task DeleteStorePost(string storeId) - { - var userId = GetUserId(); - var store = await _Repo.FindStore(storeId, GetUserId()); - if(store == null) - return NotFound(); - await _Repo.RemoveStore(storeId, userId); - StatusMessage = "Store removed successfully"; - return RedirectToAction(nameof(ListStores)); - } + [HttpPost] + [Route("{storeId}/delete")] + public async Task DeleteStorePost(string storeId) + { + var userId = GetUserId(); + var store = await _Repo.FindStore(storeId, GetUserId()); + if (store == null) + return NotFound(); + await _Repo.RemoveStore(storeId, userId); + StatusMessage = "Store removed successfully"; + return RedirectToAction(nameof(ListStores)); + } - [HttpGet] - [Route("{storeId}")] - public async Task UpdateStore(string storeId) - { - var store = await _Repo.FindStore(storeId, GetUserId()); - if(store == null) - return NotFound(); + [HttpGet] + [Route("{storeId}")] + public async Task UpdateStore(string storeId) + { + var store = await _Repo.FindStore(storeId, GetUserId()); + if (store == null) + return NotFound(); - var vm = new StoreViewModel(); - vm.StoreName = store.StoreName; - vm.StoreWebsite = store.StoreWebsite; - vm.NetworkFee = !store.GetStoreBlob(_Network).NetworkFeeDisabled; - vm.SpeedPolicy = store.SpeedPolicy; - vm.DerivationScheme = store.DerivationStrategy; - vm.StatusMessage = StatusMessage; - return View(vm); - } + var vm = new StoreViewModel(); + vm.StoreName = store.StoreName; + vm.StoreWebsite = store.StoreWebsite; + vm.NetworkFee = !store.GetStoreBlob(_Network).NetworkFeeDisabled; + vm.SpeedPolicy = store.SpeedPolicy; + vm.DerivationScheme = store.DerivationStrategy; + vm.StatusMessage = StatusMessage; + return View(vm); + } - [HttpPost] - [Route("{storeId}")] - public async Task UpdateStore(string storeId, StoreViewModel model, string command) - { - if(!ModelState.IsValid) - { - return View(model); - } - var store = await _Repo.FindStore(storeId, GetUserId()); - if(store == null) - return NotFound(); + [HttpPost] + [Route("{storeId}")] + public async Task UpdateStore(string storeId, StoreViewModel model, string command) + { + if (!ModelState.IsValid) + { + return View(model); + } + var store = await _Repo.FindStore(storeId, GetUserId()); + if (store == null) + return NotFound(); - if(command == "Save") - { - bool needUpdate = false; - if(store.SpeedPolicy != model.SpeedPolicy) - { - needUpdate = true; - store.SpeedPolicy = model.SpeedPolicy; - } - if(store.StoreName != model.StoreName) - { - needUpdate = true; - store.StoreName = model.StoreName; - } - if(store.StoreWebsite != model.StoreWebsite) - { - needUpdate = true; - store.StoreWebsite = model.StoreWebsite; - } + if (command == "Save") + { + bool needUpdate = false; + if (store.SpeedPolicy != model.SpeedPolicy) + { + needUpdate = true; + store.SpeedPolicy = model.SpeedPolicy; + } + if (store.StoreName != model.StoreName) + { + needUpdate = true; + store.StoreName = model.StoreName; + } + if (store.StoreWebsite != model.StoreWebsite) + { + needUpdate = true; + store.StoreWebsite = model.StoreWebsite; + } - if(store.DerivationStrategy != model.DerivationScheme) - { - needUpdate = true; - try - { - var strategy = ParseDerivationStrategy(model.DerivationScheme); - await _Wallet.TrackAsync(strategy); - await _CallbackController.RegisterCallbackUriAsync(strategy, Request); - store.DerivationStrategy = model.DerivationScheme; - } - catch - { - ModelState.AddModelError(nameof(model.DerivationScheme), "Invalid Derivation Scheme"); - return View(model); - } - } + if (store.DerivationStrategy != model.DerivationScheme) + { + needUpdate = true; + try + { + var strategy = ParseDerivationStrategy(model.DerivationScheme); + await _Wallet.TrackAsync(strategy); + await _CallbackController.RegisterCallbackUriAsync(strategy, Request); + store.DerivationStrategy = model.DerivationScheme; + } + catch + { + ModelState.AddModelError(nameof(model.DerivationScheme), "Invalid Derivation Scheme"); + return View(model); + } + } - if(store.GetStoreBlob(_Network).NetworkFeeDisabled != !model.NetworkFee) - { - var blob = store.GetStoreBlob(_Network); - blob.NetworkFeeDisabled = !model.NetworkFee; - store.SetStoreBlob(blob, _Network); - needUpdate = true; - } + if (store.GetStoreBlob(_Network).NetworkFeeDisabled != !model.NetworkFee) + { + var blob = store.GetStoreBlob(_Network); + blob.NetworkFeeDisabled = !model.NetworkFee; + store.SetStoreBlob(blob, _Network); + needUpdate = true; + } - if(needUpdate) - { - await _Repo.UpdateStore(store); - StatusMessage = "Store successfully updated"; - } + if (needUpdate) + { + await _Repo.UpdateStore(store); + StatusMessage = "Store successfully updated"; + } - return RedirectToAction(nameof(UpdateStore), new - { - storeId = storeId - }); - } - else - { - var facto = new DerivationStrategyFactory(_Network); - var scheme = facto.Parse(model.DerivationScheme); - var line = scheme.GetLineFor(DerivationFeature.Deposit); + return RedirectToAction(nameof(UpdateStore), new + { + storeId = storeId + }); + } + else + { + var facto = new DerivationStrategyFactory(_Network); + var scheme = facto.Parse(model.DerivationScheme); + var line = scheme.GetLineFor(DerivationFeature.Deposit); - for(int i = 0; i < 10; i++) - { - var address = line.Derive((uint)i); - model.AddressSamples.Add((line.Path.Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(_Network).ToString())); - } - return View(model); - } - } + for (int i = 0; i < 10; i++) + { + var address = line.Derive((uint)i); + model.AddressSamples.Add((line.Path.Derive((uint)i).ToString(), address.ScriptPubKey.GetDestinationAddress(_Network).ToString())); + } + return View(model); + } + } - private DerivationStrategyBase ParseDerivationStrategy(string derivationScheme) - { - return new DerivationStrategyFactory(_Network).Parse(derivationScheme); - } + private DerivationStrategyBase ParseDerivationStrategy(string derivationScheme) + { + return new DerivationStrategyFactory(_Network).Parse(derivationScheme); + } - [HttpGet] - [Route("{storeId}/Tokens")] - public async Task ListTokens(string storeId) - { - var model = new TokensViewModel(); - var tokens = await _TokenRepository.GetTokensByStoreIdAsync(storeId); - model.StatusMessage = StatusMessage; - model.Tokens = tokens.Select(t => new TokenViewModel() - { - Facade = t.Facade, - Label = t.Label, - SIN = t.SIN, - Id = t.Value - }).ToArray(); - return View(model); - } + [HttpGet] + [Route("{storeId}/Tokens")] + public async Task ListTokens(string storeId) + { + var model = new TokensViewModel(); + var tokens = await _TokenRepository.GetTokensByStoreIdAsync(storeId); + model.StatusMessage = StatusMessage; + model.Tokens = tokens.Select(t => new TokenViewModel() + { + Facade = t.Facade, + Label = t.Label, + SIN = t.SIN, + Id = t.Value + }).ToArray(); + return View(model); + } - [HttpPost] - [Route("/api-tokens")] - [Route("{storeId}/Tokens/Create")] - public async Task CreateToken(string storeId, CreateTokenViewModel model) - { - if(!ModelState.IsValid) - { - return View(model); - } - model.Label = model.Label ?? String.Empty; - if(storeId == null) // Permissions are not checked by Policy if the storeId is not passed by url - { - storeId = model.StoreId; - var userId = GetUserId(); - if(userId == null) - return Unauthorized(); - var store = await _Repo.FindStore(storeId, userId); - if(store == null) - return Unauthorized(); - } + [HttpPost] + [Route("/api-tokens")] + [Route("{storeId}/Tokens/Create")] + public async Task CreateToken(string storeId, CreateTokenViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + model.Label = model.Label ?? String.Empty; + if (storeId == null) // Permissions are not checked by Policy if the storeId is not passed by url + { + storeId = model.StoreId; + var userId = GetUserId(); + if (userId == null) + return Unauthorized(); + var store = await _Repo.FindStore(storeId, userId); + if (store == null) + return Unauthorized(); + } - var tokenRequest = new TokenRequest() - { - Facade = model.Facade, - Label = model.Label, - Id = model.PublicKey == null ? null : NBitpayClient.Extensions.BitIdExtensions.GetBitIDSIN(new PubKey(model.PublicKey)) - }; + var tokenRequest = new TokenRequest() + { + Facade = model.Facade, + Label = model.Label, + Id = model.PublicKey == null ? null : NBitpayClient.Extensions.BitIdExtensions.GetBitIDSIN(new PubKey(model.PublicKey)) + }; - string pairingCode = null; - if(model.PublicKey == null) - { - tokenRequest.PairingCode = await _TokenRepository.CreatePairingCodeAsync(); - await _TokenRepository.UpdatePairingCode(new PairingCodeEntity() - { - Id = tokenRequest.PairingCode, - Facade = model.Facade, - Label = model.Label, - }); - await _TokenRepository.PairWithStoreAsync(tokenRequest.PairingCode, storeId); - pairingCode = tokenRequest.PairingCode; - } - else - { - pairingCode = ((DataWrapper>)await _TokenController.Tokens(tokenRequest)).Data[0].PairingCode; - } + string pairingCode = null; + if (model.PublicKey == null) + { + tokenRequest.PairingCode = await _TokenRepository.CreatePairingCodeAsync(); + await _TokenRepository.UpdatePairingCode(new PairingCodeEntity() + { + Id = tokenRequest.PairingCode, + Facade = model.Facade, + Label = model.Label, + }); + await _TokenRepository.PairWithStoreAsync(tokenRequest.PairingCode, storeId); + pairingCode = tokenRequest.PairingCode; + } + else + { + pairingCode = ((DataWrapper>)await _TokenController.Tokens(tokenRequest)).Data[0].PairingCode; + } - return RedirectToAction(nameof(RequestPairing), new - { - pairingCode = pairingCode, - selectedStore = storeId - }); - } + return RedirectToAction(nameof(RequestPairing), new + { + pairingCode = pairingCode, + selectedStore = storeId + }); + } - [HttpGet] - [Route("/api-tokens")] - [Route("{storeId}/Tokens/Create")] - public async Task CreateToken(string storeId) - { - var userId = GetUserId(); - if(string.IsNullOrWhiteSpace(userId)) - return Unauthorized(); - var model = new CreateTokenViewModel(); - model.Facade = "merchant"; - ViewBag.HidePublicKey = storeId == null; - ViewBag.ShowStores = storeId == null; - ViewBag.ShowMenu = storeId != null; - model.StoreId = storeId; - if(storeId == null) - { - model.Stores = new SelectList(await _Repo.GetStoresByUserId(userId), nameof(StoreData.Id), nameof(StoreData.StoreName), storeId); - } - - return View(model); - } + [HttpGet] + [Route("/api-tokens")] + [Route("{storeId}/Tokens/Create")] + public async Task CreateToken(string storeId) + { + var userId = GetUserId(); + if (string.IsNullOrWhiteSpace(userId)) + return Unauthorized(); + var model = new CreateTokenViewModel(); + model.Facade = "merchant"; + ViewBag.HidePublicKey = storeId == null; + ViewBag.ShowStores = storeId == null; + ViewBag.ShowMenu = storeId != null; + model.StoreId = storeId; + if (storeId == null) + { + model.Stores = new SelectList(await _Repo.GetStoresByUserId(userId), nameof(StoreData.Id), nameof(StoreData.StoreName), storeId); + } + + return View(model); + } - [HttpPost] - [Route("{storeId}/Tokens/Delete")] - public async Task DeleteToken(string storeId, string tokenId) - { - var token = await _TokenRepository.GetToken(tokenId); - if(token == null || - token.StoreId != storeId || - !await _TokenRepository.DeleteToken(tokenId)) - StatusMessage = "Failure to revoke this token"; - else - StatusMessage = "Token revoked"; - return RedirectToAction(nameof(ListTokens)); - } + [HttpPost] + [Route("{storeId}/Tokens/Delete")] + public async Task DeleteToken(string storeId, string tokenId) + { + var token = await _TokenRepository.GetToken(tokenId); + if (token == null || + token.StoreId != storeId || + !await _TokenRepository.DeleteToken(tokenId)) + StatusMessage = "Failure to revoke this token"; + else + StatusMessage = "Token revoked"; + return RedirectToAction(nameof(ListTokens)); + } - [HttpGet] - [Route("/api-access-request")] - public async Task RequestPairing(string pairingCode, string selectedStore = null) - { - var pairing = await _TokenRepository.GetPairingAsync(pairingCode); - if(pairing == null) - { - StatusMessage = "Unknown pairing code"; - return RedirectToAction(nameof(ListStores)); - } - else - { - var stores = await _Repo.GetStoresByUserId(GetUserId()); - return View(new PairingModel() - { - Id = pairing.Id, - Facade = pairing.Facade, - Label = pairing.Label, - SIN = pairing.SIN ?? "Server-Initiated Pairing", - SelectedStore = selectedStore ?? stores.FirstOrDefault()?.Id, - Stores = stores.Select(s => new PairingModel.StoreViewModel() - { - Id = s.Id, - Name = string.IsNullOrEmpty(s.StoreName) ? s.Id : s.StoreName - }).ToArray() - }); - } - } + [HttpGet] + [Route("/api-access-request")] + public async Task RequestPairing(string pairingCode, string selectedStore = null) + { + var pairing = await _TokenRepository.GetPairingAsync(pairingCode); + if (pairing == null) + { + StatusMessage = "Unknown pairing code"; + return RedirectToAction(nameof(ListStores)); + } + else + { + var stores = await _Repo.GetStoresByUserId(GetUserId()); + return View(new PairingModel() + { + Id = pairing.Id, + Facade = pairing.Facade, + Label = pairing.Label, + SIN = pairing.SIN ?? "Server-Initiated Pairing", + SelectedStore = selectedStore ?? stores.FirstOrDefault()?.Id, + Stores = stores.Select(s => new PairingModel.StoreViewModel() + { + Id = s.Id, + Name = string.IsNullOrEmpty(s.StoreName) ? s.Id : s.StoreName + }).ToArray() + }); + } + } - [HttpPost] - [Route("api-access-request")] - public async Task Pair(string pairingCode, string selectedStore) - { - if(pairingCode == null) - return NotFound(); - var store = await _Repo.FindStore(selectedStore, GetUserId()); - var pairing = await _TokenRepository.GetPairingAsync(pairingCode); - if(store == null || pairing == null) - return NotFound(); + [HttpPost] + [Route("api-access-request")] + public async Task Pair(string pairingCode, string selectedStore) + { + if (pairingCode == null) + return NotFound(); + var store = await _Repo.FindStore(selectedStore, GetUserId()); + var pairing = await _TokenRepository.GetPairingAsync(pairingCode); + if (store == null || pairing == null) + return NotFound(); - var pairingResult = await _TokenRepository.PairWithStoreAsync(pairingCode, store.Id); - if(pairingResult == PairingResult.Complete || pairingResult == PairingResult.Partial) - { - StatusMessage = "Pairing is successfull"; - if(pairingResult == PairingResult.Partial) - StatusMessage = "Server initiated pairing code: " + pairingCode; - return RedirectToAction(nameof(ListTokens), new - { - storeId = store.Id - }); - } - else - { - StatusMessage = $"Pairing failed ({pairingResult})"; - return RedirectToAction(nameof(ListTokens), new - { - storeId = store.Id - }); - } - } + var pairingResult = await _TokenRepository.PairWithStoreAsync(pairingCode, store.Id); + if (pairingResult == PairingResult.Complete || pairingResult == PairingResult.Partial) + { + StatusMessage = "Pairing is successfull"; + if (pairingResult == PairingResult.Partial) + StatusMessage = "Server initiated pairing code: " + pairingCode; + return RedirectToAction(nameof(ListTokens), new + { + storeId = store.Id + }); + } + else + { + StatusMessage = $"Pairing failed ({pairingResult})"; + return RedirectToAction(nameof(ListTokens), new + { + storeId = store.Id + }); + } + } - private string GetUserId() - { - return _UserManager.GetUserId(User); - } - } + private string GetUserId() + { + return _UserManager.GetUserId(User); + } + } } diff --git a/BTCPayServer/Data/AddressInvoiceData.cs b/BTCPayServer/Data/AddressInvoiceData.cs index 7ec57ae3b..bf8bd0c5c 100644 --- a/BTCPayServer/Data/AddressInvoiceData.cs +++ b/BTCPayServer/Data/AddressInvoiceData.cs @@ -5,26 +5,26 @@ using System.Threading.Tasks; namespace BTCPayServer.Data { - public class AddressInvoiceData - { - public string Address - { - get; set; - } + public class AddressInvoiceData + { + public string Address + { + get; set; + } - public InvoiceData InvoiceData - { - get; set; - } + public InvoiceData InvoiceData + { + get; set; + } - public string InvoiceDataId - { - get; set; - } + public string InvoiceDataId + { + get; set; + } - public DateTimeOffset? CreatedTime - { - get; set; - } - } + public DateTimeOffset? CreatedTime + { + get; set; + } + } } diff --git a/BTCPayServer/Data/ApplicationDbContext.cs b/BTCPayServer/Data/ApplicationDbContext.cs index 177fb0845..6089a14e1 100644 --- a/BTCPayServer/Data/ApplicationDbContext.cs +++ b/BTCPayServer/Data/ApplicationDbContext.cs @@ -10,126 +10,126 @@ using Microsoft.EntityFrameworkCore.Infrastructure; namespace BTCPayServer.Data { - public class ApplicationDbContext : IdentityDbContext - { - public ApplicationDbContext() - { + public class ApplicationDbContext : IdentityDbContext + { + public ApplicationDbContext() + { - } - public ApplicationDbContext(DbContextOptions options) - : base(options) - { - } + } + public ApplicationDbContext(DbContextOptions options) + : base(options) + { + } - public DbSet Invoices - { - get; set; - } + public DbSet Invoices + { + get; set; + } - public DbSet HistoricalAddressInvoices - { - get; set; - } + public DbSet HistoricalAddressInvoices + { + get; set; + } - public DbSet PendingInvoices - { - get; set; - } - public DbSet RefundAddresses - { - get; set; - } + public DbSet PendingInvoices + { + get; set; + } + public DbSet RefundAddresses + { + get; set; + } - public DbSet Payments - { - get; set; - } + public DbSet Payments + { + get; set; + } - public DbSet Stores - { - get; set; - } + public DbSet Stores + { + get; set; + } - public DbSet UserStore - { - get; set; - } + public DbSet UserStore + { + get; set; + } - public DbSet AddressInvoices - { - get; set; - } + public DbSet AddressInvoices + { + get; set; + } - public DbSet Settings - { - get; set; - } + public DbSet Settings + { + get; set; + } - public DbSet PairingCodes - { - get; set; - } + public DbSet PairingCodes + { + get; set; + } - public DbSet PairedSINData - { - get; set; - } + public DbSet PairedSINData + { + get; set; + } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - var isConfigured = optionsBuilder.Options.Extensions.OfType().Any(); - if(!isConfigured) - optionsBuilder.UseSqlite("Data Source=temp.db"); - } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + var isConfigured = optionsBuilder.Options.Extensions.OfType().Any(); + if (!isConfigured) + optionsBuilder.UseSqlite("Data Source=temp.db"); + } - protected override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); - builder.Entity() - .HasIndex(o => o.StoreDataId); + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + builder.Entity() + .HasIndex(o => o.StoreDataId); - builder.Entity() - .HasIndex(o => o.InvoiceDataId); + builder.Entity() + .HasIndex(o => o.InvoiceDataId); - builder.Entity() - .HasIndex(o => o.InvoiceDataId); + builder.Entity() + .HasIndex(o => o.InvoiceDataId); - builder.Entity() - .HasKey(t => new - { - t.ApplicationUserId, - t.StoreDataId - }); + builder.Entity() + .HasKey(t => new + { + t.ApplicationUserId, + t.StoreDataId + }); - builder.Entity() - .HasOne(pt => pt.ApplicationUser) - .WithMany(p => p.UserStores) - .HasForeignKey(pt => pt.ApplicationUserId); + builder.Entity() + .HasOne(pt => pt.ApplicationUser) + .WithMany(p => p.UserStores) + .HasForeignKey(pt => pt.ApplicationUserId); - builder.Entity() - .HasOne(pt => pt.StoreData) - .WithMany(t => t.UserStores) - .HasForeignKey(pt => pt.StoreDataId); + builder.Entity() + .HasOne(pt => pt.StoreData) + .WithMany(t => t.UserStores) + .HasForeignKey(pt => pt.StoreDataId); - builder.Entity() - .HasKey(o => o.Address); + builder.Entity() + .HasKey(o => o.Address); - builder.Entity() - .HasKey(o => o.Id); + builder.Entity() + .HasKey(o => o.Id); - builder.Entity(b => - { - b.HasIndex(o => o.SIN); - b.HasIndex(o => o.StoreDataId); - }); + builder.Entity(b => + { + b.HasIndex(o => o.SIN); + b.HasIndex(o => o.StoreDataId); + }); - builder.Entity() - .HasKey(o => new - { - o.InvoiceDataId, - o.Address - }); - } - } + builder.Entity() + .HasKey(o => new + { + o.InvoiceDataId, + o.Address + }); + } + } } diff --git a/BTCPayServer/Data/ApplicationDbContextFactory.cs b/BTCPayServer/Data/ApplicationDbContextFactory.cs index d6368313f..be1d86ffd 100644 --- a/BTCPayServer/Data/ApplicationDbContextFactory.cs +++ b/BTCPayServer/Data/ApplicationDbContextFactory.cs @@ -9,42 +9,42 @@ using Hangfire.PostgreSql; namespace BTCPayServer.Data { - public enum DatabaseType - { - Sqlite, - Postgres - } - public class ApplicationDbContextFactory - { - string _ConnectionString; - DatabaseType _Type; - public ApplicationDbContextFactory(DatabaseType type, string connectionString) - { - _ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); - _Type = type; - } + public enum DatabaseType + { + Sqlite, + Postgres + } + public class ApplicationDbContextFactory + { + string _ConnectionString; + DatabaseType _Type; + public ApplicationDbContextFactory(DatabaseType type, string connectionString) + { + _ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + _Type = type; + } - public ApplicationDbContext CreateContext() - { - var builder = new DbContextOptionsBuilder(); - ConfigureBuilder(builder); - return new ApplicationDbContext(builder.Options); - } + public ApplicationDbContext CreateContext() + { + var builder = new DbContextOptionsBuilder(); + ConfigureBuilder(builder); + return new ApplicationDbContext(builder.Options); + } - public void ConfigureBuilder(DbContextOptionsBuilder builder) - { - if(_Type == DatabaseType.Sqlite) - builder.UseSqlite(_ConnectionString); - else if(_Type == DatabaseType.Postgres) - builder.UseNpgsql(_ConnectionString); - } + public void ConfigureBuilder(DbContextOptionsBuilder builder) + { + if (_Type == DatabaseType.Sqlite) + builder.UseSqlite(_ConnectionString); + else if (_Type == DatabaseType.Postgres) + builder.UseNpgsql(_ConnectionString); + } - public void ConfigureHangfireBuilder(IGlobalConfiguration builder) - { - if(_Type == DatabaseType.Sqlite) - builder.UseMemoryStorage(); //Sql provider does not support multiple workers - else if(_Type == DatabaseType.Postgres) - builder.UsePostgreSqlStorage(_ConnectionString); - } - } + public void ConfigureHangfireBuilder(IGlobalConfiguration builder) + { + if (_Type == DatabaseType.Sqlite) + builder.UseMemoryStorage(); //Sql provider does not support multiple workers + else if (_Type == DatabaseType.Postgres) + builder.UsePostgreSqlStorage(_ConnectionString); + } + } } diff --git a/BTCPayServer/Data/HistoricalAddressInvoiceData.cs b/BTCPayServer/Data/HistoricalAddressInvoiceData.cs index 9c0345189..a00e5d32b 100644 --- a/BTCPayServer/Data/HistoricalAddressInvoiceData.cs +++ b/BTCPayServer/Data/HistoricalAddressInvoiceData.cs @@ -7,24 +7,24 @@ namespace BTCPayServer.Data { public class HistoricalAddressInvoiceData { - public string InvoiceDataId - { - get; set; - } + public string InvoiceDataId + { + get; set; + } - public string Address - { - get; set; - } + public string Address + { + get; set; + } - public DateTimeOffset Assigned - { - get; set; - } + public DateTimeOffset Assigned + { + get; set; + } - public DateTimeOffset? UnAssigned - { - get; set; - } - } + public DateTimeOffset? UnAssigned + { + get; set; + } + } } diff --git a/BTCPayServer/Data/InvoiceData.cs b/BTCPayServer/Data/InvoiceData.cs index bbbc29845..68a2b7a08 100644 --- a/BTCPayServer/Data/InvoiceData.cs +++ b/BTCPayServer/Data/InvoiceData.cs @@ -6,70 +6,70 @@ using System.Threading.Tasks; namespace BTCPayServer.Data { - public class InvoiceData - { - public string StoreDataId - { - get; set; - } - public StoreData StoreData - { - get; set; - } + public class InvoiceData + { + public string StoreDataId + { + get; set; + } + public StoreData StoreData + { + get; set; + } - public string Id - { - get; set; - } + public string Id + { + get; set; + } - public DateTimeOffset Created - { - get; set; - } + public DateTimeOffset Created + { + get; set; + } - public List Payments - { - get; set; - } + public List Payments + { + get; set; + } - public List RefundAddresses - { - get; set; - } + public List RefundAddresses + { + get; set; + } - public List HistoricalAddressInvoices - { - get; set; - } + public List HistoricalAddressInvoices + { + get; set; + } - public byte[] Blob - { - get; set; - } - public string ItemCode - { - get; - set; - } - public string OrderId - { - get; - set; - } - public string Status - { - get; - set; - } - public string ExceptionStatus - { - get; - set; - } - public string CustomerEmail - { - get; - set; - } - } + public byte[] Blob + { + get; set; + } + public string ItemCode + { + get; + set; + } + public string OrderId + { + get; + set; + } + public string Status + { + get; + set; + } + public string ExceptionStatus + { + get; + set; + } + public string CustomerEmail + { + get; + set; + } + } } diff --git a/BTCPayServer/Data/PairedSINData.cs b/BTCPayServer/Data/PairedSINData.cs index 8355fa5fa..b3680c835 100644 --- a/BTCPayServer/Data/PairedSINData.cs +++ b/BTCPayServer/Data/PairedSINData.cs @@ -7,33 +7,33 @@ namespace BTCPayServer.Data { public class PairedSINData { - public string Id - { - get; set; - } + public string Id + { + get; set; + } - public string Facade - { - get; set; - } - - public string StoreDataId - { - get; set; - } - public string Label - { - get; - set; - } - public DateTimeOffset PairingTime - { - get; - set; - } - public string SIN - { - get; set; - } - } + public string Facade + { + get; set; + } + + public string StoreDataId + { + get; set; + } + public string Label + { + get; + set; + } + public DateTimeOffset PairingTime + { + get; + set; + } + public string SIN + { + get; set; + } + } } diff --git a/BTCPayServer/Data/PairingCodeData.cs b/BTCPayServer/Data/PairingCodeData.cs index 44f2ecf56..a008c8a4f 100644 --- a/BTCPayServer/Data/PairingCodeData.cs +++ b/BTCPayServer/Data/PairingCodeData.cs @@ -7,44 +7,44 @@ namespace BTCPayServer.Data { public class PairingCodeData { - public string Id - { - get; set; - } - - public string Facade - { - get; set; - } - public string StoreDataId - { - get; set; - } - public DateTimeOffset Expiration - { - get; - set; - } + public string Id + { + get; set; + } - public string Label - { - get; - set; - } - public string SIN - { - get; - set; - } - public DateTime DateCreated - { - get; - set; - } - public string TokenValue - { - get; - set; - } - } + public string Facade + { + get; set; + } + public string StoreDataId + { + get; set; + } + public DateTimeOffset Expiration + { + get; + set; + } + + public string Label + { + get; + set; + } + public string SIN + { + get; + set; + } + public DateTime DateCreated + { + get; + set; + } + public string TokenValue + { + get; + set; + } + } } diff --git a/BTCPayServer/Data/PaymentData.cs b/BTCPayServer/Data/PaymentData.cs index 0245e74bd..a2260be52 100644 --- a/BTCPayServer/Data/PaymentData.cs +++ b/BTCPayServer/Data/PaymentData.cs @@ -5,25 +5,25 @@ using System.Threading.Tasks; namespace BTCPayServer.Data { - public class PaymentData - { - public string Id - { - get; set; - } + public class PaymentData + { + public string Id + { + get; set; + } - public string InvoiceDataId - { - get; set; - } - public InvoiceData InvoiceData - { - get; set; - } + public string InvoiceDataId + { + get; set; + } + public InvoiceData InvoiceData + { + get; set; + } - public byte[] Blob - { - get; set; - } - } + public byte[] Blob + { + get; set; + } + } } diff --git a/BTCPayServer/Data/PendingInvoiceData.cs b/BTCPayServer/Data/PendingInvoiceData.cs index 7dff807bc..3fd9a7bcc 100644 --- a/BTCPayServer/Data/PendingInvoiceData.cs +++ b/BTCPayServer/Data/PendingInvoiceData.cs @@ -7,9 +7,9 @@ namespace BTCPayServer.Data { public class PendingInvoiceData { - public string Id - { - get; set; - } - } + public string Id + { + get; set; + } + } } diff --git a/BTCPayServer/Data/RefundData.cs b/BTCPayServer/Data/RefundData.cs index 0b186769a..4d4473909 100644 --- a/BTCPayServer/Data/RefundData.cs +++ b/BTCPayServer/Data/RefundData.cs @@ -7,21 +7,21 @@ namespace BTCPayServer.Data { public class RefundAddressesData { - public string Id - { - get; set; - } - public string InvoiceDataId - { - get; set; - } - public InvoiceData InvoiceData - { - get; set; - } - public byte[] Blob - { - get; set; - } - } + public string Id + { + get; set; + } + public string InvoiceDataId + { + get; set; + } + public InvoiceData InvoiceData + { + get; set; + } + public byte[] Blob + { + get; set; + } + } } diff --git a/BTCPayServer/Data/SettingData.cs b/BTCPayServer/Data/SettingData.cs index e6a783613..34e2693ef 100644 --- a/BTCPayServer/Data/SettingData.cs +++ b/BTCPayServer/Data/SettingData.cs @@ -7,14 +7,14 @@ namespace BTCPayServer.Data { public class SettingData { - public string Id - { - get; set; - } + public string Id + { + get; set; + } - public string Value - { - get; set; - } - } + public string Value + { + get; set; + } + } } diff --git a/BTCPayServer/Data/StoreData.cs b/BTCPayServer/Data/StoreData.cs index c834c0c29..c76702e5e 100644 --- a/BTCPayServer/Data/StoreData.cs +++ b/BTCPayServer/Data/StoreData.cs @@ -13,69 +13,69 @@ namespace BTCPayServer.Data { public class StoreData { - public string Id - { - get; - set; - } + public string Id + { + get; + set; + } - public List UserStores - { - get; set; - } + public List UserStores + { + get; set; + } - public string DerivationStrategy - { - get; set; - } + public string DerivationStrategy + { + get; set; + } - public string StoreName - { - get; set; - } + public string StoreName + { + get; set; + } - public SpeedPolicy SpeedPolicy - { - get; set; - } + public SpeedPolicy SpeedPolicy + { + get; set; + } - public string StoreWebsite - { - get; set; - } + public string StoreWebsite + { + get; set; + } - public byte[] StoreCertificate - { - get; set; - } + public byte[] StoreCertificate + { + get; set; + } - [NotMapped] - public string Role - { - get; set; - } - public byte[] StoreBlob - { - get; - set; - } + [NotMapped] + public string Role + { + get; set; + } + public byte[] StoreBlob + { + get; + set; + } - public StoreBlob GetStoreBlob(Network network) - { - return StoreBlob == null ? new StoreBlob() : new Serializer(network).ToObject(Encoding.UTF8.GetString(StoreBlob)); - } + public StoreBlob GetStoreBlob(Network network) + { + return StoreBlob == null ? new StoreBlob() : new Serializer(network).ToObject(Encoding.UTF8.GetString(StoreBlob)); + } - public void SetStoreBlob(StoreBlob storeBlob, Network network) - { - StoreBlob = Encoding.UTF8.GetBytes(new Serializer(network).ToString(storeBlob)); - } - } + public void SetStoreBlob(StoreBlob storeBlob, Network network) + { + StoreBlob = Encoding.UTF8.GetBytes(new Serializer(network).ToString(storeBlob)); + } + } - public class StoreBlob - { - public bool NetworkFeeDisabled - { - get; set; - } - } + public class StoreBlob + { + public bool NetworkFeeDisabled + { + get; set; + } + } } diff --git a/BTCPayServer/Data/UserStore.cs b/BTCPayServer/Data/UserStore.cs index 6a3f90758..f410b6c2e 100644 --- a/BTCPayServer/Data/UserStore.cs +++ b/BTCPayServer/Data/UserStore.cs @@ -6,29 +6,29 @@ using System.Threading.Tasks; namespace BTCPayServer.Data { - public class UserStore - { - public string ApplicationUserId - { - get; set; - } - public ApplicationUser ApplicationUser - { - get; set; - } + public class UserStore + { + public string ApplicationUserId + { + get; set; + } + public ApplicationUser ApplicationUser + { + get; set; + } - public string StoreDataId - { - get; set; - } - public StoreData StoreData - { - get; set; - } - public string Role - { - get; - set; - } - } + public string StoreDataId + { + get; set; + } + public StoreData StoreData + { + get; set; + } + public string Role + { + get; + set; + } + } } diff --git a/BTCPayServer/Extensions.cs b/BTCPayServer/Extensions.cs index 5d07792bd..4136a1331 100644 --- a/BTCPayServer/Extensions.cs +++ b/BTCPayServer/Extensions.cs @@ -14,54 +14,54 @@ using System.Text.Encodings.Web; namespace BTCPayServer { - public static class Extensions - { - public static string WithTrailingSlash(this string str) - { - if(str.EndsWith("/")) - return str; - return str + "/"; - } + public static class Extensions + { + public static string WithTrailingSlash(this string str) + { + if (str.EndsWith("/")) + return str; + return str + "/"; + } - public static string GetAbsoluteRoot(this HttpRequest request) - { - return string.Concat( - request.Scheme, - "://", - request.Host.ToUriComponent(), - request.PathBase.ToUriComponent()); - } + public static string GetAbsoluteRoot(this HttpRequest request) + { + return string.Concat( + request.Scheme, + "://", + request.Host.ToUriComponent(), + request.PathBase.ToUriComponent()); + } - public static IServiceCollection ConfigureBTCPayServer(this IServiceCollection services, IConfiguration conf) - { - services.Configure(o => - { - o.LoadArgs(conf); - }); - return services; - } + public static IServiceCollection ConfigureBTCPayServer(this IServiceCollection services, IConfiguration conf) + { + services.Configure(o => + { + o.LoadArgs(conf); + }); + return services; + } - public static BitIdentity GetBitIdentity(this Controller controller, bool throws = true) - { - if(!(controller.User.Identity is BitIdentity)) - return throws ? throw new UnauthorizedAccessException("no-bitid") : (BitIdentity)null; - return (BitIdentity)controller.User.Identity; - } + public static BitIdentity GetBitIdentity(this Controller controller, bool throws = true) + { + if (!(controller.User.Identity is BitIdentity)) + return throws ? throw new UnauthorizedAccessException("no-bitid") : (BitIdentity)null; + return (BitIdentity)controller.User.Identity; + } - private static JsonSerializerSettings jsonSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; - public static string ToJson(this object o) - { - var res = JsonConvert.SerializeObject(o, Formatting.None, jsonSettings); - return res; - } + private static JsonSerializerSettings jsonSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; + public static string ToJson(this object o) + { + var res = JsonConvert.SerializeObject(o, Formatting.None, jsonSettings); + return res; + } - public static HtmlString ToSrvModel(this object o) - { - var encodedJson = JavaScriptEncoder.Default.Encode(o.ToJson()); - return new HtmlString("var srvModel = JSON.parse('" + encodedJson + "');"); - } + public static HtmlString ToSrvModel(this object o) + { + var encodedJson = JavaScriptEncoder.Default.Encode(o.ToJson()); + return new HtmlString("var srvModel = JSON.parse('" + encodedJson + "');"); + } - } + } } diff --git a/BTCPayServer/Filters/OnlyMediaTypeAttribute.cs b/BTCPayServer/Filters/OnlyMediaTypeAttribute.cs index 9592b6f73..abca0f908 100644 --- a/BTCPayServer/Filters/OnlyMediaTypeAttribute.cs +++ b/BTCPayServer/Filters/OnlyMediaTypeAttribute.cs @@ -7,72 +7,72 @@ using System.Text; namespace BTCPayServer.Filters { - public class MediaTypeConstraintAttribute : Attribute, IActionConstraint - { - public MediaTypeConstraintAttribute(string mediaType) - { - MediaType = mediaType ?? throw new ArgumentNullException(nameof(mediaType)); - } + public class MediaTypeConstraintAttribute : Attribute, IActionConstraint + { + public MediaTypeConstraintAttribute(string mediaType) + { + MediaType = mediaType ?? throw new ArgumentNullException(nameof(mediaType)); + } - public string MediaType - { - get; set; - } + public string MediaType + { + get; set; + } - public int Order => 100; + public int Order => 100; - public bool Accept(ActionConstraintContext context) - { - var match = context.RouteContext.HttpContext.Request.ContentType?.StartsWith(MediaType, StringComparison.Ordinal); - return match.HasValue && match.Value; - } - } + public bool Accept(ActionConstraintContext context) + { + var match = context.RouteContext.HttpContext.Request.ContentType?.StartsWith(MediaType, StringComparison.Ordinal); + return match.HasValue && match.Value; + } + } - public class BitpayAPIConstraintAttribute : Attribute, IActionConstraint - { - public BitpayAPIConstraintAttribute(bool isBitpayAPI = true) - { - IsBitpayAPI = isBitpayAPI; - } + public class BitpayAPIConstraintAttribute : Attribute, IActionConstraint + { + public BitpayAPIConstraintAttribute(bool isBitpayAPI = true) + { + IsBitpayAPI = isBitpayAPI; + } - public bool IsBitpayAPI - { - get; set; - } - public int Order => 100; + public bool IsBitpayAPI + { + get; set; + } + public int Order => 100; - public bool Accept(ActionConstraintContext context) - { - var hasVersion = context.RouteContext.HttpContext.Request.Headers["x-accept-version"].Where(h => h == "2.0.0").Any(); - var hasIdentity = context.RouteContext.HttpContext.Request.Headers["x-identity"].Any(); - return (hasVersion || hasIdentity) == IsBitpayAPI; - } - } + public bool Accept(ActionConstraintContext context) + { + var hasVersion = context.RouteContext.HttpContext.Request.Headers["x-accept-version"].Where(h => h == "2.0.0").Any(); + var hasIdentity = context.RouteContext.HttpContext.Request.Headers["x-identity"].Any(); + return (hasVersion || hasIdentity) == IsBitpayAPI; + } + } - public class AcceptMediaTypeConstraintAttribute : Attribute, IActionConstraint - { - public AcceptMediaTypeConstraintAttribute(string mediaType, bool expectedValue = true) - { - MediaType = mediaType ?? throw new ArgumentNullException(nameof(mediaType)); - ExpectedValue = expectedValue; - } + public class AcceptMediaTypeConstraintAttribute : Attribute, IActionConstraint + { + public AcceptMediaTypeConstraintAttribute(string mediaType, bool expectedValue = true) + { + MediaType = mediaType ?? throw new ArgumentNullException(nameof(mediaType)); + ExpectedValue = expectedValue; + } - public bool ExpectedValue - { - get; set; - } + public bool ExpectedValue + { + get; set; + } - public string MediaType - { - get; set; - } + public string MediaType + { + get; set; + } - public int Order => 100; + public int Order => 100; - public bool Accept(ActionConstraintContext context) - { - var hasHeader = context.RouteContext.HttpContext.Request.Headers["Accept"].Any(m => m.StartsWith(MediaType, StringComparison.Ordinal)); - return hasHeader == ExpectedValue; - } - } + public bool Accept(ActionConstraintContext context) + { + var hasHeader = context.RouteContext.HttpContext.Request.Headers["Accept"].Any(m => m.StartsWith(MediaType, StringComparison.Ordinal)); + return hasHeader == ExpectedValue; + } + } } diff --git a/BTCPayServer/Filters/XFrameOptionsAttribute.cs b/BTCPayServer/Filters/XFrameOptionsAttribute.cs index d273e33c5..99b2c2be6 100644 --- a/BTCPayServer/Filters/XFrameOptionsAttribute.cs +++ b/BTCPayServer/Filters/XFrameOptionsAttribute.cs @@ -6,28 +6,28 @@ using System.Threading.Tasks; namespace BTCPayServer.Filters { - public class XFrameOptionsAttribute : Attribute, IActionFilter - { - public XFrameOptionsAttribute(string value) - { - Value = value; - } - public string Value - { - get; set; - } - public void OnActionExecuted(ActionExecutedContext context) - { - - } + public class XFrameOptionsAttribute : Attribute, IActionFilter + { + public XFrameOptionsAttribute(string value) + { + Value = value; + } + public string Value + { + get; set; + } + public void OnActionExecuted(ActionExecutedContext context) + { - public void OnActionExecuting(ActionExecutingContext context) - { - var existing = context.HttpContext.Response.Headers["x-frame-options"].FirstOrDefault(); - if(existing != null && Value == null) - context.HttpContext.Response.Headers.Remove("x-frame-options"); - else - context.HttpContext.Response.Headers["x-frame-options"] = Value; - } - } + } + + public void OnActionExecuting(ActionExecutingContext context) + { + var existing = context.HttpContext.Response.Headers["x-frame-options"].FirstOrDefault(); + if (existing != null && Value == null) + context.HttpContext.Response.Headers.Remove("x-frame-options"); + else + context.HttpContext.Response.Headers["x-frame-options"] = Value; + } + } } diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index b929e1f00..c970ef178 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -37,178 +37,178 @@ using Microsoft.Extensions.Caching.Memory; namespace BTCPayServer.Hosting { - public static class BTCPayServerServices - { - public class OwnStoreAuthorizationRequirement : IAuthorizationRequirement - { - public OwnStoreAuthorizationRequirement() - { - } + public static class BTCPayServerServices + { + public class OwnStoreAuthorizationRequirement : IAuthorizationRequirement + { + public OwnStoreAuthorizationRequirement() + { + } - public OwnStoreAuthorizationRequirement(string role) - { - Role = role; - } + public OwnStoreAuthorizationRequirement(string role) + { + Role = role; + } - public string Role - { - get; set; - } - } + public string Role + { + get; set; + } + } - public class OwnStoreHandler : AuthorizationHandler - { - StoreRepository _StoreRepository; - UserManager _UserManager; - public OwnStoreHandler(StoreRepository storeRepository, UserManager userManager) - { - _StoreRepository = storeRepository; - _UserManager = userManager; - } - protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OwnStoreAuthorizationRequirement requirement) - { - object storeId = null; - if(!((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).RouteData.Values.TryGetValue("storeId", out storeId)) - context.Succeed(requirement); - else if(storeId != null) - { - var user = _UserManager.GetUserId(((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).HttpContext.User); - if(user != null) - { - var store = await _StoreRepository.FindStore((string)storeId, user); - if(store != null) - if(requirement.Role == null || requirement.Role == store.Role) - context.Succeed(requirement); - } - } - } - } - class BTCPayServerConfigureOptions : IConfigureOptions - { - BTCPayServerOptions _Options; - public BTCPayServerConfigureOptions(BTCPayServerOptions options) - { - _Options = options; - } - public void Configure(MvcOptions options) - { - if(_Options.RequireHttps) - options.Filters.Add(new RequireHttpsAttribute()); - } - } - public static IServiceCollection AddBTCPayServer(this IServiceCollection services) - { - services.AddDbContext((provider, o) => - { - var factory = provider.GetRequiredService(); - factory.ConfigureBuilder(o); - }); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(o => o.GetRequiredService>().Value); - services.TryAddSingleton, BTCPayServerConfigureOptions>(); - services.TryAddSingleton(o => - { - var runtime = new BTCPayServerRuntime(); - runtime.Configure(o.GetRequiredService()); - return runtime; - }); - services.AddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(o => o.GetRequiredService().InvoiceRepository); - services.TryAddSingleton(o => o.GetRequiredService().Network); - services.TryAddSingleton(o => o.GetRequiredService().DBFactory); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(o => new NBXplorerFeeProvider() - { - Fallback = new FeeRate(100, 1), - BlockTarget = 20, - ExplorerClient = o.GetRequiredService() - }); - services.TryAddSingleton(o => - { - var runtime = o.GetRequiredService(); - return runtime.Explorer; - }); - services.TryAddSingleton(o => - { - if(o.GetRequiredService().Network == Network.Main) - return new Bitpay(new Key(), new Uri("https://bitpay.com/")); - else - return new Bitpay(new Key(), new Uri("https://test.bitpay.com/")); - }); - services.TryAddSingleton(o => - { - return new CachedRateProvider(new CoinAverageRateProvider(), o.GetRequiredService()) { CacheSpan = TimeSpan.FromMinutes(1.0) }; - }); - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(o => o.GetRequiredService()); - services.TryAddScoped(); - services.TryAddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - // Add application services. - services.AddTransient(); + public class OwnStoreHandler : AuthorizationHandler + { + StoreRepository _StoreRepository; + UserManager _UserManager; + public OwnStoreHandler(StoreRepository storeRepository, UserManager userManager) + { + _StoreRepository = storeRepository; + _UserManager = userManager; + } + protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OwnStoreAuthorizationRequirement requirement) + { + object storeId = null; + if (!((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).RouteData.Values.TryGetValue("storeId", out storeId)) + context.Succeed(requirement); + else if (storeId != null) + { + var user = _UserManager.GetUserId(((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).HttpContext.User); + if (user != null) + { + var store = await _StoreRepository.FindStore((string)storeId, user); + if (store != null) + if (requirement.Role == null || requirement.Role == store.Role) + context.Succeed(requirement); + } + } + } + } + class BTCPayServerConfigureOptions : IConfigureOptions + { + BTCPayServerOptions _Options; + public BTCPayServerConfigureOptions(BTCPayServerOptions options) + { + _Options = options; + } + public void Configure(MvcOptions options) + { + if (_Options.RequireHttps) + options.Filters.Add(new RequireHttpsAttribute()); + } + } + public static IServiceCollection AddBTCPayServer(this IServiceCollection services) + { + services.AddDbContext((provider, o) => + { + var factory = provider.GetRequiredService(); + factory.ConfigureBuilder(o); + }); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(o => o.GetRequiredService>().Value); + services.TryAddSingleton, BTCPayServerConfigureOptions>(); + services.TryAddSingleton(o => + { + var runtime = new BTCPayServerRuntime(); + runtime.Configure(o.GetRequiredService()); + return runtime; + }); + services.AddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(o => o.GetRequiredService().InvoiceRepository); + services.TryAddSingleton(o => o.GetRequiredService().Network); + services.TryAddSingleton(o => o.GetRequiredService().DBFactory); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(o => new NBXplorerFeeProvider() + { + Fallback = new FeeRate(100, 1), + BlockTarget = 20, + ExplorerClient = o.GetRequiredService() + }); + services.TryAddSingleton(o => + { + var runtime = o.GetRequiredService(); + return runtime.Explorer; + }); + services.TryAddSingleton(o => + { + if (o.GetRequiredService().Network == Network.Main) + return new Bitpay(new Key(), new Uri("https://bitpay.com/")); + else + return new Bitpay(new Key(), new Uri("https://test.bitpay.com/")); + }); + services.TryAddSingleton(o => + { + return new CachedRateProvider(new CoinAverageRateProvider(), o.GetRequiredService()) { CacheSpan = TimeSpan.FromMinutes(1.0) }; + }); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(o => o.GetRequiredService()); + services.TryAddScoped(); + services.TryAddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + // Add application services. + services.AddTransient(); - services.AddAuthorization(o => - { - o.AddPolicy("CanAccessStore", builder => - { - builder.AddRequirements(new OwnStoreAuthorizationRequirement()); - }); + services.AddAuthorization(o => + { + o.AddPolicy("CanAccessStore", builder => + { + builder.AddRequirements(new OwnStoreAuthorizationRequirement()); + }); - o.AddPolicy("OwnStore", builder => - { - builder.AddRequirements(new OwnStoreAuthorizationRequirement("Owner")); - }); - }); + o.AddPolicy("OwnStore", builder => + { + builder.AddRequirements(new OwnStoreAuthorizationRequirement("Owner")); + }); + }); - return services; - } + return services; + } - public static IApplicationBuilder UsePayServer(this IApplicationBuilder app) - { - if(app.ApplicationServices.GetRequiredService().RequireHttps) - { - var options = new RewriteOptions().AddRedirectToHttps(); - app.UseRewriter(options); - } + public static IApplicationBuilder UsePayServer(this IApplicationBuilder app) + { + if (app.ApplicationServices.GetRequiredService().RequireHttps) + { + var options = new RewriteOptions().AddRedirectToHttps(); + app.UseRewriter(options); + } - using(var scope = app.ApplicationServices.GetService().CreateScope()) - { - //Wait the DB is ready - Retry(() => - { - scope.ServiceProvider.GetRequiredService().Database.Migrate(); - }); - } - app.UseMiddleware(); - return app; - } + using (var scope = app.ApplicationServices.GetService().CreateScope()) + { + //Wait the DB is ready + Retry(() => + { + scope.ServiceProvider.GetRequiredService().Database.Migrate(); + }); + } + app.UseMiddleware(); + return app; + } - static void Retry(Action act) - { - CancellationTokenSource cts = new CancellationTokenSource(10000); - while(true) - { - try - { - act(); - return; - } - catch - { - if(cts.IsCancellationRequested) - throw; - Thread.Sleep(1000); - } - } - } - } + static void Retry(Action act) + { + CancellationTokenSource cts = new CancellationTokenSource(10000); + while (true) + { + try + { + act(); + return; + } + catch + { + if (cts.IsCancellationRequested) + throw; + Thread.Sleep(1000); + } + } + } + } } diff --git a/BTCPayServer/Hosting/BTCpayMiddleware.cs b/BTCPayServer/Hosting/BTCpayMiddleware.cs index e2f2731bd..0ab85d4f9 100644 --- a/BTCPayServer/Hosting/BTCpayMiddleware.cs +++ b/BTCPayServer/Hosting/BTCpayMiddleware.cs @@ -25,94 +25,94 @@ using BTCPayServer.Controllers; namespace BTCPayServer.Hosting { - public class BTCPayMiddleware - { - TokenRepository _TokenRepository; - RequestDelegate _Next; - CallbackController _CallbackController; - public BTCPayMiddleware(RequestDelegate next, - TokenRepository tokenRepo, - CallbackController callbackController) - { - _TokenRepository = tokenRepo ?? throw new ArgumentNullException(nameof(tokenRepo)); - _Next = next ?? throw new ArgumentNullException(nameof(next)); - _CallbackController = callbackController; - } + public class BTCPayMiddleware + { + TokenRepository _TokenRepository; + RequestDelegate _Next; + CallbackController _CallbackController; + public BTCPayMiddleware(RequestDelegate next, + TokenRepository tokenRepo, + CallbackController callbackController) + { + _TokenRepository = tokenRepo ?? throw new ArgumentNullException(nameof(tokenRepo)); + _Next = next ?? throw new ArgumentNullException(nameof(next)); + _CallbackController = callbackController; + } - bool _Registered; - public async Task Invoke(HttpContext httpContext) - { - if(!_Registered) - { - var callback = await _CallbackController.RegisterCallbackBlockUriAsync(httpContext.Request); - Logs.PayServer.LogInformation($"Registering block callback to " + callback); - _Registered = true; - } + bool _Registered; + public async Task Invoke(HttpContext httpContext) + { + if (!_Registered) + { + var callback = await _CallbackController.RegisterCallbackBlockUriAsync(httpContext.Request); + Logs.PayServer.LogInformation($"Registering block callback to " + callback); + _Registered = true; + } - httpContext.Request.Headers.TryGetValue("x-signature", out StringValues values); - var sig = values.FirstOrDefault(); - httpContext.Request.Headers.TryGetValue("x-identity", out values); - var id = values.FirstOrDefault(); - if(!string.IsNullOrEmpty(sig) && !string.IsNullOrEmpty(id)) - { - httpContext.Request.EnableRewind(); + httpContext.Request.Headers.TryGetValue("x-signature", out StringValues values); + var sig = values.FirstOrDefault(); + httpContext.Request.Headers.TryGetValue("x-identity", out values); + var id = values.FirstOrDefault(); + if (!string.IsNullOrEmpty(sig) && !string.IsNullOrEmpty(id)) + { + httpContext.Request.EnableRewind(); - string body = string.Empty; - if(httpContext.Request.ContentLength != 0 && httpContext.Request.Body != null) - { - using(StreamReader reader = new StreamReader(httpContext.Request.Body, Encoding.UTF8, true, 1024, true)) - { - body = reader.ReadToEnd(); - } - httpContext.Request.Body.Position = 0; - } + string body = string.Empty; + if (httpContext.Request.ContentLength != 0 && httpContext.Request.Body != null) + { + using (StreamReader reader = new StreamReader(httpContext.Request.Body, Encoding.UTF8, true, 1024, true)) + { + body = reader.ReadToEnd(); + } + httpContext.Request.Body.Position = 0; + } - var url = httpContext.Request.GetEncodedUrl(); - try - { - var key = new PubKey(id); - if(BitIdExtensions.CheckBitIDSignature(key, sig, url, body)) - { - var bitid = new BitIdentity(key); - httpContext.User = new GenericPrincipal(bitid, new string[0]); - Logs.PayServer.LogDebug($"BitId signature check success for SIN {bitid.SIN}"); - } - } - catch(FormatException) { } - if(!(httpContext.User.Identity is BitIdentity)) - Logs.PayServer.LogDebug("BitId signature check failed"); - } + var url = httpContext.Request.GetEncodedUrl(); + try + { + var key = new PubKey(id); + if (BitIdExtensions.CheckBitIDSignature(key, sig, url, body)) + { + var bitid = new BitIdentity(key); + httpContext.User = new GenericPrincipal(bitid, new string[0]); + Logs.PayServer.LogDebug($"BitId signature check success for SIN {bitid.SIN}"); + } + } + catch (FormatException) { } + if (!(httpContext.User.Identity is BitIdentity)) + Logs.PayServer.LogDebug("BitId signature check failed"); + } - try - { - await _Next(httpContext); - } - catch(UnauthorizedAccessException ex) - { - await HandleBitpayHttpException(httpContext, new BitpayHttpException(401, ex.Message)); - } - catch(BitpayHttpException ex) - { - await HandleBitpayHttpException(httpContext, ex); - } - catch(Exception ex) - { - Logs.PayServer.LogCritical(new EventId(), ex, "Unhandled exception in BTCPayMiddleware"); - throw; - } - } + try + { + await _Next(httpContext); + } + catch (UnauthorizedAccessException ex) + { + await HandleBitpayHttpException(httpContext, new BitpayHttpException(401, ex.Message)); + } + catch (BitpayHttpException ex) + { + await HandleBitpayHttpException(httpContext, ex); + } + catch (Exception ex) + { + Logs.PayServer.LogCritical(new EventId(), ex, "Unhandled exception in BTCPayMiddleware"); + throw; + } + } - private static async Task HandleBitpayHttpException(HttpContext httpContext, BitpayHttpException ex) - { - httpContext.Response.StatusCode = ex.StatusCode; - using(var writer = new StreamWriter(httpContext.Response.Body, new UTF8Encoding(false), 1024, true)) - { - httpContext.Response.ContentType = "application/json"; - var result = JsonConvert.SerializeObject(new BitpayErrorsModel(ex)); - writer.Write(result); - await writer.FlushAsync(); - } - } - } + private static async Task HandleBitpayHttpException(HttpContext httpContext, BitpayHttpException ex) + { + httpContext.Response.StatusCode = ex.StatusCode; + using (var writer = new StreamWriter(httpContext.Response.Body, new UTF8Encoding(false), 1024, true)) + { + httpContext.Response.ContentType = "application/json"; + var result = JsonConvert.SerializeObject(new BitpayErrorsModel(ex)); + writer.Write(result); + await writer.FlushAsync(); + } + } + } } diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs index ac2887823..dcf6d3549 100644 --- a/BTCPayServer/Hosting/Startup.cs +++ b/BTCPayServer/Hosting/Startup.cs @@ -39,117 +39,117 @@ using Microsoft.AspNetCore.Mvc.Cors.Internal; namespace BTCPayServer.Hosting { - public class Startup - { - class NeedRole : IDashboardAuthorizationFilter - { - string _Role; - public NeedRole(string role) - { - _Role = role; - } - public bool Authorize([NotNull] DashboardContext context) - { - return context.GetHttpContext().User.IsInRole(_Role); - } - } - public Startup(IConfiguration conf, IHostingEnvironment env) - { - Configuration = conf; - _Env = env; - } - IHostingEnvironment _Env; - public IConfiguration Configuration - { - get; set; - } - - public void ConfigureServices(IServiceCollection services) - { - services.ConfigureBTCPayServer(Configuration); - services.AddMemoryCache(); - services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); + public class Startup + { + class NeedRole : IDashboardAuthorizationFilter + { + string _Role; + public NeedRole(string role) + { + _Role = role; + } + public bool Authorize([NotNull] DashboardContext context) + { + return context.GetHttpContext().User.IsInRole(_Role); + } + } + public Startup(IConfiguration conf, IHostingEnvironment env) + { + Configuration = conf; + _Env = env; + } + IHostingEnvironment _Env; + public IConfiguration Configuration + { + get; set; + } - // Big hack, tests fails because Hangfire fail at initializing at the second test run - AddHangfireFix(services); - services.AddBTCPayServer(); - services.AddMvc(o => - { - o.Filters.Add(new XFrameOptionsAttribute("DENY")); - }); - } + public void ConfigureServices(IServiceCollection services) + { + services.ConfigureBTCPayServer(Configuration); + services.AddMemoryCache(); + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); - // Big hack, tests fails if only call AddHangfire because Hangfire fail at initializing at the second test run - private void AddHangfireFix(IServiceCollection services) - { - Action configuration = o => - { - var scope = AspNetCoreJobActivator.Current.BeginScope(null); - var options = (ApplicationDbContextFactory)scope.Resolve(typeof(ApplicationDbContextFactory)); - options.ConfigureHangfireBuilder(o); - }; + // Big hack, tests fails because Hangfire fail at initializing at the second test run + AddHangfireFix(services); + services.AddBTCPayServer(); + services.AddMvc(o => + { + o.Filters.Add(new XFrameOptionsAttribute("DENY")); + }); + } - ServiceCollectionDescriptorExtensions.TryAddSingleton>(services, (IServiceProvider serviceProvider) => new Action((config) => - { - ILoggerFactory service = ServiceProviderServiceExtensions.GetService(serviceProvider); - if(service != null) - { - Hangfire.GlobalConfigurationExtensions.UseLogProvider(config, new AspNetCoreLogProvider(service)); - } - IServiceScopeFactory service2 = ServiceProviderServiceExtensions.GetService(serviceProvider); - if(service2 != null) - { - Hangfire.GlobalConfigurationExtensions.UseActivator(config, new AspNetCoreJobActivator(service2)); - } - configuration(config); - })); + // Big hack, tests fails if only call AddHangfire because Hangfire fail at initializing at the second test run + private void AddHangfireFix(IServiceCollection services) + { + Action configuration = o => + { + var scope = AspNetCoreJobActivator.Current.BeginScope(null); + var options = (ApplicationDbContextFactory)scope.Resolve(typeof(ApplicationDbContextFactory)); + options.ConfigureHangfireBuilder(o); + }; - services.AddHangfire(configuration); - services.AddCors(o => - { - o.AddPolicy("BitpayAPI", b => - { - b.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); - }); - }); + ServiceCollectionDescriptorExtensions.TryAddSingleton>(services, (IServiceProvider serviceProvider) => new Action((config) => + { + ILoggerFactory service = ServiceProviderServiceExtensions.GetService(serviceProvider); + if (service != null) + { + Hangfire.GlobalConfigurationExtensions.UseLogProvider(config, new AspNetCoreLogProvider(service)); + } + IServiceScopeFactory service2 = ServiceProviderServiceExtensions.GetService(serviceProvider); + if (service2 != null) + { + Hangfire.GlobalConfigurationExtensions.UseActivator(config, new AspNetCoreJobActivator(service2)); + } + configuration(config); + })); - services.Configure>(o => - { - o.Value.DeveloperMode = _Env.IsDevelopment(); - }); - } + services.AddHangfire(configuration); + services.AddCors(o => + { + o.AddPolicy("BitpayAPI", b => + { + b.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); + }); + }); - public void Configure( - IApplicationBuilder app, - IHostingEnvironment env, - IServiceProvider prov, - ILoggerFactory loggerFactory) - { - if(env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - app.UseBrowserLink(); - } + services.Configure>(o => + { + o.Value.DeveloperMode = _Env.IsDevelopment(); + }); + } + + public void Configure( + IApplicationBuilder app, + IHostingEnvironment env, + IServiceProvider prov, + ILoggerFactory loggerFactory) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseBrowserLink(); + } - Logs.Configure(loggerFactory); + Logs.Configure(loggerFactory); - //App insight do not that by itself... - loggerFactory.AddApplicationInsights(prov, LogLevel.Information); + //App insight do not that by itself... + loggerFactory.AddApplicationInsights(prov, LogLevel.Information); - app.UsePayServer(); - app.UseStaticFiles(); - app.UseAuthentication(); - app.UseHangfireServer(); - app.UseHangfireDashboard("/hangfire", new DashboardOptions() { Authorization = new[] { new NeedRole(Roles.ServerAdmin) } }); - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); - } - } + app.UsePayServer(); + app.UseStaticFiles(); + app.UseAuthentication(); + app.UseHangfireServer(); + app.UseHangfireDashboard("/hangfire", new DashboardOptions() { Authorization = new[] { new NeedRole(Roles.ServerAdmin) } }); + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); + } + } } diff --git a/BTCPayServer/Logging/ConsoleLogger.cs b/BTCPayServer/Logging/ConsoleLogger.cs index ecd1af282..bf9e2492b 100644 --- a/BTCPayServer/Logging/ConsoleLogger.cs +++ b/BTCPayServer/Logging/ConsoleLogger.cs @@ -10,391 +10,391 @@ using System.Threading.Tasks; namespace BTCPayServer.Logging { - public class CustomConsoleLogProvider : ILoggerProvider - { - ConsoleLoggerProcessor _Processor = new ConsoleLoggerProcessor(); - public ILogger CreateLogger(string categoryName) - { - return new CustomConsoleLogger(categoryName, (a,b) => true, false, _Processor); - } + public class CustomConsoleLogProvider : ILoggerProvider + { + ConsoleLoggerProcessor _Processor = new ConsoleLoggerProcessor(); + public ILogger CreateLogger(string categoryName) + { + return new CustomConsoleLogger(categoryName, (a, b) => true, false, _Processor); + } - public void Dispose() - { - - } - } + public void Dispose() + { - /// - /// A variant of ASP.NET Core ConsoleLogger which does not make new line for the category - /// - public class CustomConsoleLogger : ILogger - { - private static readonly string _loglevelPadding = ": "; - private static readonly string _messagePadding; - private static readonly string _newLineWithMessagePadding; + } + } - // ConsoleColor does not have a value to specify the 'Default' color - private readonly ConsoleColor? DefaultConsoleColor = null; + /// + /// A variant of ASP.NET Core ConsoleLogger which does not make new line for the category + /// + public class CustomConsoleLogger : ILogger + { + private static readonly string _loglevelPadding = ": "; + private static readonly string _messagePadding; + private static readonly string _newLineWithMessagePadding; - private readonly ConsoleLoggerProcessor _queueProcessor; - private Func _filter; + // ConsoleColor does not have a value to specify the 'Default' color + private readonly ConsoleColor? DefaultConsoleColor = null; - [ThreadStatic] - private static StringBuilder _logBuilder; + private readonly ConsoleLoggerProcessor _queueProcessor; + private Func _filter; - static CustomConsoleLogger() - { - var logLevelString = GetLogLevelString(LogLevel.Information); - _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); - _newLineWithMessagePadding = Environment.NewLine + _messagePadding; - } + [ThreadStatic] + private static StringBuilder _logBuilder; - public CustomConsoleLogger(string name, Func filter, bool includeScopes, ConsoleLoggerProcessor loggerProcessor) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - Filter = filter ?? ((category, logLevel) => true); - IncludeScopes = includeScopes; + static CustomConsoleLogger() + { + var logLevelString = GetLogLevelString(LogLevel.Information); + _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); + _newLineWithMessagePadding = Environment.NewLine + _messagePadding; + } - _queueProcessor = loggerProcessor; + public CustomConsoleLogger(string name, Func filter, bool includeScopes, ConsoleLoggerProcessor loggerProcessor) + { + Name = name ?? throw new ArgumentNullException(nameof(name)); + Filter = filter ?? ((category, logLevel) => true); + IncludeScopes = includeScopes; - if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Console = new WindowsLogConsole(); - } - else - { - Console = new AnsiLogConsole(new AnsiSystemConsole()); - } - } + _queueProcessor = loggerProcessor; - public IConsole Console - { - get - { - return _queueProcessor.Console; - } - set - { - _queueProcessor.Console = value ?? throw new ArgumentNullException(nameof(value)); - } - } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Console = new WindowsLogConsole(); + } + else + { + Console = new AnsiLogConsole(new AnsiSystemConsole()); + } + } - public Func Filter - { - get - { - return _filter; - } - set - { - _filter = value ?? throw new ArgumentNullException(nameof(value)); - } - } + public IConsole Console + { + get + { + return _queueProcessor.Console; + } + set + { + _queueProcessor.Console = value ?? throw new ArgumentNullException(nameof(value)); + } + } - public bool IncludeScopes - { - get; set; - } + public Func Filter + { + get + { + return _filter; + } + set + { + _filter = value ?? throw new ArgumentNullException(nameof(value)); + } + } - public string Name - { - get; - } + public bool IncludeScopes + { + get; set; + } - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - if(!IsEnabled(logLevel)) - { - return; - } + public string Name + { + get; + } - if(formatter == null) - { - throw new ArgumentNullException(nameof(formatter)); - } + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + if (!IsEnabled(logLevel)) + { + return; + } - var message = formatter(state, exception); + if (formatter == null) + { + throw new ArgumentNullException(nameof(formatter)); + } - if(!string.IsNullOrEmpty(message) || exception != null) - { - WriteMessage(logLevel, Name, eventId.Id, message, exception); - } - } + var message = formatter(state, exception); - public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception) - { - var logBuilder = _logBuilder; - _logBuilder = null; + if (!string.IsNullOrEmpty(message) || exception != null) + { + WriteMessage(logLevel, Name, eventId.Id, message, exception); + } + } - if(logBuilder == null) - { - logBuilder = new StringBuilder(); - } + public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception) + { + var logBuilder = _logBuilder; + _logBuilder = null; - var logLevelColors = default(ConsoleColors); - var logLevelString = string.Empty; + if (logBuilder == null) + { + logBuilder = new StringBuilder(); + } - // Example: - // INFO: ConsoleApp.Program[10] - // Request received + var logLevelColors = default(ConsoleColors); + var logLevelString = string.Empty; - logLevelColors = GetLogLevelConsoleColors(logLevel); - logLevelString = GetLogLevelString(logLevel); - // category and event id - var lenBefore = logBuilder.ToString().Length; - logBuilder.Append(_loglevelPadding); - logBuilder.Append(logName); - logBuilder.Append(": "); - var lenAfter = logBuilder.ToString().Length; - while(lenAfter++ < 18) - logBuilder.Append(" "); - // scope information - if(IncludeScopes) - { - GetScopeInformation(logBuilder); - } + // Example: + // INFO: ConsoleApp.Program[10] + // Request received - if(!string.IsNullOrEmpty(message)) - { - // message - //logBuilder.Append(_messagePadding); + logLevelColors = GetLogLevelConsoleColors(logLevel); + logLevelString = GetLogLevelString(logLevel); + // category and event id + var lenBefore = logBuilder.ToString().Length; + logBuilder.Append(_loglevelPadding); + logBuilder.Append(logName); + logBuilder.Append(": "); + var lenAfter = logBuilder.ToString().Length; + while (lenAfter++ < 18) + logBuilder.Append(" "); + // scope information + if (IncludeScopes) + { + GetScopeInformation(logBuilder); + } - var len = logBuilder.Length; - logBuilder.AppendLine(message); - logBuilder.Replace(Environment.NewLine, _newLineWithMessagePadding, len, message.Length); - } + if (!string.IsNullOrEmpty(message)) + { + // message + //logBuilder.Append(_messagePadding); - // Example: - // System.InvalidOperationException - // at Namespace.Class.Function() in File:line X - if(exception != null) - { - // exception message - logBuilder.AppendLine(exception.ToString()); - } + var len = logBuilder.Length; + logBuilder.AppendLine(message); + logBuilder.Replace(Environment.NewLine, _newLineWithMessagePadding, len, message.Length); + } - if(logBuilder.Length > 0) - { - var hasLevel = !string.IsNullOrEmpty(logLevelString); - // Queue log message - _queueProcessor.EnqueueMessage(new LogMessageEntry() - { - Message = logBuilder.ToString(), - MessageColor = DefaultConsoleColor, - LevelString = hasLevel ? logLevelString : null, - LevelBackground = hasLevel ? logLevelColors.Background : null, - LevelForeground = hasLevel ? logLevelColors.Foreground : null - }); - } + // Example: + // System.InvalidOperationException + // at Namespace.Class.Function() in File:line X + if (exception != null) + { + // exception message + logBuilder.AppendLine(exception.ToString()); + } - logBuilder.Clear(); - if(logBuilder.Capacity > 1024) - { - logBuilder.Capacity = 1024; - } - _logBuilder = logBuilder; - } + if (logBuilder.Length > 0) + { + var hasLevel = !string.IsNullOrEmpty(logLevelString); + // Queue log message + _queueProcessor.EnqueueMessage(new LogMessageEntry() + { + Message = logBuilder.ToString(), + MessageColor = DefaultConsoleColor, + LevelString = hasLevel ? logLevelString : null, + LevelBackground = hasLevel ? logLevelColors.Background : null, + LevelForeground = hasLevel ? logLevelColors.Foreground : null + }); + } - public bool IsEnabled(LogLevel logLevel) - { - return Filter(Name, logLevel); - } + logBuilder.Clear(); + if (logBuilder.Capacity > 1024) + { + logBuilder.Capacity = 1024; + } + _logBuilder = logBuilder; + } - public IDisposable BeginScope(TState state) - { - if(state == null) - { - throw new ArgumentNullException(nameof(state)); - } + public bool IsEnabled(LogLevel logLevel) + { + return Filter(Name, logLevel); + } - return ConsoleLogScope.Push(Name, state); - } + public IDisposable BeginScope(TState state) + { + if (state == null) + { + throw new ArgumentNullException(nameof(state)); + } - private static string GetLogLevelString(LogLevel logLevel) - { - switch(logLevel) - { - case LogLevel.Trace: - return "trce"; - case LogLevel.Debug: - return "dbug"; - case LogLevel.Information: - return "info"; - case LogLevel.Warning: - return "warn"; - case LogLevel.Error: - return "fail"; - case LogLevel.Critical: - return "crit"; - default: - throw new ArgumentOutOfRangeException(nameof(logLevel)); - } - } + return ConsoleLogScope.Push(Name, state); + } - private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) - { - // We must explicitly set the background color if we are setting the foreground color, - // since just setting one can look bad on the users console. - switch(logLevel) - { - case LogLevel.Critical: - return new ConsoleColors(ConsoleColor.White, ConsoleColor.Red); - case LogLevel.Error: - return new ConsoleColors(ConsoleColor.Black, ConsoleColor.Red); - case LogLevel.Warning: - return new ConsoleColors(ConsoleColor.Yellow, ConsoleColor.Black); - case LogLevel.Information: - return new ConsoleColors(ConsoleColor.DarkGreen, ConsoleColor.Black); - case LogLevel.Debug: - return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); - case LogLevel.Trace: - return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); - default: - return new ConsoleColors(DefaultConsoleColor, DefaultConsoleColor); - } - } + private static string GetLogLevelString(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Trace: + return "trce"; + case LogLevel.Debug: + return "dbug"; + case LogLevel.Information: + return "info"; + case LogLevel.Warning: + return "warn"; + case LogLevel.Error: + return "fail"; + case LogLevel.Critical: + return "crit"; + default: + throw new ArgumentOutOfRangeException(nameof(logLevel)); + } + } - private void GetScopeInformation(StringBuilder builder) - { - var current = ConsoleLogScope.Current; - string scopeLog = string.Empty; - var length = builder.Length; + private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) + { + // We must explicitly set the background color if we are setting the foreground color, + // since just setting one can look bad on the users console. + switch (logLevel) + { + case LogLevel.Critical: + return new ConsoleColors(ConsoleColor.White, ConsoleColor.Red); + case LogLevel.Error: + return new ConsoleColors(ConsoleColor.Black, ConsoleColor.Red); + case LogLevel.Warning: + return new ConsoleColors(ConsoleColor.Yellow, ConsoleColor.Black); + case LogLevel.Information: + return new ConsoleColors(ConsoleColor.DarkGreen, ConsoleColor.Black); + case LogLevel.Debug: + return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); + case LogLevel.Trace: + return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); + default: + return new ConsoleColors(DefaultConsoleColor, DefaultConsoleColor); + } + } - while(current != null) - { - if(length == builder.Length) - { - scopeLog = $"=> {current}"; - } - else - { - scopeLog = $"=> {current} "; - } + private void GetScopeInformation(StringBuilder builder) + { + var current = ConsoleLogScope.Current; + string scopeLog = string.Empty; + var length = builder.Length; - builder.Insert(length, scopeLog); - current = current.Parent; - } - if(builder.Length > length) - { - builder.Insert(length, _messagePadding); - builder.AppendLine(); - } - } + while (current != null) + { + if (length == builder.Length) + { + scopeLog = $"=> {current}"; + } + else + { + scopeLog = $"=> {current} "; + } - private struct ConsoleColors - { - public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) - { - Foreground = foreground; - Background = background; - } + builder.Insert(length, scopeLog); + current = current.Parent; + } + if (builder.Length > length) + { + builder.Insert(length, _messagePadding); + builder.AppendLine(); + } + } - public ConsoleColor? Foreground - { - get; - } + private struct ConsoleColors + { + public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) + { + Foreground = foreground; + Background = background; + } - public ConsoleColor? Background - { - get; - } - } + public ConsoleColor? Foreground + { + get; + } - private class AnsiSystemConsole : IAnsiSystemConsole - { - public void Write(string message) - { - System.Console.Write(message); - } + public ConsoleColor? Background + { + get; + } + } - public void WriteLine(string message) - { - System.Console.WriteLine(message); - } - } - } + private class AnsiSystemConsole : IAnsiSystemConsole + { + public void Write(string message) + { + System.Console.Write(message); + } - public class ConsoleLoggerProcessor : IDisposable - { - private const int _maxQueuedMessages = 1024; + public void WriteLine(string message) + { + System.Console.WriteLine(message); + } + } + } - private readonly BlockingCollection _messageQueue = new BlockingCollection(_maxQueuedMessages); - private readonly Task _outputTask; + public class ConsoleLoggerProcessor : IDisposable + { + private const int _maxQueuedMessages = 1024; - public IConsole Console; + private readonly BlockingCollection _messageQueue = new BlockingCollection(_maxQueuedMessages); + private readonly Task _outputTask; - public ConsoleLoggerProcessor() - { - // Start Console message queue processor - _outputTask = Task.Factory.StartNew( - ProcessLogQueue, - this, - TaskCreationOptions.LongRunning); - } + public IConsole Console; - public virtual void EnqueueMessage(LogMessageEntry message) - { - if(!_messageQueue.IsAddingCompleted) - { - try - { - _messageQueue.Add(message); - return; - } - catch(InvalidOperationException) { } - } + public ConsoleLoggerProcessor() + { + // Start Console message queue processor + _outputTask = Task.Factory.StartNew( + ProcessLogQueue, + this, + TaskCreationOptions.LongRunning); + } - // Adding is completed so just log the message - WriteMessage(message); - } + public virtual void EnqueueMessage(LogMessageEntry message) + { + if (!_messageQueue.IsAddingCompleted) + { + try + { + _messageQueue.Add(message); + return; + } + catch (InvalidOperationException) { } + } - // for testing - internal virtual void WriteMessage(LogMessageEntry message) - { - if(message.LevelString != null) - { - Console.Write(message.LevelString, message.LevelBackground, message.LevelForeground); - } + // Adding is completed so just log the message + WriteMessage(message); + } - Console.Write(message.Message, message.MessageColor, message.MessageColor); - Console.Flush(); - } + // for testing + internal virtual void WriteMessage(LogMessageEntry message) + { + if (message.LevelString != null) + { + Console.Write(message.LevelString, message.LevelBackground, message.LevelForeground); + } - private void ProcessLogQueue() - { - foreach(var message in _messageQueue.GetConsumingEnumerable()) - { - WriteMessage(message); - } - } + Console.Write(message.Message, message.MessageColor, message.MessageColor); + Console.Flush(); + } - private static void ProcessLogQueue(object state) - { - var consoleLogger = (ConsoleLoggerProcessor)state; + private void ProcessLogQueue() + { + foreach (var message in _messageQueue.GetConsumingEnumerable()) + { + WriteMessage(message); + } + } - consoleLogger.ProcessLogQueue(); - } + private static void ProcessLogQueue(object state) + { + var consoleLogger = (ConsoleLoggerProcessor)state; - public void Dispose() - { - _messageQueue.CompleteAdding(); + consoleLogger.ProcessLogQueue(); + } - try - { - _outputTask.Wait(1500); // with timeout in-case Console is locked by user input - } - catch(TaskCanceledException) { } - catch(AggregateException ex) when(ex.InnerExceptions.Count == 1 && ex.InnerExceptions[0] is TaskCanceledException) { } - } - } + public void Dispose() + { + _messageQueue.CompleteAdding(); - public struct LogMessageEntry - { - public string LevelString; - public ConsoleColor? LevelBackground; - public ConsoleColor? LevelForeground; - public ConsoleColor? MessageColor; - public string Message; - } + try + { + _outputTask.Wait(1500); // with timeout in-case Console is locked by user input + } + catch (TaskCanceledException) { } + catch (AggregateException ex) when (ex.InnerExceptions.Count == 1 && ex.InnerExceptions[0] is TaskCanceledException) { } + } + } + + public struct LogMessageEntry + { + public string LevelString; + public ConsoleColor? LevelBackground; + public ConsoleColor? LevelForeground; + public ConsoleColor? MessageColor; + public string Message; + } } diff --git a/BTCPayServer/Logging/Logs.cs b/BTCPayServer/Logging/Logs.cs index c616dbfc9..463911995 100644 --- a/BTCPayServer/Logging/Logs.cs +++ b/BTCPayServer/Logging/Logs.cs @@ -7,48 +7,48 @@ using System.Threading.Tasks; namespace BTCPayServer.Logging { - public class Logs - { - static Logs() - { - Configure(new FuncLoggerFactory(n => NullLogger.Instance)); - } - public static void Configure(ILoggerFactory factory) - { - Configuration = factory.CreateLogger("Configuration"); - PayServer = factory.CreateLogger("PayServer"); - } - public static ILogger Configuration - { - get; set; - } - public static ILogger PayServer - { - get; set; - } - public const int ColumnLength = 16; - } + public class Logs + { + static Logs() + { + Configure(new FuncLoggerFactory(n => NullLogger.Instance)); + } + public static void Configure(ILoggerFactory factory) + { + Configuration = factory.CreateLogger("Configuration"); + PayServer = factory.CreateLogger("PayServer"); + } + public static ILogger Configuration + { + get; set; + } + public static ILogger PayServer + { + get; set; + } + public const int ColumnLength = 16; + } - public class FuncLoggerFactory : ILoggerFactory - { - private Func createLogger; - public FuncLoggerFactory(Func createLogger) - { - this.createLogger = createLogger; - } - public void AddProvider(ILoggerProvider provider) - { + public class FuncLoggerFactory : ILoggerFactory + { + private Func createLogger; + public FuncLoggerFactory(Func createLogger) + { + this.createLogger = createLogger; + } + public void AddProvider(ILoggerProvider provider) + { - } + } - public ILogger CreateLogger(string categoryName) - { - return createLogger(categoryName); - } + public ILogger CreateLogger(string categoryName) + { + return createLogger(categoryName); + } - public void Dispose() - { + public void Dispose() + { - } - } + } + } } diff --git a/BTCPayServer/Migrations/20171012020112_PendingInvoices.cs b/BTCPayServer/Migrations/20171012020112_PendingInvoices.cs index 47ff49392..4f66f788a 100644 --- a/BTCPayServer/Migrations/20171012020112_PendingInvoices.cs +++ b/BTCPayServer/Migrations/20171012020112_PendingInvoices.cs @@ -4,51 +4,51 @@ using System.Collections.Generic; namespace BTCPayServer.Migrations { - public partial class PendingInvoices : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - if(SupportDropColumn(migrationBuilder.ActiveProvider)) - { - migrationBuilder.DropColumn( - name: "Name", - table: "PairingCodes"); + public partial class PendingInvoices : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + if (SupportDropColumn(migrationBuilder.ActiveProvider)) + { + migrationBuilder.DropColumn( + name: "Name", + table: "PairingCodes"); - migrationBuilder.DropColumn( - name: "Name", - table: "PairedSINData"); - } - migrationBuilder.CreateTable( - name: "PendingInvoices", - columns: table => new - { - Id = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PendingInvoices", x => x.Id); - }); - } + migrationBuilder.DropColumn( + name: "Name", + table: "PairedSINData"); + } + migrationBuilder.CreateTable( + name: "PendingInvoices", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PendingInvoices", x => x.Id); + }); + } - private bool SupportDropColumn(string activeProvider) - { - return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite"; - } + private bool SupportDropColumn(string activeProvider) + { + return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite"; + } - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PendingInvoices"); + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PendingInvoices"); - migrationBuilder.AddColumn( - name: "Name", - table: "PairingCodes", - nullable: true); + migrationBuilder.AddColumn( + name: "Name", + table: "PairingCodes", + nullable: true); - migrationBuilder.AddColumn( - name: "Name", - table: "PairedSINData", - nullable: true); - } - } + migrationBuilder.AddColumn( + name: "Name", + table: "PairedSINData", + nullable: true); + } + } } diff --git a/BTCPayServer/Models/AccountViewModels/LoginWithRecoveryCodeViewModel.cs b/BTCPayServer/Models/AccountViewModels/LoginWithRecoveryCodeViewModel.cs index b51745499..4c20017bc 100644 --- a/BTCPayServer/Models/AccountViewModels/LoginWithRecoveryCodeViewModel.cs +++ b/BTCPayServer/Models/AccountViewModels/LoginWithRecoveryCodeViewModel.cs @@ -8,9 +8,9 @@ namespace BTCPayServer.Models.AccountViewModels { public class LoginWithRecoveryCodeViewModel { - [Required] - [DataType(DataType.Text)] - [Display(Name = "Recovery Code")] - public string RecoveryCode { get; set; } + [Required] + [DataType(DataType.Text)] + [Display(Name = "Recovery Code")] + public string RecoveryCode { get; set; } } } diff --git a/BTCPayServer/Models/ApplicationUser.cs b/BTCPayServer/Models/ApplicationUser.cs index 19440a4c9..d5c04ccad 100644 --- a/BTCPayServer/Models/ApplicationUser.cs +++ b/BTCPayServer/Models/ApplicationUser.cs @@ -10,15 +10,15 @@ namespace BTCPayServer.Models // Add profile data for application users by adding properties to the ApplicationUser class public class ApplicationUser : IdentityUser { - public List UserStores - { - get; - set; - } + public List UserStores + { + get; + set; + } - public bool RequiresEmailConfirmation - { - get; set; - } - } + public bool RequiresEmailConfirmation + { + get; set; + } + } } diff --git a/BTCPayServer/Models/BitpayErrorsModel.cs b/BTCPayServer/Models/BitpayErrorsModel.cs index f7d8ebc00..1225749c2 100644 --- a/BTCPayServer/Models/BitpayErrorsModel.cs +++ b/BTCPayServer/Models/BitpayErrorsModel.cs @@ -5,35 +5,35 @@ using System.Text; namespace BTCPayServer.Models { - public class BitpayErrorsModel - { - public BitpayErrorsModel() - { + public class BitpayErrorsModel + { + public BitpayErrorsModel() + { - } - public BitpayErrorsModel(BitpayHttpException ex) - { - Error = ex.Message; - } + } + public BitpayErrorsModel(BitpayHttpException ex) + { + Error = ex.Message; + } - [JsonProperty("errors", DefaultValueHandling = DefaultValueHandling.Ignore)] - public BitpayErrorModel[] Errors - { - get; set; - } - [JsonProperty("error", DefaultValueHandling = DefaultValueHandling.Ignore)] - public string Error - { - get; set; - } - } + [JsonProperty("errors", DefaultValueHandling = DefaultValueHandling.Ignore)] + public BitpayErrorModel[] Errors + { + get; set; + } + [JsonProperty("error", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string Error + { + get; set; + } + } - public class BitpayErrorModel - { - [JsonProperty("error")] - public string Error - { - get; set; - } - } + public class BitpayErrorModel + { + [JsonProperty("error")] + public string Error + { + get; set; + } + } } diff --git a/BTCPayServer/Models/ConfirmModel.cs b/BTCPayServer/Models/ConfirmModel.cs index 5a112ca31..172db1eb5 100644 --- a/BTCPayServer/Models/ConfirmModel.cs +++ b/BTCPayServer/Models/ConfirmModel.cs @@ -7,17 +7,17 @@ namespace BTCPayServer.Models { public class ConfirmModel { - public string Title - { - get; set; - } - public string Description - { - get; set; - } - public string Action - { - get; set; - } - } + public string Title + { + get; set; + } + public string Description + { + get; set; + } + public string Action + { + get; set; + } + } } diff --git a/BTCPayServer/Models/DataWrapper.cs b/BTCPayServer/Models/DataWrapper.cs index 46211884d..4d708cda1 100644 --- a/BTCPayServer/Models/DataWrapper.cs +++ b/BTCPayServer/Models/DataWrapper.cs @@ -5,33 +5,33 @@ using System.Text; namespace BTCPayServer.Models { - public class DataWrapper - { - public static DataWrapper Create(T obj) - { - return new DataWrapper(obj); - } - } - public class DataWrapper - { - public DataWrapper() - { + public class DataWrapper + { + public static DataWrapper Create(T obj) + { + return new DataWrapper(obj); + } + } + public class DataWrapper + { + public DataWrapper() + { - } - public DataWrapper(T data) - { - Data = data; - } + } + public DataWrapper(T data) + { + Data = data; + } - [JsonProperty("facade", NullValueHandling = NullValueHandling.Ignore)] - public string Facade - { - get; set; - } - [JsonProperty("data")] - public T Data - { - get; set; - } - } + [JsonProperty("facade", NullValueHandling = NullValueHandling.Ignore)] + public string Facade + { + get; set; + } + [JsonProperty("data")] + public T Data + { + get; set; + } + } } diff --git a/BTCPayServer/Models/GetTokensResponse.cs b/BTCPayServer/Models/GetTokensResponse.cs index dea8ae5e7..246b1e2da 100644 --- a/BTCPayServer/Models/GetTokensResponse.cs +++ b/BTCPayServer/Models/GetTokensResponse.cs @@ -12,43 +12,43 @@ using System.IO; namespace BTCPayServer.Models { - //{"data":[{"pos":"FfZ6WCa8TunAvPCpQZXkdBsoH4Yo18FyPaJ5X5qjrVVY"},{"pos/invoice":"H1pwwh2tMeSCri9rh5VvHWEHokGdf2EGtghfZkUEbeZv"},{"merchant":"89zEBr9orAc6wgybAABp8ioGcjYeFrUaZgMzjxNuqYty"},{"merchant/invoice":"8e7ijDxGfJsWXWgJuKXjjNgxnX1xpsBM8cTZCFnU7ehj"}]} - public class GetTokensResponse : IActionResult - { - BitTokenEntity[] _Tokens; - public GetTokensResponse(BitTokenEntity[] tokens) - { - if(tokens == null) - throw new ArgumentNullException(nameof(tokens)); - this._Tokens = tokens; - } + //{"data":[{"pos":"FfZ6WCa8TunAvPCpQZXkdBsoH4Yo18FyPaJ5X5qjrVVY"},{"pos/invoice":"H1pwwh2tMeSCri9rh5VvHWEHokGdf2EGtghfZkUEbeZv"},{"merchant":"89zEBr9orAc6wgybAABp8ioGcjYeFrUaZgMzjxNuqYty"},{"merchant/invoice":"8e7ijDxGfJsWXWgJuKXjjNgxnX1xpsBM8cTZCFnU7ehj"}]} + public class GetTokensResponse : IActionResult + { + BitTokenEntity[] _Tokens; + public GetTokensResponse(BitTokenEntity[] tokens) + { + if (tokens == null) + throw new ArgumentNullException(nameof(tokens)); + this._Tokens = tokens; + } - [JsonProperty(PropertyName = "data")] - //{"pos":"FfZ6WCa8TunAvPCpQZXkdBsoH4Yo18FyPaJ5X5qjrVVY"} - public JArray Data - { - get; set; - } + [JsonProperty(PropertyName = "data")] + //{"pos":"FfZ6WCa8TunAvPCpQZXkdBsoH4Yo18FyPaJ5X5qjrVVY"} + public JArray Data + { + get; set; + } - public async Task ExecuteResultAsync(ActionContext context) - { - JObject jobj = new JObject(); - JArray jarray = new JArray(); - jobj.Add("data", jarray); - foreach(var token in _Tokens) - { - JObject item = new JObject(); - jarray.Add(item); - JProperty jProp = new JProperty(token.Facade); - item.Add(jProp); - jProp.Value = token.Value; - } - context.HttpContext.Response.Headers.Add("Content-Type", new Microsoft.Extensions.Primitives.StringValues("application/json")); - var str = JsonConvert.SerializeObject(jobj); - using(var writer = new StreamWriter(context.HttpContext.Response.Body, new UTF8Encoding(false), 1024 * 10, true)) - { - await writer.WriteAsync(str); - } - } - } + public async Task ExecuteResultAsync(ActionContext context) + { + JObject jobj = new JObject(); + JArray jarray = new JArray(); + jobj.Add("data", jarray); + foreach (var token in _Tokens) + { + JObject item = new JObject(); + jarray.Add(item); + JProperty jProp = new JProperty(token.Facade); + item.Add(jProp); + jProp.Value = token.Value; + } + context.HttpContext.Response.Headers.Add("Content-Type", new Microsoft.Extensions.Primitives.StringValues("application/json")); + var str = JsonConvert.SerializeObject(jobj); + using (var writer = new StreamWriter(context.HttpContext.Response.Body, new UTF8Encoding(false), 1024 * 10, true)) + { + await writer.WriteAsync(str); + } + } + } } diff --git a/BTCPayServer/Models/InvoiceResponse.cs b/BTCPayServer/Models/InvoiceResponse.cs index a4ad6b34f..08b9db6ef 100644 --- a/BTCPayServer/Models/InvoiceResponse.cs +++ b/BTCPayServer/Models/InvoiceResponse.cs @@ -6,220 +6,220 @@ using System.Text; namespace BTCPayServer.Models { - class DateTimeJsonConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return objectType == typeof(DateTimeOffset); - } + class DateTimeJsonConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(DateTimeOffset); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var v = (long)reader.Value; - Check(v); - return unixRef + TimeSpan.FromMilliseconds((long)v); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var v = (long)reader.Value; + Check(v); + return unixRef + TimeSpan.FromMilliseconds((long)v); + } - static DateTimeOffset unixRef = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var date = ((DateTimeOffset)value).ToUniversalTime(); - long v = (long)(date - unixRef).TotalMilliseconds; - Check(v); - writer.WriteValue(v); - } + static DateTimeOffset unixRef = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var date = ((DateTimeOffset)value).ToUniversalTime(); + long v = (long)(date - unixRef).TotalMilliseconds; + Check(v); + writer.WriteValue(v); + } - private static void Check(long v) - { - if(v < 0) - throw new FormatException("Invalid datetime (less than 1/1/1970)"); - } - } + private static void Check(long v) + { + if (v < 0) + throw new FormatException("Invalid datetime (less than 1/1/1970)"); + } + } - //{"facade":"pos/invoice","data":{,}} - public class InvoiceResponse - { - //"url":"https://test.bitpay.com/invoice?id=9saCHtp1zyPcNoi3rDdBu8" - [JsonProperty("url")] - public string Url - { - get; set; - } - //"posData":"posData" - [JsonProperty("posData")] - public string PosData - { - get; set; - } - //status":"new" - [JsonProperty("status")] - public string Status - { - get; set; - } - //"btcPrice":"0.001157" - [JsonProperty("btcPrice")] - public string BTCPrice - { - get; set; - } + //{"facade":"pos/invoice","data":{,}} + public class InvoiceResponse + { + //"url":"https://test.bitpay.com/invoice?id=9saCHtp1zyPcNoi3rDdBu8" + [JsonProperty("url")] + public string Url + { + get; set; + } + //"posData":"posData" + [JsonProperty("posData")] + public string PosData + { + get; set; + } + //status":"new" + [JsonProperty("status")] + public string Status + { + get; set; + } + //"btcPrice":"0.001157" + [JsonProperty("btcPrice")] + public string BTCPrice + { + get; set; + } - //"btcDue":"0.001160" - [JsonProperty("btcDue")] - public string BTCDue - { - get; set; - } + //"btcDue":"0.001160" + [JsonProperty("btcDue")] + public string BTCDue + { + get; set; + } - //"price":5 - [JsonProperty("price")] - public double Price - { - get; set; - } + //"price":5 + [JsonProperty("price")] + public double Price + { + get; set; + } - //"currency":"USD" - [JsonProperty("currency")] - public string Currency - { - get; set; - } + //"currency":"USD" + [JsonProperty("currency")] + public string Currency + { + get; set; + } - //"exRates":{"USD":4320.02} - [JsonProperty("exRates")] - public Dictionary ExRates - { - get; set; - } + //"exRates":{"USD":4320.02} + [JsonProperty("exRates")] + public Dictionary ExRates + { + get; set; + } - //"buyerTotalBtcAmount":"0.001160" - [JsonProperty("buyerTotalBtcAmount")] - public string BuyerTotalBtcAmount - { - get; set; - } + //"buyerTotalBtcAmount":"0.001160" + [JsonProperty("buyerTotalBtcAmount")] + public string BuyerTotalBtcAmount + { + get; set; + } - //"itemDesc":"Some description" - [JsonProperty("itemDesc")] - public string ItemDesc - { - get; set; - } + //"itemDesc":"Some description" + [JsonProperty("itemDesc")] + public string ItemDesc + { + get; set; + } - //"orderId":"orderId" - [JsonProperty("orderId")] - public string OrderId - { - get; set; - } + //"orderId":"orderId" + [JsonProperty("orderId")] + public string OrderId + { + get; set; + } - //"guid":"e238ce2a-06da-47e9-aefd-2588d4aa5f8d" - [JsonProperty("guid")] - public string Guid - { - get; set; - } - //"id":"9saCHtp1zyPcNoi3rDdBu8" - [JsonProperty("id")] - public string Id - { - get; set; - } + //"guid":"e238ce2a-06da-47e9-aefd-2588d4aa5f8d" + [JsonProperty("guid")] + public string Guid + { + get; set; + } + //"id":"9saCHtp1zyPcNoi3rDdBu8" + [JsonProperty("id")] + public string Id + { + get; set; + } - [JsonConverter(typeof(DateTimeJsonConverter))] - [JsonProperty("invoiceTime")] - public DateTimeOffset InvoiceTime - { - get; set; - } + [JsonConverter(typeof(DateTimeJsonConverter))] + [JsonProperty("invoiceTime")] + public DateTimeOffset InvoiceTime + { + get; set; + } - [JsonConverter(typeof(DateTimeJsonConverter))] - [JsonProperty("expirationTime")] - public DateTimeOffset ExpirationTime - { - get; set; - } + [JsonConverter(typeof(DateTimeJsonConverter))] + [JsonProperty("expirationTime")] + public DateTimeOffset ExpirationTime + { + get; set; + } - [JsonConverter(typeof(DateTimeJsonConverter))] - [JsonProperty("currentTime")] - public DateTimeOffset CurrentTime - { - get; set; - } + [JsonConverter(typeof(DateTimeJsonConverter))] + [JsonProperty("currentTime")] + public DateTimeOffset CurrentTime + { + get; set; + } - //"lowFeeDetected":false - [JsonProperty("lowFeeDetected")] - public bool LowFeeDetected - { - get; set; - } + //"lowFeeDetected":false + [JsonProperty("lowFeeDetected")] + public bool LowFeeDetected + { + get; set; + } - //"btcPaid":"0.000000" - [JsonProperty("btcPaid")] - public string BTCPaid - { - get; set; - } + //"btcPaid":"0.000000" + [JsonProperty("btcPaid")] + public string BTCPaid + { + get; set; + } - //"rate":4320.02 - [JsonProperty("rate")] - public double Rate - { - get; set; - } + //"rate":4320.02 + [JsonProperty("rate")] + public double Rate + { + get; set; + } - //"exceptionStatus":false - //Can be `paidPartial`, `paidOver`, or false - [JsonProperty("exceptionStatus")] - public JToken ExceptionStatus - { - get; set; - } + //"exceptionStatus":false + //Can be `paidPartial`, `paidOver`, or false + [JsonProperty("exceptionStatus")] + public JToken ExceptionStatus + { + get; set; + } - //"paymentUrls":{"BIP21":"bitcoin:muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv?amount=0.001160","BIP72":"bitcoin:muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv?amount=0.001160&r=https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8","BIP72b":"bitcoin:?r=https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8","BIP73":"https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8"} - [JsonProperty("paymentUrls")] - public NBitpayClient.InvoicePaymentUrls PaymentUrls - { - get; set; - } - //"refundAddressRequestPending":false - [JsonProperty("refundAddressRequestPending")] - public bool RefundAddressRequestPending - { - get; set; - } - //"buyerPaidBtcMinerFee":"0.000003" - [JsonProperty("buyerPaidBtcMinerFee")] - public string BuyerPaidBtcMinerFee - { - get; set; - } + //"paymentUrls":{"BIP21":"bitcoin:muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv?amount=0.001160","BIP72":"bitcoin:muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv?amount=0.001160&r=https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8","BIP72b":"bitcoin:?r=https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8","BIP73":"https://test.bitpay.com/i/9saCHtp1zyPcNoi3rDdBu8"} + [JsonProperty("paymentUrls")] + public NBitpayClient.InvoicePaymentUrls PaymentUrls + { + get; set; + } + //"refundAddressRequestPending":false + [JsonProperty("refundAddressRequestPending")] + public bool RefundAddressRequestPending + { + get; set; + } + //"buyerPaidBtcMinerFee":"0.000003" + [JsonProperty("buyerPaidBtcMinerFee")] + public string BuyerPaidBtcMinerFee + { + get; set; + } - //"bitcoinAddress":"muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv" - [JsonProperty("bitcoinAddress")] - public string BitcoinAddress - { - get; set; - } - //"token":"9jF3TU7A8inKHDRQXFrKcRnMkLXWGQ2yKf7pnjMKGHEfpwTNV35HytrD9FXDBy25Li" - [JsonProperty("token")] - public string Token - { - get; set; - } + //"bitcoinAddress":"muFQCEbfRJohcds3bkfv1sRFj8uVTfv2wv" + [JsonProperty("bitcoinAddress")] + public string BitcoinAddress + { + get; set; + } + //"token":"9jF3TU7A8inKHDRQXFrKcRnMkLXWGQ2yKf7pnjMKGHEfpwTNV35HytrD9FXDBy25Li" + [JsonProperty("token")] + public string Token + { + get; set; + } - [JsonProperty("flags")] - public Flags Flags - { - get; set; - } - } - public class Flags - { - [JsonProperty("refundable")] - public bool Refundable - { - get; set; - } - } + [JsonProperty("flags")] + public Flags Flags + { + get; set; + } + } + public class Flags + { + [JsonProperty("refundable")] + public bool Refundable + { + get; set; + } + } } diff --git a/BTCPayServer/Models/InvoicingModels/CreateInvoiceModel.cs b/BTCPayServer/Models/InvoicingModels/CreateInvoiceModel.cs index b6b5c76b1..065ecff54 100644 --- a/BTCPayServer/Models/InvoicingModels/CreateInvoiceModel.cs +++ b/BTCPayServer/Models/InvoicingModels/CreateInvoiceModel.cs @@ -7,52 +7,52 @@ using System.Threading.Tasks; namespace BTCPayServer.Models.InvoicingModels { - public class CreateInvoiceModel - { - [Required] - public double? Amount - { - get; set; - } + public class CreateInvoiceModel + { + [Required] + public double? Amount + { + get; set; + } - [Required] - public string StoreId - { - get; set; - } + [Required] + public string StoreId + { + get; set; + } - public string OrderId - { - get; set; - } + public string OrderId + { + get; set; + } - public string ItemDesc - { - get; set; - } + public string ItemDesc + { + get; set; + } - public string PosData - { - get; set; - } + public string PosData + { + get; set; + } - [EmailAddress] - public string BuyerEmail - { - get; set; - } + [EmailAddress] + public string BuyerEmail + { + get; set; + } - [Url] - public string NotificationUrl - { - get; set; - } + [Url] + public string NotificationUrl + { + get; set; + } - public SelectList Stores - { - get; - set; - } - } + public SelectList Stores + { + get; + set; + } + } } diff --git a/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs b/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs index 320c4d4e9..72d2e16e5 100644 --- a/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs +++ b/BTCPayServer/Models/InvoicingModels/InvoiceDetailsModel.cs @@ -9,138 +9,138 @@ namespace BTCPayServer.Models.InvoicingModels { public class InvoiceDetailsModel { - public class Payment - { - public int Confirmations - { - get; set; - } - public BitcoinAddress DepositAddress - { - get; set; - } - public string Amount - { - get; set; - } - public string TransactionId - { - get; set; - } - public DateTimeOffset ReceivedTime - { - get; - internal set; - } - public string TransactionLink - { - get; - set; - } - } + public class Payment + { + public int Confirmations + { + get; set; + } + public BitcoinAddress DepositAddress + { + get; set; + } + public string Amount + { + get; set; + } + public string TransactionId + { + get; set; + } + public DateTimeOffset ReceivedTime + { + get; + internal set; + } + public string TransactionLink + { + get; + set; + } + } - public string StatusMessage - { - get; set; - } - public String Id - { - get; set; - } + public string StatusMessage + { + get; set; + } + public String Id + { + get; set; + } - public List Payments - { - get; set; - } = new List(); + public List Payments + { + get; set; + } = new List(); - public string Status - { - get; set; - } + public string Status + { + get; set; + } - public DateTimeOffset CreatedDate - { - get; set; - } + public DateTimeOffset CreatedDate + { + get; set; + } - public DateTimeOffset ExpirationDate - { - get; set; - } + public DateTimeOffset ExpirationDate + { + get; set; + } - public string OrderId - { - get; set; - } - public string RefundEmail - { - get; - set; - } - public BuyerInformation BuyerInformation - { - get; - set; - } - public object StoreName - { - get; - internal set; - } - public string StoreLink - { - get; - set; - } - public double Rate - { - get; - internal set; - } - public string NotificationUrl - { - get; - internal set; - } - public string Fiat - { - get; - set; - } - public string BTC - { - get; - set; - } - public string BTCDue - { - get; - set; - } - public string BTCPaid - { - get; - internal set; - } - public String NetworkFee - { - get; - internal set; - } - public ProductInformation ProductInformation - { - get; - internal set; - } - public BitcoinAddress BitcoinAddress - { - get; - internal set; - } - public string PaymentUrl - { - get; - set; - } - } + public string OrderId + { + get; set; + } + public string RefundEmail + { + get; + set; + } + public BuyerInformation BuyerInformation + { + get; + set; + } + public object StoreName + { + get; + internal set; + } + public string StoreLink + { + get; + set; + } + public double Rate + { + get; + internal set; + } + public string NotificationUrl + { + get; + internal set; + } + public string Fiat + { + get; + set; + } + public string BTC + { + get; + set; + } + public string BTCDue + { + get; + set; + } + public string BTCPaid + { + get; + internal set; + } + public String NetworkFee + { + get; + internal set; + } + public ProductInformation ProductInformation + { + get; + internal set; + } + public BitcoinAddress BitcoinAddress + { + get; + internal set; + } + public string PaymentUrl + { + get; + set; + } + } } diff --git a/BTCPayServer/Models/InvoicingModels/InvoicesModel.cs b/BTCPayServer/Models/InvoicingModels/InvoicesModel.cs index 86eaa69cc..ded7c45fd 100644 --- a/BTCPayServer/Models/InvoicingModels/InvoicesModel.cs +++ b/BTCPayServer/Models/InvoicingModels/InvoicesModel.cs @@ -7,53 +7,53 @@ namespace BTCPayServer.Models.InvoicingModels { public class InvoicesModel { - public int Skip - { - get; set; - } - public int Count - { - get; set; - } - public string SearchTerm - { - get; set; - } + public int Skip + { + get; set; + } + public int Count + { + get; set; + } + public string SearchTerm + { + get; set; + } - public List Invoices - { - get; set; - } = new List(); - public string StatusMessage - { - get; - set; - } - } + public List Invoices + { + get; set; + } = new List(); + public string StatusMessage + { + get; + set; + } + } - public class InvoiceModel - { - public DateTimeOffset Date - { - get; set; - } + public class InvoiceModel + { + public DateTimeOffset Date + { + get; set; + } - public string InvoiceId - { - get; set; - } + public string InvoiceId + { + get; set; + } - public string Status - { - get; set; - } - public string AmountCurrency - { - get; set; - } - public string StatusMessage - { - get; set; - } - } + public string Status + { + get; set; + } + public string AmountCurrency + { + get; set; + } + public string StatusMessage + { + get; set; + } + } } diff --git a/BTCPayServer/Models/InvoicingModels/PaymentModel.cs b/BTCPayServer/Models/InvoicingModels/PaymentModel.cs index 0c11f8dd8..5e5e55a5e 100644 --- a/BTCPayServer/Models/InvoicingModels/PaymentModel.cs +++ b/BTCPayServer/Models/InvoicingModels/PaymentModel.cs @@ -5,31 +5,31 @@ using System.Threading.Tasks; namespace BTCPayServer.Models.InvoicingModels { - public class PaymentModel - { - public string ServerUrl { get; set; } - public string InvoiceId { get; set; } - public string BtcAddress { get; set; } - public string BtcDue { get; set; } - public string CustomerEmail { get; set; } - public int ExpirationSeconds { get; set; } - public string Status { get; set; } - public string MerchantRefLink { get; set; } - public int MaxTimeSeconds { get; set; } + public class PaymentModel + { + public string ServerUrl { get; set; } + public string InvoiceId { get; set; } + public string BtcAddress { get; set; } + public string BtcDue { get; set; } + public string CustomerEmail { get; set; } + public int ExpirationSeconds { get; set; } + public string Status { get; set; } + public string MerchantRefLink { get; set; } + public int MaxTimeSeconds { get; set; } - // These properties are not used in client side code - public string StoreName { get; set; } - public string ItemDesc { get; set; } - public string TimeLeft { get; set; } - public string Rate { get; set; } - public string BtcAmount { get; set; } - public string TxFees { get; set; } - public string InvoiceBitcoinUrl { get; set; } - public string BtcTotalDue { get; set; } - public int TxCount { get; set; } - public string BtcPaid { get; set; } - public string StoreEmail { get; set; } + // These properties are not used in client side code + public string StoreName { get; set; } + public string ItemDesc { get; set; } + public string TimeLeft { get; set; } + public string Rate { get; set; } + public string BtcAmount { get; set; } + public string TxFees { get; set; } + public string InvoiceBitcoinUrl { get; set; } + public string BtcTotalDue { get; set; } + public int TxCount { get; set; } + public string BtcPaid { get; set; } + public string StoreEmail { get; set; } - public string OrderId { get; set; } - } + public string OrderId { get; set; } + } } diff --git a/BTCPayServer/Models/InvoicingModels/UpdateCustomerModel.cs b/BTCPayServer/Models/InvoicingModels/UpdateCustomerModel.cs index 8a4cfd3d9..262fe354b 100644 --- a/BTCPayServer/Models/InvoicingModels/UpdateCustomerModel.cs +++ b/BTCPayServer/Models/InvoicingModels/UpdateCustomerModel.cs @@ -8,11 +8,11 @@ namespace BTCPayServer.Models.InvoicingModels { public class UpdateCustomerModel { - [EmailAddress] - [Required] - public string Email - { - get; set; - } - } + [EmailAddress] + [Required] + public string Email + { + get; set; + } + } } diff --git a/BTCPayServer/Models/ManageViewModels/EnableAuthenticatorViewModel.cs b/BTCPayServer/Models/ManageViewModels/EnableAuthenticatorViewModel.cs index 9ac8d40bd..9ba033259 100644 --- a/BTCPayServer/Models/ManageViewModels/EnableAuthenticatorViewModel.cs +++ b/BTCPayServer/Models/ManageViewModels/EnableAuthenticatorViewModel.cs @@ -9,15 +9,15 @@ namespace BTCPayServer.Models.ManageViewModels { public class EnableAuthenticatorViewModel { - [Required] - [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Text)] - [Display(Name = "Verification Code")] - public string Code { get; set; } + [Required] + [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] + [DataType(DataType.Text)] + [Display(Name = "Verification Code")] + public string Code { get; set; } - [ReadOnly(true)] - public string SharedKey { get; set; } + [ReadOnly(true)] + public string SharedKey { get; set; } - public string AuthenticatorUri { get; set; } + public string AuthenticatorUri { get; set; } } } diff --git a/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs b/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs index 05d54d013..2bda905bc 100644 --- a/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs +++ b/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs @@ -12,25 +12,25 @@ namespace BTCPayServer.Models.ManageViewModels public string Username { get; set; } - [Required] - [EmailAddress] - [MaxLength(50)] - public string Email - { - get; set; - } + [Required] + [EmailAddress] + [MaxLength(50)] + public string Email + { + get; set; + } - public bool IsEmailConfirmed { get; set; } + public bool IsEmailConfirmed { get; set; } - [Phone] + [Phone] [Display(Name = "Phone number")] - [MaxLength(50)] - public string PhoneNumber { get; set; } + [MaxLength(50)] + public string PhoneNumber { get; set; } - public string StatusMessage - { - get; set; - } + public string StatusMessage + { + get; set; + } - } + } } diff --git a/BTCPayServer/Models/ServerViewModels/EmailsViewModel.cs b/BTCPayServer/Models/ServerViewModels/EmailsViewModel.cs index 7abed7697..47307dfc2 100644 --- a/BTCPayServer/Models/ServerViewModels/EmailsViewModel.cs +++ b/BTCPayServer/Models/ServerViewModels/EmailsViewModel.cs @@ -10,20 +10,20 @@ namespace BTCPayServer.Models.ServerViewModels { public class EmailsViewModel { - public string StatusMessage - { - get; set; - } - public EmailSettings Settings - { - get; set; - } + public string StatusMessage + { + get; set; + } + public EmailSettings Settings + { + get; set; + } - [Required] - [EmailAddress] - public string TestEmail - { - get; set; - } - } + [Required] + [EmailAddress] + public string TestEmail + { + get; set; + } + } } diff --git a/BTCPayServer/Models/ServerViewModels/UsersViewModel.cs b/BTCPayServer/Models/ServerViewModels/UsersViewModel.cs index f5cf2c2bb..230fb2cba 100644 --- a/BTCPayServer/Models/ServerViewModels/UsersViewModel.cs +++ b/BTCPayServer/Models/ServerViewModels/UsersViewModel.cs @@ -7,27 +7,27 @@ namespace BTCPayServer.Models.ServerViewModels { public class UsersViewModel { - public class UserViewModel - { - public string Name - { - get; set; - } - public string Email - { - get; set; - } - } + public class UserViewModel + { + public string Name + { + get; set; + } + public string Email + { + get; set; + } + } - public string StatusMessage - { - get; set; - } + public string StatusMessage + { + get; set; + } - public List Users - { - get; set; - } = new List(); - } + public List Users + { + get; set; + } = new List(); + } } diff --git a/BTCPayServer/Models/StoreViewModels/CreateStoreViewModel.cs b/BTCPayServer/Models/StoreViewModels/CreateStoreViewModel.cs index 0565c17bb..734bd0c98 100644 --- a/BTCPayServer/Models/StoreViewModels/CreateStoreViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/CreateStoreViewModel.cs @@ -8,12 +8,12 @@ namespace BTCPayServer.Models.StoreViewModels { public class CreateStoreViewModel { - [Required] - [MaxLength(50)] - [MinLength(1)] - public string Name - { - get; set; - } - } + [Required] + [MaxLength(50)] + [MinLength(1)] + public string Name + { + get; set; + } + } } diff --git a/BTCPayServer/Models/StoreViewModels/PairingModel.cs b/BTCPayServer/Models/StoreViewModels/PairingModel.cs index 01ea06d68..5d34a8799 100644 --- a/BTCPayServer/Models/StoreViewModels/PairingModel.cs +++ b/BTCPayServer/Models/StoreViewModels/PairingModel.cs @@ -8,44 +8,44 @@ namespace BTCPayServer.Models.StoreViewModels { public class PairingModel { - public class StoreViewModel - { - public string Name - { - get; set; - } - public string Id - { - get; set; - } - } - public string Id - { - get; set; - } - public string Label - { - get; set; - } - public string Facade - { - get; set; - } - public string SIN - { - get; set; - } - public StoreViewModel[] Stores - { - get; - set; - } + public class StoreViewModel + { + public string Name + { + get; set; + } + public string Id + { + get; set; + } + } + public string Id + { + get; set; + } + public string Label + { + get; set; + } + public string Facade + { + get; set; + } + public string SIN + { + get; set; + } + public StoreViewModel[] Stores + { + get; + set; + } - [Display(Name = "Pair to")] - [Required] - public string SelectedStore - { - get; set; - } - } + [Display(Name = "Pair to")] + [Required] + public string SelectedStore + { + get; set; + } + } } diff --git a/BTCPayServer/Models/StoreViewModels/StoreViewModel.cs b/BTCPayServer/Models/StoreViewModels/StoreViewModel.cs index 203b75dc7..579a55cb2 100644 --- a/BTCPayServer/Models/StoreViewModels/StoreViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/StoreViewModel.cs @@ -10,50 +10,50 @@ namespace BTCPayServer.Models.StoreViewModels { public class StoreViewModel { - [Display(Name = "Store Name")] - [Required] - [MaxLength(50)] - [MinLength(1)] - public string StoreName - { - get; set; - } + [Display(Name = "Store Name")] + [Required] + [MaxLength(50)] + [MinLength(1)] + public string StoreName + { + get; set; + } - [Url] - [Display(Name = "Store Website")] - [MaxLength(500)] - public string StoreWebsite - { - get; - set; - } + [Url] + [Display(Name = "Store Website")] + [MaxLength(500)] + public string StoreWebsite + { + get; + set; + } - [DerivationStrategyValidator] - public string DerivationScheme - { - get; set; - } + [DerivationStrategyValidator] + public string DerivationScheme + { + get; set; + } - [Display(Name = "Consider the invoice confirmed when the payment transaction...")] - public SpeedPolicy SpeedPolicy - { - get; set; - } + [Display(Name = "Consider the invoice confirmed when the payment transaction...")] + public SpeedPolicy SpeedPolicy + { + get; set; + } - [Display(Name = "Add network fee to invoice (vary with mining fees)")] - public bool NetworkFee - { - get; set; - } + [Display(Name = "Add network fee to invoice (vary with mining fees)")] + public bool NetworkFee + { + get; set; + } - public List<(string KeyPath, string Address)> AddressSamples - { - get; set; - } = new List<(string KeyPath, string Address)>(); + public List<(string KeyPath, string Address)> AddressSamples + { + get; set; + } = new List<(string KeyPath, string Address)>(); - public string StatusMessage - { - get; set; - } - } + public string StatusMessage + { + get; set; + } + } } diff --git a/BTCPayServer/Models/StoreViewModels/StoresViewModel.cs b/BTCPayServer/Models/StoreViewModels/StoresViewModel.cs index 32fb2ea9d..67b25c472 100644 --- a/BTCPayServer/Models/StoreViewModels/StoresViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/StoresViewModel.cs @@ -8,34 +8,34 @@ namespace BTCPayServer.Models.StoreViewModels { public class StoresViewModel { - public string StatusMessage - { - get; set; - } - public List Stores - { - get; set; - } = new List(); - public class StoreViewModel - { - public string Name - { - get; set; - } + public string StatusMessage + { + get; set; + } + public List Stores + { + get; set; + } = new List(); + public class StoreViewModel + { + public string Name + { + get; set; + } - public string WebSite - { - get; set; - } + public string WebSite + { + get; set; + } - public string Id - { - get; set; - } - public Money Balance - { - get; set; - } - } - } + public string Id + { + get; set; + } + public Money Balance + { + get; set; + } + } + } } diff --git a/BTCPayServer/Models/StoreViewModels/TokensViewModel.cs b/BTCPayServer/Models/StoreViewModels/TokensViewModel.cs index f5dd739dc..694b5d64d 100644 --- a/BTCPayServer/Models/StoreViewModels/TokensViewModel.cs +++ b/BTCPayServer/Models/StoreViewModels/TokensViewModel.cs @@ -8,65 +8,65 @@ using System.Threading.Tasks; namespace BTCPayServer.Models.StoreViewModels { - public class CreateTokenViewModel - { - [PubKeyValidatorAttribute] - public string PublicKey - { - get; set; - } - - public string Label - { - get; set; - } - - [Required] - public string Facade - { - get; set; - } - - [Required] - public string StoreId - { - get; set; - } - - public SelectList Stores - { - get; set; - } - } - public class TokenViewModel - { - public string Id - { - get; set; - } - public string Label - { - get; set; - } - public string SIN - { - get; set; - } - public string Facade - { - get; set; - } - } - public class TokensViewModel + public class CreateTokenViewModel { - public TokenViewModel[] Tokens - { - get; set; - } - public string StatusMessage - { - get; - set; - } - } + [PubKeyValidatorAttribute] + public string PublicKey + { + get; set; + } + + public string Label + { + get; set; + } + + [Required] + public string Facade + { + get; set; + } + + [Required] + public string StoreId + { + get; set; + } + + public SelectList Stores + { + get; set; + } + } + public class TokenViewModel + { + public string Id + { + get; set; + } + public string Label + { + get; set; + } + public string SIN + { + get; set; + } + public string Facade + { + get; set; + } + } + public class TokensViewModel + { + public TokenViewModel[] Tokens + { + get; set; + } + public string StatusMessage + { + get; + set; + } + } } diff --git a/BTCPayServer/Models/TokenRequest.cs b/BTCPayServer/Models/TokenRequest.cs index 8513a01f5..2479af21c 100644 --- a/BTCPayServer/Models/TokenRequest.cs +++ b/BTCPayServer/Models/TokenRequest.cs @@ -6,83 +6,83 @@ using NBitcoin; namespace BTCPayServer.Models { - public class TokenRequest - { - [JsonProperty(PropertyName = "id")] - public string Id - { - get; set; - } + public class TokenRequest + { + [JsonProperty(PropertyName = "id")] + public string Id + { + get; set; + } - [JsonProperty(PropertyName = "guid")] - public string Guid - { - get; set; - } - [JsonProperty(PropertyName = "facade")] - public string Facade - { - get; set; - } - [JsonProperty(PropertyName = "count")] - public int Count - { - get; set; - } - [JsonProperty(PropertyName = "label")] - public string Label - { - get; set; - } + [JsonProperty(PropertyName = "guid")] + public string Guid + { + get; set; + } + [JsonProperty(PropertyName = "facade")] + public string Facade + { + get; set; + } + [JsonProperty(PropertyName = "count")] + public int Count + { + get; set; + } + [JsonProperty(PropertyName = "label")] + public string Label + { + get; set; + } - [JsonProperty(PropertyName = "pairingCode")] - public string PairingCode - { - get; set; - } - } + [JsonProperty(PropertyName = "pairingCode")] + public string PairingCode + { + get; set; + } + } - public class PairingCodeResponse - { - [JsonProperty(PropertyName = "pairingCode")] - public string PairingCode - { - get; set; - } + public class PairingCodeResponse + { + [JsonProperty(PropertyName = "pairingCode")] + public string PairingCode + { + get; set; + } - [JsonProperty(PropertyName = "pairingExpiration")] - [JsonConverter(typeof(DateTimeJsonConverter))] - public DateTimeOffset PairingExpiration - { - get; set; - } + [JsonProperty(PropertyName = "pairingExpiration")] + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTimeOffset PairingExpiration + { + get; set; + } - [JsonProperty(PropertyName = "dateCreated")] - [JsonConverter(typeof(DateTimeJsonConverter))] - public DateTimeOffset DateCreated - { - get; set; - } + [JsonProperty(PropertyName = "dateCreated")] + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTimeOffset DateCreated + { + get; set; + } - [JsonProperty(PropertyName = "facade")] - public string Facade - { - get; - set; - } + [JsonProperty(PropertyName = "facade")] + public string Facade + { + get; + set; + } - [JsonProperty(PropertyName = "token")] - public string Token - { - get; - set; - } + [JsonProperty(PropertyName = "token")] + public string Token + { + get; + set; + } - [JsonProperty(PropertyName = "label")] - public string Label - { - get; - set; - } - } + [JsonProperty(PropertyName = "label")] + public string Label + { + get; + set; + } + } } diff --git a/BTCPayServer/Program.cs b/BTCPayServer/Program.cs index 5a9b92314..4c4a23408 100644 --- a/BTCPayServer/Program.cs +++ b/BTCPayServer/Program.cs @@ -18,60 +18,60 @@ using System.Threading; namespace BTCPayServer { - class Program - { - static void Main(string[] args) - { - ServicePointManager.DefaultConnectionLimit = 100; - IWebHost host = null; - CustomConsoleLogProvider loggerProvider = new CustomConsoleLogProvider(); + class Program + { + static void Main(string[] args) + { + ServicePointManager.DefaultConnectionLimit = 100; + IWebHost host = null; + CustomConsoleLogProvider loggerProvider = new CustomConsoleLogProvider(); - var loggerFactory = new LoggerFactory(); - loggerFactory.AddProvider(loggerProvider); - var logger = loggerFactory.CreateLogger("Configuration"); - try - { - var conf = new DefaultConfiguration() { Logger = logger }.CreateConfiguration(args); - if(conf == null) - return; + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(loggerProvider); + var logger = loggerFactory.CreateLogger("Configuration"); + try + { + var conf = new DefaultConfiguration() { Logger = logger }.CreateConfiguration(args); + if (conf == null) + return; - host = new WebHostBuilder() - .UseKestrel() - .UseIISIntegration() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseConfiguration(conf) - .UseApplicationInsights() - .ConfigureLogging(l => - { - l.AddFilter("Microsoft", LogLevel.Error); - l.AddProvider(new CustomConsoleLogProvider()); - }) - .UseStartup() - .Build(); - host.StartAsync().GetAwaiter().GetResult(); - var urls = host.ServerFeatures.Get().Addresses; - foreach(var url in urls) - { - logger.LogInformation("Listening on " + url); - } - host.WaitForShutdown(); - } - catch(ConfigException ex) - { - if(!string.IsNullOrEmpty(ex.Message)) - Logs.Configuration.LogError(ex.Message); - } - catch(Exception exception) - { - logger.LogError("Exception thrown while running the server"); - logger.LogError(exception.ToString()); - } - finally - { - if(host != null) - host.Dispose(); - loggerProvider.Dispose(); - } - } - } + host = new WebHostBuilder() + .UseKestrel() + .UseIISIntegration() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseConfiguration(conf) + .UseApplicationInsights() + .ConfigureLogging(l => + { + l.AddFilter("Microsoft", LogLevel.Error); + l.AddProvider(new CustomConsoleLogProvider()); + }) + .UseStartup() + .Build(); + host.StartAsync().GetAwaiter().GetResult(); + var urls = host.ServerFeatures.Get().Addresses; + foreach (var url in urls) + { + logger.LogInformation("Listening on " + url); + } + host.WaitForShutdown(); + } + catch (ConfigException ex) + { + if (!string.IsNullOrEmpty(ex.Message)) + Logs.Configuration.LogError(ex.Message); + } + catch (Exception exception) + { + logger.LogError("Exception thrown while running the server"); + logger.LogError(exception.ToString()); + } + finally + { + if (host != null) + host.Dispose(); + loggerProvider.Dispose(); + } + } + } } diff --git a/BTCPayServer/Roles.cs b/BTCPayServer/Roles.cs index 6bc53a391..bebb40e94 100644 --- a/BTCPayServer/Roles.cs +++ b/BTCPayServer/Roles.cs @@ -7,6 +7,6 @@ namespace BTCPayServer { public class Roles { - public const string ServerAdmin = "ServerAdmin"; + public const string ServerAdmin = "ServerAdmin"; } } diff --git a/BTCPayServer/Services/BTCPayServerEnvironment.cs b/BTCPayServer/Services/BTCPayServerEnvironment.cs index 6f73f8b7c..bc98cbd7f 100644 --- a/BTCPayServer/Services/BTCPayServerEnvironment.cs +++ b/BTCPayServer/Services/BTCPayServerEnvironment.cs @@ -10,37 +10,37 @@ namespace BTCPayServer.Services { public class BTCPayServerEnvironment { - public BTCPayServerEnvironment(IHostingEnvironment env) - { - Version = typeof(BTCPayServerEnvironment).GetTypeInfo().Assembly.GetCustomAttribute().Version; + public BTCPayServerEnvironment(IHostingEnvironment env) + { + Version = typeof(BTCPayServerEnvironment).GetTypeInfo().Assembly.GetCustomAttribute().Version; #if DEBUG - Build = "Debug"; + Build = "Debug"; #else Build = "Release"; #endif - Environment = env; - } - public IHostingEnvironment Environment - { - get; set; - } - public string Version - { - get; set; - } - public string Build - { - get; set; - } - public override string ToString() - { - StringBuilder txt = new StringBuilder(); - txt.Append($"@Copyright BTCPayServer v{Version}"); - if(!Environment.IsProduction() || Build.Equals("Release", StringComparison.OrdinalIgnoreCase)) - { - txt.Append($" Environment: {Environment.EnvironmentName} Build: {Build}"); - } - return txt.ToString(); - } - } + Environment = env; + } + public IHostingEnvironment Environment + { + get; set; + } + public string Version + { + get; set; + } + public string Build + { + get; set; + } + public override string ToString() + { + StringBuilder txt = new StringBuilder(); + txt.Append($"@Copyright BTCPayServer v{Version}"); + if (!Environment.IsProduction() || Build.Equals("Release", StringComparison.OrdinalIgnoreCase)) + { + txt.Append($" Environment: {Environment.EnvironmentName} Build: {Build}"); + } + return txt.ToString(); + } + } } diff --git a/BTCPayServer/Services/Fees/FixedFeeProvider.cs b/BTCPayServer/Services/Fees/FixedFeeProvider.cs index 20fb597ed..5b6e21682 100644 --- a/BTCPayServer/Services/Fees/FixedFeeProvider.cs +++ b/BTCPayServer/Services/Fees/FixedFeeProvider.cs @@ -6,21 +6,21 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Fees { - public class FixedFeeProvider : IFeeProvider - { - public FixedFeeProvider(FeeRate feeRate) - { - FeeRate = feeRate; - } + public class FixedFeeProvider : IFeeProvider + { + public FixedFeeProvider(FeeRate feeRate) + { + FeeRate = feeRate; + } - public FeeRate FeeRate - { - get; set; - } + public FeeRate FeeRate + { + get; set; + } - public Task GetFeeRateAsync() - { - return Task.FromResult(FeeRate); - } - } + public Task GetFeeRateAsync() + { + return Task.FromResult(FeeRate); + } + } } diff --git a/BTCPayServer/Services/Fees/IFeeProvider.cs b/BTCPayServer/Services/Fees/IFeeProvider.cs index 30d7844d7..75c3a0ab9 100644 --- a/BTCPayServer/Services/Fees/IFeeProvider.cs +++ b/BTCPayServer/Services/Fees/IFeeProvider.cs @@ -8,8 +8,8 @@ using System.Threading.Tasks; namespace BTCPayServer.Services { - public interface IFeeProvider - { - Task GetFeeRateAsync(); - } + public interface IFeeProvider + { + Task GetFeeRateAsync(); + } } diff --git a/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs b/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs index bb0482d63..48958dc44 100644 --- a/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs +++ b/BTCPayServer/Services/Fees/NBxplorerFeeProvider.cs @@ -8,30 +8,30 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Fees { - public class NBXplorerFeeProvider : IFeeProvider - { - public ExplorerClient ExplorerClient - { - get; set; - } - public FeeRate Fallback - { - get; set; - } - public int BlockTarget - { - get; set; - } - public async Task GetFeeRateAsync() - { - try - { - return (await ExplorerClient.GetFeeRateAsync(BlockTarget).ConfigureAwait(false)).FeeRate; - } - catch(NBXplorerException ex) when(ex.Error.HttpCode == 400 && ex.Error.Code == "fee-estimation-unavailable") - { - return Fallback; - } - } - } + public class NBXplorerFeeProvider : IFeeProvider + { + public ExplorerClient ExplorerClient + { + get; set; + } + public FeeRate Fallback + { + get; set; + } + public int BlockTarget + { + get; set; + } + public async Task GetFeeRateAsync() + { + try + { + return (await ExplorerClient.GetFeeRateAsync(BlockTarget).ConfigureAwait(false)).FeeRate; + } + catch (NBXplorerException ex) when (ex.Error.HttpCode == 400 && ex.Error.Code == "fee-estimation-unavailable") + { + return Fallback; + } + } + } } diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index 3e621a79c..618636f67 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -12,328 +12,328 @@ using BTCPayServer.Data; namespace BTCPayServer.Services.Invoices { - public class BuyerInformation - { - [JsonProperty(PropertyName = "buyerName")] - public string BuyerName - { - get; set; - } - [JsonProperty(PropertyName = "buyerEmail")] - public string BuyerEmail - { - get; set; - } - [JsonProperty(PropertyName = "buyerCountry")] - public string BuyerCountry - { - get; set; - } - [JsonProperty(PropertyName = "buyerZip")] - public string BuyerZip - { - get; set; - } - [JsonProperty(PropertyName = "buyerState")] - public string BuyerState - { - get; set; - } - [JsonProperty(PropertyName = "buyerCity")] - public string BuyerCity - { - get; set; - } - [JsonProperty(PropertyName = "buyerAddress2")] - public string BuyerAddress2 - { - get; set; - } - [JsonProperty(PropertyName = "buyerAddress1")] - public string BuyerAddress1 - { - get; set; - } + public class BuyerInformation + { + [JsonProperty(PropertyName = "buyerName")] + public string BuyerName + { + get; set; + } + [JsonProperty(PropertyName = "buyerEmail")] + public string BuyerEmail + { + get; set; + } + [JsonProperty(PropertyName = "buyerCountry")] + public string BuyerCountry + { + get; set; + } + [JsonProperty(PropertyName = "buyerZip")] + public string BuyerZip + { + get; set; + } + [JsonProperty(PropertyName = "buyerState")] + public string BuyerState + { + get; set; + } + [JsonProperty(PropertyName = "buyerCity")] + public string BuyerCity + { + get; set; + } + [JsonProperty(PropertyName = "buyerAddress2")] + public string BuyerAddress2 + { + get; set; + } + [JsonProperty(PropertyName = "buyerAddress1")] + public string BuyerAddress1 + { + get; set; + } - [JsonProperty(PropertyName = "buyerPhone")] - public string BuyerPhone - { - get; set; - } - } + [JsonProperty(PropertyName = "buyerPhone")] + public string BuyerPhone + { + get; set; + } + } - public class ProductInformation - { - [JsonProperty(PropertyName = "itemDesc")] - public string ItemDesc - { - get; set; - } - [JsonProperty(PropertyName = "itemCode")] - public string ItemCode - { - get; set; - } - [JsonProperty(PropertyName = "physical")] - public bool Physical - { - get; set; - } + public class ProductInformation + { + [JsonProperty(PropertyName = "itemDesc")] + public string ItemDesc + { + get; set; + } + [JsonProperty(PropertyName = "itemCode")] + public string ItemCode + { + get; set; + } + [JsonProperty(PropertyName = "physical")] + public bool Physical + { + get; set; + } - [JsonProperty(PropertyName = "price")] - public double Price - { - get; set; - } + [JsonProperty(PropertyName = "price")] + public double Price + { + get; set; + } - [JsonProperty(PropertyName = "currency")] - public string Currency - { - get; set; - } - } + [JsonProperty(PropertyName = "currency")] + public string Currency + { + get; set; + } + } - public enum SpeedPolicy - { - HighSpeed = 0, - MediumSpeed = 1, - LowSpeed = 2 - } - public class InvoiceEntity - { - public string Id - { - get; set; - } - public string StoreId - { - get; set; - } + public enum SpeedPolicy + { + HighSpeed = 0, + MediumSpeed = 1, + LowSpeed = 2 + } + public class InvoiceEntity + { + public string Id + { + get; set; + } + public string StoreId + { + get; set; + } - public int GetTxCount() - { - return Calculate().TxCount; - } + public int GetTxCount() + { + return Calculate().TxCount; + } - public string OrderId - { - get; set; - } + public string OrderId + { + get; set; + } - public Money GetTotalCryptoDue() - { - return Calculate().TotalDue; - } + public Money GetTotalCryptoDue() + { + return Calculate().TotalDue; + } - private (Money TotalDue, Money Paid, int TxCount) Calculate() - { - var totalDue = Money.Coins((decimal)(ProductInformation.Price / Rate)) + TxFee; - var paid = Money.Zero; - int txCount = 1; - var payments = - Payments - .OrderByDescending(p => p.ReceivedTime) - .Select(_ => - { - paid += _.Output.Value; - return _; - }) - .TakeWhile(_ => - { - var paidEnough = totalDue <= paid; - if(!paidEnough) - { - txCount++; - totalDue += TxFee; - } - return !paidEnough; - }) - .ToArray(); - return (totalDue, paid, txCount); - } + private (Money TotalDue, Money Paid, int TxCount) Calculate() + { + var totalDue = Money.Coins((decimal)(ProductInformation.Price / Rate)) + TxFee; + var paid = Money.Zero; + int txCount = 1; + var payments = + Payments + .OrderByDescending(p => p.ReceivedTime) + .Select(_ => + { + paid += _.Output.Value; + return _; + }) + .TakeWhile(_ => + { + var paidEnough = totalDue <= paid; + if (!paidEnough) + { + txCount++; + totalDue += TxFee; + } + return !paidEnough; + }) + .ToArray(); + return (totalDue, paid, txCount); + } - public Money GetTotalPaid() - { - return Calculate().Paid; - } - public Money GetCryptoDue() - { - var o = Calculate(); - var v = o.TotalDue - o.Paid; - return v < Money.Zero ? Money.Zero : v; - } + public Money GetTotalPaid() + { + return Calculate().Paid; + } + public Money GetCryptoDue() + { + var o = Calculate(); + var v = o.TotalDue - o.Paid; + return v < Money.Zero ? Money.Zero : v; + } - public SpeedPolicy SpeedPolicy - { - get; set; - } - public double Rate - { - get; set; - } - public DateTimeOffset InvoiceTime - { - get; set; - } - public DateTimeOffset ExpirationTime - { - get; set; - } - public BitcoinAddress DepositAddress - { - get; set; - } - public ProductInformation ProductInformation - { - get; set; - } - public BuyerInformation BuyerInformation - { - get; set; - } - public string PosData - { - get; - set; - } - public string DerivationStrategy - { - get; - set; - } - public string Status - { - get; - set; - } - public string ExceptionStatus - { - get; set; - } - public List Payments - { - get; set; - } - public bool Refundable - { - get; - set; - } - public string RefundMail - { - get; - set; - } - public string RedirectURL - { - get; - set; - } - public Money TxFee - { - get; - set; - } - public bool FullNotifications - { - get; - set; - } - public string NotificationURL - { - get; - set; - } - public string ServerUrl - { - get; - set; - } - public DateTimeOffset? MonitoringExpiration - { - get; - set; - } - public HistoricalAddressInvoiceData[] HistoricalAddresses - { - get; - set; - } + public SpeedPolicy SpeedPolicy + { + get; set; + } + public double Rate + { + get; set; + } + public DateTimeOffset InvoiceTime + { + get; set; + } + public DateTimeOffset ExpirationTime + { + get; set; + } + public BitcoinAddress DepositAddress + { + get; set; + } + public ProductInformation ProductInformation + { + get; set; + } + public BuyerInformation BuyerInformation + { + get; set; + } + public string PosData + { + get; + set; + } + public string DerivationStrategy + { + get; + set; + } + public string Status + { + get; + set; + } + public string ExceptionStatus + { + get; set; + } + public List Payments + { + get; set; + } + public bool Refundable + { + get; + set; + } + public string RefundMail + { + get; + set; + } + public string RedirectURL + { + get; + set; + } + public Money TxFee + { + get; + set; + } + public bool FullNotifications + { + get; + set; + } + public string NotificationURL + { + get; + set; + } + public string ServerUrl + { + get; + set; + } + public DateTimeOffset? MonitoringExpiration + { + get; + set; + } + public HistoricalAddressInvoiceData[] HistoricalAddresses + { + get; + set; + } - public bool IsExpired() - { - return DateTimeOffset.UtcNow > ExpirationTime; - } + public bool IsExpired() + { + return DateTimeOffset.UtcNow > ExpirationTime; + } - public InvoiceResponse EntityToDTO() - { - ServerUrl = ServerUrl ?? ""; - InvoiceResponse dto = new InvoiceResponse - { - Id = Id, - OrderId = OrderId, - PosData = PosData, - CurrentTime = DateTimeOffset.UtcNow, - InvoiceTime = InvoiceTime, - ExpirationTime = ExpirationTime, - BTCPrice = Money.Coins((decimal)(1.0 / Rate)).ToString(), - Status = Status, - Url = ServerUrl.WithTrailingSlash() + "invoice?id=" + Id, - Currency = ProductInformation.Currency, - Flags = new Flags() { Refundable = Refundable } - }; - Populate(ProductInformation, dto); - Populate(BuyerInformation, dto); - dto.ExRates = new Dictionary - { - { ProductInformation.Currency, Rate } - }; - dto.PaymentUrls = new InvoicePaymentUrls() - { - BIP72 = $"bitcoin:{DepositAddress}?amount={GetCryptoDue()}&r={ServerUrl.WithTrailingSlash() + ($"i/{Id}")}", - BIP72b = $"bitcoin:?r={ServerUrl.WithTrailingSlash() + ($"i/{Id}")}", - BIP73 = ServerUrl.WithTrailingSlash() + ($"i/{Id}"), - BIP21 = $"bitcoin:{DepositAddress}?amount={GetCryptoDue()}", - }; - dto.BitcoinAddress = DepositAddress.ToString(); - dto.Token = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); //No idea what it is useful for - dto.Guid = Guid.NewGuid().ToString(); + public InvoiceResponse EntityToDTO() + { + ServerUrl = ServerUrl ?? ""; + InvoiceResponse dto = new InvoiceResponse + { + Id = Id, + OrderId = OrderId, + PosData = PosData, + CurrentTime = DateTimeOffset.UtcNow, + InvoiceTime = InvoiceTime, + ExpirationTime = ExpirationTime, + BTCPrice = Money.Coins((decimal)(1.0 / Rate)).ToString(), + Status = Status, + Url = ServerUrl.WithTrailingSlash() + "invoice?id=" + Id, + Currency = ProductInformation.Currency, + Flags = new Flags() { Refundable = Refundable } + }; + Populate(ProductInformation, dto); + Populate(BuyerInformation, dto); + dto.ExRates = new Dictionary + { + { ProductInformation.Currency, Rate } + }; + dto.PaymentUrls = new InvoicePaymentUrls() + { + BIP72 = $"bitcoin:{DepositAddress}?amount={GetCryptoDue()}&r={ServerUrl.WithTrailingSlash() + ($"i/{Id}")}", + BIP72b = $"bitcoin:?r={ServerUrl.WithTrailingSlash() + ($"i/{Id}")}", + BIP73 = ServerUrl.WithTrailingSlash() + ($"i/{Id}"), + BIP21 = $"bitcoin:{DepositAddress}?amount={GetCryptoDue()}", + }; + dto.BitcoinAddress = DepositAddress.ToString(); + dto.Token = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); //No idea what it is useful for + dto.Guid = Guid.NewGuid().ToString(); - var paid = Payments.Select(p => p.Output.Value).Sum(); - dto.BTCPaid = paid.ToString(); - dto.BTCDue = GetCryptoDue().ToString(); + var paid = Payments.Select(p => p.Output.Value).Sum(); + dto.BTCPaid = paid.ToString(); + dto.BTCDue = GetCryptoDue().ToString(); - dto.ExceptionStatus = ExceptionStatus == null ? new JValue(false) : new JValue(ExceptionStatus); - return dto; - } + dto.ExceptionStatus = ExceptionStatus == null ? new JValue(false) : new JValue(ExceptionStatus); + return dto; + } - private void Populate(TFrom from, TDest dest) - { - var str = JsonConvert.SerializeObject(from); - JsonConvert.PopulateObject(str, dest); - } + private void Populate(TFrom from, TDest dest) + { + var str = JsonConvert.SerializeObject(from); + JsonConvert.PopulateObject(str, dest); + } - public Money GetNetworkFee() - { - var item = Calculate(); - return TxFee * item.TxCount; - } - } + public Money GetNetworkFee() + { + var item = Calculate(); + return TxFee * item.TxCount; + } + } - public class PaymentEntity - { - public DateTimeOffset ReceivedTime - { - get; set; - } - public OutPoint Outpoint - { - get; set; - } - public TxOut Output - { - get; set; - } - } + public class PaymentEntity + { + public DateTimeOffset ReceivedTime + { + get; set; + } + public OutPoint Outpoint + { + get; set; + } + public TxOut Output + { + get; set; + } + } } diff --git a/BTCPayServer/Services/Invoices/InvoiceNotificationManager.cs b/BTCPayServer/Services/Invoices/InvoiceNotificationManager.cs index 054c425d8..76e3040e3 100644 --- a/BTCPayServer/Services/Invoices/InvoiceNotificationManager.cs +++ b/BTCPayServer/Services/Invoices/InvoiceNotificationManager.cs @@ -18,109 +18,109 @@ using System.Collections.Concurrent; namespace BTCPayServer.Services.Invoices { - public class InvoiceNotificationManager - { - public static HttpClient _Client = new HttpClient(); + public class InvoiceNotificationManager + { + public static HttpClient _Client = new HttpClient(); - public class ScheduledJob - { - public int TryCount - { - get; set; - } + public class ScheduledJob + { + public int TryCount + { + get; set; + } - public InvoiceEntity Invoice - { - get; set; - } - } + public InvoiceEntity Invoice + { + get; set; + } + } - public ILogger Logger - { - get; set; - } + public ILogger Logger + { + get; set; + } - IBackgroundJobClient _JobClient; - public InvoiceNotificationManager( - IBackgroundJobClient jobClient, - ILogger logger) - { - Logger = logger as ILogger ?? NullLogger.Instance; - _JobClient = jobClient; - } + IBackgroundJobClient _JobClient; + public InvoiceNotificationManager( + IBackgroundJobClient jobClient, + ILogger logger) + { + Logger = logger as ILogger ?? NullLogger.Instance; + _JobClient = jobClient; + } - public void Notify(InvoiceEntity invoice) - { - var invoiceStr = NBitcoin.JsonConverters.Serializer.ToString(new ScheduledJob() { TryCount = 0, Invoice = invoice }); - if(!string.IsNullOrEmpty(invoice.NotificationURL)) - _JobClient.Schedule(() => NotifyHttp(invoiceStr), TimeSpan.Zero); - } + public void Notify(InvoiceEntity invoice) + { + var invoiceStr = NBitcoin.JsonConverters.Serializer.ToString(new ScheduledJob() { TryCount = 0, Invoice = invoice }); + if (!string.IsNullOrEmpty(invoice.NotificationURL)) + _JobClient.Schedule(() => NotifyHttp(invoiceStr), TimeSpan.Zero); + } - ConcurrentDictionary _Executing = new ConcurrentDictionary(); - public async Task NotifyHttp(string invoiceData) - { - var job = NBitcoin.JsonConverters.Serializer.ToObject(invoiceData); - var jobId = GetHttpJobId(job.Invoice); + ConcurrentDictionary _Executing = new ConcurrentDictionary(); + public async Task NotifyHttp(string invoiceData) + { + var job = NBitcoin.JsonConverters.Serializer.ToObject(invoiceData); + var jobId = GetHttpJobId(job.Invoice); - if(!_Executing.TryAdd(jobId, jobId)) - return; //For some reason, Hangfire fire the job several time + if (!_Executing.TryAdd(jobId, jobId)) + return; //For some reason, Hangfire fire the job several time - Logger.LogInformation("Running " + jobId); - bool reschedule = false; - CancellationTokenSource cts = new CancellationTokenSource(10000); - try - { - var request = new HttpRequestMessage(); - request.Method = HttpMethod.Post; + Logger.LogInformation("Running " + jobId); + bool reschedule = false; + CancellationTokenSource cts = new CancellationTokenSource(10000); + try + { + var request = new HttpRequestMessage(); + request.Method = HttpMethod.Post; - var dto = job.Invoice.EntityToDTO(); - InvoicePaymentNotification notification = new InvoicePaymentNotification() - { - Id = dto.Id, - Url = dto.Url, - BTCDue = dto.BTCDue, - BTCPaid = dto.BTCPaid, - BTCPrice = dto.BTCPrice, - Currency = dto.Currency, - CurrentTime = dto.CurrentTime, - ExceptionStatus = dto.ExceptionStatus, - ExpirationTime = dto.ExpirationTime, - InvoiceTime = dto.InvoiceTime, - PosData = dto.PosData, - Price = dto.Price, - Rate = dto.Rate, - Status = dto.Status, - BuyerFields = job.Invoice.RefundMail == null ? null : new Newtonsoft.Json.Linq.JObject() { new JProperty("buyerEmail", job.Invoice.RefundMail) } - }; - request.RequestUri = new Uri(job.Invoice.NotificationURL, UriKind.Absolute); - request.Content = new StringContent(JsonConvert.SerializeObject(notification), Encoding.UTF8, "application/json"); - var response = await _Client.SendAsync(request, cts.Token); - reschedule = response.StatusCode != System.Net.HttpStatusCode.OK; - Logger.LogInformation("Job " + jobId + " returned " + response.StatusCode); - } - catch(Exception ex) - { - reschedule = true; - Logger.LogInformation("Job " + jobId + " threw exception " + ex.Message); - } - finally { cts.Dispose(); _Executing.TryRemove(jobId, out jobId); } + var dto = job.Invoice.EntityToDTO(); + InvoicePaymentNotification notification = new InvoicePaymentNotification() + { + Id = dto.Id, + Url = dto.Url, + BTCDue = dto.BTCDue, + BTCPaid = dto.BTCPaid, + BTCPrice = dto.BTCPrice, + Currency = dto.Currency, + CurrentTime = dto.CurrentTime, + ExceptionStatus = dto.ExceptionStatus, + ExpirationTime = dto.ExpirationTime, + InvoiceTime = dto.InvoiceTime, + PosData = dto.PosData, + Price = dto.Price, + Rate = dto.Rate, + Status = dto.Status, + BuyerFields = job.Invoice.RefundMail == null ? null : new Newtonsoft.Json.Linq.JObject() { new JProperty("buyerEmail", job.Invoice.RefundMail) } + }; + request.RequestUri = new Uri(job.Invoice.NotificationURL, UriKind.Absolute); + request.Content = new StringContent(JsonConvert.SerializeObject(notification), Encoding.UTF8, "application/json"); + var response = await _Client.SendAsync(request, cts.Token); + reschedule = response.StatusCode != System.Net.HttpStatusCode.OK; + Logger.LogInformation("Job " + jobId + " returned " + response.StatusCode); + } + catch (Exception ex) + { + reschedule = true; + Logger.LogInformation("Job " + jobId + " threw exception " + ex.Message); + } + finally { cts.Dispose(); _Executing.TryRemove(jobId, out jobId); } - job.TryCount++; + job.TryCount++; - if(job.TryCount < MaxTry && reschedule) - { - Logger.LogInformation("Rescheduling " + jobId + " in 10 minutes, remaining try " + (MaxTry - job.TryCount)); + if (job.TryCount < MaxTry && reschedule) + { + Logger.LogInformation("Rescheduling " + jobId + " in 10 minutes, remaining try " + (MaxTry - job.TryCount)); - invoiceData = NBitcoin.JsonConverters.Serializer.ToString(job); - _JobClient.Schedule(() => NotifyHttp(invoiceData), TimeSpan.FromMinutes(10.0)); - } - } + invoiceData = NBitcoin.JsonConverters.Serializer.ToString(job); + _JobClient.Schedule(() => NotifyHttp(invoiceData), TimeSpan.FromMinutes(10.0)); + } + } - int MaxTry = 6; + int MaxTry = 6; - private static string GetHttpJobId(InvoiceEntity invoice) - { - return $"{invoice.Id}-{invoice.Status}-HTTP"; - } - } + private static string GetHttpJobId(InvoiceEntity invoice) + { + return $"{invoice.Id}-{invoice.Status}-HTTP"; + } + } } diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs index bee3430f1..e0f8dfa2f 100644 --- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs +++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs @@ -19,464 +19,464 @@ using BTCPayServer.Models.InvoicingModels; namespace BTCPayServer.Services.Invoices { - public class InvoiceRepository - { + public class InvoiceRepository + { - private readonly DBreezeEngine _Engine; - public DBreezeEngine Engine - { - get - { - return _Engine; - } - } + private readonly DBreezeEngine _Engine; + public DBreezeEngine Engine + { + get + { + return _Engine; + } + } - Network _Network; - public Network Network - { - get - { - return _Network; - } - set - { - _Network = value; - } - } + Network _Network; + public Network Network + { + get + { + return _Network; + } + set + { + _Network = value; + } + } - private ApplicationDbContextFactory _ContextFactory; - public InvoiceRepository(ApplicationDbContextFactory contextFactory, DBreezeEngine engine, Network network) - { - _Engine = engine; - _Network = network; - _ContextFactory = contextFactory; - } + private ApplicationDbContextFactory _ContextFactory; + public InvoiceRepository(ApplicationDbContextFactory contextFactory, DBreezeEngine engine, Network network) + { + _Engine = engine; + _Network = network; + _ContextFactory = contextFactory; + } - public async Task AddPendingInvoice(string invoiceId) - { - using(var ctx = _ContextFactory.CreateContext()) - { - ctx.PendingInvoices.Add(new PendingInvoiceData() { Id = invoiceId }); - await ctx.SaveChangesAsync(); - } - } + public async Task AddPendingInvoice(string invoiceId) + { + using (var ctx = _ContextFactory.CreateContext()) + { + ctx.PendingInvoices.Add(new PendingInvoiceData() { Id = invoiceId }); + await ctx.SaveChangesAsync(); + } + } - public async Task RemovePendingInvoice(string invoiceId) - { - using(var ctx = _ContextFactory.CreateContext()) - { - ctx.PendingInvoices.Remove(new PendingInvoiceData() { Id = invoiceId }); - try - { - await ctx.SaveChangesAsync(); - return true; - } - catch(DbUpdateException) { return false; } - } - } + public async Task RemovePendingInvoice(string invoiceId) + { + using (var ctx = _ContextFactory.CreateContext()) + { + ctx.PendingInvoices.Remove(new PendingInvoiceData() { Id = invoiceId }); + try + { + await ctx.SaveChangesAsync(); + return true; + } + catch (DbUpdateException) { return false; } + } + } - public async Task GetInvoiceIdFromScriptPubKey(Script scriptPubKey) - { - using(var db = _ContextFactory.CreateContext()) - { - var result = await db.AddressInvoices.FindAsync(scriptPubKey.Hash.ToString()); - return result?.InvoiceDataId; - } - } + public async Task GetInvoiceIdFromScriptPubKey(Script scriptPubKey) + { + using (var db = _ContextFactory.CreateContext()) + { + var result = await db.AddressInvoices.FindAsync(scriptPubKey.Hash.ToString()); + return result?.InvoiceDataId; + } + } - public async Task GetPendingInvoices() - { - using(var ctx = _ContextFactory.CreateContext()) - { - return await ctx.PendingInvoices.Select(p => p.Id).ToArrayAsync(); - } - } + public async Task GetPendingInvoices() + { + using (var ctx = _ContextFactory.CreateContext()) + { + return await ctx.PendingInvoices.Select(p => p.Id).ToArrayAsync(); + } + } - public async Task UpdateInvoice(string invoiceId, UpdateCustomerModel data) - { - using(var ctx = _ContextFactory.CreateContext()) - { - var invoiceData = await ctx.Invoices.FindAsync(invoiceId).ConfigureAwait(false); - if(invoiceData == null) - return; - if(invoiceData.CustomerEmail == null && data.Email != null) - { - invoiceData.CustomerEmail = data.Email; - } - await ctx.SaveChangesAsync().ConfigureAwait(false); - } - } + public async Task UpdateInvoice(string invoiceId, UpdateCustomerModel data) + { + using (var ctx = _ContextFactory.CreateContext()) + { + var invoiceData = await ctx.Invoices.FindAsync(invoiceId).ConfigureAwait(false); + if (invoiceData == null) + return; + if (invoiceData.CustomerEmail == null && data.Email != null) + { + invoiceData.CustomerEmail = data.Email; + } + await ctx.SaveChangesAsync().ConfigureAwait(false); + } + } - public async Task CreateInvoiceAsync(string storeId, InvoiceEntity invoice) - { - invoice = Clone(invoice); - invoice.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); - invoice.Payments = new List(); - invoice.StoreId = storeId; - using(var context = _ContextFactory.CreateContext()) - { - await context.AddAsync(new InvoiceData() - { - StoreDataId = storeId, - Id = invoice.Id, - Created = invoice.InvoiceTime, - Blob = ToBytes(invoice), - OrderId = invoice.OrderId, - Status = invoice.Status, - ItemCode = invoice.ProductInformation.ItemCode, - CustomerEmail = invoice.RefundMail - }).ConfigureAwait(false); + public async Task CreateInvoiceAsync(string storeId, InvoiceEntity invoice) + { + invoice = Clone(invoice); + invoice.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16)); + invoice.Payments = new List(); + invoice.StoreId = storeId; + using (var context = _ContextFactory.CreateContext()) + { + await context.AddAsync(new InvoiceData() + { + StoreDataId = storeId, + Id = invoice.Id, + Created = invoice.InvoiceTime, + Blob = ToBytes(invoice), + OrderId = invoice.OrderId, + Status = invoice.Status, + ItemCode = invoice.ProductInformation.ItemCode, + CustomerEmail = invoice.RefundMail + }).ConfigureAwait(false); - context.AddressInvoices.Add(new AddressInvoiceData() - { - Address = invoice.DepositAddress.ScriptPubKey.Hash.ToString(), - InvoiceDataId = invoice.Id, - CreatedTime = DateTimeOffset.UtcNow, - }); + context.AddressInvoices.Add(new AddressInvoiceData() + { + Address = invoice.DepositAddress.ScriptPubKey.Hash.ToString(), + InvoiceDataId = invoice.Id, + CreatedTime = DateTimeOffset.UtcNow, + }); - context.HistoricalAddressInvoices.Add(new HistoricalAddressInvoiceData() - { - InvoiceDataId = invoice.Id, - Address = invoice.DepositAddress.ToString(), - Assigned = DateTimeOffset.UtcNow - }); - await context.SaveChangesAsync().ConfigureAwait(false); - } + context.HistoricalAddressInvoices.Add(new HistoricalAddressInvoiceData() + { + InvoiceDataId = invoice.Id, + Address = invoice.DepositAddress.ToString(), + Assigned = DateTimeOffset.UtcNow + }); + await context.SaveChangesAsync().ConfigureAwait(false); + } - AddToTextSearch(invoice.Id, - invoice.Id, - invoice.DepositAddress.ToString(), - invoice.InvoiceTime.ToString(CultureInfo.InvariantCulture), - invoice.ProductInformation.Price.ToString(CultureInfo.InvariantCulture), - invoice.GetTotalCryptoDue().ToString(), - invoice.OrderId, - ToString(invoice.BuyerInformation), - ToString(invoice.ProductInformation), - invoice.StoreId - ); + AddToTextSearch(invoice.Id, + invoice.Id, + invoice.DepositAddress.ToString(), + invoice.InvoiceTime.ToString(CultureInfo.InvariantCulture), + invoice.ProductInformation.Price.ToString(CultureInfo.InvariantCulture), + invoice.GetTotalCryptoDue().ToString(), + invoice.OrderId, + ToString(invoice.BuyerInformation), + ToString(invoice.ProductInformation), + invoice.StoreId + ); - return invoice; - } + return invoice; + } - public async Task NewAddress(string invoiceId, BitcoinAddress bitcoinAddress) - { - using(var context = _ContextFactory.CreateContext()) - { - var invoice = await context.Invoices.FirstOrDefaultAsync(i => i.Id == invoiceId); - if(invoice == null) - return false; - var invoiceEntity = ToObject(invoice.Blob); - var old = invoiceEntity.DepositAddress; - invoiceEntity.DepositAddress = bitcoinAddress; - invoice.Blob = ToBytes(invoiceEntity); - if(old != null) - { - MarkUnassigned(invoiceId, old, context); - } - context.AddressInvoices.Add(new AddressInvoiceData() { Address = bitcoinAddress.ScriptPubKey.Hash.ToString(), InvoiceDataId = invoiceId, CreatedTime = DateTimeOffset.UtcNow }); - context.HistoricalAddressInvoices.Add(new HistoricalAddressInvoiceData() - { - InvoiceDataId = invoiceId, - Address = bitcoinAddress.ToString(), - Assigned = DateTimeOffset.UtcNow - }); + public async Task NewAddress(string invoiceId, BitcoinAddress bitcoinAddress) + { + using (var context = _ContextFactory.CreateContext()) + { + var invoice = await context.Invoices.FirstOrDefaultAsync(i => i.Id == invoiceId); + if (invoice == null) + return false; + var invoiceEntity = ToObject(invoice.Blob); + var old = invoiceEntity.DepositAddress; + invoiceEntity.DepositAddress = bitcoinAddress; + invoice.Blob = ToBytes(invoiceEntity); + if (old != null) + { + MarkUnassigned(invoiceId, old, context); + } + context.AddressInvoices.Add(new AddressInvoiceData() { Address = bitcoinAddress.ScriptPubKey.Hash.ToString(), InvoiceDataId = invoiceId, CreatedTime = DateTimeOffset.UtcNow }); + context.HistoricalAddressInvoices.Add(new HistoricalAddressInvoiceData() + { + InvoiceDataId = invoiceId, + Address = bitcoinAddress.ToString(), + Assigned = DateTimeOffset.UtcNow + }); - await context.SaveChangesAsync(); - AddToTextSearch(invoice.Id, bitcoinAddress.ToString()); - return true; - } - } + await context.SaveChangesAsync(); + AddToTextSearch(invoice.Id, bitcoinAddress.ToString()); + return true; + } + } - private static void MarkUnassigned(string invoiceId, BitcoinAddress old, ApplicationDbContext context) - { - var historical = new HistoricalAddressInvoiceData(); - historical.InvoiceDataId = invoiceId; - historical.Address = old.ToString(); - historical.UnAssigned = DateTimeOffset.UtcNow; - context.Attach(historical); - context.Entry(historical).Property(o => o.UnAssigned).IsModified = true; - } + private static void MarkUnassigned(string invoiceId, BitcoinAddress old, ApplicationDbContext context) + { + var historical = new HistoricalAddressInvoiceData(); + historical.InvoiceDataId = invoiceId; + historical.Address = old.ToString(); + historical.UnAssigned = DateTimeOffset.UtcNow; + context.Attach(historical); + context.Entry(historical).Property(o => o.UnAssigned).IsModified = true; + } - public async Task UnaffectAddress(string invoiceId) - { - using(var context = _ContextFactory.CreateContext()) - { - var invoiceData = await context.FindAsync(invoiceId).ConfigureAwait(false); - if(invoiceData == null) - return; - var invoiceEntity = ToObject(invoiceData.Blob); - if(invoiceEntity.DepositAddress == null) - return; - MarkUnassigned(invoiceId, invoiceEntity.DepositAddress, context); - try - { - await context.SaveChangesAsync(); - } - catch(DbUpdateException) { } //Possibly, it was unassigned before - } - } + public async Task UnaffectAddress(string invoiceId) + { + using (var context = _ContextFactory.CreateContext()) + { + var invoiceData = await context.FindAsync(invoiceId).ConfigureAwait(false); + if (invoiceData == null) + return; + var invoiceEntity = ToObject(invoiceData.Blob); + if (invoiceEntity.DepositAddress == null) + return; + MarkUnassigned(invoiceId, invoiceEntity.DepositAddress, context); + try + { + await context.SaveChangesAsync(); + } + catch (DbUpdateException) { } //Possibly, it was unassigned before + } + } - private string[] SearchInvoice(string searchTerms) - { - using(var tx = _Engine.GetTransaction()) - { - return tx.TextSearch("InvoiceSearch").Block(searchTerms) - .GetDocumentIDs() - .Select(id => Encoders.Base58.EncodeData(id)) - .ToArray(); - } - } + private string[] SearchInvoice(string searchTerms) + { + using (var tx = _Engine.GetTransaction()) + { + return tx.TextSearch("InvoiceSearch").Block(searchTerms) + .GetDocumentIDs() + .Select(id => Encoders.Base58.EncodeData(id)) + .ToArray(); + } + } - void AddToTextSearch(string invoiceId, params string[] terms) - { - using(var tx = _Engine.GetTransaction()) - { - tx.TextInsert("InvoiceSearch", Encoders.Base58.DecodeData(invoiceId), string.Join(" ", terms.Where(t => !String.IsNullOrWhiteSpace(t)))); - tx.Commit(); - } - } + void AddToTextSearch(string invoiceId, params string[] terms) + { + using (var tx = _Engine.GetTransaction()) + { + tx.TextInsert("InvoiceSearch", Encoders.Base58.DecodeData(invoiceId), string.Join(" ", terms.Where(t => !String.IsNullOrWhiteSpace(t)))); + tx.Commit(); + } + } - public async Task UpdateInvoiceStatus(string invoiceId, string status, string exceptionStatus) - { - using(var context = _ContextFactory.CreateContext()) - { - var invoiceData = await context.FindAsync(invoiceId).ConfigureAwait(false); - if(invoiceData == null) - return; - invoiceData.Status = status; - invoiceData.ExceptionStatus = exceptionStatus; - await context.SaveChangesAsync().ConfigureAwait(false); - } - } + public async Task UpdateInvoiceStatus(string invoiceId, string status, string exceptionStatus) + { + using (var context = _ContextFactory.CreateContext()) + { + var invoiceData = await context.FindAsync(invoiceId).ConfigureAwait(false); + if (invoiceData == null) + return; + invoiceData.Status = status; + invoiceData.ExceptionStatus = exceptionStatus; + await context.SaveChangesAsync().ConfigureAwait(false); + } + } - public async Task GetInvoice(string storeId, string id, bool includeHistoricalAddresses = false) - { - using(var context = _ContextFactory.CreateContext()) - { - IQueryable query = - context - .Invoices - .Include(o => o.Payments) - .Include(o => o.RefundAddresses); - if(includeHistoricalAddresses) - query = query.Include(o => o.HistoricalAddressInvoices); - query = query.Where(i => i.Id == id); + public async Task GetInvoice(string storeId, string id, bool includeHistoricalAddresses = false) + { + using (var context = _ContextFactory.CreateContext()) + { + IQueryable query = + context + .Invoices + .Include(o => o.Payments) + .Include(o => o.RefundAddresses); + if (includeHistoricalAddresses) + query = query.Include(o => o.HistoricalAddressInvoices); + query = query.Where(i => i.Id == id); - if(storeId != null) - query = query.Where(i => i.StoreDataId == storeId); + if (storeId != null) + query = query.Where(i => i.StoreDataId == storeId); - var invoice = await query.FirstOrDefaultAsync().ConfigureAwait(false); - if(invoice == null) - return null; + var invoice = await query.FirstOrDefaultAsync().ConfigureAwait(false); + if (invoice == null) + return null; - return ToEntity(invoice); - } - } + return ToEntity(invoice); + } + } - private InvoiceEntity ToEntity(InvoiceData invoice) - { - var entity = ToObject(invoice.Blob); - entity.Payments = invoice.Payments.Select(p => ToObject(p.Blob)).ToList(); - entity.ExceptionStatus = invoice.ExceptionStatus; - entity.Status = invoice.Status; - entity.RefundMail = invoice.CustomerEmail; - entity.Refundable = invoice.RefundAddresses.Count != 0; - if(invoice.HistoricalAddressInvoices != null) - { - entity.HistoricalAddresses = invoice.HistoricalAddressInvoices.ToArray(); - } - return entity; - } + private InvoiceEntity ToEntity(InvoiceData invoice) + { + var entity = ToObject(invoice.Blob); + entity.Payments = invoice.Payments.Select(p => ToObject(p.Blob)).ToList(); + entity.ExceptionStatus = invoice.ExceptionStatus; + entity.Status = invoice.Status; + entity.RefundMail = invoice.CustomerEmail; + entity.Refundable = invoice.RefundAddresses.Count != 0; + if (invoice.HistoricalAddressInvoices != null) + { + entity.HistoricalAddresses = invoice.HistoricalAddressInvoices.ToArray(); + } + return entity; + } - public async Task GetInvoices(InvoiceQuery queryObject) - { - using(var context = _ContextFactory.CreateContext()) - { - IQueryable query = context - .Invoices - .Include(o => o.Payments) - .Include(o => o.RefundAddresses); + public async Task GetInvoices(InvoiceQuery queryObject) + { + using (var context = _ContextFactory.CreateContext()) + { + IQueryable query = context + .Invoices + .Include(o => o.Payments) + .Include(o => o.RefundAddresses); - if(!string.IsNullOrEmpty(queryObject.InvoiceId)) - { - query = query.Where(i => i.Id == queryObject.InvoiceId); - } + if (!string.IsNullOrEmpty(queryObject.InvoiceId)) + { + query = query.Where(i => i.Id == queryObject.InvoiceId); + } - if(!string.IsNullOrEmpty(queryObject.StoreId)) - { - query = query.Where(i => i.StoreDataId == queryObject.StoreId); - } + if (!string.IsNullOrEmpty(queryObject.StoreId)) + { + query = query.Where(i => i.StoreDataId == queryObject.StoreId); + } - if(queryObject.UserId != null) - { - query = query.Where(i => i.StoreData.UserStores.Any(u => u.ApplicationUserId == queryObject.UserId)); - } + if (queryObject.UserId != null) + { + query = query.Where(i => i.StoreData.UserStores.Any(u => u.ApplicationUserId == queryObject.UserId)); + } - if(!string.IsNullOrEmpty(queryObject.TextSearch)) - { - var ids = new HashSet(SearchInvoice(queryObject.TextSearch)); - if(ids.Count == 0) - return new InvoiceEntity[0]; - query = query.Where(i => ids.Contains(i.Id)); - } + if (!string.IsNullOrEmpty(queryObject.TextSearch)) + { + var ids = new HashSet(SearchInvoice(queryObject.TextSearch)); + if (ids.Count == 0) + return new InvoiceEntity[0]; + query = query.Where(i => ids.Contains(i.Id)); + } - if(queryObject.StartDate != null) - query = query.Where(i => queryObject.StartDate.Value <= i.Created); + if (queryObject.StartDate != null) + query = query.Where(i => queryObject.StartDate.Value <= i.Created); - if(queryObject.EndDate != null) - query = query.Where(i => i.Created <= queryObject.EndDate.Value); + if (queryObject.EndDate != null) + query = query.Where(i => i.Created <= queryObject.EndDate.Value); - if(queryObject.ItemCode != null) - query = query.Where(i => i.ItemCode == queryObject.ItemCode); + if (queryObject.ItemCode != null) + query = query.Where(i => i.ItemCode == queryObject.ItemCode); - if(queryObject.OrderId != null) - query = query.Where(i => i.OrderId == queryObject.OrderId); + if (queryObject.OrderId != null) + query = query.Where(i => i.OrderId == queryObject.OrderId); - if(queryObject.Status != null) - query = query.Where(i => i.Status == queryObject.Status); + if (queryObject.Status != null) + query = query.Where(i => i.Status == queryObject.Status); - query = query.OrderByDescending(q => q.Created); + query = query.OrderByDescending(q => q.Created); - if(queryObject.Skip != null) - query = query.Skip(queryObject.Skip.Value); + if (queryObject.Skip != null) + query = query.Skip(queryObject.Skip.Value); - if(queryObject.Count != null) - query = query.Take(queryObject.Count.Value); + if (queryObject.Count != null) + query = query.Take(queryObject.Count.Value); - var data = await query.ToArrayAsync().ConfigureAwait(false); + var data = await query.ToArrayAsync().ConfigureAwait(false); - return data.Select(ToEntity).ToArray(); - } + return data.Select(ToEntity).ToArray(); + } - } + } - public async Task AddRefundsAsync(string invoiceId, TxOut[] outputs) - { - if(outputs.Length == 0) - return; - outputs = outputs.Take(10).ToArray(); - using(var context = _ContextFactory.CreateContext()) - { - int i = 0; - foreach(var output in outputs) - { - await context.RefundAddresses.AddAsync(new RefundAddressesData() - { - Id = invoiceId + "-" + i, - InvoiceDataId = invoiceId, - Blob = ToBytes(output) - }).ConfigureAwait(false); - i++; - } - await context.SaveChangesAsync().ConfigureAwait(false); - } + public async Task AddRefundsAsync(string invoiceId, TxOut[] outputs) + { + if (outputs.Length == 0) + return; + outputs = outputs.Take(10).ToArray(); + using (var context = _ContextFactory.CreateContext()) + { + int i = 0; + foreach (var output in outputs) + { + await context.RefundAddresses.AddAsync(new RefundAddressesData() + { + Id = invoiceId + "-" + i, + InvoiceDataId = invoiceId, + Blob = ToBytes(output) + }).ConfigureAwait(false); + i++; + } + await context.SaveChangesAsync().ConfigureAwait(false); + } - var addresses = outputs.Select(o => o.ScriptPubKey.GetDestinationAddress(_Network)).Where(a => a != null).ToArray(); - AddToTextSearch(invoiceId, addresses.Select(a => a.ToString()).ToArray()); - } + var addresses = outputs.Select(o => o.ScriptPubKey.GetDestinationAddress(_Network)).Where(a => a != null).ToArray(); + AddToTextSearch(invoiceId, addresses.Select(a => a.ToString()).ToArray()); + } - public async Task AddPayment(string invoiceId, Coin receivedCoin) - { - using(var context = _ContextFactory.CreateContext()) - { - PaymentEntity entity = new PaymentEntity - { - Outpoint = receivedCoin.Outpoint, - Output = receivedCoin.TxOut, - ReceivedTime = DateTime.UtcNow - }; + public async Task AddPayment(string invoiceId, Coin receivedCoin) + { + using (var context = _ContextFactory.CreateContext()) + { + PaymentEntity entity = new PaymentEntity + { + Outpoint = receivedCoin.Outpoint, + Output = receivedCoin.TxOut, + ReceivedTime = DateTime.UtcNow + }; - PaymentData data = new PaymentData - { - Id = receivedCoin.Outpoint.ToString(), - Blob = ToBytes(entity), - InvoiceDataId = invoiceId - }; + PaymentData data = new PaymentData + { + Id = receivedCoin.Outpoint.ToString(), + Blob = ToBytes(entity), + InvoiceDataId = invoiceId + }; - await context.Payments.AddAsync(data).ConfigureAwait(false); + await context.Payments.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return entity; - } - } + await context.SaveChangesAsync().ConfigureAwait(false); + return entity; + } + } - private T ToObject(byte[] value) - { - return NBitcoin.JsonConverters.Serializer.ToObject(ZipUtils.Unzip(value), Network); - } + private T ToObject(byte[] value) + { + return NBitcoin.JsonConverters.Serializer.ToObject(ZipUtils.Unzip(value), Network); + } - private byte[] ToBytes(T obj) - { - return ZipUtils.Zip(NBitcoin.JsonConverters.Serializer.ToString(obj)); - } + private byte[] ToBytes(T obj) + { + return ZipUtils.Zip(NBitcoin.JsonConverters.Serializer.ToString(obj)); + } - private T Clone(T invoice) - { - return NBitcoin.JsonConverters.Serializer.ToObject(ToString(invoice), Network); - } + private T Clone(T invoice) + { + return NBitcoin.JsonConverters.Serializer.ToObject(ToString(invoice), Network); + } - private string ToString(T data) - { - return NBitcoin.JsonConverters.Serializer.ToString(data, Network); - } - } + private string ToString(T data) + { + return NBitcoin.JsonConverters.Serializer.ToString(data, Network); + } + } - public class InvoiceQuery - { - public string StoreId - { - get; set; - } - public string UserId - { - get; set; - } - public string TextSearch - { - get; set; - } - public DateTimeOffset? StartDate - { - get; set; - } + public class InvoiceQuery + { + public string StoreId + { + get; set; + } + public string UserId + { + get; set; + } + public string TextSearch + { + get; set; + } + public DateTimeOffset? StartDate + { + get; set; + } - public DateTimeOffset? EndDate - { - get; set; - } + public DateTimeOffset? EndDate + { + get; set; + } - public int? Skip - { - get; set; - } + public int? Skip + { + get; set; + } - public int? Count - { - get; set; - } + public int? Count + { + get; set; + } - public string OrderId - { - get; set; - } + public string OrderId + { + get; set; + } - public string ItemCode - { - get; set; - } + public string ItemCode + { + get; set; + } - public string Status - { - get; set; - } - public string InvoiceId - { - get; - set; - } - } + public string Status + { + get; set; + } + public string InvoiceId + { + get; + set; + } + } } diff --git a/BTCPayServer/Services/Invoices/InvoiceWatcher.cs b/BTCPayServer/Services/Invoices/InvoiceWatcher.cs index f1c8640f0..7942491d0 100644 --- a/BTCPayServer/Services/Invoices/InvoiceWatcher.cs +++ b/BTCPayServer/Services/Invoices/InvoiceWatcher.cs @@ -16,342 +16,342 @@ using BTCPayServer.Services.Wallets; namespace BTCPayServer.Services.Invoices { - public class InvoiceWatcher : IHostedService - { - InvoiceRepository _InvoiceRepository; - ExplorerClient _ExplorerClient; - DerivationStrategyFactory _DerivationFactory; - InvoiceNotificationManager _NotificationManager; - BTCPayWallet _Wallet; + public class InvoiceWatcher : IHostedService + { + InvoiceRepository _InvoiceRepository; + ExplorerClient _ExplorerClient; + DerivationStrategyFactory _DerivationFactory; + InvoiceNotificationManager _NotificationManager; + BTCPayWallet _Wallet; - public InvoiceWatcher(ExplorerClient explorerClient, - InvoiceRepository invoiceRepository, - BTCPayWallet wallet, - InvoiceNotificationManager notificationManager) - { - LongPollingMode = explorerClient.Network == Network.RegTest; - PollInterval = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0); - _Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); - _ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient)); - _DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network); - _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); - _NotificationManager = notificationManager ?? throw new ArgumentNullException(nameof(notificationManager)); - } + public InvoiceWatcher(ExplorerClient explorerClient, + InvoiceRepository invoiceRepository, + BTCPayWallet wallet, + InvoiceNotificationManager notificationManager) + { + LongPollingMode = explorerClient.Network == Network.RegTest; + PollInterval = explorerClient.Network == Network.RegTest ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromMinutes(1.0); + _Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); + _ExplorerClient = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient)); + _DerivationFactory = new DerivationStrategyFactory(_ExplorerClient.Network); + _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); + _NotificationManager = notificationManager ?? throw new ArgumentNullException(nameof(notificationManager)); + } - public bool LongPollingMode - { - get; set; - } + public bool LongPollingMode + { + get; set; + } - public async Task NotifyReceived(Script scriptPubKey) - { - var invoice = await _InvoiceRepository.GetInvoiceIdFromScriptPubKey(scriptPubKey); - if(invoice != null) - _WatchRequests.Add(invoice); - } + public async Task NotifyReceived(Script scriptPubKey) + { + var invoice = await _InvoiceRepository.GetInvoiceIdFromScriptPubKey(scriptPubKey); + if (invoice != null) + _WatchRequests.Add(invoice); + } - public async Task NotifyBlock() - { - foreach(var invoice in await _InvoiceRepository.GetPendingInvoices()) - { - _WatchRequests.Add(invoice); - } - } + public async Task NotifyBlock() + { + foreach (var invoice in await _InvoiceRepository.GetPendingInvoices()) + { + _WatchRequests.Add(invoice); + } + } - private async Task UpdateInvoice(string invoiceId) - { - UTXOChanges changes = null; - while(true) - { - try - { - var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId).ConfigureAwait(false); - if(invoice == null) - break; - var stateBefore = invoice.Status; - var result = await UpdateInvoice(changes, invoice).ConfigureAwait(false); - changes = result.Changes; - if(result.NeedSave) - await _InvoiceRepository.UpdateInvoiceStatus(invoice.Id, invoice.Status, invoice.ExceptionStatus).ConfigureAwait(false); + private async Task UpdateInvoice(string invoiceId) + { + UTXOChanges changes = null; + while (true) + { + try + { + var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId).ConfigureAwait(false); + if (invoice == null) + break; + var stateBefore = invoice.Status; + var result = await UpdateInvoice(changes, invoice).ConfigureAwait(false); + changes = result.Changes; + if (result.NeedSave) + await _InvoiceRepository.UpdateInvoiceStatus(invoice.Id, invoice.Status, invoice.ExceptionStatus).ConfigureAwait(false); - var changed = stateBefore != invoice.Status; - if(changed) - { - Logs.PayServer.LogInformation($"Invoice {invoice.Id}: {stateBefore} => {invoice.Status}"); - } + var changed = stateBefore != invoice.Status; + if (changed) + { + Logs.PayServer.LogInformation($"Invoice {invoice.Id}: {stateBefore} => {invoice.Status}"); + } - var expirationMonitoring = invoice.MonitoringExpiration.HasValue ? invoice.MonitoringExpiration.Value : invoice.InvoiceTime + TimeSpan.FromMinutes(60); - if(invoice.Status == "complete" || - ((invoice.Status == "invalid" || invoice.Status == "expired") && expirationMonitoring < DateTimeOffset.UtcNow)) - { - if(await _InvoiceRepository.RemovePendingInvoice(invoice.Id).ConfigureAwait(false)) - Logs.PayServer.LogInformation("Stopped watching invoice " + invoiceId); - break; - } + var expirationMonitoring = invoice.MonitoringExpiration.HasValue ? invoice.MonitoringExpiration.Value : invoice.InvoiceTime + TimeSpan.FromMinutes(60); + if (invoice.Status == "complete" || + ((invoice.Status == "invalid" || invoice.Status == "expired") && expirationMonitoring < DateTimeOffset.UtcNow)) + { + if (await _InvoiceRepository.RemovePendingInvoice(invoice.Id).ConfigureAwait(false)) + Logs.PayServer.LogInformation("Stopped watching invoice " + invoiceId); + break; + } - if(!changed || _Cts.Token.IsCancellationRequested) - break; - } - catch(OperationCanceledException) when(_Cts.Token.IsCancellationRequested) - { - break; - } - catch(Exception ex) - { - Logs.PayServer.LogError(ex, "Unhandled error on watching invoice " + invoiceId); - await Task.Delay(10000, _Cts.Token).ConfigureAwait(false); - } - } - } + if (!changed || _Cts.Token.IsCancellationRequested) + break; + } + catch (OperationCanceledException) when (_Cts.Token.IsCancellationRequested) + { + break; + } + catch (Exception ex) + { + Logs.PayServer.LogError(ex, "Unhandled error on watching invoice " + invoiceId); + await Task.Delay(10000, _Cts.Token).ConfigureAwait(false); + } + } + } - private async Task<(bool NeedSave, UTXOChanges Changes)> UpdateInvoice(UTXOChanges changes, InvoiceEntity invoice) - { - bool needSave = false; - //Fetch unknown payments - var strategy = _DerivationFactory.Parse(invoice.DerivationStrategy); - changes = await _ExplorerClient.SyncAsync(strategy, changes, !LongPollingMode, _Cts.Token).ConfigureAwait(false); + private async Task<(bool NeedSave, UTXOChanges Changes)> UpdateInvoice(UTXOChanges changes, InvoiceEntity invoice) + { + bool needSave = false; + //Fetch unknown payments + var strategy = _DerivationFactory.Parse(invoice.DerivationStrategy); + changes = await _ExplorerClient.SyncAsync(strategy, changes, !LongPollingMode, _Cts.Token).ConfigureAwait(false); - var utxos = changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs).ToArray(); - var invoiceIds = utxos.Select(u => _InvoiceRepository.GetInvoiceIdFromScriptPubKey(u.Output.ScriptPubKey)).ToArray(); - utxos = - utxos - .Where((u, i) => invoiceIds[i].GetAwaiter().GetResult() == invoice.Id) - .ToArray(); + var utxos = changes.Confirmed.UTXOs.Concat(changes.Unconfirmed.UTXOs).ToArray(); + var invoiceIds = utxos.Select(u => _InvoiceRepository.GetInvoiceIdFromScriptPubKey(u.Output.ScriptPubKey)).ToArray(); + utxos = + utxos + .Where((u, i) => invoiceIds[i].GetAwaiter().GetResult() == invoice.Id) + .ToArray(); - List receivedCoins = new List(); - foreach(var received in utxos) - if(received.Output.ScriptPubKey == invoice.DepositAddress.ScriptPubKey) - receivedCoins.Add(new Coin(received.Outpoint, received.Output)); + List receivedCoins = new List(); + foreach (var received in utxos) + if (received.Output.ScriptPubKey == invoice.DepositAddress.ScriptPubKey) + receivedCoins.Add(new Coin(received.Outpoint, received.Output)); - var alreadyAccounted = new HashSet(invoice.Payments.Select(p => p.Outpoint)); - BitcoinAddress generatedAddress = null; - bool dirtyAddress = false; - foreach(var coin in receivedCoins.Where(c => !alreadyAccounted.Contains(c.Outpoint))) - { - var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin).ConfigureAwait(false); - invoice.Payments.Add(payment); - if(coin.ScriptPubKey == invoice.DepositAddress.ScriptPubKey && generatedAddress == null) - { - dirtyAddress = true; - } - } - ////// + var alreadyAccounted = new HashSet(invoice.Payments.Select(p => p.Outpoint)); + BitcoinAddress generatedAddress = null; + bool dirtyAddress = false; + foreach (var coin in receivedCoins.Where(c => !alreadyAccounted.Contains(c.Outpoint))) + { + var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin).ConfigureAwait(false); + invoice.Payments.Add(payment); + if (coin.ScriptPubKey == invoice.DepositAddress.ScriptPubKey && generatedAddress == null) + { + dirtyAddress = true; + } + } + ////// - if(invoice.Status == "new" && invoice.ExpirationTime < DateTimeOffset.UtcNow) - { - needSave = true; - await _InvoiceRepository.UnaffectAddress(invoice.Id); - invoice.Status = "expired"; - } + if (invoice.Status == "new" && invoice.ExpirationTime < DateTimeOffset.UtcNow) + { + needSave = true; + await _InvoiceRepository.UnaffectAddress(invoice.Id); + invoice.Status = "expired"; + } - if(invoice.Status == "new" || invoice.Status == "expired") - { - var totalPaid = invoice.Payments.Select(p => p.Output.Value).Sum(); - if(totalPaid >= invoice.GetTotalCryptoDue()) - { - if(invoice.Status == "new") - { - invoice.Status = "paid"; - if(invoice.FullNotifications) - { - _NotificationManager.Notify(invoice); - } - invoice.ExceptionStatus = null; - await _InvoiceRepository.UnaffectAddress(invoice.Id); - needSave = true; - } - else if(invoice.Status == "expired") - { - invoice.ExceptionStatus = "paidLate"; - needSave = true; - } - } + if (invoice.Status == "new" || invoice.Status == "expired") + { + var totalPaid = invoice.Payments.Select(p => p.Output.Value).Sum(); + if (totalPaid >= invoice.GetTotalCryptoDue()) + { + if (invoice.Status == "new") + { + invoice.Status = "paid"; + if (invoice.FullNotifications) + { + _NotificationManager.Notify(invoice); + } + invoice.ExceptionStatus = null; + await _InvoiceRepository.UnaffectAddress(invoice.Id); + needSave = true; + } + else if (invoice.Status == "expired") + { + invoice.ExceptionStatus = "paidLate"; + needSave = true; + } + } - if(totalPaid > invoice.GetTotalCryptoDue() && invoice.ExceptionStatus != "paidOver") - { - invoice.ExceptionStatus = "paidOver"; - await _InvoiceRepository.UnaffectAddress(invoice.Id); - needSave = true; - } + if (totalPaid > invoice.GetTotalCryptoDue() && invoice.ExceptionStatus != "paidOver") + { + invoice.ExceptionStatus = "paidOver"; + await _InvoiceRepository.UnaffectAddress(invoice.Id); + needSave = true; + } - if(totalPaid < invoice.GetTotalCryptoDue() && invoice.Payments.Count != 0 && invoice.ExceptionStatus != "paidPartial") - { - Logs.PayServer.LogInformation("Paid to " + invoice.DepositAddress); - invoice.ExceptionStatus = "paidPartial"; - needSave = true; - if(dirtyAddress) - { - var address = await _Wallet.ReserveAddressAsync(_DerivationFactory.Parse(invoice.DerivationStrategy)); - Logs.PayServer.LogInformation("Generate new " + address); - await _InvoiceRepository.NewAddress(invoice.Id, address); - } - } - } + if (totalPaid < invoice.GetTotalCryptoDue() && invoice.Payments.Count != 0 && invoice.ExceptionStatus != "paidPartial") + { + Logs.PayServer.LogInformation("Paid to " + invoice.DepositAddress); + invoice.ExceptionStatus = "paidPartial"; + needSave = true; + if (dirtyAddress) + { + var address = await _Wallet.ReserveAddressAsync(_DerivationFactory.Parse(invoice.DerivationStrategy)); + Logs.PayServer.LogInformation("Generate new " + address); + await _InvoiceRepository.NewAddress(invoice.Id, address); + } + } + } - if(invoice.Status == "paid") - { - if(!invoice.MonitoringExpiration.HasValue || invoice.MonitoringExpiration > DateTimeOffset.UtcNow) - { - var transactions = await GetPaymentsWithTransaction(invoice); - if(invoice.SpeedPolicy == SpeedPolicy.HighSpeed) - { - transactions = transactions.Where(t => !t.Transaction.Transaction.RBF); - } - else if(invoice.SpeedPolicy == SpeedPolicy.MediumSpeed) - { - transactions = transactions.Where(t => t.Transaction.Confirmations >= 1); - } - else if(invoice.SpeedPolicy == SpeedPolicy.LowSpeed) - { - transactions = transactions.Where(t => t.Transaction.Confirmations >= 6); - } + if (invoice.Status == "paid") + { + if (!invoice.MonitoringExpiration.HasValue || invoice.MonitoringExpiration > DateTimeOffset.UtcNow) + { + var transactions = await GetPaymentsWithTransaction(invoice); + if (invoice.SpeedPolicy == SpeedPolicy.HighSpeed) + { + transactions = transactions.Where(t => !t.Transaction.Transaction.RBF); + } + else if (invoice.SpeedPolicy == SpeedPolicy.MediumSpeed) + { + transactions = transactions.Where(t => t.Transaction.Confirmations >= 1); + } + else if (invoice.SpeedPolicy == SpeedPolicy.LowSpeed) + { + transactions = transactions.Where(t => t.Transaction.Confirmations >= 6); + } - var totalConfirmed = transactions.Select(t => t.Payment.Output.Value).Sum(); - if(totalConfirmed >= invoice.GetTotalCryptoDue()) - { - await _InvoiceRepository.UnaffectAddress(invoice.Id); - invoice.Status = "confirmed"; - _NotificationManager.Notify(invoice); - needSave = true; - } - } - else - { - await _InvoiceRepository.UnaffectAddress(invoice.Id); - invoice.Status = "invalid"; - needSave = true; - } - } + var totalConfirmed = transactions.Select(t => t.Payment.Output.Value).Sum(); + if (totalConfirmed >= invoice.GetTotalCryptoDue()) + { + await _InvoiceRepository.UnaffectAddress(invoice.Id); + invoice.Status = "confirmed"; + _NotificationManager.Notify(invoice); + needSave = true; + } + } + else + { + await _InvoiceRepository.UnaffectAddress(invoice.Id); + invoice.Status = "invalid"; + needSave = true; + } + } - if(invoice.Status == "confirmed") - { - var transactions = await GetPaymentsWithTransaction(invoice); - transactions = transactions.Where(t => t.Transaction.Confirmations >= 6); - var totalConfirmed = transactions.Select(t => t.Payment.Output.Value).Sum(); - if(totalConfirmed >= invoice.GetTotalCryptoDue()) - { - invoice.Status = "complete"; - if(invoice.FullNotifications) - _NotificationManager.Notify(invoice); - needSave = true; - } - } + if (invoice.Status == "confirmed") + { + var transactions = await GetPaymentsWithTransaction(invoice); + transactions = transactions.Where(t => t.Transaction.Confirmations >= 6); + var totalConfirmed = transactions.Select(t => t.Payment.Output.Value).Sum(); + if (totalConfirmed >= invoice.GetTotalCryptoDue()) + { + invoice.Status = "complete"; + if (invoice.FullNotifications) + _NotificationManager.Notify(invoice); + needSave = true; + } + } - return (needSave, changes); - } + return (needSave, changes); + } - private async Task> GetPaymentsWithTransaction(InvoiceEntity invoice) - { - var getPayments = invoice.Payments - .Select(async o => (Payment: o, Transaction: await _ExplorerClient.GetTransactionAsync(o.Outpoint.Hash, _Cts.Token))) - .ToArray(); - await Task.WhenAll(getPayments).ConfigureAwait(false); - var transactions = getPayments.Select(c => (Payment: c.Result.Payment, Transaction: c.Result.Transaction)); - return transactions; - } + private async Task> GetPaymentsWithTransaction(InvoiceEntity invoice) + { + var getPayments = invoice.Payments + .Select(async o => (Payment: o, Transaction: await _ExplorerClient.GetTransactionAsync(o.Outpoint.Hash, _Cts.Token))) + .ToArray(); + await Task.WhenAll(getPayments).ConfigureAwait(false); + var transactions = getPayments.Select(c => (Payment: c.Result.Payment, Transaction: c.Result.Transaction)); + return transactions; + } - TimeSpan _PollInterval; - public TimeSpan PollInterval - { - get - { - return _PollInterval; - } - set - { - _PollInterval = value; - if(_UpdatePendingInvoices != null) - { - _UpdatePendingInvoices.Change(0, (int)value.TotalMilliseconds); - } - } - } + TimeSpan _PollInterval; + public TimeSpan PollInterval + { + get + { + return _PollInterval; + } + set + { + _PollInterval = value; + if (_UpdatePendingInvoices != null) + { + _UpdatePendingInvoices.Change(0, (int)value.TotalMilliseconds); + } + } + } - public async Task WatchAsync(string invoiceId, bool singleShot = false) - { - if(invoiceId == null) - throw new ArgumentNullException(nameof(invoiceId)); - if(!singleShot) - await _InvoiceRepository.AddPendingInvoice(invoiceId).ConfigureAwait(false); - _WatchRequests.Add(invoiceId); - } + public async Task WatchAsync(string invoiceId, bool singleShot = false) + { + if (invoiceId == null) + throw new ArgumentNullException(nameof(invoiceId)); + if (!singleShot) + await _InvoiceRepository.AddPendingInvoice(invoiceId).ConfigureAwait(false); + _WatchRequests.Add(invoiceId); + } - BlockingCollection _WatchRequests = new BlockingCollection(new ConcurrentQueue()); + BlockingCollection _WatchRequests = new BlockingCollection(new ConcurrentQueue()); - public void Dispose() - { - _Cts.Cancel(); - } + public void Dispose() + { + _Cts.Cancel(); + } - Thread _Thread; - TaskCompletionSource _RunningTask; - CancellationTokenSource _Cts; - Timer _UpdatePendingInvoices; + Thread _Thread; + TaskCompletionSource _RunningTask; + CancellationTokenSource _Cts; + Timer _UpdatePendingInvoices; - public Task StartAsync(CancellationToken cancellationToken) - { - _RunningTask = new TaskCompletionSource(); - _Cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - _Thread = new Thread(Run) { Name = "InvoiceWatcher" }; - _Thread.Start(); - _UpdatePendingInvoices = new Timer(async s => - { - foreach(var pending in await _InvoiceRepository.GetPendingInvoices()) - { - _WatchRequests.Add(pending); - } - }, null, 0, (int)PollInterval.TotalMilliseconds); - return Task.CompletedTask; - } + public Task StartAsync(CancellationToken cancellationToken) + { + _RunningTask = new TaskCompletionSource(); + _Cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + _Thread = new Thread(Run) { Name = "InvoiceWatcher" }; + _Thread.Start(); + _UpdatePendingInvoices = new Timer(async s => + { + foreach (var pending in await _InvoiceRepository.GetPendingInvoices()) + { + _WatchRequests.Add(pending); + } + }, null, 0, (int)PollInterval.TotalMilliseconds); + return Task.CompletedTask; + } - void Run() - { - Logs.PayServer.LogInformation("Start watching invoices"); - ConcurrentDictionary> updating = new ConcurrentDictionary>(); - try - { - foreach(var item in _WatchRequests.GetConsumingEnumerable(_Cts.Token)) - { - try - { - _Cts.Token.ThrowIfCancellationRequested(); - var localItem = item; - // If the invoice is already updating, ignore - Lazy updateInvoice = new Lazy(() => UpdateInvoice(localItem), false); - if(updating.TryAdd(item, updateInvoice)) - { - updateInvoice.Value.ContinueWith(i => updating.TryRemove(item, out updateInvoice)); - } - } - catch(Exception ex) when(!_Cts.Token.IsCancellationRequested) - { - Logs.PayServer.LogCritical(ex, $"Error in the InvoiceWatcher loop (Invoice {item})"); - _Cts.Token.WaitHandle.WaitOne(2000); - } - } - } - catch(OperationCanceledException) - { - try - { - Task.WaitAll(updating.Select(c => c.Value.Value).ToArray()); - } - catch(AggregateException) { } - _RunningTask.TrySetResult(true); - } - finally - { - Logs.PayServer.LogInformation("Stop watching invoices"); - } - } + void Run() + { + Logs.PayServer.LogInformation("Start watching invoices"); + ConcurrentDictionary> updating = new ConcurrentDictionary>(); + try + { + foreach (var item in _WatchRequests.GetConsumingEnumerable(_Cts.Token)) + { + try + { + _Cts.Token.ThrowIfCancellationRequested(); + var localItem = item; + // If the invoice is already updating, ignore + Lazy updateInvoice = new Lazy(() => UpdateInvoice(localItem), false); + if (updating.TryAdd(item, updateInvoice)) + { + updateInvoice.Value.ContinueWith(i => updating.TryRemove(item, out updateInvoice)); + } + } + catch (Exception ex) when (!_Cts.Token.IsCancellationRequested) + { + Logs.PayServer.LogCritical(ex, $"Error in the InvoiceWatcher loop (Invoice {item})"); + _Cts.Token.WaitHandle.WaitOne(2000); + } + } + } + catch (OperationCanceledException) + { + try + { + Task.WaitAll(updating.Select(c => c.Value.Value).ToArray()); + } + catch (AggregateException) { } + _RunningTask.TrySetResult(true); + } + finally + { + Logs.PayServer.LogInformation("Stop watching invoices"); + } + } - public Task StopAsync(CancellationToken cancellationToken) - { - _UpdatePendingInvoices.Dispose(); - _Cts.Cancel(); - return Task.WhenAny(_RunningTask.Task, Task.Delay(-1, cancellationToken)); - } - } + public Task StopAsync(CancellationToken cancellationToken) + { + _UpdatePendingInvoices.Dispose(); + _Cts.Cancel(); + return Task.WhenAny(_RunningTask.Task, Task.Delay(-1, cancellationToken)); + } + } } diff --git a/BTCPayServer/Services/Mails/EmailSender.cs b/BTCPayServer/Services/Mails/EmailSender.cs index e6ec7c25e..c663cdd3b 100644 --- a/BTCPayServer/Services/Mails/EmailSender.cs +++ b/BTCPayServer/Services/Mails/EmailSender.cs @@ -7,34 +7,34 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Mails { - // This class is used by the application to send email for account confirmation and password reset. - // For more details see https://go.microsoft.com/fwlink/?LinkID=532713 - public class EmailSender : IEmailSender - { - IBackgroundJobClient _JobClient; - SettingsRepository _Repository; - public EmailSender(IBackgroundJobClient jobClient, SettingsRepository repository) - { - if(jobClient == null) - throw new ArgumentNullException(nameof(jobClient)); - _JobClient = jobClient; - _Repository = repository; - } - public Task SendEmailAsync(string email, string subject, string message) - { - _JobClient.Schedule(() => SendMailCore(email, subject, message), TimeSpan.Zero); - return Task.CompletedTask; - } + // This class is used by the application to send email for account confirmation and password reset. + // For more details see https://go.microsoft.com/fwlink/?LinkID=532713 + public class EmailSender : IEmailSender + { + IBackgroundJobClient _JobClient; + SettingsRepository _Repository; + public EmailSender(IBackgroundJobClient jobClient, SettingsRepository repository) + { + if (jobClient == null) + throw new ArgumentNullException(nameof(jobClient)); + _JobClient = jobClient; + _Repository = repository; + } + public Task SendEmailAsync(string email, string subject, string message) + { + _JobClient.Schedule(() => SendMailCore(email, subject, message), TimeSpan.Zero); + return Task.CompletedTask; + } - public async Task SendMailCore(string email, string subject, string message) - { - var settings = await _Repository.GetSettingAsync(); - if(settings == null) - throw new InvalidOperationException("Email settings not configured"); - var smtp = settings.CreateSmtpClient(); - MailMessage mail = new MailMessage(settings.From, email, subject, message); - mail.IsBodyHtml = true; - await smtp.SendMailAsync(mail); - } - } + public async Task SendMailCore(string email, string subject, string message) + { + var settings = await _Repository.GetSettingAsync(); + if (settings == null) + throw new InvalidOperationException("Email settings not configured"); + var smtp = settings.CreateSmtpClient(); + MailMessage mail = new MailMessage(settings.From, email, subject, message); + mail.IsBodyHtml = true; + await smtp.SendMailAsync(mail); + } + } } diff --git a/BTCPayServer/Services/Mails/EmailSettings.cs b/BTCPayServer/Services/Mails/EmailSettings.cs index 45abc6548..289b18c3a 100644 --- a/BTCPayServer/Services/Mails/EmailSettings.cs +++ b/BTCPayServer/Services/Mails/EmailSettings.cs @@ -10,50 +10,50 @@ namespace BTCPayServer.Services.Mails { public class EmailSettings { - [Required] - public string Server - { - get; set; - } + [Required] + public string Server + { + get; set; + } - [Required] - public int? Port - { - get; set; - } + [Required] + public int? Port + { + get; set; + } - [Required] - public String Login - { - get; set; - } + [Required] + public String Login + { + get; set; + } - [Required] - public String Password - { - get; set; - } + [Required] + public String Password + { + get; set; + } - [EmailAddress] - public string From - { - get; set; - } + [EmailAddress] + public string From + { + get; set; + } - public bool EnableSSL - { - get; set; - } + public bool EnableSSL + { + get; set; + } - public SmtpClient CreateSmtpClient() - { - SmtpClient client = new SmtpClient(Server, Port.Value); - client.EnableSsl = true; - client.UseDefaultCredentials = false; - client.Credentials = new NetworkCredential(Login, Password); - client.DeliveryMethod = SmtpDeliveryMethod.Network; - client.Timeout = 10000; - return client; - } - } + public SmtpClient CreateSmtpClient() + { + SmtpClient client = new SmtpClient(Server, Port.Value); + client.EnableSsl = true; + client.UseDefaultCredentials = false; + client.Credentials = new NetworkCredential(Login, Password); + client.DeliveryMethod = SmtpDeliveryMethod.Network; + client.Timeout = 10000; + return client; + } + } } diff --git a/BTCPayServer/Services/PoliciesSettings.cs b/BTCPayServer/Services/PoliciesSettings.cs index ad10a78c4..abbaf406d 100644 --- a/BTCPayServer/Services/PoliciesSettings.cs +++ b/BTCPayServer/Services/PoliciesSettings.cs @@ -7,9 +7,9 @@ namespace BTCPayServer.Services { public class PoliciesSettings { - public bool RequiresConfirmedEmail - { - get; set; - } - } + public bool RequiresConfirmedEmail + { + get; set; + } + } } diff --git a/BTCPayServer/Services/Rates/BitpayRateProvider.cs b/BTCPayServer/Services/Rates/BitpayRateProvider.cs index a33874aae..f4affe53d 100644 --- a/BTCPayServer/Services/Rates/BitpayRateProvider.cs +++ b/BTCPayServer/Services/Rates/BitpayRateProvider.cs @@ -7,30 +7,30 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Rates { - public class BitpayRateProvider : IRateProvider - { - Bitpay _Bitpay; - public BitpayRateProvider(Bitpay bitpay) - { - if(bitpay == null) - throw new ArgumentNullException(nameof(bitpay)); - _Bitpay = bitpay; - } - public async Task GetRateAsync(string currency) - { - var rates = await _Bitpay.GetRatesAsync().ConfigureAwait(false); - var rate = rates.GetRate(currency); - if(rate == 0m) - throw new RateUnavailableException(currency); - return (decimal)rate; - } + public class BitpayRateProvider : IRateProvider + { + Bitpay _Bitpay; + public BitpayRateProvider(Bitpay bitpay) + { + if (bitpay == null) + throw new ArgumentNullException(nameof(bitpay)); + _Bitpay = bitpay; + } + public async Task GetRateAsync(string currency) + { + var rates = await _Bitpay.GetRatesAsync().ConfigureAwait(false); + var rate = rates.GetRate(currency); + if (rate == 0m) + throw new RateUnavailableException(currency); + return (decimal)rate; + } - public async Task> GetRatesAsync() - { - return (await _Bitpay.GetRatesAsync().ConfigureAwait(false)) - .AllRates - .Select(r => new Rate() { Currency = r.Code, Value = r.Value }) - .ToList(); - } - } + public async Task> GetRatesAsync() + { + return (await _Bitpay.GetRatesAsync().ConfigureAwait(false)) + .AllRates + .Select(r => new Rate() { Currency = r.Code, Value = r.Value }) + .ToList(); + } + } } diff --git a/BTCPayServer/Services/Rates/CachedRateProvider.cs b/BTCPayServer/Services/Rates/CachedRateProvider.cs index df5c8c4c3..2cb01962d 100644 --- a/BTCPayServer/Services/Rates/CachedRateProvider.cs +++ b/BTCPayServer/Services/Rates/CachedRateProvider.cs @@ -6,49 +6,49 @@ using Microsoft.Extensions.Caching.Memory; namespace BTCPayServer.Services.Rates { - public class CachedRateProvider : IRateProvider - { - private IRateProvider _Inner; - private IMemoryCache _MemoryCache; + public class CachedRateProvider : IRateProvider + { + private IRateProvider _Inner; + private IMemoryCache _MemoryCache; - public CachedRateProvider(IRateProvider inner, IMemoryCache memoryCache) - { - if(inner == null) - throw new ArgumentNullException(nameof(inner)); - if(memoryCache == null) - throw new ArgumentNullException(nameof(memoryCache)); - this._Inner = inner; - this._MemoryCache = memoryCache; - } + public CachedRateProvider(IRateProvider inner, IMemoryCache memoryCache) + { + if (inner == null) + throw new ArgumentNullException(nameof(inner)); + if (memoryCache == null) + throw new ArgumentNullException(nameof(memoryCache)); + this._Inner = inner; + this._MemoryCache = memoryCache; + } - public TimeSpan CacheSpan - { - get; - set; - } = TimeSpan.FromMinutes(1.0); + public TimeSpan CacheSpan + { + get; + set; + } = TimeSpan.FromMinutes(1.0); - public Task GetRateAsync(string currency) - { - return _MemoryCache.GetOrCreateAsync("CURR_" + currency, (ICacheEntry entry) => - { - entry.AbsoluteExpiration = DateTimeOffset.UtcNow + CacheSpan; - return _Inner.GetRateAsync(currency); - }); - } + public Task GetRateAsync(string currency) + { + return _MemoryCache.GetOrCreateAsync("CURR_" + currency, (ICacheEntry entry) => + { + entry.AbsoluteExpiration = DateTimeOffset.UtcNow + CacheSpan; + return _Inner.GetRateAsync(currency); + }); + } - private bool TryGetFromCache(string key, out object obj) - { - obj = _MemoryCache.Get(key); - return obj != null; - } + private bool TryGetFromCache(string key, out object obj) + { + obj = _MemoryCache.Get(key); + return obj != null; + } - public Task> GetRatesAsync() - { - return _MemoryCache.GetOrCreateAsync("GLOBAL_RATES", (ICacheEntry entry) => - { - entry.AbsoluteExpiration = DateTimeOffset.UtcNow + CacheSpan; - return _Inner.GetRatesAsync(); - }); - } - } -} \ No newline at end of file + public Task> GetRatesAsync() + { + return _MemoryCache.GetOrCreateAsync("GLOBAL_RATES", (ICacheEntry entry) => + { + entry.AbsoluteExpiration = DateTimeOffset.UtcNow + CacheSpan; + return _Inner.GetRatesAsync(); + }); + } + } +} diff --git a/BTCPayServer/Services/Rates/CoinAverageRateProvider.cs b/BTCPayServer/Services/Rates/CoinAverageRateProvider.cs index 9f7b3e0ba..866b1167b 100644 --- a/BTCPayServer/Services/Rates/CoinAverageRateProvider.cs +++ b/BTCPayServer/Services/Rates/CoinAverageRateProvider.cs @@ -8,109 +8,109 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Rates { - public class CoinAverageException : Exception - { - public CoinAverageException(string message) : base(message) - { + public class CoinAverageException : Exception + { + public CoinAverageException(string message) : base(message) + { - } - } - public class CoinAverageRateProvider : IRateProvider - { - public class RatesJson - { - public class RateJson - { - public string Code - { - get; set; - } - public decimal Rate - { - get; set; - } - } + } + } + public class CoinAverageRateProvider : IRateProvider + { + public class RatesJson + { + public class RateJson + { + public string Code + { + get; set; + } + public decimal Rate + { + get; set; + } + } - [JsonProperty("rates")] - public JObject RatesInternal - { - get; set; - } - [JsonIgnore] - public List Rates - { - get; set; - } + [JsonProperty("rates")] + public JObject RatesInternal + { + get; set; + } + [JsonIgnore] + public List Rates + { + get; set; + } - [JsonIgnore] - public Dictionary RatesByCurrency - { - get; set; - } + [JsonIgnore] + public Dictionary RatesByCurrency + { + get; set; + } - public decimal GetRate(string currency) - { - if(!RatesByCurrency.TryGetValue(currency.ToUpperInvariant(), out decimal currUSD)) - throw new RateUnavailableException(currency); + public decimal GetRate(string currency) + { + if (!RatesByCurrency.TryGetValue(currency.ToUpperInvariant(), out decimal currUSD)) + throw new RateUnavailableException(currency); - if(!RatesByCurrency.TryGetValue("BTC", out decimal btcUSD)) - throw new RateUnavailableException(currency); + if (!RatesByCurrency.TryGetValue("BTC", out decimal btcUSD)) + throw new RateUnavailableException(currency); - return currUSD / btcUSD; - } - public void CalculateDictionary() - { - RatesByCurrency = new Dictionary(); - Rates = new List(); - foreach(var rate in RatesInternal.OfType()) - { - var rateJson = new RateJson(); - rateJson.Code = rate.Name; - rateJson.Rate = rate.Value["rate"].Value(); - RatesByCurrency.Add(rate.Name, rateJson.Rate); - Rates.Add(rateJson); - } - } - } - static HttpClient _Client = new HttpClient(); + return currUSD / btcUSD; + } + public void CalculateDictionary() + { + RatesByCurrency = new Dictionary(); + Rates = new List(); + foreach (var rate in RatesInternal.OfType()) + { + var rateJson = new RateJson(); + rateJson.Code = rate.Name; + rateJson.Rate = rate.Value["rate"].Value(); + RatesByCurrency.Add(rate.Name, rateJson.Rate); + Rates.Add(rateJson); + } + } + } + static HttpClient _Client = new HttpClient(); - public string Market - { - get; set; - } = "global"; - public async Task GetRateAsync(string currency) - { - RatesJson rates = await GetRatesCore(); - return rates.GetRate(currency); - } + public string Market + { + get; set; + } = "global"; + public async Task GetRateAsync(string currency) + { + RatesJson rates = await GetRatesCore(); + return rates.GetRate(currency); + } - private async Task GetRatesCore() - { - var resp = await _Client.GetAsync("https://apiv2.bitcoinaverage.com/constants/exchangerates/" + Market); - using(resp) - { + private async Task GetRatesCore() + { + var resp = await _Client.GetAsync("https://apiv2.bitcoinaverage.com/constants/exchangerates/" + Market); + using (resp) + { - if((int)resp.StatusCode == 401) - throw new CoinAverageException("Unauthorized access to the API"); - if((int)resp.StatusCode == 429) - throw new CoinAverageException("Exceed API limits"); - if((int)resp.StatusCode == 403) - throw new CoinAverageException("Unauthorized access to the API, premium plan needed"); - resp.EnsureSuccessStatusCode(); - var rates = JsonConvert.DeserializeObject(await resp.Content.ReadAsStringAsync()); - rates.CalculateDictionary(); - return rates; - } - } + if ((int)resp.StatusCode == 401) + throw new CoinAverageException("Unauthorized access to the API"); + if ((int)resp.StatusCode == 429) + throw new CoinAverageException("Exceed API limits"); + if ((int)resp.StatusCode == 403) + throw new CoinAverageException("Unauthorized access to the API, premium plan needed"); + resp.EnsureSuccessStatusCode(); + var rates = JsonConvert.DeserializeObject(await resp.Content.ReadAsStringAsync()); + rates.CalculateDictionary(); + return rates; + } + } - public async Task> GetRatesAsync() - { - RatesJson rates = await GetRatesCore(); - return rates.Rates.Select(o => new Rate() - { - Currency = o.Code, - Value = rates.GetRate(o.Code) - }).ToList(); - } - } + public async Task> GetRatesAsync() + { + RatesJson rates = await GetRatesCore(); + return rates.Rates.Select(o => new Rate() + { + Currency = o.Code, + Value = rates.GetRate(o.Code) + }).ToList(); + } + } } diff --git a/BTCPayServer/Services/Rates/CurrencyNameTable.cs b/BTCPayServer/Services/Rates/CurrencyNameTable.cs index 636aedbb4..f7987e2be 100644 --- a/BTCPayServer/Services/Rates/CurrencyNameTable.cs +++ b/BTCPayServer/Services/Rates/CurrencyNameTable.cs @@ -7,77 +7,77 @@ using System.Text; namespace BTCPayServer.Services.Rates { - public class CurrencyData - { - public string Name - { - get; - internal set; - } - public string Code - { - get; - internal set; - } - public int Divisibility - { - get; - internal set; - } - public string Symbol - { - get; - internal set; - } - } - public class CurrencyNameTable + public class CurrencyData { - public CurrencyNameTable() - { - _Currencies = LoadCurrency().ToDictionary(k => k.Code); - } + public string Name + { + get; + internal set; + } + public string Code + { + get; + internal set; + } + public int Divisibility + { + get; + internal set; + } + public string Symbol + { + get; + internal set; + } + } + public class CurrencyNameTable + { + public CurrencyNameTable() + { + _Currencies = LoadCurrency().ToDictionary(k => k.Code); + } - Dictionary _Currencies; + Dictionary _Currencies; - static CurrencyData[] LoadCurrency() - { - var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BTCPayServer.Currencies.txt"); - string content = null; - using(var reader = new StreamReader(stream, Encoding.UTF8)) - { - content = reader.ReadToEnd(); - } - var currencies = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); - Dictionary dico = new Dictionary(); - foreach(var currency in currencies) - { - var splitted = currency.Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); - if(splitted.Length < 3) - continue; - CurrencyData info = new CurrencyData(); - info.Name = splitted[0]; - info.Code = splitted[1]; - int divisibility; - if(!int.TryParse(splitted[2], out divisibility)) - continue; - info.Divisibility = divisibility; - if(!dico.ContainsKey(info.Code)) - dico.Add(info.Code, info); - if(splitted.Length >= 4) - { - info.Symbol = splitted[3]; - } - } - return dico.Values.ToArray(); - } + static CurrencyData[] LoadCurrency() + { + var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BTCPayServer.Currencies.txt"); + string content = null; + using (var reader = new StreamReader(stream, Encoding.UTF8)) + { + content = reader.ReadToEnd(); + } + var currencies = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); + Dictionary dico = new Dictionary(); + foreach (var currency in currencies) + { + var splitted = currency.Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (splitted.Length < 3) + continue; + CurrencyData info = new CurrencyData(); + info.Name = splitted[0]; + info.Code = splitted[1]; + int divisibility; + if (!int.TryParse(splitted[2], out divisibility)) + continue; + info.Divisibility = divisibility; + if (!dico.ContainsKey(info.Code)) + dico.Add(info.Code, info); + if (splitted.Length >= 4) + { + info.Symbol = splitted[3]; + } + } + return dico.Values.ToArray(); + } - public CurrencyData GetCurrencyData(string currency) - { - CurrencyData result; - _Currencies.TryGetValue(currency.ToUpperInvariant(), out result); - return result; - } - - } + public CurrencyData GetCurrencyData(string currency) + { + CurrencyData result; + _Currencies.TryGetValue(currency.ToUpperInvariant(), out result); + return result; + } + + } } diff --git a/BTCPayServer/Services/Rates/IRateProvider.cs b/BTCPayServer/Services/Rates/IRateProvider.cs index 47db655fc..19a33ae45 100644 --- a/BTCPayServer/Services/Rates/IRateProvider.cs +++ b/BTCPayServer/Services/Rates/IRateProvider.cs @@ -5,29 +5,29 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Rates { - public class Rate - { - public Rate() - { + public class Rate + { + public Rate() + { - } - public Rate(string currency, decimal value) - { - Value = value; - Currency = currency; - } - public string Currency - { - get; set; - } - public decimal Value - { - get; set; - } - } + } + public Rate(string currency, decimal value) + { + Value = value; + Currency = currency; + } + public string Currency + { + get; set; + } + public decimal Value + { + get; set; + } + } public interface IRateProvider { - Task GetRateAsync(string currency); - Task> GetRatesAsync(); - } + Task GetRateAsync(string currency); + Task> GetRatesAsync(); + } } diff --git a/BTCPayServer/Services/Rates/MockRateProvider.cs b/BTCPayServer/Services/Rates/MockRateProvider.cs index 93528cc15..6cd8dadb0 100644 --- a/BTCPayServer/Services/Rates/MockRateProvider.cs +++ b/BTCPayServer/Services/Rates/MockRateProvider.cs @@ -6,30 +6,30 @@ using System.Threading.Tasks; namespace BTCPayServer.Services.Rates { - public class MockRateProvider : IRateProvider - { - List _Rates; + public class MockRateProvider : IRateProvider + { + List _Rates; - public MockRateProvider(params Rate[] rates) - { - _Rates = new List(rates); - } - public MockRateProvider(List rates) - { - _Rates = rates; - } - public Task GetRateAsync(string currency) - { - var rate = _Rates.FirstOrDefault(r => r.Currency.Equals(currency, StringComparison.OrdinalIgnoreCase)); - if(rate == null) - throw new RateUnavailableException(currency); - return Task.FromResult(rate.Value); - } + public MockRateProvider(params Rate[] rates) + { + _Rates = new List(rates); + } + public MockRateProvider(List rates) + { + _Rates = rates; + } + public Task GetRateAsync(string currency) + { + var rate = _Rates.FirstOrDefault(r => r.Currency.Equals(currency, StringComparison.OrdinalIgnoreCase)); + if (rate == null) + throw new RateUnavailableException(currency); + return Task.FromResult(rate.Value); + } - public Task> GetRatesAsync() - { - ICollection rates = _Rates; - return Task.FromResult(rates); - } - } + public Task> GetRatesAsync() + { + ICollection rates = _Rates; + return Task.FromResult(rates); + } + } } diff --git a/BTCPayServer/Services/Rates/RateUnavailableException.cs b/BTCPayServer/Services/Rates/RateUnavailableException.cs index 5bab03409..a21cbf71f 100644 --- a/BTCPayServer/Services/Rates/RateUnavailableException.cs +++ b/BTCPayServer/Services/Rates/RateUnavailableException.cs @@ -6,16 +6,16 @@ namespace BTCPayServer.Services.Rates { public class RateUnavailableException : Exception { - public RateUnavailableException(string currency) : base("Rate unavailable for currency " + currency) - { - if(currency == null) - throw new ArgumentNullException(nameof(currency)); - Currency = currency; - } + public RateUnavailableException(string currency) : base("Rate unavailable for currency " + currency) + { + if (currency == null) + throw new ArgumentNullException(nameof(currency)); + Currency = currency; + } - public string Currency - { - get; set; - } - } + public string Currency + { + get; set; + } + } } diff --git a/BTCPayServer/Services/SettingsRepository.cs b/BTCPayServer/Services/SettingsRepository.cs index 30d4d9235..51e80bfa7 100644 --- a/BTCPayServer/Services/SettingsRepository.cs +++ b/BTCPayServer/Services/SettingsRepository.cs @@ -11,56 +11,56 @@ using Newtonsoft.Json; namespace BTCPayServer.Services { - public class SettingsRepository - { - private ApplicationDbContextFactory _ContextFactory; - public SettingsRepository(ApplicationDbContextFactory contextFactory) - { - _ContextFactory = contextFactory; - } + public class SettingsRepository + { + private ApplicationDbContextFactory _ContextFactory; + public SettingsRepository(ApplicationDbContextFactory contextFactory) + { + _ContextFactory = contextFactory; + } - public async Task GetSettingAsync() - { - var name = typeof(T).FullName; - using(var ctx = _ContextFactory.CreateContext()) - { - var data = await ctx.Settings.Where(s => s.Id == name).FirstOrDefaultAsync(); - if(data == null) - return default(T); - return Deserialize(data.Value); - } - } + public async Task GetSettingAsync() + { + var name = typeof(T).FullName; + using (var ctx = _ContextFactory.CreateContext()) + { + var data = await ctx.Settings.Where(s => s.Id == name).FirstOrDefaultAsync(); + if (data == null) + return default(T); + return Deserialize(data.Value); + } + } - public async Task UpdateSetting(T obj) - { - var name = obj.GetType().FullName; - using(var ctx = _ContextFactory.CreateContext()) - { - var settings = new SettingData(); - settings.Id = name; - settings.Value = Serialize(obj); - ctx.Attach(settings); - ctx.Entry(settings).State = EntityState.Modified; - try - { - await ctx.SaveChangesAsync(); - } - catch(DbUpdateException) - { - ctx.Entry(settings).State = EntityState.Added; - await ctx.SaveChangesAsync(); - } - } - } + public async Task UpdateSetting(T obj) + { + var name = obj.GetType().FullName; + using (var ctx = _ContextFactory.CreateContext()) + { + var settings = new SettingData(); + settings.Id = name; + settings.Value = Serialize(obj); + ctx.Attach(settings); + ctx.Entry(settings).State = EntityState.Modified; + try + { + await ctx.SaveChangesAsync(); + } + catch (DbUpdateException) + { + ctx.Entry(settings).State = EntityState.Added; + await ctx.SaveChangesAsync(); + } + } + } - private T Deserialize(string value) - { - return JsonConvert.DeserializeObject(value); - } + private T Deserialize(string value) + { + return JsonConvert.DeserializeObject(value); + } - private string Serialize(T obj) - { - return JsonConvert.SerializeObject(obj); - } - } + private string Serialize(T obj) + { + return JsonConvert.SerializeObject(obj); + } + } } diff --git a/BTCPayServer/Services/Stores/StoreRepository.cs b/BTCPayServer/Services/Stores/StoreRepository.cs index 2713dda3c..371cdc946 100644 --- a/BTCPayServer/Services/Stores/StoreRepository.cs +++ b/BTCPayServer/Services/Stores/StoreRepository.cs @@ -10,99 +10,99 @@ using Microsoft.EntityFrameworkCore; namespace BTCPayServer.Services.Stores { - public class StoreRepository - { - private ApplicationDbContextFactory _ContextFactory; - public StoreRepository(ApplicationDbContextFactory contextFactory) - { - _ContextFactory = contextFactory ?? throw new ArgumentNullException(nameof(contextFactory)); - } + public class StoreRepository + { + private ApplicationDbContextFactory _ContextFactory; + public StoreRepository(ApplicationDbContextFactory contextFactory) + { + _ContextFactory = contextFactory ?? throw new ArgumentNullException(nameof(contextFactory)); + } - public async Task FindStore(string storeId) - { - using(var ctx = _ContextFactory.CreateContext()) - { - return await ctx.FindAsync(storeId).ConfigureAwait(false); - } - } + public async Task FindStore(string storeId) + { + using (var ctx = _ContextFactory.CreateContext()) + { + return await ctx.FindAsync(storeId).ConfigureAwait(false); + } + } - public async Task FindStore(string storeId, string userId) - { - if(userId == null) - throw new ArgumentNullException(nameof(userId)); - using(var ctx = _ContextFactory.CreateContext()) - { - return (await ctx - .UserStore - .Where(us => us.ApplicationUserId == userId && us.StoreDataId == storeId) - .Select(us => new - { - Store = us.StoreData, - Role = us.Role - }).ToArrayAsync()) - .Select(us => - { - us.Store.Role = us.Role; - return us.Store; - }).FirstOrDefault(); - } - } + public async Task FindStore(string storeId, string userId) + { + if (userId == null) + throw new ArgumentNullException(nameof(userId)); + using (var ctx = _ContextFactory.CreateContext()) + { + return (await ctx + .UserStore + .Where(us => us.ApplicationUserId == userId && us.StoreDataId == storeId) + .Select(us => new + { + Store = us.StoreData, + Role = us.Role + }).ToArrayAsync()) + .Select(us => + { + us.Store.Role = us.Role; + return us.Store; + }).FirstOrDefault(); + } + } - public async Task GetStoresByUserId(string userId) - { - using(var ctx = _ContextFactory.CreateContext()) - { - return await ctx.UserStore - .Where(u => u.ApplicationUserId == userId) - .Select(u => u.StoreData) - .ToArrayAsync(); - } - } + public async Task GetStoresByUserId(string userId) + { + using (var ctx = _ContextFactory.CreateContext()) + { + return await ctx.UserStore + .Where(u => u.ApplicationUserId == userId) + .Select(u => u.StoreData) + .ToArrayAsync(); + } + } - public async Task CreateStore(string ownerId, string name) - { - if(string.IsNullOrEmpty(name)) - throw new ArgumentException("name should not be empty", nameof(name)); - using(var ctx = _ContextFactory.CreateContext()) - { - StoreData store = new StoreData - { - Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)), - StoreName = name - }; - var userStore = new UserStore - { - StoreDataId = store.Id, - ApplicationUserId = ownerId, - Role = "Owner" - }; - await ctx.AddAsync(store).ConfigureAwait(false); - await ctx.AddAsync(userStore).ConfigureAwait(false); - await ctx.SaveChangesAsync().ConfigureAwait(false); - return store; - } - } + public async Task CreateStore(string ownerId, string name) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("name should not be empty", nameof(name)); + using (var ctx = _ContextFactory.CreateContext()) + { + StoreData store = new StoreData + { + Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)), + StoreName = name + }; + var userStore = new UserStore + { + StoreDataId = store.Id, + ApplicationUserId = ownerId, + Role = "Owner" + }; + await ctx.AddAsync(store).ConfigureAwait(false); + await ctx.AddAsync(userStore).ConfigureAwait(false); + await ctx.SaveChangesAsync().ConfigureAwait(false); + return store; + } + } - public async Task RemoveStore(string storeId, string userId) - { - using(var ctx = _ContextFactory.CreateContext()) - { - var storeUser = await ctx.UserStore.FirstOrDefaultAsync(o => o.StoreDataId == storeId && o.ApplicationUserId == userId); - if(storeUser == null) - return; - ctx.UserStore.Remove(storeUser); - await ctx.SaveChangesAsync(); - } - } + public async Task RemoveStore(string storeId, string userId) + { + using (var ctx = _ContextFactory.CreateContext()) + { + var storeUser = await ctx.UserStore.FirstOrDefaultAsync(o => o.StoreDataId == storeId && o.ApplicationUserId == userId); + if (storeUser == null) + return; + ctx.UserStore.Remove(storeUser); + await ctx.SaveChangesAsync(); + } + } - public async Task UpdateStore(StoreData store) - { - using(var ctx = _ContextFactory.CreateContext()) - { - var existing = await ctx.FindAsync(store.Id); - ctx.Entry(existing).CurrentValues.SetValues(store); - await ctx.SaveChangesAsync().ConfigureAwait(false); - } - } - } + public async Task UpdateStore(StoreData store) + { + using (var ctx = _ContextFactory.CreateContext()) + { + var existing = await ctx.FindAsync(store.Id); + ctx.Entry(existing).CurrentValues.SetValues(store); + await ctx.SaveChangesAsync().ConfigureAwait(false); + } + } + } } diff --git a/BTCPayServer/Services/Wallets/BTCPayWallet.cs b/BTCPayServer/Services/Wallets/BTCPayWallet.cs index 53848a742..93693d754 100644 --- a/BTCPayServer/Services/Wallets/BTCPayWallet.cs +++ b/BTCPayServer/Services/Wallets/BTCPayWallet.cs @@ -10,52 +10,52 @@ using BTCPayServer.Data; namespace BTCPayServer.Services.Wallets { - public class BTCPayWallet - { - private ExplorerClient _Client; - private Serializer _Serializer; - ApplicationDbContextFactory _DBFactory; + public class BTCPayWallet + { + private ExplorerClient _Client; + private Serializer _Serializer; + ApplicationDbContextFactory _DBFactory; - public BTCPayWallet(ExplorerClient client, ApplicationDbContextFactory factory) - { - if(client == null) - throw new ArgumentNullException(nameof(client)); - if(factory == null) - throw new ArgumentNullException(nameof(factory)); - _Client = client; - _DBFactory = factory; - _Serializer = new NBXplorer.Serializer(_Client.Network); - } + public BTCPayWallet(ExplorerClient client, ApplicationDbContextFactory factory) + { + if (client == null) + throw new ArgumentNullException(nameof(client)); + if (factory == null) + throw new ArgumentNullException(nameof(factory)); + _Client = client; + _DBFactory = factory; + _Serializer = new NBXplorer.Serializer(_Client.Network); + } - public async Task ReserveAddressAsync(DerivationStrategyBase derivationStrategy) - { - var pathInfo = await _Client.GetUnusedAsync(derivationStrategy, DerivationFeature.Deposit, 0, true).ConfigureAwait(false); - return pathInfo.ScriptPubKey.GetDestinationAddress(_Client.Network); - } + public async Task ReserveAddressAsync(DerivationStrategyBase derivationStrategy) + { + var pathInfo = await _Client.GetUnusedAsync(derivationStrategy, DerivationFeature.Deposit, 0, true).ConfigureAwait(false); + return pathInfo.ScriptPubKey.GetDestinationAddress(_Client.Network); + } - public async Task TrackAsync(DerivationStrategyBase derivationStrategy) - { - await _Client.TrackAsync(derivationStrategy); - } + public async Task TrackAsync(DerivationStrategyBase derivationStrategy) + { + await _Client.TrackAsync(derivationStrategy); + } - private byte[] ToBytes(T obj) - { - return ZipUtils.Zip(_Serializer.ToString(obj)); - } + private byte[] ToBytes(T obj) + { + return ZipUtils.Zip(_Serializer.ToString(obj)); + } - public Task BroadcastTransactionsAsync(List transactions) - { - var tasks = transactions.Select(t => _Client.BroadcastAsync(t)).ToArray(); - return Task.WhenAll(tasks); - } + public Task BroadcastTransactionsAsync(List transactions) + { + var tasks = transactions.Select(t => _Client.BroadcastAsync(t)).ToArray(); + return Task.WhenAll(tasks); + } - public async Task GetBalance(DerivationStrategyBase derivationStrategy) - { - var result = await _Client.SyncAsync(derivationStrategy, null, true); - return result.Confirmed.UTXOs.Select(u => u.Output.Value) - .Concat(result.Unconfirmed.UTXOs.Select(u => u.Output.Value)) - .Sum(); - } - } + public async Task GetBalance(DerivationStrategyBase derivationStrategy) + { + var result = await _Client.SyncAsync(derivationStrategy, null, true); + return result.Confirmed.UTXOs.Select(u => u.Output.Value) + .Concat(result.Unconfirmed.UTXOs.Select(u => u.Output.Value)) + .Sum(); + } + } } diff --git a/BTCPayServer/Validations/DerivationStrategyValidatorAttribute.cs b/BTCPayServer/Validations/DerivationStrategyValidatorAttribute.cs index 4ebba59c2..33054a5b1 100644 --- a/BTCPayServer/Validations/DerivationStrategyValidatorAttribute.cs +++ b/BTCPayServer/Validations/DerivationStrategyValidatorAttribute.cs @@ -7,26 +7,26 @@ using System.Text; namespace BTCPayServer.Validations { - public class DerivationStrategyValidatorAttribute : ValidationAttribute - { - protected override ValidationResult IsValid(object value, ValidationContext validationContext) - { - if(value == null) - { - return ValidationResult.Success; - } - var network = (Network)validationContext.GetService(typeof(Network)); - if(network == null) - return new ValidationResult("No Network specified"); - try - { - new DerivationStrategyFactory(network).Parse((string)value); - return ValidationResult.Success; - } - catch(Exception ex) - { - return new ValidationResult(ex.Message); - } - } - } + public class DerivationStrategyValidatorAttribute : ValidationAttribute + { + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (value == null) + { + return ValidationResult.Success; + } + var network = (Network)validationContext.GetService(typeof(Network)); + if (network == null) + return new ValidationResult("No Network specified"); + try + { + new DerivationStrategyFactory(network).Parse((string)value); + return ValidationResult.Success; + } + catch (Exception ex) + { + return new ValidationResult(ex.Message); + } + } + } } diff --git a/BTCPayServer/Validations/EmailValidator.cs b/BTCPayServer/Validations/EmailValidator.cs index 2ef40ea38..805690c8e 100644 --- a/BTCPayServer/Validations/EmailValidator.cs +++ b/BTCPayServer/Validations/EmailValidator.cs @@ -8,14 +8,14 @@ namespace BTCPayServer.Validations { public class EmailValidator { - static Regex _Email; - public static bool IsEmail(string str) - { - if(String.IsNullOrWhiteSpace(str)) - return false; - if(_Email == null) - _Email = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled, TimeSpan.FromSeconds(2.0)); - return _Email.IsMatch(str); - } - } + static Regex _Email; + public static bool IsEmail(string str) + { + if (String.IsNullOrWhiteSpace(str)) + return false; + if (_Email == null) + _Email = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled, TimeSpan.FromSeconds(2.0)); + return _Email.IsMatch(str); + } + } } diff --git a/BTCPayServer/Validations/PubKeyValidator.cs b/BTCPayServer/Validations/PubKeyValidator.cs index d6847bb61..a308a2b01 100644 --- a/BTCPayServer/Validations/PubKeyValidator.cs +++ b/BTCPayServer/Validations/PubKeyValidator.cs @@ -6,23 +6,23 @@ using System.Text; namespace BTCPayServer.Validations { - public class PubKeyValidatorAttribute : ValidationAttribute - { - protected override ValidationResult IsValid(object value, ValidationContext validationContext) - { - if(value == null) - { - return ValidationResult.Success; - } - try - { - new PubKey((string)value); - return ValidationResult.Success; - } - catch(Exception ex) - { - return new ValidationResult(ex.Message); - } - } - } + public class PubKeyValidatorAttribute : ValidationAttribute + { + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (value == null) + { + return ValidationResult.Success; + } + try + { + new PubKey((string)value); + return ValidationResult.Success; + } + catch (Exception ex) + { + return new ValidationResult(ex.Message); + } + } + } } diff --git a/BTCPayServer/Views/Account/ConfirmEmail.cshtml b/BTCPayServer/Views/Account/ConfirmEmail.cshtml index d73d4097f..55ceaee89 100644 --- a/BTCPayServer/Views/Account/ConfirmEmail.cshtml +++ b/BTCPayServer/Views/Account/ConfirmEmail.cshtml @@ -1,14 +1,14 @@ @{ - ViewData["Title"] = "Confirm email"; + ViewData["Title"] = "Confirm email"; }
-
+
-
-
- @Html.Partial("_StatusMessage", "Thank you for confirming your email.") -
-
-
-
\ No newline at end of file +
+
+ @Html.Partial("_StatusMessage", "Thank you for confirming your email.") +
+
+ + diff --git a/BTCPayServer/Views/Account/Login.cshtml b/BTCPayServer/Views/Account/Login.cshtml index d6f5bd014..f1a69ab9e 100644 --- a/BTCPayServer/Views/Account/Login.cshtml +++ b/BTCPayServer/Views/Account/Login.cshtml @@ -6,88 +6,88 @@ @inject SignInManager SignInManager @{ - ViewData["Title"] = "Log in"; + ViewData["Title"] = "Log in"; }
-
-
-
-

@ViewData["Title"]

-
-
-
-
-
-

Use a local account to log in.

-
-
-
- - - -
-
- - - -
-
-
- -
-
-
- -
- -
-
-
-
-
-

Use another service to log in.

-
- @{ - var loginProviders = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList(); - if(loginProviders.Count == 0) - { -
-

- There are no external authentication services configured. See this article - for details on setting up this ASP.NET application to support logging in via external services. -

-
- } - else - { -
-
-

- @foreach(var provider in loginProviders) - { - - } -

-
-
- } - } -
-
-
-
+
+
+
+

@ViewData["Title"]

+
+
+
+
+
+

Use a local account to log in.

+
+
+
+ + + +
+
+ + + +
+
+
+ +
+
+
+ +
+ +
+
+
+
+
+

Use another service to log in.

+
+ @{ + var loginProviders = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList(); + if(loginProviders.Count == 0) + { +
+

+ There are no external authentication services configured. See this article + for details on setting up this ASP.NET application to support logging in via external services. +

+
+ } + else + { +
+
+

+ @foreach(var provider in loginProviders) + { + + } +

+
+
+ } + } +
+
+
+
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") + @await Html.PartialAsync("_ValidationScriptsPartial") } diff --git a/BTCPayServer/Views/Account/LoginWith2fa.cshtml b/BTCPayServer/Views/Account/LoginWith2fa.cshtml index ec2e9c7df..0d7be98e9 100644 --- a/BTCPayServer/Views/Account/LoginWith2fa.cshtml +++ b/BTCPayServer/Views/Account/LoginWith2fa.cshtml @@ -1,53 +1,53 @@ @model LoginWith2faViewModel @{ - ViewData["Title"] = "Two-factor authentication"; + ViewData["Title"] = "Two-factor authentication"; }
-
-
-
-

@ViewData["Title"]

-
-
-
-
-
-
-
- -
-
- - - -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-

- Don't have access to your authenticator device? You can - log in with a recovery code. -

-
-
-
+
+
+
+

@ViewData["Title"]

+
+
+
+
+
+
+
+ +
+
+ + + +
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+

+ Don't have access to your authenticator device? You can + log in with a recovery code. +

+
+
+
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") + @await Html.PartialAsync("_ValidationScriptsPartial") } diff --git a/BTCPayServer/Views/Account/Register.cshtml b/BTCPayServer/Views/Account/Register.cshtml index 6e58d603e..67ddab5c3 100644 --- a/BTCPayServer/Views/Account/Register.cshtml +++ b/BTCPayServer/Views/Account/Register.cshtml @@ -1,46 +1,46 @@ @model RegisterViewModel @{ - ViewData["Title"] = "Register"; + ViewData["Title"] = "Register"; }
-
-
-
- @Html.Partial("_StatusMessage", TempData["StatusMessage"]) -
-
-
-
-

@ViewData["Title"]

-
-
-
-
-

Create a new account.

-
-
-
- - - -
-
- - - -
-
- - - -
- -
-
-
-
+
+
+
+ @Html.Partial("_StatusMessage", TempData["StatusMessage"]) +
+
+
+
+

@ViewData["Title"]

+
+
+
+
+

Create a new account.

+
+
+
+ + + +
+
+ + + +
+
+ + + +
+ +
+
+
+
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") + @await Html.PartialAsync("_ValidationScriptsPartial") } diff --git a/BTCPayServer/Views/Home/Home.cshtml b/BTCPayServer/Views/Home/Home.cshtml index 92d978a68..ff6e2894a 100644 --- a/BTCPayServer/Views/Home/Home.cshtml +++ b/BTCPayServer/Views/Home/Home.cshtml @@ -1,133 +1,133 @@ @{ - ViewData["Title"] = "Home Page"; - ViewBag.AlwaysShrinkNavBar = false; + ViewData["Title"] = "Home Page"; + ViewBag.AlwaysShrinkNavBar = false; }
-
-
-

Welcome to BTCPay Server

-

BTCPay Server is a free and open source server for merchants wanting to accept Bitcoin for their business. The API is compatible with Bitpay service to allow seamless migration.

- Getting started -
-
+
+
+

Welcome to BTCPay Server

+

BTCPay Server is a free and open source server for merchants wanting to accept Bitcoin for their business. The API is compatible with Bitpay service to allow seamless migration.

+ Getting started +
+
-
-
-
-

A Payment Server for Bitcoin

-
-
-
-
-
-
-
-
- -

Secure

-

The payment server does not need to know your private keys, so your money can't be stolen.

-
-
-
-
- -

Easy

-

A user-friendly Bitcoin checkout page for your customers.

-
-
-
-
- -

Visibility

-

Manage, generate reports, and search for your invoices easily.

-
-
-
-
+
+
+
+

A Payment Server for Bitcoin

+
+
+
+
+
+
+
+
+ +

Secure

+

The payment server does not need to know your private keys, so your money can't be stolen.

+
+
+
+
+ +

Easy

+

A user-friendly Bitcoin checkout page for your customers.

+
+
+
+
+ +

Visibility

+

Manage, generate reports, and search for your invoices easily.

+
+
+
+
-
-

You don't want to depend on us? Self-Host it yourself!

- Read The Doc! -
+
+

You don't want to depend on us? Self-Host it yourself!

+ Read The Doc! +
-
-
-
-

Special thanks

-
-

Thanks to those who gave me some time to work on this project, or helped me.

-
-
-
-
- - - -

- DG Lab -

-
- -
- - - -

- Designer -

-
-
-
+
+
+
+

Special thanks

+
+

Thanks to those who gave me some time to work on this project, or helped me.

+
+
+
+
+ + + +

+ DG Lab +

+
+ +
+ + + +

+ Designer +

+
+
+
-
-

Donate

-

Donation to this address will be reinvested into the development of this tool

- -

3BpfdkF93GwFRWdrAN3SNsRAsi6d158YQi

-
+
+

Donate

+

Donation to this address will be reinvested into the development of this tool

+ +

3BpfdkF93GwFRWdrAN3SNsRAsi6d158YQi

+
-
-
-
-

Let's Get In Touch!

-
-

An open source project is nothing without its community, come and get in touch with us!

-
-
-
- -
- - - -

- On Github -

-
-
-
+
+
+
+

Let's Get In Touch!

+
+

An open source project is nothing without its community, come and get in touch with us!

+
+
+
+ +
+ + + +

+ On Github +

+
+
+
diff --git a/BTCPayServer/Views/Invoice/Checkout.cshtml b/BTCPayServer/Views/Invoice/Checkout.cshtml index 4f6ba2254..a02273ede 100644 --- a/BTCPayServer/Views/Invoice/Checkout.cshtml +++ b/BTCPayServer/Views/Invoice/Checkout.cshtml @@ -619,4 +619,4 @@ - \ No newline at end of file + diff --git a/BTCPayServer/Views/Invoice/CreateInvoice.cshtml b/BTCPayServer/Views/Invoice/CreateInvoice.cshtml index 54f04702a..d8540a97c 100644 --- a/BTCPayServer/Views/Invoice/CreateInvoice.cshtml +++ b/BTCPayServer/Views/Invoice/CreateInvoice.cshtml @@ -1,60 +1,60 @@ @model BTCPayServer.Models.InvoicingModels.CreateInvoiceModel @{ - ViewData["Title"] = "Create an invoice"; + ViewData["Title"] = "Create an invoice"; }
-
-
-
-

@ViewData["Title"]

-
-
-
-
-
-
-
-
- * - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- -
-
- Back to List -
-
-
-
\ No newline at end of file +
+
+
+

@ViewData["Title"]

+
+
+
+
+
+
+
+
+ * + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+ Back to List +
+
+
+ diff --git a/BTCPayServer/Views/Invoice/Invoice.cshtml b/BTCPayServer/Views/Invoice/Invoice.cshtml index 6781d8803..d0b17e743 100644 --- a/BTCPayServer/Views/Invoice/Invoice.cshtml +++ b/BTCPayServer/Views/Invoice/Invoice.cshtml @@ -1,6 +1,6 @@ @model InvoiceDetailsModel @{ - ViewData["Title"] = "Invoice " + Model.Id; + ViewData["Title"] = "Invoice " + Model.Id; }
-
+
-
-
- @Html.Partial("_StatusMessage", Model.StatusMessage) -
-
+
+
+ @Html.Partial("_StatusMessage", Model.StatusMessage) +
+
-
-
-

@ViewData["Title"]

-
-

Invoice details

-
-
+
+
+

@ViewData["Title"]

+
+

Invoice details

+
+
-
-
-

Information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Store@Model.StoreName
Id@Model.Id
Created date@Model.CreatedDate
Expiration date@Model.ExpirationDate
Status@Model.Status
Refund email@Model.RefundEmail
Order Id@Model.OrderId
Rate@Model.Rate
Total fiat due@Model.Fiat
Network Fee@Model.NetworkFee
Total crypto due@Model.BTC
Crypto due@Model.BTCDue
Crypto paid@Model.BTCPaid
Notification Url@Model.NotificationUrl
Payment address@Model.BitcoinAddress
Payment Url@Model.PaymentUrl
-
+
+
+

Information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Store@Model.StoreName
Id@Model.Id
Created date@Model.CreatedDate
Expiration date@Model.ExpirationDate
Status@Model.Status
Refund email@Model.RefundEmail
Order Id@Model.OrderId
Rate@Model.Rate
Total fiat due@Model.Fiat
Network Fee@Model.NetworkFee
Total crypto due@Model.BTC
Crypto due@Model.BTCDue
Crypto paid@Model.BTCPaid
Notification Url@Model.NotificationUrl
Payment address@Model.BitcoinAddress
Payment Url@Model.PaymentUrl
+
-
-

Buyer information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name - - @Model.BuyerInformation.BuyerName
Email@Model.BuyerInformation.BuyerEmail
Phone@Model.BuyerInformation.BuyerPhone
Address 1@Model.BuyerInformation.BuyerAddress1
Address 2@Model.BuyerInformation.BuyerAddress2
City@Model.BuyerInformation.BuyerCity
State@Model.BuyerInformation.BuyerState
Country@Model.BuyerInformation.BuyerCountry
Zip@Model.BuyerInformation.BuyerZip
+
+

Buyer information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name + + @Model.BuyerInformation.BuyerName
Email@Model.BuyerInformation.BuyerEmail
Phone@Model.BuyerInformation.BuyerPhone
Address 1@Model.BuyerInformation.BuyerAddress1
Address 2@Model.BuyerInformation.BuyerAddress2
City@Model.BuyerInformation.BuyerCity
State@Model.BuyerInformation.BuyerState
Country@Model.BuyerInformation.BuyerCountry
Zip@Model.BuyerInformation.BuyerZip
-

Product information

- - - - - - - - - - - - - -
Item code@Model.ProductInformation.ItemCode
Item Description@Model.ProductInformation.ItemDesc
Price@Model.ProductInformation.Price @Model.ProductInformation.Currency
-
-
-
-
-

Payments

-
-
- -
-
- - - - - - - - - - - @foreach(var payment in Model.Payments) - { - - - - - - - } - -
DateDeposit addressTransaction IdConfirmations
@payment.ReceivedTime@payment.DepositAddress@payment.TransactionId@payment.Confirmations
-
-
-
-
\ No newline at end of file +

Product information

+ + + + + + + + + + + + + +
Item code@Model.ProductInformation.ItemCode
Item Description@Model.ProductInformation.ItemDesc
Price@Model.ProductInformation.Price @Model.ProductInformation.Currency
+ + +
+
+

Payments

+
+
+ +
+
+ + + + + + + + + + + @foreach(var payment in Model.Payments) + { + + + + + + + } + +
DateDeposit addressTransaction IdConfirmations
@payment.ReceivedTime@payment.DepositAddress@payment.TransactionId@payment.Confirmations
+
+
+ + diff --git a/BTCPayServer/Views/Invoice/ListInvoices.cshtml b/BTCPayServer/Views/Invoice/ListInvoices.cshtml index dadc97cb3..64111fba1 100644 --- a/BTCPayServer/Views/Invoice/ListInvoices.cshtml +++ b/BTCPayServer/Views/Invoice/ListInvoices.cshtml @@ -1,78 +1,78 @@ @model InvoicesModel @{ - ViewData["Title"] = "Invoices"; + ViewData["Title"] = "Invoices"; }
-
+
-
-
- @Html.Partial("_StatusMessage", Model.StatusMessage) -
-
+
+
+ @Html.Partial("_StatusMessage", Model.StatusMessage) +
+
-
-
-

@ViewData["Title"]

-
-

Create, search or pay an invoice.

-
-
- - - - -
-
-
-
+
+
+

@ViewData["Title"]

+
+

Create, search or pay an invoice.

+
+
+ + + + +
+
+
+
-
- Create a new invoice - - - - - - - - - - - - @foreach(var invoice in Model.Invoices) - { - - - - - - - - } - -
DateInvoiceIdStatusAmountActions
@invoice.Date@invoice.InvoiceId@invoice.Status@invoice.AmountCurrencyCheckout - Details
- - @if(Model.Skip != 0) - { - + Create a new invoice + + + + + + + + + + + + @foreach(var invoice in Model.Invoices) + { + + + + + + + + } + +
DateInvoiceIdStatusAmountActions
@invoice.Date@invoice.InvoiceId@invoice.Status@invoice.AmountCurrencyCheckout - Details
+ + @if(Model.Skip != 0) + { + << - - } - >> - -
+ +
-
-
\ No newline at end of file + + diff --git a/BTCPayServer/Views/Manage/Disable2fa.cshtml b/BTCPayServer/Views/Manage/Disable2fa.cshtml index 626d6308d..b06ef1f0e 100644 --- a/BTCPayServer/Views/Manage/Disable2fa.cshtml +++ b/BTCPayServer/Views/Manage/Disable2fa.cshtml @@ -1,26 +1,26 @@ @{ - ViewData["Title"] = "Disable two-factor authentication (2FA)"; - ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); + ViewData["Title"] = "Disable two-factor authentication (2FA)"; + ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); }

@ViewData["Title"]

-
- -
+
+ +
diff --git a/BTCPayServer/Views/Manage/EnableAuthenticator.cshtml b/BTCPayServer/Views/Manage/EnableAuthenticator.cshtml index 68f76753d..b515d09b4 100644 --- a/BTCPayServer/Views/Manage/EnableAuthenticator.cshtml +++ b/BTCPayServer/Views/Manage/EnableAuthenticator.cshtml @@ -1,60 +1,60 @@ @model EnableAuthenticatorViewModel @{ - ViewData["Title"] = "Enable authenticator"; - ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); + ViewData["Title"] = "Enable authenticator"; + ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); }

@ViewData["Title"]

-

To use an authenticator app go through the following steps:

-
    -
  1. -

    - Download a two-factor authenticator app like Microsoft Authenticator for - Windows Phone, - Android and - iOS or - Google Authenticator for - Android and - iOS. -

    -
  2. -
  3. -

    Scan the QR Code or enter this key @Model.SharedKey into your two factor authenticator app. Spaces and casing do not matter.

    -
    -
    -
  4. -
  5. -

    - Once you have scanned the QR code or input the key above, your two factor authentication app will provide you - with a unique code. Enter the code in the confirmation box below. -

    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    -
  6. -
+

To use an authenticator app go through the following steps:

+
    +
  1. +

    + Download a two-factor authenticator app like Microsoft Authenticator for + Windows Phone, + Android and + iOS or + Google Authenticator for + Android and + iOS. +

    +
  2. +
  3. +

    Scan the QR Code or enter this key @Model.SharedKey into your two factor authenticator app. Spaces and casing do not matter.

    +
    +
    +
  4. +
  5. +

    + Once you have scanned the QR code or input the key above, your two factor authentication app will provide you + with a unique code. Enter the code in the confirmation box below. +

    +
    +
    +
    +
    + + + +
    + +
    +
    +
    +
    +
  6. +
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") - - + + } diff --git a/BTCPayServer/Views/Manage/ExternalLogins.cshtml b/BTCPayServer/Views/Manage/ExternalLogins.cshtml index 9a2f4e1f0..b6aad3af8 100644 --- a/BTCPayServer/Views/Manage/ExternalLogins.cshtml +++ b/BTCPayServer/Views/Manage/ExternalLogins.cshtml @@ -1,21 +1,21 @@ @model ExternalLoginsViewModel @{ - ViewData["Title"] = "Manage your external logins"; - ViewData.AddActivePage(ManageNavPages.ExternalLogins); + ViewData["Title"] = "Manage your external logins"; + ViewData.AddActivePage(ManageNavPages.ExternalLogins); } @Html.Partial("_StatusMessage", Model.StatusMessage) -@if (Model.CurrentLogins?.Count > 0) +@if(Model.CurrentLogins?.Count > 0) {

Registered Logins

- @foreach (var login in Model.CurrentLogins) + @foreach(var login in Model.CurrentLogins) {
@login.LoginProvider - @if (Model.ShowRemoveButton) + @if(Model.ShowRemoveButton) {
@@ -35,14 +35,14 @@
} -@if (Model.OtherLogins?.Count > 0) +@if(Model.OtherLogins?.Count > 0) {

Add another service to log in.


- @foreach (var provider in Model.OtherLogins) + @foreach(var provider in Model.OtherLogins) { } diff --git a/BTCPayServer/Views/Manage/GenerateRecoveryCodes.cshtml b/BTCPayServer/Views/Manage/GenerateRecoveryCodes.cshtml index 3ed07d769..336c93d11 100644 --- a/BTCPayServer/Views/Manage/GenerateRecoveryCodes.cshtml +++ b/BTCPayServer/Views/Manage/GenerateRecoveryCodes.cshtml @@ -1,7 +1,7 @@ @model GenerateRecoveryCodesViewModel @{ - ViewData["Title"] = "Recovery codes"; - ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); + ViewData["Title"] = "Recovery codes"; + ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); }

@ViewData["Title"]

@@ -16,9 +16,9 @@
- @for (var row = 0; row < Model.RecoveryCodes.Count(); row += 2) + @for(var row = 0; row < Model.RecoveryCodes.Count(); row += 2) { @Model.RecoveryCodes[row] @Model.RecoveryCodes[row + 1]
}
-
\ No newline at end of file + diff --git a/BTCPayServer/Views/Manage/Index.cshtml b/BTCPayServer/Views/Manage/Index.cshtml index 0fd58edb6..feb2326f0 100644 --- a/BTCPayServer/Views/Manage/Index.cshtml +++ b/BTCPayServer/Views/Manage/Index.cshtml @@ -1,45 +1,45 @@ @model IndexViewModel @{ - ViewData["Title"] = "Profile"; - ViewData.AddActivePage(ManageNavPages.Index); + ViewData["Title"] = "Profile"; + ViewData.AddActivePage(ManageNavPages.Index); }

@ViewData["Title"]

@Html.Partial("_StatusMessage", Model.StatusMessage)
-
-
-
+
+
+
-
- -
- - -
-
- - @if(Model.IsEmailConfirmed) - { -
- - -
- } - else - { - - - } - -
- - -
+
+
+
+ + +
+
+ + @if(Model.IsEmailConfirmed) + { +
+ + +
+ } + else + { + + + } + +
+ +
+
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") + @await Html.PartialAsync("_ValidationScriptsPartial") } diff --git a/BTCPayServer/Views/Manage/ManageNavPages.cs b/BTCPayServer/Views/Manage/ManageNavPages.cs index 4becffef9..ce3bf2a39 100644 --- a/BTCPayServer/Views/Manage/ManageNavPages.cs +++ b/BTCPayServer/Views/Manage/ManageNavPages.cs @@ -19,18 +19,18 @@ namespace BTCPayServer.Views.Manage public static string TwoFactorAuthentication => "TwoFactorAuthentication"; - public static string Tokens => "Tokens"; + public static string Tokens => "Tokens"; - public static string TokensNavClass(ViewContext viewContext) => PageNavClass(viewContext, Tokens); + public static string TokensNavClass(ViewContext viewContext) => PageNavClass(viewContext, Tokens); - public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index); + public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index); public static string ChangePasswordNavClass(ViewContext viewContext) => PageNavClass(viewContext, ChangePassword); public static string ExternalLoginsNavClass(ViewContext viewContext) => PageNavClass(viewContext, ExternalLogins); public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication); - + public static string PageNavClass(ViewContext viewContext, string page) { var activePage = viewContext.ViewData["ActivePage"] as string; diff --git a/BTCPayServer/Views/Manage/ResetAuthenticator.cshtml b/BTCPayServer/Views/Manage/ResetAuthenticator.cshtml index a1058bc50..595113d6d 100644 --- a/BTCPayServer/Views/Manage/ResetAuthenticator.cshtml +++ b/BTCPayServer/Views/Manage/ResetAuthenticator.cshtml @@ -1,6 +1,6 @@ @{ - ViewData["Title"] = "Reset authenticator key"; - ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); + ViewData["Title"] = "Reset authenticator key"; + ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); }

@ViewData["Title"]

@@ -18,4 +18,4 @@
- \ No newline at end of file + diff --git a/BTCPayServer/Views/Manage/SetPassword.cshtml b/BTCPayServer/Views/Manage/SetPassword.cshtml index 8600ef251..56c359935 100644 --- a/BTCPayServer/Views/Manage/SetPassword.cshtml +++ b/BTCPayServer/Views/Manage/SetPassword.cshtml @@ -1,7 +1,7 @@ @model SetPasswordViewModel @{ - ViewData["Title"] = "Set password"; - ViewData.AddActivePage(ManageNavPages.ChangePassword); + ViewData["Title"] = "Set password"; + ViewData.AddActivePage(ManageNavPages.ChangePassword); }

Set your password

diff --git a/BTCPayServer/Views/Manage/TwoFactorAuthentication.cshtml b/BTCPayServer/Views/Manage/TwoFactorAuthentication.cshtml index 6cc151544..2741ee194 100644 --- a/BTCPayServer/Views/Manage/TwoFactorAuthentication.cshtml +++ b/BTCPayServer/Views/Manage/TwoFactorAuthentication.cshtml @@ -1,27 +1,27 @@ @model TwoFactorAuthenticationViewModel @{ - ViewData["Title"] = "Two-factor authentication"; - ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); + ViewData["Title"] = "Two-factor authentication"; + ViewData.AddActivePage(ManageNavPages.TwoFactorAuthentication); }

@ViewData["Title"]

-@if (Model.Is2faEnabled) +@if(Model.Is2faEnabled) { - if (Model.RecoveryCodesLeft == 0) + if(Model.RecoveryCodesLeft == 0) {
You have no recovery codes left.

You must generate a new set of recovery codes before you can log in with a recovery code.

} - else if (Model.RecoveryCodesLeft == 1) + else if(Model.RecoveryCodesLeft == 1) {
You have 1 recovery code left.

You can generate a new set of recovery codes.

} - else if (Model.RecoveryCodesLeft <= 3) + else if(Model.RecoveryCodesLeft <= 3) {
You have @Model.RecoveryCodesLeft recovery codes left. @@ -34,7 +34,7 @@ }
Authenticator app
-@if (!Model.HasAuthenticator) +@if(!Model.HasAuthenticator) { Add authenticator app } diff --git a/BTCPayServer/Views/Manage/_Nav.cshtml b/BTCPayServer/Views/Manage/_Nav.cshtml index 70fa6131b..09923f9d5 100644 --- a/BTCPayServer/Views/Manage/_Nav.cshtml +++ b/BTCPayServer/Views/Manage/_Nav.cshtml @@ -7,7 +7,7 @@
+ diff --git a/BTCPayServer/Views/Stores/ListTokens.cshtml b/BTCPayServer/Views/Stores/ListTokens.cshtml index 77222cbbd..7b8839529 100644 --- a/BTCPayServer/Views/Stores/ListTokens.cshtml +++ b/BTCPayServer/Views/Stores/ListTokens.cshtml @@ -1,8 +1,8 @@ @model TokensViewModel @{ - Layout = "../Shared/_NavLayout.cshtml"; - ViewData["Title"] = "Access Tokens"; - ViewData.AddActivePage(StoreNavPages.Tokens); + Layout = "../Shared/_NavLayout.cshtml"; + ViewData["Title"] = "Access Tokens"; + ViewData.AddActivePage(StoreNavPages.Tokens); }

@ViewData["Title"]

@@ -10,28 +10,27 @@ @Html.Partial("_StatusMessage", Model.StatusMessage) Create a new token - - - - - - - - - - @foreach(var token in Model.Tokens) - { - - - - - - - } - + + + + + + + + + + @foreach(var token in Model.Tokens) + { + + + + + + } +
LabelSINFacadeActions
@token.Label@token.SIN@token.Facade -
- - -
-
LabelSINFacadeActions
@token.Label@token.SIN@token.Facade +
+ + +
+
diff --git a/BTCPayServer/Views/Stores/RequestPairing.cshtml b/BTCPayServer/Views/Stores/RequestPairing.cshtml index d387386e3..7b1e5f9ab 100644 --- a/BTCPayServer/Views/Stores/RequestPairing.cshtml +++ b/BTCPayServer/Views/Stores/RequestPairing.cshtml @@ -1,43 +1,43 @@ @model PairingModel @{ - ViewData["Title"] = "Pairing permission"; + ViewData["Title"] = "Pairing permission"; }
-
-
-
-

@ViewData["Title"]

-
-

Create and manage store settings.

-
-
-
- - - - - - - - - - - - - -
Label@Model.Label
Facade@Model.Facade
SIN@Model.SIN
-
-
-
-
- - - -
- - -
-
-
-
\ No newline at end of file +
+
+
+

@ViewData["Title"]

+
+

Create and manage store settings.

+
+
+
+ + + + + + + + + + + + + +
Label@Model.Label
Facade@Model.Facade
SIN@Model.SIN
+
+
+
+
+ + + +
+ + +
+
+
+ diff --git a/BTCPayServer/Views/Stores/StoreNavPages.cs b/BTCPayServer/Views/Stores/StoreNavPages.cs index 9fa9cbe44..91fd277e0 100644 --- a/BTCPayServer/Views/Stores/StoreNavPages.cs +++ b/BTCPayServer/Views/Stores/StoreNavPages.cs @@ -7,24 +7,24 @@ using Microsoft.AspNetCore.Mvc.ViewFeatures; namespace BTCPayServer.Views.Stores { - public static class StoreNavPages - { - public static string ActivePageKey => "ActivePage"; - public static string Index => "Index"; + public static class StoreNavPages + { + public static string ActivePageKey => "ActivePage"; + public static string Index => "Index"; - public static string Tokens => "Tokens"; + public static string Tokens => "Tokens"; - public static string TokensNavClass(ViewContext viewContext) => PageNavClass(viewContext, Tokens); + public static string TokensNavClass(ViewContext viewContext) => PageNavClass(viewContext, Tokens); - public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index); + public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index); - public static string PageNavClass(ViewContext viewContext, string page) - { - var activePage = viewContext.ViewData["ActivePage"] as string; - return string.Equals(activePage, page, StringComparison.OrdinalIgnoreCase) ? "active" : null; - } + public static string PageNavClass(ViewContext viewContext, string page) + { + var activePage = viewContext.ViewData["ActivePage"] as string; + return string.Equals(activePage, page, StringComparison.OrdinalIgnoreCase) ? "active" : null; + } - public static void AddActivePage(this ViewDataDictionary viewData, string activePage) => viewData[ActivePageKey] = activePage; - } + public static void AddActivePage(this ViewDataDictionary viewData, string activePage) => viewData[ActivePageKey] = activePage; + } } diff --git a/BTCPayServer/Views/Stores/UpdateStore.cshtml b/BTCPayServer/Views/Stores/UpdateStore.cshtml index f4548901c..4003abeac 100644 --- a/BTCPayServer/Views/Stores/UpdateStore.cshtml +++ b/BTCPayServer/Views/Stores/UpdateStore.cshtml @@ -1,120 +1,120 @@ @model StoreViewModel @{ - Layout = "../Shared/_NavLayout.cshtml"; - ViewData["Title"] = "Profile"; - ViewData.AddActivePage(BTCPayServer.Views.Stores.StoreNavPages.Index); + Layout = "../Shared/_NavLayout.cshtml"; + ViewData["Title"] = "Profile"; + ViewData.AddActivePage(BTCPayServer.Views.Stores.StoreNavPages.Index); }

@ViewData["Title"]

@Html.Partial("_StatusMessage", Model.StatusMessage)
-
-
-
+
+
+
-
-
-
- - - -
-
- - - -
-
- - -
-
- - - -
-
-
Derivation Scheme
- @if(Model.AddressSamples.Count == 0) - { - The DerivationScheme represents the destination of the funds received by your invoice. It is generated by your wallet software. Please, verify that you are generating the right addresses by clicking on 'Check ExtPubKey' - } -
-
- - -
-
- @if(Model.AddressSamples.Count == 0) - { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Address typeExample
P2WPKHxpub
P2SH-P2WPKHxpub-[p2sh]
P2PKHxpub-[legacy]
Multi-sig P2WSH2-of-xpub1-xpub2
Multi-sig P2SH-P2WSH2-of-xpub1-xpub2-[p2sh]
Multi-sig P2SH2-of-xpub1-xpub2-[legacy]
- } - else - { - - - - - - - - - @foreach(var sample in Model.AddressSamples) - { - - - - - } - -
Key pathAddress
@sample.KeyPath@sample.Address
- } -
- - -
-
+
+
+
+ + + +
+
+ + + +
+
+ + +
+
+ + + +
+
+
Derivation Scheme
+ @if(Model.AddressSamples.Count == 0) + { + The DerivationScheme represents the destination of the funds received by your invoice. It is generated by your wallet software. Please, verify that you are generating the right addresses by clicking on 'Check ExtPubKey' + } +
+
+ + +
+
+ @if(Model.AddressSamples.Count == 0) + { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Address typeExample
P2WPKHxpub
P2SH-P2WPKHxpub-[p2sh]
P2PKHxpub-[legacy]
Multi-sig P2WSH2-of-xpub1-xpub2
Multi-sig P2SH-P2WSH2-of-xpub1-xpub2-[p2sh]
Multi-sig P2SH2-of-xpub1-xpub2-[legacy]
+ } + else + { + + + + + + + + + @foreach(var sample in Model.AddressSamples) + { + + + + + } + +
Key pathAddress
@sample.KeyPath@sample.Address
+ } +
+ + +
+
@section Scripts { - @await Html.PartialAsync("_ValidationScriptsPartial") + @await Html.PartialAsync("_ValidationScriptsPartial") } diff --git a/BTCPayServer/Views/Stores/_Nav.cshtml b/BTCPayServer/Views/Stores/_Nav.cshtml index da0c96a1f..143ceec1e 100644 --- a/BTCPayServer/Views/Stores/_Nav.cshtml +++ b/BTCPayServer/Views/Stores/_Nav.cshtml @@ -3,6 +3,6 @@ diff --git a/BTCPayServer/Views/Stores/_ViewStart.cshtml b/BTCPayServer/Views/Stores/_ViewStart.cshtml index 7b42a1b68..7c89f5078 100644 --- a/BTCPayServer/Views/Stores/_ViewStart.cshtml +++ b/BTCPayServer/Views/Stores/_ViewStart.cshtml @@ -1,3 +1,3 @@ @{ - ViewBag.MainTitle = "Manage store"; + ViewBag.MainTitle = "Manage store"; } diff --git a/BTCPayServer/ZipUtils.cs b/BTCPayServer/ZipUtils.cs index b0ab7a91e..6e89ec9aa 100644 --- a/BTCPayServer/ZipUtils.cs +++ b/BTCPayServer/ZipUtils.cs @@ -8,27 +8,27 @@ namespace BTCPayServer { class ZipUtils { - public static byte[] Zip(string unzipped) - { - MemoryStream ms = new MemoryStream(); - using(GZipStream gzip = new GZipStream(ms, CompressionMode.Compress)) - { - StreamWriter writer = new StreamWriter(gzip, Encoding.UTF8); - writer.Write(unzipped); - writer.Flush(); - } - return ms.ToArray(); - } + public static byte[] Zip(string unzipped) + { + MemoryStream ms = new MemoryStream(); + using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress)) + { + StreamWriter writer = new StreamWriter(gzip, Encoding.UTF8); + writer.Write(unzipped); + writer.Flush(); + } + return ms.ToArray(); + } - public static string Unzip(byte[] bytes) - { - MemoryStream ms = new MemoryStream(bytes); - using(GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress)) - { - StreamReader reader = new StreamReader(gzip, Encoding.UTF8); - var unzipped = reader.ReadToEnd(); - return unzipped; - } - } - } + public static string Unzip(byte[] bytes) + { + MemoryStream ms = new MemoryStream(bytes); + using (GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress)) + { + StreamReader reader = new StreamReader(gzip, Encoding.UTF8); + var unzipped = reader.ReadToEnd(); + return unzipped; + } + } + } } diff --git a/BTCPayServer/wwwroot/css/bootstrap-theme.css b/BTCPayServer/wwwroot/css/bootstrap-theme.css index 31d888266..e9957d86d 100644 --- a/BTCPayServer/wwwroot/css/bootstrap-theme.css +++ b/BTCPayServer/wwwroot/css/bootstrap-theme.css @@ -9,579 +9,641 @@ .btn-info, .btn-warning, .btn-danger { - text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); -} -.btn-default:active, -.btn-primary:active, -.btn-success:active, -.btn-info:active, -.btn-warning:active, -.btn-danger:active, -.btn-default.active, -.btn-primary.active, -.btn-success.active, -.btn-info.active, -.btn-warning.active, -.btn-danger.active { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); -} -.btn-default.disabled, -.btn-primary.disabled, -.btn-success.disabled, -.btn-info.disabled, -.btn-warning.disabled, -.btn-danger.disabled, -.btn-default[disabled], -.btn-primary[disabled], -.btn-success[disabled], -.btn-info[disabled], -.btn-warning[disabled], -.btn-danger[disabled], -fieldset[disabled] .btn-default, -fieldset[disabled] .btn-primary, -fieldset[disabled] .btn-success, -fieldset[disabled] .btn-info, -fieldset[disabled] .btn-warning, -fieldset[disabled] .btn-danger { - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-default .badge, -.btn-primary .badge, -.btn-success .badge, -.btn-info .badge, -.btn-warning .badge, -.btn-danger .badge { - text-shadow: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); } + + .btn-default:active, + .btn-primary:active, + .btn-success:active, + .btn-info:active, + .btn-warning:active, + .btn-danger:active, + .btn-default.active, + .btn-primary.active, + .btn-success.active, + .btn-info.active, + .btn-warning.active, + .btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + } + + .btn-default.disabled, + .btn-primary.disabled, + .btn-success.disabled, + .btn-info.disabled, + .btn-warning.disabled, + .btn-danger.disabled, + .btn-default[disabled], + .btn-primary[disabled], + .btn-success[disabled], + .btn-info[disabled], + .btn-warning[disabled], + .btn-danger[disabled], + fieldset[disabled] .btn-default, + fieldset[disabled] .btn-primary, + fieldset[disabled] .btn-success, + fieldset[disabled] .btn-info, + fieldset[disabled] .btn-warning, + fieldset[disabled] .btn-danger { + -webkit-box-shadow: none; + box-shadow: none; + } + + .btn-default .badge, + .btn-primary .badge, + .btn-success .badge, + .btn-info .badge, + .btn-warning .badge, + .btn-danger .badge { + text-shadow: none; + } + .btn:active, .btn.active { - background-image: none; + background-image: none; } + .btn-default { - text-shadow: 0 1px 0 #fff; - background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); - background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); - background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #dbdbdb; - border-color: #ccc; -} -.btn-default:hover, -.btn-default:focus { - background-color: #e0e0e0; - background-position: 0 -15px; -} -.btn-default:active, -.btn-default.active { - background-color: #e0e0e0; - border-color: #dbdbdb; -} -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled.focus, -.btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { - background-color: #e0e0e0; - background-image: none; + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; } + + .btn-default:hover, + .btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; + } + + .btn-default:active, + .btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; + } + + .btn-default.disabled, + .btn-default[disabled], + fieldset[disabled] .btn-default, + .btn-default.disabled:hover, + .btn-default[disabled]:hover, + fieldset[disabled] .btn-default:hover, + .btn-default.disabled:focus, + .btn-default[disabled]:focus, + fieldset[disabled] .btn-default:focus, + .btn-default.disabled.focus, + .btn-default[disabled].focus, + fieldset[disabled] .btn-default.focus, + .btn-default.disabled:active, + .btn-default[disabled]:active, + fieldset[disabled] .btn-default:active, + .btn-default.disabled.active, + .btn-default[disabled].active, + fieldset[disabled] .btn-default.active { + background-color: #e0e0e0; + background-image: none; + } + .btn-primary { - background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); - background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #245580; -} -.btn-primary:hover, -.btn-primary:focus { - background-color: #265a88; - background-position: 0 -15px; -} -.btn-primary:active, -.btn-primary.active { - background-color: #265a88; - border-color: #245580; -} -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled.focus, -.btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - background-color: #265a88; - background-image: none; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; } + + .btn-primary:hover, + .btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; + } + + .btn-primary:active, + .btn-primary.active { + background-color: #265a88; + border-color: #245580; + } + + .btn-primary.disabled, + .btn-primary[disabled], + fieldset[disabled] .btn-primary, + .btn-primary.disabled:hover, + .btn-primary[disabled]:hover, + fieldset[disabled] .btn-primary:hover, + .btn-primary.disabled:focus, + .btn-primary[disabled]:focus, + fieldset[disabled] .btn-primary:focus, + .btn-primary.disabled.focus, + .btn-primary[disabled].focus, + fieldset[disabled] .btn-primary.focus, + .btn-primary.disabled:active, + .btn-primary[disabled]:active, + fieldset[disabled] .btn-primary:active, + .btn-primary.disabled.active, + .btn-primary[disabled].active, + fieldset[disabled] .btn-primary.active { + background-color: #265a88; + background-image: none; + } + .btn-success { - background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); - background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); - background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #3e8f3e; -} -.btn-success:hover, -.btn-success:focus { - background-color: #419641; - background-position: 0 -15px; -} -.btn-success:active, -.btn-success.active { - background-color: #419641; - border-color: #3e8f3e; -} -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled.focus, -.btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { - background-color: #419641; - background-image: none; + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; } + + .btn-success:hover, + .btn-success:focus { + background-color: #419641; + background-position: 0 -15px; + } + + .btn-success:active, + .btn-success.active { + background-color: #419641; + border-color: #3e8f3e; + } + + .btn-success.disabled, + .btn-success[disabled], + fieldset[disabled] .btn-success, + .btn-success.disabled:hover, + .btn-success[disabled]:hover, + fieldset[disabled] .btn-success:hover, + .btn-success.disabled:focus, + .btn-success[disabled]:focus, + fieldset[disabled] .btn-success:focus, + .btn-success.disabled.focus, + .btn-success[disabled].focus, + fieldset[disabled] .btn-success.focus, + .btn-success.disabled:active, + .btn-success[disabled]:active, + fieldset[disabled] .btn-success:active, + .btn-success.disabled.active, + .btn-success[disabled].active, + fieldset[disabled] .btn-success.active { + background-color: #419641; + background-image: none; + } + .btn-info { - background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); - background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); - background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #28a4c9; -} -.btn-info:hover, -.btn-info:focus { - background-color: #2aabd2; - background-position: 0 -15px; -} -.btn-info:active, -.btn-info.active { - background-color: #2aabd2; - border-color: #28a4c9; -} -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled.focus, -.btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { - background-color: #2aabd2; - background-image: none; + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; } + + .btn-info:hover, + .btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; + } + + .btn-info:active, + .btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; + } + + .btn-info.disabled, + .btn-info[disabled], + fieldset[disabled] .btn-info, + .btn-info.disabled:hover, + .btn-info[disabled]:hover, + fieldset[disabled] .btn-info:hover, + .btn-info.disabled:focus, + .btn-info[disabled]:focus, + fieldset[disabled] .btn-info:focus, + .btn-info.disabled.focus, + .btn-info[disabled].focus, + fieldset[disabled] .btn-info.focus, + .btn-info.disabled:active, + .btn-info[disabled]:active, + fieldset[disabled] .btn-info:active, + .btn-info.disabled.active, + .btn-info[disabled].active, + fieldset[disabled] .btn-info.active { + background-color: #2aabd2; + background-image: none; + } + .btn-warning { - background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); - background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #e38d13; -} -.btn-warning:hover, -.btn-warning:focus { - background-color: #eb9316; - background-position: 0 -15px; -} -.btn-warning:active, -.btn-warning.active { - background-color: #eb9316; - border-color: #e38d13; -} -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled.focus, -.btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { - background-color: #eb9316; - background-image: none; + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; } + + .btn-warning:hover, + .btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; + } + + .btn-warning:active, + .btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; + } + + .btn-warning.disabled, + .btn-warning[disabled], + fieldset[disabled] .btn-warning, + .btn-warning.disabled:hover, + .btn-warning[disabled]:hover, + fieldset[disabled] .btn-warning:hover, + .btn-warning.disabled:focus, + .btn-warning[disabled]:focus, + fieldset[disabled] .btn-warning:focus, + .btn-warning.disabled.focus, + .btn-warning[disabled].focus, + fieldset[disabled] .btn-warning.focus, + .btn-warning.disabled:active, + .btn-warning[disabled]:active, + fieldset[disabled] .btn-warning:active, + .btn-warning.disabled.active, + .btn-warning[disabled].active, + fieldset[disabled] .btn-warning.active { + background-color: #eb9316; + background-image: none; + } + .btn-danger { - background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); - background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); - background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-color: #b92c28; -} -.btn-danger:hover, -.btn-danger:focus { - background-color: #c12e2a; - background-position: 0 -15px; -} -.btn-danger:active, -.btn-danger.active { - background-color: #c12e2a; - border-color: #b92c28; -} -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled.focus, -.btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { - background-color: #c12e2a; - background-image: none; + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; } + + .btn-danger:hover, + .btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; + } + + .btn-danger:active, + .btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; + } + + .btn-danger.disabled, + .btn-danger[disabled], + fieldset[disabled] .btn-danger, + .btn-danger.disabled:hover, + .btn-danger[disabled]:hover, + fieldset[disabled] .btn-danger:hover, + .btn-danger.disabled:focus, + .btn-danger[disabled]:focus, + fieldset[disabled] .btn-danger:focus, + .btn-danger.disabled.focus, + .btn-danger[disabled].focus, + fieldset[disabled] .btn-danger.focus, + .btn-danger.disabled:active, + .btn-danger[disabled]:active, + fieldset[disabled] .btn-danger:active, + .btn-danger.disabled.active, + .btn-danger[disabled].active, + fieldset[disabled] .btn-danger.active { + background-color: #c12e2a; + background-image: none; + } + .thumbnail, .img-thumbnail { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); - box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); } + .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { - background-color: #e8e8e8; - background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); - background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); - background-repeat: repeat-x; + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; } + .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { - background-color: #2e6da4; - background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); - background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); - background-repeat: repeat-x; + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; } + .navbar-default { - background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); - background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); - background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); -} -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .active > a { - background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); - background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); - background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); - background-repeat: repeat-x; - -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); - box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); } + + .navbar-default .navbar-nav > .open > a, + .navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + } + .navbar-brand, .navbar-nav > li > a { - text-shadow: 0 1px 0 rgba(255, 255, 255, .25); + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); } + .navbar-inverse { - background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); - background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); - background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - background-repeat: repeat-x; - border-radius: 4px; -} -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .active > a { - background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); - background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); - background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); - background-repeat: repeat-x; - -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); - box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); -} -.navbar-inverse .navbar-brand, -.navbar-inverse .navbar-nav > li > a { - text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; } + + .navbar-inverse .navbar-nav > .open > a, + .navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + } + + .navbar-inverse .navbar-brand, + .navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); + } + .navbar-static-top, .navbar-fixed-top, .navbar-fixed-bottom { - border-radius: 0; + border-radius: 0; } + @media (max-width: 767px) { - .navbar .navbar-nav .open .dropdown-menu > .active > a, - .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #fff; - background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); - background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); - background-repeat: repeat-x; - } + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } } + .alert { - text-shadow: 0 1px 0 rgba(255, 255, 255, .2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); } + .alert-success { - background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); - background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); - background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); - background-repeat: repeat-x; - border-color: #b2dba1; + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; } + .alert-info { - background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); - background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); - background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); - background-repeat: repeat-x; - border-color: #9acfea; + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; } + .alert-warning { - background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); - background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); - background-repeat: repeat-x; - border-color: #f5e79e; + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; } + .alert-danger { - background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); - background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); - background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); - background-repeat: repeat-x; - border-color: #dca7a7; + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; } + .progress { - background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); - background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); - background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; } + .progress-bar { - background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); - background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; } + .progress-bar-success { - background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); - background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; } + .progress-bar-info { - background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); - background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; } + .progress-bar-warning { - background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); - background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; } + .progress-bar-danger { - background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); - background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; } + .progress-bar-striped { - 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); + 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); } + .list-group { - border-radius: 4px; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); - box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); } + .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { - text-shadow: 0 -1px 0 #286090; - background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); - background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); - background-repeat: repeat-x; - border-color: #2b669a; -} -.list-group-item.active .badge, -.list-group-item.active:hover .badge, -.list-group-item.active:focus .badge { - text-shadow: none; + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; } + + .list-group-item.active .badge, + .list-group-item.active:hover .badge, + .list-group-item.active:focus .badge { + text-shadow: none; + } + .panel { - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); - box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); } + .panel-default > .panel-heading { - background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); - background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; } + .panel-primary > .panel-heading { - background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); - background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; } + .panel-success > .panel-heading { - background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); - background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); - background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; } + .panel-info > .panel-heading { - background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); - background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); - background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; } + .panel-warning > .panel-heading { - background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); - background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; } + .panel-danger > .panel-heading { - background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); - background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); - background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); - background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; } + .well { - background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); - background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); - background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); - background-repeat: repeat-x; - border-color: #dcdcdc; - -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); - box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); } /*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/BTCPayServer/wwwroot/css/bootstrap-theme.css.map b/BTCPayServer/wwwroot/css/bootstrap-theme.css.map index d876f60fb..4be24d84b 100644 --- a/BTCPayServer/wwwroot/css/bootstrap-theme.css.map +++ b/BTCPayServer/wwwroot/css/bootstrap-theme.css.map @@ -1 +1,8 @@ -{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT","file":"bootstrap-theme.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.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\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-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\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.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\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.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\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.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\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.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\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.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\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.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\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}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\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\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\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","// 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","// 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"]} \ No newline at end of file +{ + "version": 3, + "sources": [ "bootstrap-theme.css", "less/theme.less", "less/mixins/vendor-prefixes.less", "less/mixins/gradients.less", "less/mixins/reset-filter.less" ], + "names": [], + "mappings": "AAAA;;;;GAIG;ACeH;;;;;;EAME,yCAAA;EC2CA,4FAAA;EACQ,oFAAA;CFvDT;ACgBC;;;;;;;;;;;;ECsCA,yDAAA;EACQ,iDAAA;CFxCT;ACMC;;;;;;;;;;;;;;;;;;ECiCA,yBAAA;EACQ,iBAAA;CFnBT;AC/BD;;;;;;EAuBI,kBAAA;CDgBH;ACyBC;;EAEE,uBAAA;CDvBH;AC4BD;EErEI,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;EAuC2C,0BAAA;EAA2B,mBAAA;CDjBvE;ACpBC;;EAEE,0BAAA;EACA,6BAAA;CDsBH;ACnBC;;EAEE,0BAAA;EACA,sBAAA;CDqBH;ACfG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6BL;ACbD;EEtEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8DD;AC5DC;;EAEE,0BAAA;EACA,6BAAA;CD8DH;AC3DC;;EAEE,0BAAA;EACA,sBAAA;CD6DH;ACvDG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqEL;ACpDD;EEvEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsGD;ACpGC;;EAEE,0BAAA;EACA,6BAAA;CDsGH;ACnGC;;EAEE,0BAAA;EACA,sBAAA;CDqGH;AC/FG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6GL;AC3FD;EExEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ID;AC5IC;;EAEE,0BAAA;EACA,6BAAA;CD8IH;AC3IC;;EAEE,0BAAA;EACA,sBAAA;CD6IH;ACvIG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqJL;AClID;EEzEI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CDsLD;ACpLC;;EAEE,0BAAA;EACA,6BAAA;CDsLH;ACnLC;;EAEE,0BAAA;EACA,sBAAA;CDqLH;AC/KG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CD6LL;ACzKD;EE1EI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EAEA,uHAAA;ECnBF,oEAAA;EH4CA,4BAAA;EACA,sBAAA;CD8ND;AC5NC;;EAEE,0BAAA;EACA,6BAAA;CD8NH;AC3NC;;EAEE,0BAAA;EACA,sBAAA;CD6NH;ACvNG;;;;;;;;;;;;;;;;;;EAME,0BAAA;EACA,uBAAA;CDqOL;AC1MD;;EClCE,mDAAA;EACQ,2CAAA;CFgPT;ACrMD;;EE3FI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF0FF,0BAAA;CD2MD;ACzMD;;;EEhGI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFgGF,0BAAA;CD+MD;ACtMD;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EH+HA,mBAAA;ECjEA,4FAAA;EACQ,oFAAA;CF8QT;ACjND;;EE7GI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,yDAAA;EACQ,iDAAA;CFwRT;AC9MD;;EAEE,+CAAA;CDgND;AC5MD;EEhII,sEAAA;EACA,iEAAA;EACA,2FAAA;EAAA,oEAAA;EACA,4BAAA;EACA,uHAAA;ECnBF,oEAAA;EHkJA,mBAAA;CDkND;ACrND;;EEhII,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;ED2CF,wDAAA;EACQ,gDAAA;CF+ST;AC/ND;;EAYI,0CAAA;CDuNH;AClND;;;EAGE,iBAAA;CDoND;AC/LD;EAfI;;;IAGE,YAAA;IE7JF,yEAAA;IACA,oEAAA;IACA,8FAAA;IAAA,uEAAA;IACA,4BAAA;IACA,uHAAA;GH+WD;CACF;AC3MD;EACE,8CAAA;EC3HA,2FAAA;EACQ,mFAAA;CFyUT;ACnMD;EEtLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+MD;AC1MD;EEvLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuND;ACjND;EExLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CD+ND;ACxND;EEzLI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EF8KF,sBAAA;CDuOD;ACxND;EEjMI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH4ZH;ACrND;EE3MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHmaH;AC3ND;EE5MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH0aH;ACjOD;EE7MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHibH;ACvOD;EE9MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHwbH;AC7OD;EE/MI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH+bH;AChPD;EElLI,8MAAA;EACA,yMAAA;EACA,sMAAA;CHqaH;AC5OD;EACE,mBAAA;EC9KA,mDAAA;EACQ,2CAAA;CF6ZT;AC7OD;;;EAGE,8BAAA;EEnOE,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFiOF,sBAAA;CDmPD;ACxPD;;;EAQI,kBAAA;CDqPH;AC3OD;ECnME,kDAAA;EACQ,0CAAA;CFibT;ACrOD;EE5PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHoeH;AC3OD;EE7PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CH2eH;ACjPD;EE9PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHkfH;ACvPD;EE/PI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHyfH;AC7PD;EEhQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHggBH;ACnQD;EEjQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;CHugBH;ACnQD;EExQI,yEAAA;EACA,oEAAA;EACA,8FAAA;EAAA,uEAAA;EACA,4BAAA;EACA,uHAAA;EFsQF,sBAAA;EC3NA,0FAAA;EACQ,kFAAA;CFqeT", + "file": "bootstrap-theme.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.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\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-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\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.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\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.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\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.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\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.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\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.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\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.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\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}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */", "/*!\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\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\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", "// 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", "// 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" ] +} diff --git a/BTCPayServer/wwwroot/css/bootstrap-theme.min.css b/BTCPayServer/wwwroot/css/bootstrap-theme.min.css index 5e3940195..14b556d29 100644 --- a/BTCPayServer/wwwroot/css/bootstrap-theme.min.css +++ b/BTCPayServer/wwwroot/css/bootstrap-theme.min.css @@ -2,5 +2,480 @@ * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{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)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -/*# sourceMappingURL=bootstrap-theme.min.css.map */ \ No newline at end of file + */ + +.btn-danger, .btn-default, .btn-info, .btn-primary, .btn-success, .btn-warning { + text-shadow: 0 -1px 0 rgba(0,0,0,.2); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075) +} + + .btn-danger.active, .btn-danger:active, .btn-default.active, .btn-default:active, .btn-info.active, .btn-info:active, .btn-primary.active, .btn-primary:active, .btn-success.active, .btn-success:active, .btn-warning.active, .btn-warning:active { + -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.125); + box-shadow: inset 0 3px 5px rgba(0,0,0,.125) + } + + .btn-danger.disabled, .btn-danger[disabled], .btn-default.disabled, .btn-default[disabled], .btn-info.disabled, .btn-info[disabled], .btn-primary.disabled, .btn-primary[disabled], .btn-success.disabled, .btn-success[disabled], .btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-danger, fieldset[disabled] .btn-default, fieldset[disabled] .btn-info, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-success, fieldset[disabled] .btn-warning { + -webkit-box-shadow: none; + box-shadow: none + } + + .btn-danger .badge, .btn-default .badge, .btn-info .badge, .btn-primary .badge, .btn-success .badge, .btn-warning .badge { + text-shadow: none + } + +.btn.active, .btn:active { + background-image: none +} + +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top,#fff 0,#e0e0e0 100%); + background-image: -o-linear-gradient(top,#fff 0,#e0e0e0 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0)); + background-image: linear-gradient(to bottom,#fff 0,#e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc +} + + .btn-default:focus, .btn-default:hover { + background-color: #e0e0e0; + background-position: 0 -15px + } + + .btn-default.active, .btn-default:active { + background-color: #e0e0e0; + border-color: #dbdbdb + } + + .btn-default.disabled, .btn-default.disabled.active, .btn-default.disabled.focus, .btn-default.disabled:active, .btn-default.disabled:focus, .btn-default.disabled:hover, .btn-default[disabled], .btn-default[disabled].active, .btn-default[disabled].focus, .btn-default[disabled]:active, .btn-default[disabled]:focus, .btn-default[disabled]:hover, fieldset[disabled] .btn-default, fieldset[disabled] .btn-default.active, fieldset[disabled] .btn-default.focus, fieldset[disabled] .btn-default:active, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default:hover { + background-color: #e0e0e0; + background-image: none + } + +.btn-primary { + background-image: -webkit-linear-gradient(top,#337ab7 0,#265a88 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#265a88 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88)); + background-image: linear-gradient(to bottom,#337ab7 0,#265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #245580 +} + + .btn-primary:focus, .btn-primary:hover { + background-color: #265a88; + background-position: 0 -15px + } + + .btn-primary.active, .btn-primary:active { + background-color: #265a88; + border-color: #245580 + } + + .btn-primary.disabled, .btn-primary.disabled.active, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled:focus, .btn-primary.disabled:hover, .btn-primary[disabled], .btn-primary[disabled].active, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled]:focus, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary.active, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary:hover { + background-color: #265a88; + background-image: none + } + +.btn-success { + background-image: -webkit-linear-gradient(top,#5cb85c 0,#419641 100%); + background-image: -o-linear-gradient(top,#5cb85c 0,#419641 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641)); + background-image: linear-gradient(to bottom,#5cb85c 0,#419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #3e8f3e +} + + .btn-success:focus, .btn-success:hover { + background-color: #419641; + background-position: 0 -15px + } + + .btn-success.active, .btn-success:active { + background-color: #419641; + border-color: #3e8f3e + } + + .btn-success.disabled, .btn-success.disabled.active, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled:focus, .btn-success.disabled:hover, .btn-success[disabled], .btn-success[disabled].active, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled]:focus, .btn-success[disabled]:hover, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success.active, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success:hover { + background-color: #419641; + background-image: none + } + +.btn-info { + background-image: -webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%); + background-image: -o-linear-gradient(top,#5bc0de 0,#2aabd2 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2)); + background-image: linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #28a4c9 +} + + .btn-info:focus, .btn-info:hover { + background-color: #2aabd2; + background-position: 0 -15px + } + + .btn-info.active, .btn-info:active { + background-color: #2aabd2; + border-color: #28a4c9 + } + + .btn-info.disabled, .btn-info.disabled.active, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled:focus, .btn-info.disabled:hover, .btn-info[disabled], .btn-info[disabled].active, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled]:focus, .btn-info[disabled]:hover, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info.active, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info:hover { + background-color: #2aabd2; + background-image: none + } + +.btn-warning { + background-image: -webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%); + background-image: -o-linear-gradient(top,#f0ad4e 0,#eb9316 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316)); + background-image: linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #e38d13 +} + + .btn-warning:focus, .btn-warning:hover { + background-color: #eb9316; + background-position: 0 -15px + } + + .btn-warning.active, .btn-warning:active { + background-color: #eb9316; + border-color: #e38d13 + } + + .btn-warning.disabled, .btn-warning.disabled.active, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled:focus, .btn-warning.disabled:hover, .btn-warning[disabled], .btn-warning[disabled].active, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled]:focus, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning.active, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning:hover { + background-color: #eb9316; + background-image: none + } + +.btn-danger { + background-image: -webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%); + background-image: -o-linear-gradient(top,#d9534f 0,#c12e2a 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a)); + background-image: linear-gradient(to bottom,#d9534f 0,#c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-color: #b92c28 +} + + .btn-danger:focus, .btn-danger:hover { + background-color: #c12e2a; + background-position: 0 -15px + } + + .btn-danger.active, .btn-danger:active { + background-color: #c12e2a; + border-color: #b92c28 + } + + .btn-danger.disabled, .btn-danger.disabled.active, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled:focus, .btn-danger.disabled:hover, .btn-danger[disabled], .btn-danger[disabled].active, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled]:focus, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger.active, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger:hover { + background-color: #c12e2a; + background-image: none + } + +.img-thumbnail, .thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.075); + box-shadow: 0 1px 2px rgba(0,0,0,.075) +} + +.dropdown-menu > li > a:focus, .dropdown-menu > li > a:hover { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%); + background-image: -o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8)); + background-image: linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x +} + +.dropdown-menu > .active > a, .dropdown-menu > .active > a:focus, .dropdown-menu > .active > a:hover { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4)); + background-image: linear-gradient(to bottom,#337ab7 0,#2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x +} + +.navbar-default { + background-image: -webkit-linear-gradient(top,#fff 0,#f8f8f8 100%); + background-image: -o-linear-gradient(top,#fff 0,#f8f8f8 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8)); + background-image: linear-gradient(to bottom,#fff 0,#f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075) +} + + .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .open > a { + background-image: -webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%); + background-image: -o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2)); + background-image: linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0,0,0,.075); + box-shadow: inset 0 3px 9px rgba(0,0,0,.075) + } + +.navbar-brand, .navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255,255,255,.25) +} + +.navbar-inverse { + background-image: -webkit-linear-gradient(top,#3c3c3c 0,#222 100%); + background-image: -o-linear-gradient(top,#3c3c3c 0,#222 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222)); + background-image: linear-gradient(to bottom,#3c3c3c 0,#222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + background-repeat: repeat-x; + border-radius: 4px +} + + .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .open > a { + background-image: -webkit-linear-gradient(top,#080808 0,#0f0f0f 100%); + background-image: -o-linear-gradient(top,#080808 0,#0f0f0f 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f)); + background-image: linear-gradient(to bottom,#080808 0,#0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0,0,0,.25); + box-shadow: inset 0 3px 9px rgba(0,0,0,.25) + } + + .navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0,0,0,.25) + } + +.navbar-fixed-bottom, .navbar-fixed-top, .navbar-static-top { + border-radius: 0 +} + +@media (max-width:767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, .navbar .navbar-nav .open .dropdown-menu > .active > a:focus, .navbar .navbar-nav .open .dropdown-menu > .active > a:hover { + color: #fff; + background-image: -webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4)); + background-image: linear-gradient(to bottom,#337ab7 0,#2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x + } +} + +.alert { + text-shadow: 0 1px 0 rgba(255,255,255,.2); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05) +} + +.alert-success { + background-image: -webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%); + background-image: -o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc)); + background-image: linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1 +} + +.alert-info { + background-image: -webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%); + background-image: -o-linear-gradient(top,#d9edf7 0,#b9def0 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0)); + background-image: linear-gradient(to bottom,#d9edf7 0,#b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea +} + +.alert-warning { + background-image: -webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%); + background-image: -o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0)); + background-image: linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e +} + +.alert-danger { + background-image: -webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%); + background-image: -o-linear-gradient(top,#f2dede 0,#e7c3c3 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3)); + background-image: linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7 +} + +.progress { + background-image: -webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%); + background-image: -o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5)); + background-image: linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar { + background-image: -webkit-linear-gradient(top,#337ab7 0,#286090 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#286090 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090)); + background-image: linear-gradient(to bottom,#337ab7 0,#286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar-success { + background-image: -webkit-linear-gradient(top,#5cb85c 0,#449d44 100%); + background-image: -o-linear-gradient(top,#5cb85c 0,#449d44 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44)); + background-image: linear-gradient(to bottom,#5cb85c 0,#449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar-info { + background-image: -webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%); + background-image: -o-linear-gradient(top,#5bc0de 0,#31b0d5 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5)); + background-image: linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar-warning { + background-image: -webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%); + background-image: -o-linear-gradient(top,#f0ad4e 0,#ec971f 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f)); + background-image: linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar-danger { + background-image: -webkit-linear-gradient(top,#d9534f 0,#c9302c 100%); + background-image: -o-linear-gradient(top,#d9534f 0,#c9302c 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c)); + background-image: linear-gradient(to bottom,#d9534f 0,#c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x +} + +.progress-bar-striped { + 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) +} + +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.075); + box-shadow: 0 1px 2px rgba(0,0,0,.075) +} + +.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top,#337ab7 0,#2b669a 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#2b669a 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a)); + background-image: linear-gradient(to bottom,#337ab7 0,#2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a +} + + .list-group-item.active .badge, .list-group-item.active:focus .badge, .list-group-item.active:hover .badge { + text-shadow: none + } + +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05); + box-shadow: 0 1px 2px rgba(0,0,0,.05) +} + +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%); + background-image: -o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8)); + background-image: linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x +} + +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -o-linear-gradient(top,#337ab7 0,#2e6da4 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4)); + background-image: linear-gradient(to bottom,#337ab7 0,#2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x +} + +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%); + background-image: -o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6)); + background-image: linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x +} + +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%); + background-image: -o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3)); + background-image: linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x +} + +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%); + background-image: -o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc)); + background-image: linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x +} + +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%); + background-image: -o-linear-gradient(top,#f2dede 0,#ebcccc 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc)); + background-image: linear-gradient(to bottom,#f2dede 0,#ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x +} + +.well { + background-image: -webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%); + background-image: -o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%); + background-image: -webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5)); + background-image: linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1) +} +/*# sourceMappingURL=bootstrap-theme.min.css.map */ diff --git a/BTCPayServer/wwwroot/css/bootstrap-theme.min.css.map b/BTCPayServer/wwwroot/css/bootstrap-theme.min.css.map index 94813e900..cf5310f00 100644 --- a/BTCPayServer/wwwroot/css/bootstrap-theme.min.css.map +++ b/BTCPayServer/wwwroot/css/bootstrap-theme.min.css.map @@ -1 +1,7 @@ -{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA","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\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\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","// 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","// 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"]} \ No newline at end of file +{ + "version": 3, + "sources": [ "less/theme.less", "less/mixins/vendor-prefixes.less", "less/mixins/gradients.less", "less/mixins/reset-filter.less" ], + "names": [], + "mappings": ";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA", + "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\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\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", "// 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", "// 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" ] +} diff --git a/BTCPayServer/wwwroot/css/creative.min.css b/BTCPayServer/wwwroot/css/creative.min.css index c534b6308..ad514d126 100644 --- a/BTCPayServer/wwwroot/css/creative.min.css +++ b/BTCPayServer/wwwroot/css/creative.min.css @@ -2,4 +2,451 @@ * Start Bootstrap - Createive v4.0.0-beta (http://startbootstrap.com/template-overviews/creative) * Copyright 2013-2017 Start Bootstrap * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-creative/blob/master/LICENSE) - */body,html{width:100%;height:100%}body{font-family:Merriweather,'Helvetica Neue',Arial,sans-serif}hr{max-width:50px;border-width:3px;border-color:#f05f40}hr.light{border-color:#fff}a{color:#f05f40;-webkit-transition:all .2s;-moz-transition:all .2s;transition:all .2s}a:focus,a:hover{color:#f05f40}h1,h2,h3,h4,h5,h6{font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}p{font-size:16px;line-height:1.5;margin-bottom:20px}.bg-primary{background-color:#f05f40!important}.bg-dark{color:#fff;background-color:#222!important}.text-faded{color:rgba(255,255,255,.7)}section{padding:100px 0}.section-heading{margin-top:0}::-moz-selection{color:#fff;background:#222;text-shadow:none}::selection{color:#fff;background:#222;text-shadow:none}img::selection{color:#fff;background:0 0}img::-moz-selection{color:#fff;background:0 0}body{-webkit-tap-highlight-color:#222}#mainNav{border-color:rgba(34,34,34,.05);background-color:#fff;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif;-webkit-transition:all .2s;-moz-transition:all .2s;transition:all .2s}#mainNav .navbar-brand{font-weight:700;text-transform:uppercase;color:#f05f40;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}#mainNav .navbar-brand:focus,#mainNav .navbar-brand:hover{color:#f05f40}#mainNav .navbar-toggle{font-size:12px;font-weight:700;text-transform:uppercase;color:#222}#mainNav .navbar-nav>li.nav-item>a.nav-link,#mainNav .navbar-nav>li.nav-item>a.nav-link:focus{font-size:13px;font-weight:700;text-transform:uppercase;color:#222}#mainNav .navbar-nav>li.nav-item>a.nav-link:focus:hover,#mainNav .navbar-nav>li.nav-item>a.nav-link:hover{color:#f05f40}#mainNav .navbar-nav>li.nav-item>a.nav-link.active,#mainNav .navbar-nav>li.nav-item>a.nav-link:focus.active{color:#f05f40!important;background-color:transparent}#mainNav .navbar-nav>li.nav-item>a.nav-link.active:hover,#mainNav .navbar-nav>li.nav-item>a.nav-link:focus.active:hover{background-color:transparent}@media (min-width:992px){#mainNav{border-color:rgba(255,255,255,.3);background-color:transparent}#mainNav .navbar-brand{color:rgba(255,255,255,.7)}#mainNav .navbar-brand:focus,#mainNav .navbar-brand:hover{color:#fff}#mainNav .navbar-nav>li.nav-item>a.nav-link,#mainNav .navbar-nav>li.nav-item>a.nav-link:focus{color:rgba(255,255,255,.7)}#mainNav .navbar-nav>li.nav-item>a.nav-link:focus:hover,#mainNav .navbar-nav>li.nav-item>a.nav-link:hover{color:#fff}#mainNav.navbar-shrink{border-color:rgba(34,34,34,.05);background-color:#fff}#mainNav.navbar-shrink .navbar-brand{font-size:16px;color:#f05f40}#mainNav.navbar-shrink .navbar-brand:focus,#mainNav.navbar-shrink .navbar-brand:hover{color:#f05f40}#mainNav.navbar-shrink .navbar-nav>li.nav-item>a.nav-link,#mainNav.navbar-shrink .navbar-nav>li.nav-item>a.nav-link:focus{color:#222}#mainNav.navbar-shrink .navbar-nav>li.nav-item>a.nav-link:focus:hover,#mainNav.navbar-shrink .navbar-nav>li.nav-item>a.nav-link:hover{color:#f05f40}}header.masthead{position:relative;width:100%;min-height:auto;text-align:center;color:#fff;background-image:url(../img/header.jpg);background-position:center;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}header.masthead .header-content{position:relative;width:100%;padding:150px 15px 100px;text-align:center}header.masthead .header-content .header-content-inner h1{font-size:30px;font-weight:700;margin-top:0;margin-bottom:0;text-transform:uppercase}header.masthead .header-content .header-content-inner hr{margin:30px auto}header.masthead .header-content .header-content-inner p{font-size:16px;font-weight:300;margin-bottom:50px;color:rgba(255,255,255,.7)}@media (min-width:768px){header.masthead{height:100%;min-height:600px}header.masthead .header-content{position:absolute;top:50%;padding:0 50px;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}header.masthead .header-content .header-content-inner{max-width:1000px;margin-right:auto;margin-left:auto}header.masthead .header-content .header-content-inner h1{font-size:50px}header.masthead .header-content .header-content-inner p{font-size:18px;max-width:80%;margin-right:auto;margin-left:auto}}.service-box{max-width:400px;margin:50px auto 0}@media (min-width:992px){.service-box{margin:20px auto 0}}.service-box p{margin-bottom:0}.portfolio-box{position:relative;display:block;max-width:650px;margin:0 auto}.portfolio-box .portfolio-box-caption{position:absolute;bottom:0;display:block;width:100%;height:100%;text-align:center;opacity:0;color:#fff;background:rgba(240,95,64,.9);-webkit-transition:all .2s;-moz-transition:all .2s;transition:all .2s}.portfolio-box .portfolio-box-caption .portfolio-box-caption-content{position:absolute;top:50%;width:100%;transform:translateY(-50%);text-align:center}.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name{padding:0 15px;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category{font-size:14px;font-weight:600;text-transform:uppercase}.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name{font-size:18px}.portfolio-box:hover .portfolio-box-caption{opacity:1}.portfolio-box:focus{outline:0}@media (min-width:768px){.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category{font-size:16px}.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name{font-size:22px}}.call-to-action{padding:50px 0}.call-to-action h2{margin:0 auto 20px}.text-primary{color:#f05f40!important}.no-gutter>[class*=col-]{padding-right:0;padding-left:0}.btn-default{color:#222;border-color:#fff;background-color:#fff}.btn-default.focus,.btn-default:focus{color:#222;border-color:#bfbfbf;background-color:#e6e6e6}.btn-default:hover{color:#222;border-color:#e0e0e0;background-color:#e6e6e6}.btn-default.active,.btn-default:active,.open>.btn-default.dropdown-toggle{color:#222;border-color:#e0e0e0;background-color:#e6e6e6}.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>.btn-default.dropdown-toggle.focus,.open>.btn-default.dropdown-toggle:focus,.open>.btn-default.dropdown-toggle:hover{color:#222;border-color:#bfbfbf;background-color:#d4d4d4}.btn-default.active,.btn-default:active,.open>.btn-default.dropdown-toggle{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{border-color:#fff;background-color:#fff}.btn-default .badge{color:#fff;background-color:#222}.btn-primary{color:#fff;border-color:#f05f40;background-color:#f05f40}.btn-primary.focus,.btn-primary:focus{color:#fff;border-color:#a4270d;background-color:#eb3812}.btn-primary:hover{color:#fff;border-color:#e13612;background-color:#eb3812}.btn-primary.active,.btn-primary:active,.open>.btn-primary.dropdown-toggle{color:#fff;border-color:#e13612;background-color:#eb3812}.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>.btn-primary.dropdown-toggle.focus,.open>.btn-primary.dropdown-toggle:focus,.open>.btn-primary.dropdown-toggle:hover{color:#fff;border-color:#a4270d;background-color:#c93110}.btn-primary.active,.btn-primary:active,.open>.btn-primary.dropdown-toggle{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{border-color:#f05f40;background-color:#f05f40}.btn-primary .badge{color:#f05f40;background-color:#fff}.btn{font-weight:700;text-transform:uppercase;border:none;border-radius:300px;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.btn-xl{padding:15px 30px} \ No newline at end of file + */ + +body, html { + width: 100%; + height: 100% +} + +body { + font-family: Merriweather,'Helvetica Neue',Arial,sans-serif +} + +hr { + max-width: 50px; + border-width: 3px; + border-color: #f05f40 +} + + hr.light { + border-color: #fff + } + +a { + color: #f05f40; + -webkit-transition: all .2s; + -moz-transition: all .2s; + transition: all .2s +} + + a:focus, a:hover { + color: #f05f40 + } + +h1, h2, h3, h4, h5, h6 { + font-family: 'Open Sans','Helvetica Neue',Arial,sans-serif +} + +p { + font-size: 16px; + line-height: 1.5; + margin-bottom: 20px +} + +.bg-primary { + background-color: #f05f40 !important +} + +.bg-dark { + color: #fff; + background-color: #222 !important +} + +.text-faded { + color: rgba(255,255,255,.7) +} + +section { + padding: 100px 0 +} + +.section-heading { + margin-top: 0 +} + +::-moz-selection { + color: #fff; + background: #222; + text-shadow: none +} + +::selection { + color: #fff; + background: #222; + text-shadow: none +} + +img::selection { + color: #fff; + background: 0 0 +} + +img::-moz-selection { + color: #fff; + background: 0 0 +} + +body { + -webkit-tap-highlight-color: #222 +} + +#mainNav { + border-color: rgba(34,34,34,.05); + background-color: #fff; + font-family: 'Open Sans','Helvetica Neue',Arial,sans-serif; + -webkit-transition: all .2s; + -moz-transition: all .2s; + transition: all .2s +} + + #mainNav .navbar-brand { + font-weight: 700; + text-transform: uppercase; + color: #f05f40; + font-family: 'Open Sans','Helvetica Neue',Arial,sans-serif + } + + #mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover { + color: #f05f40 + } + + #mainNav .navbar-toggle { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + color: #222 + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link, #mainNav .navbar-nav > li.nav-item > a.nav-link:focus { + font-size: 13px; + font-weight: 700; + text-transform: uppercase; + color: #222 + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover, #mainNav .navbar-nav > li.nav-item > a.nav-link:hover { + color: #f05f40 + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link.active, #mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active { + color: #f05f40 !important; + background-color: transparent + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover, #mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover { + background-color: transparent + } + +@media (min-width:992px) { + #mainNav { + border-color: rgba(255,255,255,.3); + background-color: transparent + } + + #mainNav .navbar-brand { + color: rgba(255,255,255,.7) + } + + #mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover { + color: #fff + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link, #mainNav .navbar-nav > li.nav-item > a.nav-link:focus { + color: rgba(255,255,255,.7) + } + + #mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover, #mainNav .navbar-nav > li.nav-item > a.nav-link:hover { + color: #fff + } + + #mainNav.navbar-shrink { + border-color: rgba(34,34,34,.05); + background-color: #fff + } + + #mainNav.navbar-shrink .navbar-brand { + font-size: 16px; + color: #f05f40 + } + + #mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover { + color: #f05f40 + } + + #mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link, #mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus { + color: #222 + } + + #mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus:hover, #mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:hover { + color: #f05f40 + } +} + +header.masthead { + position: relative; + width: 100%; + min-height: auto; + text-align: center; + color: #fff; + background-image: url(../img/header.jpg); + background-position: center; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover +} + + header.masthead .header-content { + position: relative; + width: 100%; + padding: 150px 15px 100px; + text-align: center + } + + header.masthead .header-content .header-content-inner h1 { + font-size: 30px; + font-weight: 700; + margin-top: 0; + margin-bottom: 0; + text-transform: uppercase + } + + header.masthead .header-content .header-content-inner hr { + margin: 30px auto + } + + header.masthead .header-content .header-content-inner p { + font-size: 16px; + font-weight: 300; + margin-bottom: 50px; + color: rgba(255,255,255,.7) + } + +@media (min-width:768px) { + header.masthead { + height: 100%; + min-height: 600px + } + + header.masthead .header-content { + position: absolute; + top: 50%; + padding: 0 50px; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%) + } + + header.masthead .header-content .header-content-inner { + max-width: 1000px; + margin-right: auto; + margin-left: auto + } + + header.masthead .header-content .header-content-inner h1 { + font-size: 50px + } + + header.masthead .header-content .header-content-inner p { + font-size: 18px; + max-width: 80%; + margin-right: auto; + margin-left: auto + } +} + +.service-box { + max-width: 400px; + margin: 50px auto 0 +} + +@media (min-width:992px) { + .service-box { + margin: 20px auto 0 + } +} + +.service-box p { + margin-bottom: 0 +} + +.portfolio-box { + position: relative; + display: block; + max-width: 650px; + margin: 0 auto +} + + .portfolio-box .portfolio-box-caption { + position: absolute; + bottom: 0; + display: block; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + color: #fff; + background: rgba(240,95,64,.9); + -webkit-transition: all .2s; + -moz-transition: all .2s; + transition: all .2s + } + + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content { + position: absolute; + top: 50%; + width: 100%; + transform: translateY(-50%); + text-align: center + } + + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category, .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name { + padding: 0 15px; + font-family: 'Open Sans','Helvetica Neue',Arial,sans-serif + } + + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category { + font-size: 14px; + font-weight: 600; + text-transform: uppercase + } + + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name { + font-size: 18px + } + + .portfolio-box:hover .portfolio-box-caption { + opacity: 1 + } + + .portfolio-box:focus { + outline: 0 + } + +@media (min-width:768px) { + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category { + font-size: 16px + } + + .portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name { + font-size: 22px + } +} + +.call-to-action { + padding: 50px 0 +} + + .call-to-action h2 { + margin: 0 auto 20px + } + +.text-primary { + color: #f05f40 !important +} + +.no-gutter > [class*=col-] { + padding-right: 0; + padding-left: 0 +} + +.btn-default { + color: #222; + border-color: #fff; + background-color: #fff +} + + .btn-default.focus, .btn-default:focus { + color: #222; + border-color: #bfbfbf; + background-color: #e6e6e6 + } + + .btn-default:hover { + color: #222; + border-color: #e0e0e0; + background-color: #e6e6e6 + } + + .btn-default.active, .btn-default:active, .open > .btn-default.dropdown-toggle { + color: #222; + border-color: #e0e0e0; + background-color: #e6e6e6 + } + + .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 > .btn-default.dropdown-toggle.focus, .open > .btn-default.dropdown-toggle:focus, .open > .btn-default.dropdown-toggle:hover { + color: #222; + border-color: #bfbfbf; + background-color: #d4d4d4 + } + + .btn-default.active, .btn-default:active, .open > .btn-default.dropdown-toggle { + 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 { + border-color: #fff; + background-color: #fff + } + + .btn-default .badge { + color: #fff; + background-color: #222 + } + +.btn-primary { + color: #fff; + border-color: #f05f40; + background-color: #f05f40 +} + + .btn-primary.focus, .btn-primary:focus { + color: #fff; + border-color: #a4270d; + background-color: #eb3812 + } + + .btn-primary:hover { + color: #fff; + border-color: #e13612; + background-color: #eb3812 + } + + .btn-primary.active, .btn-primary:active, .open > .btn-primary.dropdown-toggle { + color: #fff; + border-color: #e13612; + background-color: #eb3812 + } + + .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 > .btn-primary.dropdown-toggle.focus, .open > .btn-primary.dropdown-toggle:focus, .open > .btn-primary.dropdown-toggle:hover { + color: #fff; + border-color: #a4270d; + background-color: #c93110 + } + + .btn-primary.active, .btn-primary:active, .open > .btn-primary.dropdown-toggle { + 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 { + border-color: #f05f40; + background-color: #f05f40 + } + + .btn-primary .badge { + color: #f05f40; + background-color: #fff + } + +.btn { + font-weight: 700; + text-transform: uppercase; + border: none; + border-radius: 300px; + font-family: 'Open Sans','Helvetica Neue',Arial,sans-serif +} + +.btn-xl { + padding: 15px 30px +} diff --git a/BTCPayServer/wwwroot/css/css.css b/BTCPayServer/wwwroot/css/css.css index b2c9a2057..ae9a75119 100644 --- a/BTCPayServer/wwwroot/css/css.css +++ b/BTCPayServer/wwwroot/css/css.css @@ -1,280 +1,280 @@ /* cyrillic-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } /* greek */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0370-03FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } /* cyrillic-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/ZLqKeelYbATG60EpZBSDyxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/ZLqKeelYbATG60EpZBSDyxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/oHi30kwQWvpCWqAhzHcCSBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/oHi30kwQWvpCWqAhzHcCSBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/rGvHdJnr2l75qb0YND9NyBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/rGvHdJnr2l75qb0YND9NyBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } /* greek */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/mx9Uck6uB63VIKFYnEMXrRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0370-03FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/mx9Uck6uB63VIKFYnEMXrRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/mbmhprMH69Zi6eEPBYVFhRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/mbmhprMH69Zi6eEPBYVFhRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/oOeFwZNlrTefzLYmlVV1UBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/oOeFwZNlrTefzLYmlVV1UBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/RxZJdnzeo3R5zSexge8UUVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v16/RxZJdnzeo3R5zSexge8UUVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } /* cyrillic-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/77FXFjRbGzN4aCrSFhlh3hJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/77FXFjRbGzN4aCrSFhlh3hJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/isZ-wbCXNKAbnjo6_TwHThJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/isZ-wbCXNKAbnjo6_TwHThJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/UX6i4JxQDm3fVTc1CPuwqhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/UX6i4JxQDm3fVTc1CPuwqhJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } /* greek */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/jSN2CGVDbcVyCnfJfjSdfBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0370-03FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/jSN2CGVDbcVyCnfJfjSdfBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/PwZc-YbIL414wB9rB1IAPRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/PwZc-YbIL414wB9rB1IAPRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/97uahxiqZRoncBaCEI3aWxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/97uahxiqZRoncBaCEI3aWxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/d-6IYplOFocCacKzxwXSOFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v16/d-6IYplOFocCacKzxwXSOFtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } /* cyrillic-ext */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/WxrXJa0C3KdtC7lMafG4dRTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/WxrXJa0C3KdtC7lMafG4dRTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/OpXUqTo0UgQQhGj_SFdLWBTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/OpXUqTo0UgQQhGj_SFdLWBTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/1hZf02POANh32k2VkgEoUBTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/1hZf02POANh32k2VkgEoUBTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } /* greek */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/cDKhRaXnQTOVbaoxwdOr9xTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+0370-03FF; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/cDKhRaXnQTOVbaoxwdOr9xTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/K23cxWVTrIFD6DJsEVi07RTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/K23cxWVTrIFD6DJsEVi07RTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/vSzulfKSK0LLjjfeaxcREhTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/vSzulfKSK0LLjjfeaxcREhTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Roboto'; - font-style: italic; - font-weight: 400; - src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/vPcynSL0qHq_6dX7lKVByfesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v16/vPcynSL0qHq_6dX7lKVByfesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } /* cyrillic-ext */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYzTOQ_MqJVwkKsUn0wKzc2I.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYzTOQ_MqJVwkKsUn0wKzc2I.woff2) format('woff2'); + unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYzUj_cnvWIuuBMVgbX098Mw.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYzUj_cnvWIuuBMVgbX098Mw.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } /* greek-ext */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY0bcKLIaa1LC45dFaAfauRA.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY0bcKLIaa1LC45dFaAfauRA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; } /* greek */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY2o_sUJ8uO4YLWRInS22T3Y.woff2) format('woff2'); - unicode-range: U+0370-03FF; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY2o_sUJ8uO4YLWRInS22T3Y.woff2) format('woff2'); + unicode-range: U+0370-03FF; } /* vietnamese */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY76up8jxqWt8HVA3mDhkV_0.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY76up8jxqWt8HVA3mDhkV_0.woff2) format('woff2'); + unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; } /* latin-ext */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYyYE0-AqJ3nfInTTiDXDjU4.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpYyYE0-AqJ3nfInTTiDXDjU4.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; } /* latin */ @font-face { - font-family: 'Roboto Mono'; - font-style: normal; - font-weight: 400; - src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY44P5ICox8Kq3LLUNMylGO4.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + src: local('Roboto Mono'), local('RobotoMono-Regular'), url(https://fonts.gstatic.com/s/robotomono/v4/hMqPNLsu_dywMa4C_DEpY44P5ICox8Kq3LLUNMylGO4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } diff --git a/BTCPayServer/wwwroot/css/normalizer.css b/BTCPayServer/wwwroot/css/normalizer.css index e4b8cfe90..0856691d8 100644 --- a/BTCPayServer/wwwroot/css/normalizer.css +++ b/BTCPayServer/wwwroot/css/normalizer.css @@ -1,13 +1,13 @@ /*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */ html { - font-family: sans-serif; - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + font-family: sans-serif; + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } body { - margin: 0; + margin: 0; } article, @@ -22,114 +22,114 @@ menu, nav, section, summary { - display: block; + display: block; } audio, canvas, progress, video { - display: inline-block; + display: inline-block; } - audio:not([controls]) { - display: none; - height: 0; - } + audio:not([controls]) { + display: none; + height: 0; + } progress { - vertical-align: baseline; + vertical-align: baseline; } template, [hidden] { - display: none; + display: none; } a { - background-color: transparent; - -webkit-text-decoration-skip: objects; + background-color: transparent; + -webkit-text-decoration-skip: objects; } - a:active, - a:hover { - outline-width: 0; - } + a:active, + a:hover { + outline-width: 0; + } abbr[title] { - border-bottom: none; - text-decoration: underline; - text-decoration: underline dotted; + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; } b, strong { - font-weight: inherit; + font-weight: inherit; } b, strong { - font-weight: bolder; + font-weight: bolder; } dfn { - font-style: italic; + font-style: italic; } h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } mark { - background-color: #ff0; - color: #000; + background-color: #ff0; + color: #000; } small { - font-size: 80%; + font-size: 80%; } sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } img { - border-style: none; + border-style: none; } svg:not(:root) { - overflow: hidden; + overflow: hidden; } code, kbd, pre, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; + font-size: 1em; } figure { - margin: 1em 40px; + margin: 1em 40px; } hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; + height: 0; + overflow: visible; } button, @@ -137,304 +137,304 @@ input, optgroup, select, textarea { - font: inherit; - margin: 0; + font: inherit; + margin: 0; } optgroup { - font-weight: bold; + font-weight: bold; } button, input { - overflow: visible; + overflow: visible; } button, select { - text-transform: none; + text-transform: none; } button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } - button::-moz-focus-inner, - [type="button"]::-moz-focus-inner, - [type="reset"]::-moz-focus-inner, - [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; - } + button::-moz-focus-inner, + [type="button"]::-moz-focus-inner, + [type="reset"]::-moz-focus-inner, + [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; + } - button:-moz-focusring, - [type="button"]:-moz-focusring, - [type="reset"]:-moz-focusring, - [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; - } + button:-moz-focusring, + [type="button"]:-moz-focusring, + [type="reset"]:-moz-focusring, + [type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; + } fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; } textarea { - overflow: auto; + overflow: auto; } [type="checkbox"], [type="radio"] { - box-sizing: border-box; - padding: 0; + box-sizing: border-box; + padding: 0; } [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; + outline-offset: -2px; } - [type="search"]::-webkit-search-cancel-button, - [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; - } + [type="search"]::-webkit-search-cancel-button, + [type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + } ::-webkit-input-placeholder { - color: inherit; - opacity: 0.54; + color: inherit; + opacity: 0.54; } ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; + font: inherit; } @media print { - *, - *::before, - *::after, - *::first-letter, - p::first-line, - div::first-line, - blockquote::first-line, - li::first-line { - text-shadow: none !important; - box-shadow: none !important; - } + *, + *::before, + *::after, + *::first-letter, + p::first-line, + div::first-line, + blockquote::first-line, + li::first-line { + text-shadow: none !important; + box-shadow: none !important; + } - a, - a:visited { - text-decoration: underline; - } + a, + a:visited { + text-decoration: underline; + } - abbr[title]::after { - content: " (" attr(title) ")"; - } + abbr[title]::after { + content: " (" attr(title) ")"; + } - pre { - white-space: pre-wrap !important; - } + pre { + white-space: pre-wrap !important; + } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } - thead { - display: table-header-group; - } + thead { + display: table-header-group; + } - tr, - img { - page-break-inside: avoid; - } + tr, + img { + page-break-inside: avoid; + } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } - h2, - h3 { - page-break-after: avoid; - } + h2, + h3 { + page-break-after: avoid; + } - .navbar { - display: none; - } + .navbar { + display: none; + } - .btn > .caret, .action-button > .caret, - .dropup > .btn > .caret, - .dropup > .action-button > .caret { - border-top-color: #000 !important; - } + .btn > .caret, .action-button > .caret, + .dropup > .btn > .caret, + .dropup > .action-button > .caret { + border-top-color: #000 !important; + } - .tag { - border: 1px solid #000; - } + .tag { + border: 1px solid #000; + } - .table { - border-collapse: collapse !important; - } + .table { + border-collapse: collapse !important; + } - .table td, - .table th { - background-color: #fff !important; - } + .table td, + .table th { + background-color: #fff !important; + } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } } html { - box-sizing: border-box; + box-sizing: border-box; } *, *::before, *::after { - box-sizing: inherit; + box-sizing: inherit; } @-ms-viewport { - width: device-width; + width: device-width; } html { - font-size: 16px; - -ms-overflow-style: scrollbar; - -webkit-tap-highlight-color: transparent; + font-size: 16px; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; } body { - font-family: "Roboto", "Helvetica", sans-serif; - font-size: 1rem; - line-height: 1.5; - color: #373a3c; - background-color: #fff; + font-family: "Roboto", "Helvetica", sans-serif; + font-size: 1rem; + line-height: 1.5; + color: #373a3c; + background-color: #fff; } [tabindex="-1"]:focus { - outline: none !important; + outline: none !important; } h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: .5rem; + margin-top: 0; + margin-bottom: .5rem; } p { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } abbr[title], abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #818a91; + cursor: help; + border-bottom: 1px dotted #818a91; } address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; } ol, ul, dl { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } - ol ol, - ul ul, - ol ul, - ul ol { - margin-bottom: 0; - } + ol ol, + ul ul, + ol ul, + ul ol { + margin-bottom: 0; + } dt { - font-weight: bold; + font-weight: bold; } dd { - margin-bottom: .5rem; - margin-left: 0; + margin-bottom: .5rem; + margin-left: 0; } blockquote { - margin: 0 0 1rem; + margin: 0 0 1rem; } a { - color: #214497; - text-decoration: none; + color: #214497; + text-decoration: none; } - a:focus, a:hover { - color: #132858; - text-decoration: underline; - } + a:focus, a:hover { + color: #132858; + text-decoration: underline; + } - a:focus { - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } + a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } - a:not([href]):not([tabindex]) { - color: inherit; - text-decoration: none; - } + a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; + } - a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { - color: inherit; - text-decoration: none; - } + a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { + color: inherit; + text-decoration: none; + } - a:not([href]):not([tabindex]):focus { - outline: none; - } + a:not([href]):not([tabindex]):focus { + outline: none; + } pre { - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; } figure { - margin: 0 0 1rem; + margin: 0 0 1rem; } img { - vertical-align: middle; + vertical-align: middle; } [role="button"] { - cursor: pointer; + cursor: pointer; } a, @@ -446,840 +446,840 @@ label, select, summary, textarea { - touch-action: manipulation; + touch-action: manipulation; } table { - border-collapse: collapse; - background-color: transparent; + border-collapse: collapse; + background-color: transparent; } caption { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - color: #818a91; - text-align: left; - caption-side: bottom; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #818a91; + text-align: left; + caption-side: bottom; } th { - text-align: left; + text-align: left; } label { - display: inline-block; - margin-bottom: .5rem; + display: inline-block; + margin-bottom: .5rem; } button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; } input, button, select, textarea { - line-height: inherit; + line-height: inherit; } - input[type="radio"]:disabled, - input[type="checkbox"]:disabled { - cursor: not-allowed; - } + input[type="radio"]:disabled, + input[type="checkbox"]:disabled { + cursor: not-allowed; + } - input[type="date"], - input[type="time"], - input[type="datetime-local"], - input[type="month"] { - -webkit-appearance: listbox; - } + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + -webkit-appearance: listbox; + } textarea { - resize: vertical; + resize: vertical; } fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; + min-width: 0; + padding: 0; + margin: 0; + border: 0; } legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: .5rem; - font-size: 1.5rem; - line-height: inherit; + display: block; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; } input[type="search"] { - -webkit-appearance: none; + -webkit-appearance: none; } output { - display: inline-block; + display: inline-block; } [hidden] { - display: none !important; + display: none !important; } .btn, .action-button { - display: inline-block; - font-weight: normal; - line-height: 1.25; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - user-select: none; - border: 1px solid transparent; - padding: 0.5rem 1rem; - font-size: 1rem; - border-radius: 0.25rem; + display: inline-block; + font-weight: normal; + line-height: 1.25; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + user-select: none; + border: 1px solid transparent; + padding: 0.5rem 1rem; + font-size: 1rem; + border-radius: 0.25rem; } - .btn:focus, .action-button:focus, .btn.focus, .focus.action-button, .btn:active:focus, .action-button:active:focus, .btn:active.focus, .action-button:active.focus, .btn.active:focus, .active.action-button:focus, .btn.active.focus, .active.focus.action-button { - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } + .btn:focus, .action-button:focus, .btn.focus, .focus.action-button, .btn:active:focus, .action-button:active:focus, .btn:active.focus, .action-button:active.focus, .btn.active:focus, .active.action-button:focus, .btn.active.focus, .active.focus.action-button { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } - .btn:focus, .action-button:focus, .btn:hover, .action-button:hover { - text-decoration: none; - } + .btn:focus, .action-button:focus, .btn:hover, .action-button:hover { + text-decoration: none; + } - .btn.focus, .focus.action-button { - text-decoration: none; - } + .btn.focus, .focus.action-button { + text-decoration: none; + } - .btn:active, .action-button:active, .btn.active, .active.action-button { - background-image: none; - outline: 0; - } + .btn:active, .action-button:active, .btn.active, .active.action-button { + background-image: none; + outline: 0; + } - .btn.disabled, .disabled.action-button, .btn:disabled, .action-button:disabled { - cursor: not-allowed; - opacity: .65; - } + .btn.disabled, .disabled.action-button, .btn:disabled, .action-button:disabled { + cursor: not-allowed; + opacity: .65; + } a.btn.disabled, a.disabled.action-button, fieldset[disabled] a.btn, fieldset[disabled] a.action-button { - pointer-events: none; + pointer-events: none; } .btn-primary { - color: #fff; - background-color: #214497; - border-color: #214497; + color: #fff; + background-color: #214497; + border-color: #214497; } - .btn-primary:hover { - color: #fff; - background-color: #18316d; - border-color: #162d65; - } + .btn-primary:hover { + color: #fff; + background-color: #18316d; + border-color: #162d65; + } - .btn-primary:focus, .btn-primary.focus { - color: #fff; - background-color: #18316d; - border-color: #162d65; - } + .btn-primary:focus, .btn-primary.focus { + color: #fff; + background-color: #18316d; + border-color: #162d65; + } - .btn-primary:active, .btn-primary.active, - .open > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #18316d; - border-color: #162d65; - background-image: none; - } + .btn-primary:active, .btn-primary.active, + .open > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #18316d; + border-color: #162d65; + background-image: none; + } - .btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, - .open > .btn-primary.dropdown-toggle:hover, - .open > .btn-primary.dropdown-toggle:focus, - .open > .btn-primary.dropdown-toggle.focus { - color: #fff; - background-color: #112450; - border-color: #0a152e; - } + .btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, + .open > .btn-primary.dropdown-toggle:hover, + .open > .btn-primary.dropdown-toggle:focus, + .open > .btn-primary.dropdown-toggle.focus { + color: #fff; + background-color: #112450; + border-color: #0a152e; + } - .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary:disabled:focus, .btn-primary:disabled.focus { - background-color: #214497; - border-color: #214497; - } + .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary:disabled:focus, .btn-primary:disabled.focus { + background-color: #214497; + border-color: #214497; + } - .btn-primary.disabled:hover, .btn-primary:disabled:hover { - background-color: #214497; - border-color: #214497; - } + .btn-primary.disabled:hover, .btn-primary:disabled:hover { + background-color: #214497; + border-color: #214497; + } .btn-secondary { - color: #373a3c; - background-color: #fff; - border-color: #ccc; + color: #373a3c; + background-color: #fff; + border-color: #ccc; } - .btn-secondary:hover { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - } + .btn-secondary:hover { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + } - .btn-secondary:focus, .btn-secondary.focus { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - } + .btn-secondary:focus, .btn-secondary.focus { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + } - .btn-secondary:active, .btn-secondary.active, - .open > .btn-secondary.dropdown-toggle { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - background-image: none; - } + .btn-secondary:active, .btn-secondary.active, + .open > .btn-secondary.dropdown-toggle { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + background-image: none; + } - .btn-secondary:active:hover, .btn-secondary:active:focus, .btn-secondary:active.focus, .btn-secondary.active:hover, .btn-secondary.active:focus, .btn-secondary.active.focus, - .open > .btn-secondary.dropdown-toggle:hover, - .open > .btn-secondary.dropdown-toggle:focus, - .open > .btn-secondary.dropdown-toggle.focus { - color: #373a3c; - background-color: #d4d4d4; - border-color: #8c8c8c; - } + .btn-secondary:active:hover, .btn-secondary:active:focus, .btn-secondary:active.focus, .btn-secondary.active:hover, .btn-secondary.active:focus, .btn-secondary.active.focus, + .open > .btn-secondary.dropdown-toggle:hover, + .open > .btn-secondary.dropdown-toggle:focus, + .open > .btn-secondary.dropdown-toggle.focus { + color: #373a3c; + background-color: #d4d4d4; + border-color: #8c8c8c; + } - .btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus { - background-color: #fff; - border-color: #ccc; - } + .btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus { + background-color: #fff; + border-color: #ccc; + } - .btn-secondary.disabled:hover, .btn-secondary:disabled:hover { - background-color: #fff; - border-color: #ccc; - } + .btn-secondary.disabled:hover, .btn-secondary:disabled:hover { + background-color: #fff; + border-color: #ccc; + } .btn-info { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; } - .btn-info:hover { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - } + .btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + } - .btn-info:focus, .btn-info.focus { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - } + .btn-info:focus, .btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + } - .btn-info:active, .btn-info.active, - .open > .btn-info.dropdown-toggle { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - background-image: none; - } + .btn-info:active, .btn-info.active, + .open > .btn-info.dropdown-toggle { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + background-image: none; + } - .btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, - .open > .btn-info.dropdown-toggle:hover, - .open > .btn-info.dropdown-toggle:focus, - .open > .btn-info.dropdown-toggle.focus { - color: #fff; - background-color: #269abc; - border-color: #1f7e9a; - } + .btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, + .open > .btn-info.dropdown-toggle:hover, + .open > .btn-info.dropdown-toggle:focus, + .open > .btn-info.dropdown-toggle.focus { + color: #fff; + background-color: #269abc; + border-color: #1f7e9a; + } - .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info:disabled:focus, .btn-info:disabled.focus { - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info:disabled:focus, .btn-info:disabled.focus { + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-info.disabled:hover, .btn-info:disabled:hover { - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-info.disabled:hover, .btn-info:disabled:hover { + background-color: #5bc0de; + border-color: #5bc0de; + } .btn-success { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; } - .btn-success:hover { - color: #fff; - background-color: #449d44; - border-color: #419641; - } + .btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #419641; + } - .btn-success:focus, .btn-success.focus { - color: #fff; - background-color: #449d44; - border-color: #419641; - } + .btn-success:focus, .btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #419641; + } - .btn-success:active, .btn-success.active, - .open > .btn-success.dropdown-toggle { - color: #fff; - background-color: #449d44; - border-color: #419641; - background-image: none; - } + .btn-success:active, .btn-success.active, + .open > .btn-success.dropdown-toggle { + color: #fff; + background-color: #449d44; + border-color: #419641; + background-image: none; + } - .btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, - .open > .btn-success.dropdown-toggle:hover, - .open > .btn-success.dropdown-toggle:focus, - .open > .btn-success.dropdown-toggle.focus { - color: #fff; - background-color: #398439; - border-color: #2d672d; - } + .btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, + .open > .btn-success.dropdown-toggle:hover, + .open > .btn-success.dropdown-toggle:focus, + .open > .btn-success.dropdown-toggle.focus { + color: #fff; + background-color: #398439; + border-color: #2d672d; + } - .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success:disabled:focus, .btn-success:disabled.focus { - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success:disabled:focus, .btn-success:disabled.focus { + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-success.disabled:hover, .btn-success:disabled:hover { - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-success.disabled:hover, .btn-success:disabled:hover { + background-color: #5cb85c; + border-color: #5cb85c; + } .btn-warning { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; } - .btn-warning:hover { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - } + .btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + } - .btn-warning:focus, .btn-warning.focus { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - } + .btn-warning:focus, .btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + } - .btn-warning:active, .btn-warning.active, - .open > .btn-warning.dropdown-toggle { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - background-image: none; - } + .btn-warning:active, .btn-warning.active, + .open > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + background-image: none; + } - .btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, - .open > .btn-warning.dropdown-toggle:hover, - .open > .btn-warning.dropdown-toggle:focus, - .open > .btn-warning.dropdown-toggle.focus { - color: #fff; - background-color: #d58512; - border-color: #b06d0f; - } + .btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, + .open > .btn-warning.dropdown-toggle:hover, + .open > .btn-warning.dropdown-toggle:focus, + .open > .btn-warning.dropdown-toggle.focus { + color: #fff; + background-color: #d58512; + border-color: #b06d0f; + } - .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning:disabled:focus, .btn-warning:disabled.focus { - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning:disabled:focus, .btn-warning:disabled.focus { + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-warning.disabled:hover, .btn-warning:disabled:hover { - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-warning.disabled:hover, .btn-warning:disabled:hover { + background-color: #f0ad4e; + border-color: #f0ad4e; + } .btn-danger { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; + color: #fff; + background-color: #d9534f; + border-color: #d9534f; } - .btn-danger:hover { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - } + .btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + } - .btn-danger:focus, .btn-danger.focus { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - } + .btn-danger:focus, .btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + } - .btn-danger:active, .btn-danger.active, - .open > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - background-image: none; - } + .btn-danger:active, .btn-danger.active, + .open > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + background-image: none; + } - .btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, - .open > .btn-danger.dropdown-toggle:hover, - .open > .btn-danger.dropdown-toggle:focus, - .open > .btn-danger.dropdown-toggle.focus { - color: #fff; - background-color: #ac2925; - border-color: #8b211e; - } + .btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, + .open > .btn-danger.dropdown-toggle:hover, + .open > .btn-danger.dropdown-toggle:focus, + .open > .btn-danger.dropdown-toggle.focus { + color: #fff; + background-color: #ac2925; + border-color: #8b211e; + } - .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger:disabled:focus, .btn-danger:disabled.focus { - background-color: #d9534f; - border-color: #d9534f; - } + .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger:disabled:focus, .btn-danger:disabled.focus { + background-color: #d9534f; + border-color: #d9534f; + } - .btn-danger.disabled:hover, .btn-danger:disabled:hover { - background-color: #d9534f; - border-color: #d9534f; - } + .btn-danger.disabled:hover, .btn-danger:disabled:hover { + background-color: #d9534f; + border-color: #d9534f; + } .btn-outline-primary { - color: #214497; - background-image: none; - background-color: transparent; - border-color: #214497; + color: #214497; + background-image: none; + background-color: transparent; + border-color: #214497; } - .btn-outline-primary:hover { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:hover { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:focus, .btn-outline-primary.focus { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:focus, .btn-outline-primary.focus { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:active, .btn-outline-primary.active, - .open > .btn-outline-primary.dropdown-toggle { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:active, .btn-outline-primary.active, + .open > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:active:hover, .btn-outline-primary:active:focus, .btn-outline-primary:active.focus, .btn-outline-primary.active:hover, .btn-outline-primary.active:focus, .btn-outline-primary.active.focus, - .open > .btn-outline-primary.dropdown-toggle:hover, - .open > .btn-outline-primary.dropdown-toggle:focus, - .open > .btn-outline-primary.dropdown-toggle.focus { - color: #fff; - background-color: #112450; - border-color: #0a152e; - } + .btn-outline-primary:active:hover, .btn-outline-primary:active:focus, .btn-outline-primary:active.focus, .btn-outline-primary.active:hover, .btn-outline-primary.active:focus, .btn-outline-primary.active.focus, + .open > .btn-outline-primary.dropdown-toggle:hover, + .open > .btn-outline-primary.dropdown-toggle:focus, + .open > .btn-outline-primary.dropdown-toggle.focus { + color: #fff; + background-color: #112450; + border-color: #0a152e; + } - .btn-outline-primary.disabled:focus, .btn-outline-primary.disabled.focus, .btn-outline-primary:disabled:focus, .btn-outline-primary:disabled.focus { - border-color: #4772d7; - } + .btn-outline-primary.disabled:focus, .btn-outline-primary.disabled.focus, .btn-outline-primary:disabled:focus, .btn-outline-primary:disabled.focus { + border-color: #4772d7; + } - .btn-outline-primary.disabled:hover, .btn-outline-primary:disabled:hover { - border-color: #4772d7; - } + .btn-outline-primary.disabled:hover, .btn-outline-primary:disabled:hover { + border-color: #4772d7; + } .btn-outline-secondary { - color: #ccc; - background-image: none; - background-color: transparent; - border-color: #ccc; + color: #ccc; + background-image: none; + background-color: transparent; + border-color: #ccc; } - .btn-outline-secondary:hover { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:hover { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:focus, .btn-outline-secondary.focus { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:focus, .btn-outline-secondary.focus { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:active, .btn-outline-secondary.active, - .open > .btn-outline-secondary.dropdown-toggle { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:active, .btn-outline-secondary.active, + .open > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:active:hover, .btn-outline-secondary:active:focus, .btn-outline-secondary:active.focus, .btn-outline-secondary.active:hover, .btn-outline-secondary.active:focus, .btn-outline-secondary.active.focus, - .open > .btn-outline-secondary.dropdown-toggle:hover, - .open > .btn-outline-secondary.dropdown-toggle:focus, - .open > .btn-outline-secondary.dropdown-toggle.focus { - color: #fff; - background-color: #a1a1a1; - border-color: #8c8c8c; - } + .btn-outline-secondary:active:hover, .btn-outline-secondary:active:focus, .btn-outline-secondary:active.focus, .btn-outline-secondary.active:hover, .btn-outline-secondary.active:focus, .btn-outline-secondary.active.focus, + .open > .btn-outline-secondary.dropdown-toggle:hover, + .open > .btn-outline-secondary.dropdown-toggle:focus, + .open > .btn-outline-secondary.dropdown-toggle.focus { + color: #fff; + background-color: #a1a1a1; + border-color: #8c8c8c; + } - .btn-outline-secondary.disabled:focus, .btn-outline-secondary.disabled.focus, .btn-outline-secondary:disabled:focus, .btn-outline-secondary:disabled.focus { - border-color: white; - } + .btn-outline-secondary.disabled:focus, .btn-outline-secondary.disabled.focus, .btn-outline-secondary:disabled:focus, .btn-outline-secondary:disabled.focus { + border-color: white; + } - .btn-outline-secondary.disabled:hover, .btn-outline-secondary:disabled:hover { - border-color: white; - } + .btn-outline-secondary.disabled:hover, .btn-outline-secondary:disabled:hover { + border-color: white; + } .btn-outline-info { - color: #5bc0de; - background-image: none; - background-color: transparent; - border-color: #5bc0de; + color: #5bc0de; + background-image: none; + background-color: transparent; + border-color: #5bc0de; } - .btn-outline-info:hover { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:hover { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:focus, .btn-outline-info.focus { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:focus, .btn-outline-info.focus { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:active, .btn-outline-info.active, - .open > .btn-outline-info.dropdown-toggle { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:active, .btn-outline-info.active, + .open > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:active:hover, .btn-outline-info:active:focus, .btn-outline-info:active.focus, .btn-outline-info.active:hover, .btn-outline-info.active:focus, .btn-outline-info.active.focus, - .open > .btn-outline-info.dropdown-toggle:hover, - .open > .btn-outline-info.dropdown-toggle:focus, - .open > .btn-outline-info.dropdown-toggle.focus { - color: #fff; - background-color: #269abc; - border-color: #1f7e9a; - } + .btn-outline-info:active:hover, .btn-outline-info:active:focus, .btn-outline-info:active.focus, .btn-outline-info.active:hover, .btn-outline-info.active:focus, .btn-outline-info.active.focus, + .open > .btn-outline-info.dropdown-toggle:hover, + .open > .btn-outline-info.dropdown-toggle:focus, + .open > .btn-outline-info.dropdown-toggle.focus { + color: #fff; + background-color: #269abc; + border-color: #1f7e9a; + } - .btn-outline-info.disabled:focus, .btn-outline-info.disabled.focus, .btn-outline-info:disabled:focus, .btn-outline-info:disabled.focus { - border-color: #b0e1ef; - } + .btn-outline-info.disabled:focus, .btn-outline-info.disabled.focus, .btn-outline-info:disabled:focus, .btn-outline-info:disabled.focus { + border-color: #b0e1ef; + } - .btn-outline-info.disabled:hover, .btn-outline-info:disabled:hover { - border-color: #b0e1ef; - } + .btn-outline-info.disabled:hover, .btn-outline-info:disabled:hover { + border-color: #b0e1ef; + } .btn-outline-success { - color: #5cb85c; - background-image: none; - background-color: transparent; - border-color: #5cb85c; + color: #5cb85c; + background-image: none; + background-color: transparent; + border-color: #5cb85c; } - .btn-outline-success:hover { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:hover { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:focus, .btn-outline-success.focus { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:focus, .btn-outline-success.focus { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:active, .btn-outline-success.active, - .open > .btn-outline-success.dropdown-toggle { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:active, .btn-outline-success.active, + .open > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:active:hover, .btn-outline-success:active:focus, .btn-outline-success:active.focus, .btn-outline-success.active:hover, .btn-outline-success.active:focus, .btn-outline-success.active.focus, - .open > .btn-outline-success.dropdown-toggle:hover, - .open > .btn-outline-success.dropdown-toggle:focus, - .open > .btn-outline-success.dropdown-toggle.focus { - color: #fff; - background-color: #398439; - border-color: #2d672d; - } + .btn-outline-success:active:hover, .btn-outline-success:active:focus, .btn-outline-success:active.focus, .btn-outline-success.active:hover, .btn-outline-success.active:focus, .btn-outline-success.active.focus, + .open > .btn-outline-success.dropdown-toggle:hover, + .open > .btn-outline-success.dropdown-toggle:focus, + .open > .btn-outline-success.dropdown-toggle.focus { + color: #fff; + background-color: #398439; + border-color: #2d672d; + } - .btn-outline-success.disabled:focus, .btn-outline-success.disabled.focus, .btn-outline-success:disabled:focus, .btn-outline-success:disabled.focus { - border-color: #a3d7a3; - } + .btn-outline-success.disabled:focus, .btn-outline-success.disabled.focus, .btn-outline-success:disabled:focus, .btn-outline-success:disabled.focus { + border-color: #a3d7a3; + } - .btn-outline-success.disabled:hover, .btn-outline-success:disabled:hover { - border-color: #a3d7a3; - } + .btn-outline-success.disabled:hover, .btn-outline-success:disabled:hover { + border-color: #a3d7a3; + } .btn-outline-warning { - color: #f0ad4e; - background-image: none; - background-color: transparent; - border-color: #f0ad4e; + color: #f0ad4e; + background-image: none; + background-color: transparent; + border-color: #f0ad4e; } - .btn-outline-warning:hover { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:hover { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:focus, .btn-outline-warning.focus { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:focus, .btn-outline-warning.focus { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:active, .btn-outline-warning.active, - .open > .btn-outline-warning.dropdown-toggle { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:active, .btn-outline-warning.active, + .open > .btn-outline-warning.dropdown-toggle { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:active:hover, .btn-outline-warning:active:focus, .btn-outline-warning:active.focus, .btn-outline-warning.active:hover, .btn-outline-warning.active:focus, .btn-outline-warning.active.focus, - .open > .btn-outline-warning.dropdown-toggle:hover, - .open > .btn-outline-warning.dropdown-toggle:focus, - .open > .btn-outline-warning.dropdown-toggle.focus { - color: #fff; - background-color: #d58512; - border-color: #b06d0f; - } + .btn-outline-warning:active:hover, .btn-outline-warning:active:focus, .btn-outline-warning:active.focus, .btn-outline-warning.active:hover, .btn-outline-warning.active:focus, .btn-outline-warning.active.focus, + .open > .btn-outline-warning.dropdown-toggle:hover, + .open > .btn-outline-warning.dropdown-toggle:focus, + .open > .btn-outline-warning.dropdown-toggle.focus { + color: #fff; + background-color: #d58512; + border-color: #b06d0f; + } - .btn-outline-warning.disabled:focus, .btn-outline-warning.disabled.focus, .btn-outline-warning:disabled:focus, .btn-outline-warning:disabled.focus { - border-color: #f8d9ac; - } + .btn-outline-warning.disabled:focus, .btn-outline-warning.disabled.focus, .btn-outline-warning:disabled:focus, .btn-outline-warning:disabled.focus { + border-color: #f8d9ac; + } - .btn-outline-warning.disabled:hover, .btn-outline-warning:disabled:hover { - border-color: #f8d9ac; - } + .btn-outline-warning.disabled:hover, .btn-outline-warning:disabled:hover { + border-color: #f8d9ac; + } .btn-outline-danger { - color: #d9534f; - background-image: none; - background-color: transparent; - border-color: #d9534f; + color: #d9534f; + background-image: none; + background-color: transparent; + border-color: #d9534f; } - .btn-outline-danger:hover { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:hover { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:focus, .btn-outline-danger.focus { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:focus, .btn-outline-danger.focus { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:active, .btn-outline-danger.active, - .open > .btn-outline-danger.dropdown-toggle { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:active, .btn-outline-danger.active, + .open > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:active:hover, .btn-outline-danger:active:focus, .btn-outline-danger:active.focus, .btn-outline-danger.active:hover, .btn-outline-danger.active:focus, .btn-outline-danger.active.focus, - .open > .btn-outline-danger.dropdown-toggle:hover, - .open > .btn-outline-danger.dropdown-toggle:focus, - .open > .btn-outline-danger.dropdown-toggle.focus { - color: #fff; - background-color: #ac2925; - border-color: #8b211e; - } + .btn-outline-danger:active:hover, .btn-outline-danger:active:focus, .btn-outline-danger:active.focus, .btn-outline-danger.active:hover, .btn-outline-danger.active:focus, .btn-outline-danger.active.focus, + .open > .btn-outline-danger.dropdown-toggle:hover, + .open > .btn-outline-danger.dropdown-toggle:focus, + .open > .btn-outline-danger.dropdown-toggle.focus { + color: #fff; + background-color: #ac2925; + border-color: #8b211e; + } - .btn-outline-danger.disabled:focus, .btn-outline-danger.disabled.focus, .btn-outline-danger:disabled:focus, .btn-outline-danger:disabled.focus { - border-color: #eba5a3; - } + .btn-outline-danger.disabled:focus, .btn-outline-danger.disabled.focus, .btn-outline-danger:disabled:focus, .btn-outline-danger:disabled.focus { + border-color: #eba5a3; + } - .btn-outline-danger.disabled:hover, .btn-outline-danger:disabled:hover { - border-color: #eba5a3; - } + .btn-outline-danger.disabled:hover, .btn-outline-danger:disabled:hover { + border-color: #eba5a3; + } .btn-link { - font-weight: normal; - color: #214497; - border-radius: 0; + font-weight: normal; + color: #214497; + border-radius: 0; } - .btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled { - background-color: transparent; - } + .btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled { + background-color: transparent; + } - .btn-link, .btn-link:focus, .btn-link:active { - border-color: transparent; - } + .btn-link, .btn-link:focus, .btn-link:active { + border-color: transparent; + } - .btn-link:hover { - border-color: transparent; - } + .btn-link:hover { + border-color: transparent; + } - .btn-link:focus, .btn-link:hover { - color: #132858; - text-decoration: underline; - background-color: transparent; - } + .btn-link:focus, .btn-link:hover { + color: #132858; + text-decoration: underline; + background-color: transparent; + } - .btn-link:disabled:focus, .btn-link:disabled:hover { - color: #818a91; - text-decoration: none; - } + .btn-link:disabled:focus, .btn-link:disabled:hover { + color: #818a91; + text-decoration: none; + } .btn-lg, .btn-group-lg > .btn, .btn-group-lg > .action-button { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; - border-radius: 0.3rem; + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + border-radius: 0.3rem; } .btn-sm, .btn-group-sm > .btn, .btn-group-sm > .action-button { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; } .btn-block, .action-button { - display: block; - width: 100%; + display: block; + width: 100%; } - .btn-block + .btn-block, .action-button + .btn-block, .btn-block + .action-button, .action-button + .action-button { - margin-top: 0.5rem; - } + .btn-block + .btn-block, .action-button + .btn-block, .btn-block + .action-button, .action-button + .action-button { + margin-top: 0.5rem; + } input[type="submit"].btn-block, input[type="submit"].action-button, input[type="reset"].btn-block, input[type="reset"].action-button, input[type="button"].btn-block, input[type="button"].action-button { - width: 100%; + width: 100%; } .modal-open { - overflow: hidden; + overflow: hidden; } .modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - display: none; - overflow: hidden; - outline: 0; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; } - .modal.fade .modal-dialog { - transition: transform .3s ease-out; - transform: translate(0, -25%); - } + .modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0, -25%); + } - .modal.in .modal-dialog { - transform: translate(0, 0); - } + .modal.in .modal-dialog { + transform: translate(0, 0); + } .modal-open .modal { - overflow-x: hidden; - overflow-y: auto; + overflow-x: hidden; + overflow-y: auto; } .modal-dialog { - position: relative; - width: auto; - margin: 10px; + position: relative; + width: auto; + margin: 10px; } .modal-content { - position: relative; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; - outline: 0; + position: relative; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; } .modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; } - .modal-backdrop.fade { - opacity: 0; - } + .modal-backdrop.fade { + opacity: 0; + } - .modal-backdrop.in { - opacity: 0.5; - } + .modal-backdrop.in { + opacity: 0.5; + } .modal-header { - padding: 15px; - border-bottom: 1px solid #e5e5e5; + padding: 15px; + border-bottom: 1px solid #e5e5e5; } - .modal-header::after { - content: ""; - display: table; - clear: both; - } + .modal-header::after { + content: ""; + display: table; + clear: both; + } - .modal-header .close { - margin-top: -2px; - } + .modal-header .close { + margin-top: -2px; + } .modal-title { - margin: 0; - line-height: 1.5; + margin: 0; + line-height: 1.5; } .modal-body { - position: relative; - padding: 15px; + position: relative; + padding: 15px; } .modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; } - .modal-footer::after { - content: ""; - display: table; - clear: both; - } + .modal-footer::after { + content: ""; + display: table; + clear: both; + } .modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; } @media (min-width: 576px) { - .modal-dialog { - max-width: 600px; - margin: 30px auto; - } + .modal-dialog { + max-width: 600px; + margin: 30px auto; + } - .modal-sm { - max-width: 300px; - } + .modal-sm { + max-width: 300px; + } } @media (min-width: 992px) { - .modal-lg { - max-width: 900px; - } + .modal-lg { + max-width: 900px; + } } /*! @@ -1290,14 +1290,14 @@ input[type="button"].action-button { */ /*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */ html { - font-family: sans-serif; - line-height: 1.15; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + font-family: sans-serif; + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } body { - margin: 0; + margin: 0; } article, @@ -1312,114 +1312,114 @@ menu, nav, section, summary { - display: block; + display: block; } audio, canvas, progress, video { - display: inline-block; + display: inline-block; } - audio:not([controls]) { - display: none; - height: 0; - } + audio:not([controls]) { + display: none; + height: 0; + } progress { - vertical-align: baseline; + vertical-align: baseline; } template, [hidden] { - display: none; + display: none; } a { - background-color: transparent; - -webkit-text-decoration-skip: objects; + background-color: transparent; + -webkit-text-decoration-skip: objects; } - a:active, - a:hover { - outline-width: 0; - } + a:active, + a:hover { + outline-width: 0; + } abbr[title] { - border-bottom: none; - text-decoration: underline; - text-decoration: underline dotted; + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; } b, strong { - font-weight: inherit; + font-weight: inherit; } b, strong { - font-weight: bolder; + font-weight: bolder; } dfn { - font-style: italic; + font-style: italic; } h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } mark { - background-color: #ff0; - color: #000; + background-color: #ff0; + color: #000; } small { - font-size: 80%; + font-size: 80%; } sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sub { - bottom: -0.25em; + bottom: -0.25em; } sup { - top: -0.5em; + top: -0.5em; } img { - border-style: none; + border-style: none; } svg:not(:root) { - overflow: hidden; + overflow: hidden; } code, kbd, pre, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; + font-size: 1em; } figure { - margin: 1em 40px; + margin: 1em 40px; } hr { - box-sizing: content-box; - height: 0; - overflow: visible; + box-sizing: content-box; + height: 0; + overflow: visible; } button, @@ -1427,304 +1427,304 @@ input, optgroup, select, textarea { - font: inherit; - margin: 0; + font: inherit; + margin: 0; } optgroup { - font-weight: bold; + font-weight: bold; } button, input { - overflow: visible; + overflow: visible; } button, select { - text-transform: none; + text-transform: none; } button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; + -webkit-appearance: button; } - button::-moz-focus-inner, - [type="button"]::-moz-focus-inner, - [type="reset"]::-moz-focus-inner, - [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; - } + button::-moz-focus-inner, + [type="button"]::-moz-focus-inner, + [type="reset"]::-moz-focus-inner, + [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; + } - button:-moz-focusring, - [type="button"]:-moz-focusring, - [type="reset"]:-moz-focusring, - [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; - } + button:-moz-focusring, + [type="button"]:-moz-focusring, + [type="reset"]:-moz-focusring, + [type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; + } fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } legend { - box-sizing: border-box; - color: inherit; - display: table; - max-width: 100%; - padding: 0; - white-space: normal; + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; } textarea { - overflow: auto; + overflow: auto; } [type="checkbox"], [type="radio"] { - box-sizing: border-box; - padding: 0; + box-sizing: border-box; + padding: 0; } [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; + -webkit-appearance: textfield; + outline-offset: -2px; } - [type="search"]::-webkit-search-cancel-button, - [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; - } + [type="search"]::-webkit-search-cancel-button, + [type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + } ::-webkit-input-placeholder { - color: inherit; - opacity: 0.54; + color: inherit; + opacity: 0.54; } ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; + -webkit-appearance: button; + font: inherit; } @media print { - *, - *::before, - *::after, - *::first-letter, - p::first-line, - div::first-line, - blockquote::first-line, - li::first-line { - text-shadow: none !important; - box-shadow: none !important; - } + *, + *::before, + *::after, + *::first-letter, + p::first-line, + div::first-line, + blockquote::first-line, + li::first-line { + text-shadow: none !important; + box-shadow: none !important; + } - a, - a:visited { - text-decoration: underline; - } + a, + a:visited { + text-decoration: underline; + } - abbr[title]::after { - content: " (" attr(title) ")"; - } + abbr[title]::after { + content: " (" attr(title) ")"; + } - pre { - white-space: pre-wrap !important; - } + pre { + white-space: pre-wrap !important; + } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } - thead { - display: table-header-group; - } + thead { + display: table-header-group; + } - tr, - img { - page-break-inside: avoid; - } + tr, + img { + page-break-inside: avoid; + } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } - h2, - h3 { - page-break-after: avoid; - } + h2, + h3 { + page-break-after: avoid; + } - .navbar { - display: none; - } + .navbar { + display: none; + } - .btn > .caret, .action-button > .caret, - .dropup > .btn > .caret, - .dropup > .action-button > .caret { - border-top-color: #000 !important; - } + .btn > .caret, .action-button > .caret, + .dropup > .btn > .caret, + .dropup > .action-button > .caret { + border-top-color: #000 !important; + } - .tag { - border: 1px solid #000; - } + .tag { + border: 1px solid #000; + } - .table { - border-collapse: collapse !important; - } + .table { + border-collapse: collapse !important; + } - .table td, - .table th { - background-color: #fff !important; - } + .table td, + .table th { + background-color: #fff !important; + } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } } html { - box-sizing: border-box; + box-sizing: border-box; } *, *::before, *::after { - box-sizing: inherit; + box-sizing: inherit; } @-ms-viewport { - width: device-width; + width: device-width; } html { - font-size: 16px; - -ms-overflow-style: scrollbar; - -webkit-tap-highlight-color: transparent; + font-size: 16px; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; } body { - font-family: "Roboto", "Helvetica", sans-serif; - font-size: 1rem; - line-height: 1.5; - color: #373a3c; - background-color: #fff; + font-family: "Roboto", "Helvetica", sans-serif; + font-size: 1rem; + line-height: 1.5; + color: #373a3c; + background-color: #fff; } [tabindex="-1"]:focus { - outline: none !important; + outline: none !important; } h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: .5rem; + margin-top: 0; + margin-bottom: .5rem; } p { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } abbr[title], abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #818a91; + cursor: help; + border-bottom: 1px dotted #818a91; } address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; } ol, ul, dl { - margin-top: 0; - margin-bottom: 1rem; + margin-top: 0; + margin-bottom: 1rem; } - ol ol, - ul ul, - ol ul, - ul ol { - margin-bottom: 0; - } + ol ol, + ul ul, + ol ul, + ul ol { + margin-bottom: 0; + } dt { - font-weight: bold; + font-weight: bold; } dd { - margin-bottom: .5rem; - margin-left: 0; + margin-bottom: .5rem; + margin-left: 0; } blockquote { - margin: 0 0 1rem; + margin: 0 0 1rem; } a { - color: #214497; - text-decoration: none; + color: #214497; + text-decoration: none; } - a:focus, a:hover { - color: #132858; - text-decoration: underline; - } + a:focus, a:hover { + color: #132858; + text-decoration: underline; + } - a:focus { - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } + a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } - a:not([href]):not([tabindex]) { - color: inherit; - text-decoration: none; - } + a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; + } - a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { - color: inherit; - text-decoration: none; - } + a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { + color: inherit; + text-decoration: none; + } - a:not([href]):not([tabindex]):focus { - outline: none; - } + a:not([href]):not([tabindex]):focus { + outline: none; + } pre { - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; } figure { - margin: 0 0 1rem; + margin: 0 0 1rem; } img { - vertical-align: middle; + vertical-align: middle; } [role="button"] { - cursor: pointer; + cursor: pointer; } a, @@ -1736,1675 +1736,1675 @@ label, select, summary, textarea { - touch-action: manipulation; + touch-action: manipulation; } table { - border-collapse: collapse; - background-color: transparent; + border-collapse: collapse; + background-color: transparent; } caption { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - color: #818a91; - text-align: left; - caption-side: bottom; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #818a91; + text-align: left; + caption-side: bottom; } th { - text-align: left; + text-align: left; } label { - display: inline-block; - margin-bottom: .5rem; + display: inline-block; + margin-bottom: .5rem; } button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; } input, button, select, textarea { - line-height: inherit; + line-height: inherit; } - input[type="radio"]:disabled, - input[type="checkbox"]:disabled { - cursor: not-allowed; - } + input[type="radio"]:disabled, + input[type="checkbox"]:disabled { + cursor: not-allowed; + } - input[type="date"], - input[type="time"], - input[type="datetime-local"], - input[type="month"] { - -webkit-appearance: listbox; - } + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + -webkit-appearance: listbox; + } textarea { - resize: vertical; + resize: vertical; } fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; + min-width: 0; + padding: 0; + margin: 0; + border: 0; } legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: .5rem; - font-size: 1.5rem; - line-height: inherit; + display: block; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; } input[type="search"] { - -webkit-appearance: none; + -webkit-appearance: none; } output { - display: inline-block; + display: inline-block; } [hidden] { - display: none !important; + display: none !important; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { - margin-bottom: 0.5rem; - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit; + margin-bottom: 0.5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; } h1, .h1 { - font-size: 2.5rem; + font-size: 2.5rem; } h2, .h2 { - font-size: 2rem; + font-size: 2rem; } h3, .h3 { - font-size: 1.75rem; + font-size: 1.75rem; } h4, .h4 { - font-size: 1.5rem; + font-size: 1.5rem; } h5, .h5 { - font-size: 1.25rem; + font-size: 1.25rem; } h6, .h6 { - font-size: 1rem; + font-size: 1rem; } .lead { - font-size: 1.25rem; - font-weight: 300; + font-size: 1.25rem; + font-weight: 300; } .display-1 { - font-size: 6rem; - font-weight: 300; + font-size: 6rem; + font-weight: 300; } .display-2 { - font-size: 5.5rem; - font-weight: 300; + font-size: 5.5rem; + font-weight: 300; } .display-3 { - font-size: 4.5rem; - font-weight: 300; + font-size: 4.5rem; + font-weight: 300; } .display-4 { - font-size: 3.5rem; - font-weight: 300; + font-size: 3.5rem; + font-weight: 300; } hr { - margin-top: 1rem; - margin-bottom: 1rem; - border: 0; - border-top: 1px solid rgba(0, 0, 0, 0.1); + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); } small, .small { - font-size: 80%; - font-weight: normal; + font-size: 80%; + font-weight: normal; } mark, .mark { - padding: 0.2em; - background-color: #fcf8e3; + padding: 0.2em; + background-color: #fcf8e3; } .list-unstyled { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } .list-inline { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } .list-inline-item { - display: inline-block; + display: inline-block; } - .list-inline-item:not(:last-child) { - margin-right: 5px; - } + .list-inline-item:not(:last-child) { + margin-right: 5px; + } .initialism { - font-size: 90%; - text-transform: uppercase; + font-size: 90%; + text-transform: uppercase; } .blockquote { - padding: 0.5rem 1rem; - margin-bottom: 1rem; - font-size: 1.25rem; - border-left: 0.25rem solid #eceeef; + padding: 0.5rem 1rem; + margin-bottom: 1rem; + font-size: 1.25rem; + border-left: 0.25rem solid #eceeef; } .blockquote-footer { - display: block; - font-size: 80%; - color: #818a91; + display: block; + font-size: 80%; + color: #818a91; } - .blockquote-footer::before { - content: "\2014 \A0"; - } + .blockquote-footer::before { + content: "\2014 \A0"; + } .blockquote-reverse { - padding-right: 1rem; - padding-left: 0; - text-align: right; - border-right: 0.25rem solid #eceeef; - border-left: 0; + padding-right: 1rem; + padding-left: 0; + text-align: right; + border-right: 0.25rem solid #eceeef; + border-left: 0; } - .blockquote-reverse .blockquote-footer::before { - content: ""; - } + .blockquote-reverse .blockquote-footer::before { + content: ""; + } - .blockquote-reverse .blockquote-footer::after { - content: "\A0 \2014"; - } + .blockquote-reverse .blockquote-footer::after { + content: "\A0 \2014"; + } dl.row > dd + dt { - clear: left; + clear: left; } .img-fluid, .carousel-inner > .carousel-item > img, .carousel-inner > .carousel-item > a > img { - max-width: 100%; - height: auto; + max-width: 100%; + height: auto; } .img-thumbnail { - padding: 0.25rem; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 0.25rem; - transition: all .2s ease-in-out; - max-width: 100%; - height: auto; + padding: 0.25rem; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0.25rem; + transition: all .2s ease-in-out; + max-width: 100%; + height: auto; } .figure { - display: inline-block; + display: inline-block; } .figure-img { - margin-bottom: 0.5rem; - line-height: 1; + margin-bottom: 0.5rem; + line-height: 1; } .figure-caption { - font-size: 90%; - color: #818a91; + font-size: 90%; + color: #818a91; } code, kbd, pre, samp { - font-family: "Roboto Mono", monospace; + font-family: "Roboto Mono", monospace; } code { - padding: 0.2rem 0.4rem; - font-size: 90%; - color: #bd4147; - background-color: #f7f7f9; - border-radius: 0.25rem; + padding: 0.2rem 0.4rem; + font-size: 90%; + color: #bd4147; + background-color: #f7f7f9; + border-radius: 0.25rem; } kbd { - padding: 0.2rem 0.4rem; - font-size: 90%; - color: #fff; - background-color: #333; - border-radius: 0.2rem; + padding: 0.2rem 0.4rem; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 0.2rem; } - kbd kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - } + kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + } pre { - display: block; - margin-top: 0; - margin-bottom: 1rem; - font-size: 90%; - color: #373a3c; + display: block; + margin-top: 0; + margin-bottom: 1rem; + font-size: 90%; + color: #373a3c; } - pre code { - padding: 0; - font-size: inherit; - color: inherit; - background-color: transparent; - border-radius: 0; - } + pre code { + padding: 0; + font-size: inherit; + color: inherit; + background-color: transparent; + border-radius: 0; + } .pre-scrollable { - max-height: 340px; - overflow-y: scroll; + max-height: 340px; + overflow-y: scroll; } .container { - margin-left: auto; - margin-right: auto; - padding-left: 15px; - padding-right: 15px; + margin-left: auto; + margin-right: auto; + padding-left: 15px; + padding-right: 15px; } - .container::after { - content: ""; - display: table; - clear: both; - } + .container::after { + content: ""; + display: table; + clear: both; + } @media (min-width: 576px) { - .container { - width: 540px; - max-width: 100%; - } + .container { + width: 540px; + max-width: 100%; + } } @media (min-width: 768px) { - .container { - width: 720px; - max-width: 100%; - } + .container { + width: 720px; + max-width: 100%; + } } @media (min-width: 992px) { - .container { - width: 960px; - max-width: 100%; - } + .container { + width: 960px; + max-width: 100%; + } } @media (min-width: 1200px) { - .container { - width: 1140px; - max-width: 100%; - } + .container { + width: 1140px; + max-width: 100%; + } } .container-fluid { - margin-left: auto; - margin-right: auto; - padding-left: 15px; - padding-right: 15px; + margin-left: auto; + margin-right: auto; + padding-left: 15px; + padding-right: 15px; } - .container-fluid::after { - content: ""; - display: table; - clear: both; - } + .container-fluid::after { + content: ""; + display: table; + clear: both; + } .row { - margin-right: -15px; - margin-left: -15px; + margin-right: -15px; + margin-left: -15px; } - .row::after { - content: ""; - display: table; - clear: both; - } + .row::after { + content: ""; + display: table; + clear: both; + } @media (min-width: 576px) { - .row { - margin-right: -15px; - margin-left: -15px; - } + .row { + margin-right: -15px; + margin-left: -15px; + } } @media (min-width: 768px) { - .row { - margin-right: -15px; - margin-left: -15px; - } + .row { + margin-right: -15px; + margin-left: -15px; + } } @media (min-width: 992px) { - .row { - margin-right: -15px; - margin-left: -15px; - } + .row { + margin-right: -15px; + margin-left: -15px; + } } @media (min-width: 1200px) { - .row { - margin-right: -15px; - margin-left: -15px; - } + .row { + margin-right: -15px; + margin-left: -15px; + } } .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; } @media (min-width: 576px) { - .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { - padding-right: 15px; - padding-left: 15px; - } + .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + padding-right: 15px; + padding-left: 15px; + } } @media (min-width: 768px) { - .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { - padding-right: 15px; - padding-left: 15px; - } + .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + padding-right: 15px; + padding-left: 15px; + } } @media (min-width: 992px) { - .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { - padding-right: 15px; - padding-left: 15px; - } + .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + padding-right: 15px; + padding-left: 15px; + } } @media (min-width: 1200px) { - .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { - padding-right: 15px; - padding-left: 15px; - } + .col-xs, .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, .col-sm, .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, .col-md, .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, .col-lg, .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, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { + padding-right: 15px; + padding-left: 15px; + } } .col-xs-1 { - float: left; - width: 8.33333%; + float: left; + width: 8.33333%; } .col-xs-2 { - float: left; - width: 16.66667%; + float: left; + width: 16.66667%; } .col-xs-3 { - float: left; - width: 25%; + float: left; + width: 25%; } .col-xs-4 { - float: left; - width: 33.33333%; + float: left; + width: 33.33333%; } .col-xs-5 { - float: left; - width: 41.66667%; + float: left; + width: 41.66667%; } .col-xs-6 { - float: left; - width: 50%; + float: left; + width: 50%; } .col-xs-7 { - float: left; - width: 58.33333%; + float: left; + width: 58.33333%; } .col-xs-8 { - float: left; - width: 66.66667%; + float: left; + width: 66.66667%; } .col-xs-9 { - float: left; - width: 75%; + float: left; + width: 75%; } .col-xs-10 { - float: left; - width: 83.33333%; + float: left; + width: 83.33333%; } .col-xs-11 { - float: left; - width: 91.66667%; + float: left; + width: 91.66667%; } .col-xs-12 { - float: left; - width: 100%; + float: left; + width: 100%; } .pull-xs-0 { - right: auto; + right: auto; } .pull-xs-1 { - right: 8.33333%; + right: 8.33333%; } .pull-xs-2 { - right: 16.66667%; + right: 16.66667%; } .pull-xs-3 { - right: 25%; + right: 25%; } .pull-xs-4 { - right: 33.33333%; + right: 33.33333%; } .pull-xs-5 { - right: 41.66667%; + right: 41.66667%; } .pull-xs-6 { - right: 50%; + right: 50%; } .pull-xs-7 { - right: 58.33333%; + right: 58.33333%; } .pull-xs-8 { - right: 66.66667%; + right: 66.66667%; } .pull-xs-9 { - right: 75%; + right: 75%; } .pull-xs-10 { - right: 83.33333%; + right: 83.33333%; } .pull-xs-11 { - right: 91.66667%; + right: 91.66667%; } .pull-xs-12 { - right: 100%; + right: 100%; } .push-xs-0 { - left: auto; + left: auto; } .push-xs-1 { - left: 8.33333%; + left: 8.33333%; } .push-xs-2 { - left: 16.66667%; + left: 16.66667%; } .push-xs-3 { - left: 25%; + left: 25%; } .push-xs-4 { - left: 33.33333%; + left: 33.33333%; } .push-xs-5 { - left: 41.66667%; + left: 41.66667%; } .push-xs-6 { - left: 50%; + left: 50%; } .push-xs-7 { - left: 58.33333%; + left: 58.33333%; } .push-xs-8 { - left: 66.66667%; + left: 66.66667%; } .push-xs-9 { - left: 75%; + left: 75%; } .push-xs-10 { - left: 83.33333%; + left: 83.33333%; } .push-xs-11 { - left: 91.66667%; + left: 91.66667%; } .push-xs-12 { - left: 100%; + left: 100%; } .offset-xs-1 { - margin-left: 8.33333%; + margin-left: 8.33333%; } .offset-xs-2 { - margin-left: 16.66667%; + margin-left: 16.66667%; } .offset-xs-3 { - margin-left: 25%; + margin-left: 25%; } .offset-xs-4 { - margin-left: 33.33333%; + margin-left: 33.33333%; } .offset-xs-5 { - margin-left: 41.66667%; + margin-left: 41.66667%; } .offset-xs-6 { - margin-left: 50%; + margin-left: 50%; } .offset-xs-7 { - margin-left: 58.33333%; + margin-left: 58.33333%; } .offset-xs-8 { - margin-left: 66.66667%; + margin-left: 66.66667%; } .offset-xs-9 { - margin-left: 75%; + margin-left: 75%; } .offset-xs-10 { - margin-left: 83.33333%; + margin-left: 83.33333%; } .offset-xs-11 { - margin-left: 91.66667%; + margin-left: 91.66667%; } @media (min-width: 576px) { - .col-sm-1 { - float: left; - width: 8.33333%; - } + .col-sm-1 { + float: left; + width: 8.33333%; + } - .col-sm-2 { - float: left; - width: 16.66667%; - } + .col-sm-2 { + float: left; + width: 16.66667%; + } - .col-sm-3 { - float: left; - width: 25%; - } + .col-sm-3 { + float: left; + width: 25%; + } - .col-sm-4 { - float: left; - width: 33.33333%; - } + .col-sm-4 { + float: left; + width: 33.33333%; + } - .col-sm-5 { - float: left; - width: 41.66667%; - } + .col-sm-5 { + float: left; + width: 41.66667%; + } - .col-sm-6 { - float: left; - width: 50%; - } + .col-sm-6 { + float: left; + width: 50%; + } - .col-sm-7 { - float: left; - width: 58.33333%; - } + .col-sm-7 { + float: left; + width: 58.33333%; + } - .col-sm-8 { - float: left; - width: 66.66667%; - } + .col-sm-8 { + float: left; + width: 66.66667%; + } - .col-sm-9 { - float: left; - width: 75%; - } + .col-sm-9 { + float: left; + width: 75%; + } - .col-sm-10 { - float: left; - width: 83.33333%; - } + .col-sm-10 { + float: left; + width: 83.33333%; + } - .col-sm-11 { - float: left; - width: 91.66667%; - } + .col-sm-11 { + float: left; + width: 91.66667%; + } - .col-sm-12 { - float: left; - width: 100%; - } + .col-sm-12 { + float: left; + width: 100%; + } - .pull-sm-0 { - right: auto; - } + .pull-sm-0 { + right: auto; + } - .pull-sm-1 { - right: 8.33333%; - } + .pull-sm-1 { + right: 8.33333%; + } - .pull-sm-2 { - right: 16.66667%; - } + .pull-sm-2 { + right: 16.66667%; + } - .pull-sm-3 { - right: 25%; - } + .pull-sm-3 { + right: 25%; + } - .pull-sm-4 { - right: 33.33333%; - } + .pull-sm-4 { + right: 33.33333%; + } - .pull-sm-5 { - right: 41.66667%; - } + .pull-sm-5 { + right: 41.66667%; + } - .pull-sm-6 { - right: 50%; - } + .pull-sm-6 { + right: 50%; + } - .pull-sm-7 { - right: 58.33333%; - } + .pull-sm-7 { + right: 58.33333%; + } - .pull-sm-8 { - right: 66.66667%; - } + .pull-sm-8 { + right: 66.66667%; + } - .pull-sm-9 { - right: 75%; - } + .pull-sm-9 { + right: 75%; + } - .pull-sm-10 { - right: 83.33333%; - } + .pull-sm-10 { + right: 83.33333%; + } - .pull-sm-11 { - right: 91.66667%; - } + .pull-sm-11 { + right: 91.66667%; + } - .pull-sm-12 { - right: 100%; - } + .pull-sm-12 { + right: 100%; + } - .push-sm-0 { - left: auto; - } + .push-sm-0 { + left: auto; + } - .push-sm-1 { - left: 8.33333%; - } + .push-sm-1 { + left: 8.33333%; + } - .push-sm-2 { - left: 16.66667%; - } + .push-sm-2 { + left: 16.66667%; + } - .push-sm-3 { - left: 25%; - } + .push-sm-3 { + left: 25%; + } - .push-sm-4 { - left: 33.33333%; - } + .push-sm-4 { + left: 33.33333%; + } - .push-sm-5 { - left: 41.66667%; - } + .push-sm-5 { + left: 41.66667%; + } - .push-sm-6 { - left: 50%; - } + .push-sm-6 { + left: 50%; + } - .push-sm-7 { - left: 58.33333%; - } + .push-sm-7 { + left: 58.33333%; + } - .push-sm-8 { - left: 66.66667%; - } + .push-sm-8 { + left: 66.66667%; + } - .push-sm-9 { - left: 75%; - } + .push-sm-9 { + left: 75%; + } - .push-sm-10 { - left: 83.33333%; - } + .push-sm-10 { + left: 83.33333%; + } - .push-sm-11 { - left: 91.66667%; - } + .push-sm-11 { + left: 91.66667%; + } - .push-sm-12 { - left: 100%; - } + .push-sm-12 { + left: 100%; + } - .offset-sm-0 { - margin-left: 0%; - } + .offset-sm-0 { + margin-left: 0%; + } - .offset-sm-1 { - margin-left: 8.33333%; - } + .offset-sm-1 { + margin-left: 8.33333%; + } - .offset-sm-2 { - margin-left: 16.66667%; - } + .offset-sm-2 { + margin-left: 16.66667%; + } - .offset-sm-3 { - margin-left: 25%; - } + .offset-sm-3 { + margin-left: 25%; + } - .offset-sm-4 { - margin-left: 33.33333%; - } + .offset-sm-4 { + margin-left: 33.33333%; + } - .offset-sm-5 { - margin-left: 41.66667%; - } + .offset-sm-5 { + margin-left: 41.66667%; + } - .offset-sm-6 { - margin-left: 50%; - } + .offset-sm-6 { + margin-left: 50%; + } - .offset-sm-7 { - margin-left: 58.33333%; - } + .offset-sm-7 { + margin-left: 58.33333%; + } - .offset-sm-8 { - margin-left: 66.66667%; - } + .offset-sm-8 { + margin-left: 66.66667%; + } - .offset-sm-9 { - margin-left: 75%; - } + .offset-sm-9 { + margin-left: 75%; + } - .offset-sm-10 { - margin-left: 83.33333%; - } + .offset-sm-10 { + margin-left: 83.33333%; + } - .offset-sm-11 { - margin-left: 91.66667%; - } + .offset-sm-11 { + margin-left: 91.66667%; + } } @media (min-width: 768px) { - .col-md-1 { - float: left; - width: 8.33333%; - } + .col-md-1 { + float: left; + width: 8.33333%; + } - .col-md-2 { - float: left; - width: 16.66667%; - } + .col-md-2 { + float: left; + width: 16.66667%; + } - .col-md-3 { - float: left; - width: 25%; - } + .col-md-3 { + float: left; + width: 25%; + } - .col-md-4 { - float: left; - width: 33.33333%; - } + .col-md-4 { + float: left; + width: 33.33333%; + } - .col-md-5 { - float: left; - width: 41.66667%; - } + .col-md-5 { + float: left; + width: 41.66667%; + } - .col-md-6 { - float: left; - width: 50%; - } + .col-md-6 { + float: left; + width: 50%; + } - .col-md-7 { - float: left; - width: 58.33333%; - } + .col-md-7 { + float: left; + width: 58.33333%; + } - .col-md-8 { - float: left; - width: 66.66667%; - } + .col-md-8 { + float: left; + width: 66.66667%; + } - .col-md-9 { - float: left; - width: 75%; - } + .col-md-9 { + float: left; + width: 75%; + } - .col-md-10 { - float: left; - width: 83.33333%; - } + .col-md-10 { + float: left; + width: 83.33333%; + } - .col-md-11 { - float: left; - width: 91.66667%; - } + .col-md-11 { + float: left; + width: 91.66667%; + } - .col-md-12 { - float: left; - width: 100%; - } + .col-md-12 { + float: left; + width: 100%; + } - .pull-md-0 { - right: auto; - } + .pull-md-0 { + right: auto; + } - .pull-md-1 { - right: 8.33333%; - } + .pull-md-1 { + right: 8.33333%; + } - .pull-md-2 { - right: 16.66667%; - } + .pull-md-2 { + right: 16.66667%; + } - .pull-md-3 { - right: 25%; - } + .pull-md-3 { + right: 25%; + } - .pull-md-4 { - right: 33.33333%; - } + .pull-md-4 { + right: 33.33333%; + } - .pull-md-5 { - right: 41.66667%; - } + .pull-md-5 { + right: 41.66667%; + } - .pull-md-6 { - right: 50%; - } + .pull-md-6 { + right: 50%; + } - .pull-md-7 { - right: 58.33333%; - } + .pull-md-7 { + right: 58.33333%; + } - .pull-md-8 { - right: 66.66667%; - } + .pull-md-8 { + right: 66.66667%; + } - .pull-md-9 { - right: 75%; - } + .pull-md-9 { + right: 75%; + } - .pull-md-10 { - right: 83.33333%; - } + .pull-md-10 { + right: 83.33333%; + } - .pull-md-11 { - right: 91.66667%; - } + .pull-md-11 { + right: 91.66667%; + } - .pull-md-12 { - right: 100%; - } + .pull-md-12 { + right: 100%; + } - .push-md-0 { - left: auto; - } + .push-md-0 { + left: auto; + } - .push-md-1 { - left: 8.33333%; - } + .push-md-1 { + left: 8.33333%; + } - .push-md-2 { - left: 16.66667%; - } + .push-md-2 { + left: 16.66667%; + } - .push-md-3 { - left: 25%; - } + .push-md-3 { + left: 25%; + } - .push-md-4 { - left: 33.33333%; - } + .push-md-4 { + left: 33.33333%; + } - .push-md-5 { - left: 41.66667%; - } + .push-md-5 { + left: 41.66667%; + } - .push-md-6 { - left: 50%; - } + .push-md-6 { + left: 50%; + } - .push-md-7 { - left: 58.33333%; - } + .push-md-7 { + left: 58.33333%; + } - .push-md-8 { - left: 66.66667%; - } + .push-md-8 { + left: 66.66667%; + } - .push-md-9 { - left: 75%; - } + .push-md-9 { + left: 75%; + } - .push-md-10 { - left: 83.33333%; - } + .push-md-10 { + left: 83.33333%; + } - .push-md-11 { - left: 91.66667%; - } + .push-md-11 { + left: 91.66667%; + } - .push-md-12 { - left: 100%; - } + .push-md-12 { + left: 100%; + } - .offset-md-0 { - margin-left: 0%; - } + .offset-md-0 { + margin-left: 0%; + } - .offset-md-1 { - margin-left: 8.33333%; - } + .offset-md-1 { + margin-left: 8.33333%; + } - .offset-md-2 { - margin-left: 16.66667%; - } + .offset-md-2 { + margin-left: 16.66667%; + } - .offset-md-3 { - margin-left: 25%; - } + .offset-md-3 { + margin-left: 25%; + } - .offset-md-4 { - margin-left: 33.33333%; - } + .offset-md-4 { + margin-left: 33.33333%; + } - .offset-md-5 { - margin-left: 41.66667%; - } + .offset-md-5 { + margin-left: 41.66667%; + } - .offset-md-6 { - margin-left: 50%; - } + .offset-md-6 { + margin-left: 50%; + } - .offset-md-7 { - margin-left: 58.33333%; - } + .offset-md-7 { + margin-left: 58.33333%; + } - .offset-md-8 { - margin-left: 66.66667%; - } + .offset-md-8 { + margin-left: 66.66667%; + } - .offset-md-9 { - margin-left: 75%; - } + .offset-md-9 { + margin-left: 75%; + } - .offset-md-10 { - margin-left: 83.33333%; - } + .offset-md-10 { + margin-left: 83.33333%; + } - .offset-md-11 { - margin-left: 91.66667%; - } + .offset-md-11 { + margin-left: 91.66667%; + } } @media (min-width: 992px) { - .col-lg-1 { - float: left; - width: 8.33333%; - } + .col-lg-1 { + float: left; + width: 8.33333%; + } - .col-lg-2 { - float: left; - width: 16.66667%; - } + .col-lg-2 { + float: left; + width: 16.66667%; + } - .col-lg-3 { - float: left; - width: 25%; - } + .col-lg-3 { + float: left; + width: 25%; + } - .col-lg-4 { - float: left; - width: 33.33333%; - } + .col-lg-4 { + float: left; + width: 33.33333%; + } - .col-lg-5 { - float: left; - width: 41.66667%; - } + .col-lg-5 { + float: left; + width: 41.66667%; + } - .col-lg-6 { - float: left; - width: 50%; - } + .col-lg-6 { + float: left; + width: 50%; + } - .col-lg-7 { - float: left; - width: 58.33333%; - } + .col-lg-7 { + float: left; + width: 58.33333%; + } - .col-lg-8 { - float: left; - width: 66.66667%; - } + .col-lg-8 { + float: left; + width: 66.66667%; + } - .col-lg-9 { - float: left; - width: 75%; - } + .col-lg-9 { + float: left; + width: 75%; + } - .col-lg-10 { - float: left; - width: 83.33333%; - } + .col-lg-10 { + float: left; + width: 83.33333%; + } - .col-lg-11 { - float: left; - width: 91.66667%; - } + .col-lg-11 { + float: left; + width: 91.66667%; + } - .col-lg-12 { - float: left; - width: 100%; - } + .col-lg-12 { + float: left; + width: 100%; + } - .pull-lg-0 { - right: auto; - } + .pull-lg-0 { + right: auto; + } - .pull-lg-1 { - right: 8.33333%; - } + .pull-lg-1 { + right: 8.33333%; + } - .pull-lg-2 { - right: 16.66667%; - } + .pull-lg-2 { + right: 16.66667%; + } - .pull-lg-3 { - right: 25%; - } + .pull-lg-3 { + right: 25%; + } - .pull-lg-4 { - right: 33.33333%; - } + .pull-lg-4 { + right: 33.33333%; + } - .pull-lg-5 { - right: 41.66667%; - } + .pull-lg-5 { + right: 41.66667%; + } - .pull-lg-6 { - right: 50%; - } + .pull-lg-6 { + right: 50%; + } - .pull-lg-7 { - right: 58.33333%; - } + .pull-lg-7 { + right: 58.33333%; + } - .pull-lg-8 { - right: 66.66667%; - } + .pull-lg-8 { + right: 66.66667%; + } - .pull-lg-9 { - right: 75%; - } + .pull-lg-9 { + right: 75%; + } - .pull-lg-10 { - right: 83.33333%; - } + .pull-lg-10 { + right: 83.33333%; + } - .pull-lg-11 { - right: 91.66667%; - } + .pull-lg-11 { + right: 91.66667%; + } - .pull-lg-12 { - right: 100%; - } + .pull-lg-12 { + right: 100%; + } - .push-lg-0 { - left: auto; - } + .push-lg-0 { + left: auto; + } - .push-lg-1 { - left: 8.33333%; - } + .push-lg-1 { + left: 8.33333%; + } - .push-lg-2 { - left: 16.66667%; - } + .push-lg-2 { + left: 16.66667%; + } - .push-lg-3 { - left: 25%; - } + .push-lg-3 { + left: 25%; + } - .push-lg-4 { - left: 33.33333%; - } + .push-lg-4 { + left: 33.33333%; + } - .push-lg-5 { - left: 41.66667%; - } + .push-lg-5 { + left: 41.66667%; + } - .push-lg-6 { - left: 50%; - } + .push-lg-6 { + left: 50%; + } - .push-lg-7 { - left: 58.33333%; - } + .push-lg-7 { + left: 58.33333%; + } - .push-lg-8 { - left: 66.66667%; - } + .push-lg-8 { + left: 66.66667%; + } - .push-lg-9 { - left: 75%; - } + .push-lg-9 { + left: 75%; + } - .push-lg-10 { - left: 83.33333%; - } + .push-lg-10 { + left: 83.33333%; + } - .push-lg-11 { - left: 91.66667%; - } + .push-lg-11 { + left: 91.66667%; + } - .push-lg-12 { - left: 100%; - } + .push-lg-12 { + left: 100%; + } - .offset-lg-0 { - margin-left: 0%; - } + .offset-lg-0 { + margin-left: 0%; + } - .offset-lg-1 { - margin-left: 8.33333%; - } + .offset-lg-1 { + margin-left: 8.33333%; + } - .offset-lg-2 { - margin-left: 16.66667%; - } + .offset-lg-2 { + margin-left: 16.66667%; + } - .offset-lg-3 { - margin-left: 25%; - } + .offset-lg-3 { + margin-left: 25%; + } - .offset-lg-4 { - margin-left: 33.33333%; - } + .offset-lg-4 { + margin-left: 33.33333%; + } - .offset-lg-5 { - margin-left: 41.66667%; - } + .offset-lg-5 { + margin-left: 41.66667%; + } - .offset-lg-6 { - margin-left: 50%; - } + .offset-lg-6 { + margin-left: 50%; + } - .offset-lg-7 { - margin-left: 58.33333%; - } + .offset-lg-7 { + margin-left: 58.33333%; + } - .offset-lg-8 { - margin-left: 66.66667%; - } + .offset-lg-8 { + margin-left: 66.66667%; + } - .offset-lg-9 { - margin-left: 75%; - } + .offset-lg-9 { + margin-left: 75%; + } - .offset-lg-10 { - margin-left: 83.33333%; - } + .offset-lg-10 { + margin-left: 83.33333%; + } - .offset-lg-11 { - margin-left: 91.66667%; - } + .offset-lg-11 { + margin-left: 91.66667%; + } } @media (min-width: 1200px) { - .col-xl-1 { - float: left; - width: 8.33333%; - } + .col-xl-1 { + float: left; + width: 8.33333%; + } - .col-xl-2 { - float: left; - width: 16.66667%; - } + .col-xl-2 { + float: left; + width: 16.66667%; + } - .col-xl-3 { - float: left; - width: 25%; - } + .col-xl-3 { + float: left; + width: 25%; + } - .col-xl-4 { - float: left; - width: 33.33333%; - } + .col-xl-4 { + float: left; + width: 33.33333%; + } - .col-xl-5 { - float: left; - width: 41.66667%; - } + .col-xl-5 { + float: left; + width: 41.66667%; + } - .col-xl-6 { - float: left; - width: 50%; - } + .col-xl-6 { + float: left; + width: 50%; + } - .col-xl-7 { - float: left; - width: 58.33333%; - } + .col-xl-7 { + float: left; + width: 58.33333%; + } - .col-xl-8 { - float: left; - width: 66.66667%; - } + .col-xl-8 { + float: left; + width: 66.66667%; + } - .col-xl-9 { - float: left; - width: 75%; - } + .col-xl-9 { + float: left; + width: 75%; + } - .col-xl-10 { - float: left; - width: 83.33333%; - } + .col-xl-10 { + float: left; + width: 83.33333%; + } - .col-xl-11 { - float: left; - width: 91.66667%; - } + .col-xl-11 { + float: left; + width: 91.66667%; + } - .col-xl-12 { - float: left; - width: 100%; - } + .col-xl-12 { + float: left; + width: 100%; + } - .pull-xl-0 { - right: auto; - } + .pull-xl-0 { + right: auto; + } - .pull-xl-1 { - right: 8.33333%; - } + .pull-xl-1 { + right: 8.33333%; + } - .pull-xl-2 { - right: 16.66667%; - } + .pull-xl-2 { + right: 16.66667%; + } - .pull-xl-3 { - right: 25%; - } + .pull-xl-3 { + right: 25%; + } - .pull-xl-4 { - right: 33.33333%; - } + .pull-xl-4 { + right: 33.33333%; + } - .pull-xl-5 { - right: 41.66667%; - } + .pull-xl-5 { + right: 41.66667%; + } - .pull-xl-6 { - right: 50%; - } + .pull-xl-6 { + right: 50%; + } - .pull-xl-7 { - right: 58.33333%; - } + .pull-xl-7 { + right: 58.33333%; + } - .pull-xl-8 { - right: 66.66667%; - } + .pull-xl-8 { + right: 66.66667%; + } - .pull-xl-9 { - right: 75%; - } + .pull-xl-9 { + right: 75%; + } - .pull-xl-10 { - right: 83.33333%; - } + .pull-xl-10 { + right: 83.33333%; + } - .pull-xl-11 { - right: 91.66667%; - } + .pull-xl-11 { + right: 91.66667%; + } - .pull-xl-12 { - right: 100%; - } + .pull-xl-12 { + right: 100%; + } - .push-xl-0 { - left: auto; - } + .push-xl-0 { + left: auto; + } - .push-xl-1 { - left: 8.33333%; - } + .push-xl-1 { + left: 8.33333%; + } - .push-xl-2 { - left: 16.66667%; - } + .push-xl-2 { + left: 16.66667%; + } - .push-xl-3 { - left: 25%; - } + .push-xl-3 { + left: 25%; + } - .push-xl-4 { - left: 33.33333%; - } + .push-xl-4 { + left: 33.33333%; + } - .push-xl-5 { - left: 41.66667%; - } + .push-xl-5 { + left: 41.66667%; + } - .push-xl-6 { - left: 50%; - } + .push-xl-6 { + left: 50%; + } - .push-xl-7 { - left: 58.33333%; - } + .push-xl-7 { + left: 58.33333%; + } - .push-xl-8 { - left: 66.66667%; - } + .push-xl-8 { + left: 66.66667%; + } - .push-xl-9 { - left: 75%; - } + .push-xl-9 { + left: 75%; + } - .push-xl-10 { - left: 83.33333%; - } + .push-xl-10 { + left: 83.33333%; + } - .push-xl-11 { - left: 91.66667%; - } + .push-xl-11 { + left: 91.66667%; + } - .push-xl-12 { - left: 100%; - } + .push-xl-12 { + left: 100%; + } - .offset-xl-0 { - margin-left: 0%; - } + .offset-xl-0 { + margin-left: 0%; + } - .offset-xl-1 { - margin-left: 8.33333%; - } + .offset-xl-1 { + margin-left: 8.33333%; + } - .offset-xl-2 { - margin-left: 16.66667%; - } + .offset-xl-2 { + margin-left: 16.66667%; + } - .offset-xl-3 { - margin-left: 25%; - } + .offset-xl-3 { + margin-left: 25%; + } - .offset-xl-4 { - margin-left: 33.33333%; - } + .offset-xl-4 { + margin-left: 33.33333%; + } - .offset-xl-5 { - margin-left: 41.66667%; - } + .offset-xl-5 { + margin-left: 41.66667%; + } - .offset-xl-6 { - margin-left: 50%; - } + .offset-xl-6 { + margin-left: 50%; + } - .offset-xl-7 { - margin-left: 58.33333%; - } + .offset-xl-7 { + margin-left: 58.33333%; + } - .offset-xl-8 { - margin-left: 66.66667%; - } + .offset-xl-8 { + margin-left: 66.66667%; + } - .offset-xl-9 { - margin-left: 75%; - } + .offset-xl-9 { + margin-left: 75%; + } - .offset-xl-10 { - margin-left: 83.33333%; - } + .offset-xl-10 { + margin-left: 83.33333%; + } - .offset-xl-11 { - margin-left: 91.66667%; - } + .offset-xl-11 { + margin-left: 91.66667%; + } } .table { - width: 100%; - max-width: 100%; - margin-bottom: 1rem; + width: 100%; + max-width: 100%; + margin-bottom: 1rem; } - .table th, - .table td { - padding: 0.75rem; - vertical-align: top; - border-top: 1px solid #eceeef; - } + .table th, + .table td { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #eceeef; + } - .table thead th { - vertical-align: bottom; - border-bottom: 2px solid #eceeef; - } + .table thead th { + vertical-align: bottom; + border-bottom: 2px solid #eceeef; + } - .table tbody + tbody { - border-top: 2px solid #eceeef; - } + .table tbody + tbody { + border-top: 2px solid #eceeef; + } - .table .table { - background-color: #fff; - } + .table .table { + background-color: #fff; + } .table-sm th, .table-sm td { - padding: 0.3rem; + padding: 0.3rem; } .table-bordered { - border: 1px solid #eceeef; + border: 1px solid #eceeef; } - .table-bordered th, - .table-bordered td { - border: 1px solid #eceeef; - } + .table-bordered th, + .table-bordered td { + border: 1px solid #eceeef; + } - .table-bordered thead th, - .table-bordered thead td { - border-bottom-width: 2px; - } + .table-bordered thead th, + .table-bordered thead td { + border-bottom-width: 2px; + } .table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(0, 0, 0, 0.05); + background-color: rgba(0, 0, 0, 0.05); } .table-hover tbody tr:hover { - background-color: rgba(0, 0, 0, 0.075); + background-color: rgba(0, 0, 0, 0.075); } .table-active, .table-active > th, .table-active > td { - background-color: rgba(0, 0, 0, 0.075); + background-color: rgba(0, 0, 0, 0.075); } .table-hover .table-active:hover { - background-color: rgba(0, 0, 0, 0.075); + background-color: rgba(0, 0, 0, 0.075); } - .table-hover .table-active:hover > td, - .table-hover .table-active:hover > th { - background-color: rgba(0, 0, 0, 0.075); - } + .table-hover .table-active:hover > td, + .table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); + } .table-success, .table-success > th, .table-success > td { - background-color: #dff0d8; + background-color: #dff0d8; } .table-hover .table-success:hover { - background-color: #d0e9c6; + background-color: #d0e9c6; } - .table-hover .table-success:hover > td, - .table-hover .table-success:hover > th { - background-color: #d0e9c6; - } + .table-hover .table-success:hover > td, + .table-hover .table-success:hover > th { + background-color: #d0e9c6; + } .table-info, .table-info > th, .table-info > td { - background-color: #d9edf7; + background-color: #d9edf7; } .table-hover .table-info:hover { - background-color: #c4e3f3; + background-color: #c4e3f3; } - .table-hover .table-info:hover > td, - .table-hover .table-info:hover > th { - background-color: #c4e3f3; - } + .table-hover .table-info:hover > td, + .table-hover .table-info:hover > th { + background-color: #c4e3f3; + } .table-warning, .table-warning > th, .table-warning > td { - background-color: #fcf8e3; + background-color: #fcf8e3; } .table-hover .table-warning:hover { - background-color: #faf2cc; + background-color: #faf2cc; } - .table-hover .table-warning:hover > td, - .table-hover .table-warning:hover > th { - background-color: #faf2cc; - } + .table-hover .table-warning:hover > td, + .table-hover .table-warning:hover > th { + background-color: #faf2cc; + } .table-danger, .table-danger > th, .table-danger > td { - background-color: #f2dede; + background-color: #f2dede; } .table-hover .table-danger:hover { - background-color: #ebcccc; + background-color: #ebcccc; } - .table-hover .table-danger:hover > td, - .table-hover .table-danger:hover > th { - background-color: #ebcccc; - } + .table-hover .table-danger:hover > td, + .table-hover .table-danger:hover > th { + background-color: #ebcccc; + } .thead-inverse th { - color: #fff; - background-color: #373a3c; + color: #fff; + background-color: #373a3c; } .thead-default th { - color: #55595c; - background-color: #eceeef; + color: #55595c; + background-color: #eceeef; } .table-inverse { - color: #eceeef; - background-color: #373a3c; + color: #eceeef; + background-color: #373a3c; } - .table-inverse th, - .table-inverse td, - .table-inverse thead th { - border-color: #55595c; - } + .table-inverse th, + .table-inverse td, + .table-inverse thead th { + border-color: #55595c; + } - .table-inverse.table-bordered { - border: 0; - } + .table-inverse.table-bordered { + border: 0; + } .table-responsive { - display: block; - width: 100%; - min-height: 0%; - overflow-x: auto; + display: block; + width: 100%; + min-height: 0%; + overflow-x: auto; } .table-reflow thead { - float: left; + float: left; } .table-reflow tbody { - display: block; - white-space: nowrap; + display: block; + white-space: nowrap; } .table-reflow th, .table-reflow td { - border-top: 1px solid #eceeef; - border-left: 1px solid #eceeef; + border-top: 1px solid #eceeef; + border-left: 1px solid #eceeef; } - .table-reflow th:last-child, - .table-reflow td:last-child { - border-right: 1px solid #eceeef; - } + .table-reflow th:last-child, + .table-reflow td:last-child { + border-right: 1px solid #eceeef; + } .table-reflow thead:last-child tr:last-child th, .table-reflow thead:last-child tr:last-child td, @@ -3412,218 +3412,218 @@ pre { .table-reflow tbody:last-child tr:last-child td, .table-reflow tfoot:last-child tr:last-child th, .table-reflow tfoot:last-child tr:last-child td { - border-bottom: 1px solid #eceeef; + border-bottom: 1px solid #eceeef; } .table-reflow tr { - float: left; + float: left; } - .table-reflow tr th, - .table-reflow tr td { - display: block !important; - border: 1px solid #eceeef; - } + .table-reflow tr th, + .table-reflow tr td { + display: block !important; + border: 1px solid #eceeef; + } .form-control { - display: block; - width: 100%; - padding: 0.5rem 0.75rem; - font-size: 1rem; - line-height: 1.25; - color: #55595c; - background-color: #fff; - background-image: none; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; + display: block; + width: 100%; + padding: 0.5rem 0.75rem; + font-size: 1rem; + line-height: 1.25; + color: #55595c; + background-color: #fff; + background-image: none; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; } - .form-control::-ms-expand { - background-color: transparent; - border: 0; - } + .form-control::-ms-expand { + background-color: transparent; + border: 0; + } - .form-control:focus { - color: #55595c; - background-color: #fff; - border-color: #66afe9; - outline: none; - } + .form-control:focus { + color: #55595c; + background-color: #fff; + border-color: #66afe9; + outline: none; + } - .form-control::placeholder { - color: #999; - opacity: 1; - } + .form-control::placeholder { + color: #999; + opacity: 1; + } - .form-control:disabled, .form-control[readonly] { - background-color: #eceeef; - opacity: 1; - } + .form-control:disabled, .form-control[readonly] { + background-color: #eceeef; + opacity: 1; + } - .form-control:disabled { - cursor: not-allowed; - } + .form-control:disabled { + cursor: not-allowed; + } select.form-control:not([size]):not([multiple]) { - height: calc(2.5rem - 2px); + height: calc(2.5rem - 2px); } select.form-control:focus::-ms-value { - color: #55595c; - background-color: #fff; + color: #55595c; + background-color: #fff; } .form-control-file, .form-control-range { - display: block; + display: block; } .col-form-label { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - margin-bottom: 0; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + margin-bottom: 0; } .col-form-label-lg { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - font-size: 1.25rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: 1.25rem; } .col-form-label-sm { - padding-top: 0.25rem; - padding-bottom: 0.25rem; - font-size: 0.875rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: 0.875rem; } .col-form-legend { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - margin-bottom: 0; - font-size: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + margin-bottom: 0; + font-size: 1rem; } .form-control-static { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - line-height: 1.25; - border: solid transparent; - border-width: 1px 0; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + line-height: 1.25; + border: solid transparent; + border-width: 1px 0; } - .form-control-static.form-control-sm, .input-group-sm > .form-control-static.form-control, - .input-group-sm > .form-control-static.input-group-addon, - .input-group-sm > .input-group-btn > .form-control-static.btn, - .input-group-sm > .input-group-btn > .form-control-static.action-button, .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control, - .input-group-lg > .form-control-static.input-group-addon, - .input-group-lg > .input-group-btn > .form-control-static.btn, - .input-group-lg > .input-group-btn > .form-control-static.action-button { - padding-right: 0; - padding-left: 0; - } + .form-control-static.form-control-sm, .input-group-sm > .form-control-static.form-control, + .input-group-sm > .form-control-static.input-group-addon, + .input-group-sm > .input-group-btn > .form-control-static.btn, + .input-group-sm > .input-group-btn > .form-control-static.action-button, .form-control-static.form-control-lg, .input-group-lg > .form-control-static.form-control, + .input-group-lg > .form-control-static.input-group-addon, + .input-group-lg > .input-group-btn > .form-control-static.btn, + .input-group-lg > .input-group-btn > .form-control-static.action-button { + padding-right: 0; + padding-left: 0; + } .form-control-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn, .input-group-sm > .input-group-btn > .action-button { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; } select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), .input-group-sm > select.input-group-addon:not([size]):not([multiple]), .input-group-sm > .input-group-btn > select.btn:not([size]):not([multiple]), .input-group-sm > .input-group-btn > select.action-button:not([size]):not([multiple]) { - height: 1.8125rem; + height: 1.8125rem; } .form-control-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn, .input-group-lg > .input-group-btn > .action-button { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; - border-radius: 0.3rem; + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + border-radius: 0.3rem; } select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), .input-group-lg > select.input-group-addon:not([size]):not([multiple]), .input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]), .input-group-lg > .input-group-btn > select.action-button:not([size]):not([multiple]) { - height: 3.16667rem; + height: 3.16667rem; } .form-group { - margin-bottom: 1rem; + margin-bottom: 1rem; } .form-text { - display: block; - margin-top: 0.25rem; + display: block; + margin-top: 0.25rem; } .form-check { - position: relative; - display: block; - margin-bottom: 0.75rem; + position: relative; + display: block; + margin-bottom: 0.75rem; } - .form-check + .form-check { - margin-top: -.25rem; - } + .form-check + .form-check { + margin-top: -.25rem; + } - .form-check.disabled .form-check-label { - color: #818a91; - cursor: not-allowed; - } + .form-check.disabled .form-check-label { + color: #818a91; + cursor: not-allowed; + } .form-check-label { - padding-left: 1.25rem; - margin-bottom: 0; - cursor: pointer; + padding-left: 1.25rem; + margin-bottom: 0; + cursor: pointer; } .form-check-input { - position: absolute; - margin-top: .25rem; - margin-left: -1.25rem; + position: absolute; + margin-top: .25rem; + margin-left: -1.25rem; } - .form-check-input:only-child { - position: static; - } + .form-check-input:only-child { + position: static; + } .form-check-inline { - position: relative; - display: inline-block; - padding-left: 1.25rem; - margin-bottom: 0; - vertical-align: middle; - cursor: pointer; + position: relative; + display: inline-block; + padding-left: 1.25rem; + margin-bottom: 0; + vertical-align: middle; + cursor: pointer; } - .form-check-inline + .form-check-inline { - margin-left: .75rem; - } + .form-check-inline + .form-check-inline { + margin-left: .75rem; + } - .form-check-inline.disabled { - color: #818a91; - cursor: not-allowed; - } + .form-check-inline.disabled { + color: #818a91; + cursor: not-allowed; + } .form-control-feedback { - margin-top: 0.25rem; + margin-top: 0.25rem; } .form-control-success, .form-control-warning, .form-control-danger { - padding-right: 2.25rem; - background-repeat: no-repeat; - background-position: center right 0.625rem; - background-size: 1.25rem 1.25rem; + padding-right: 2.25rem; + background-repeat: no-repeat; + background-position: center right 0.625rem; + background-size: 1.25rem 1.25rem; } .has-success .form-control-feedback, @@ -3631,25 +3631,25 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for .has-success .form-check-label, .has-success .form-check-inline, .has-success .custom-control { - color: #5cb85c; + color: #5cb85c; } .has-success .form-control { - border-color: #5cb85c; + border-color: #5cb85c; } - .has-success .form-control:focus { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3; - } + .has-success .form-control:focus { + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #a3d7a3; + } .has-success .input-group-addon { - color: #5cb85c; - border-color: #5cb85c; - background-color: #eaf6ea; + color: #5cb85c; + border-color: #5cb85c; + background-color: #eaf6ea; } .has-success .form-control-success { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#5cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#5cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); } .has-warning .form-control-feedback, @@ -3657,25 +3657,25 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for .has-warning .form-check-label, .has-warning .form-check-inline, .has-warning .custom-control { - color: #f0ad4e; + color: #f0ad4e; } .has-warning .form-control { - border-color: #f0ad4e; + border-color: #f0ad4e; } - .has-warning .form-control:focus { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; - } + .has-warning .form-control:focus { + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; + } .has-warning .input-group-addon { - color: #f0ad4e; - border-color: #f0ad4e; - background-color: white; + color: #f0ad4e; + border-color: #f0ad4e; + background-color: white; } .has-warning .form-control-warning { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"); } .has-danger .form-control-feedback, @@ -3683,1085 +3683,1085 @@ select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.for .has-danger .form-check-label, .has-danger .form-check-inline, .has-danger .custom-control { - color: #d9534f; + color: #d9534f; } .has-danger .form-control { - border-color: #d9534f; + border-color: #d9534f; } - .has-danger .form-control:focus { - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; - } + .has-danger .form-control:focus { + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; + } .has-danger .input-group-addon { - color: #d9534f; - border-color: #d9534f; - background-color: #fdf7f7; + color: #d9534f; + border-color: #d9534f; + background-color: #fdf7f7; } .has-danger .form-control-danger { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"); } @media (min-width: 576px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } + .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 { + display: inline-block; + width: auto; + vertical-align: middle; + } - .form-inline .form-control-static { - display: inline-block; - } + .form-inline .form-control-static { + display: inline-block; + } - .form-inline .input-group { - display: inline-table; - width: auto; - vertical-align: middle; - } + .form-inline .input-group { + display: inline-table; + width: auto; + vertical-align: middle; + } - .form-inline .input-group .input-group-addon, - .form-inline .input-group .input-group-btn, - .form-inline .input-group .form-control { - width: auto; - } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } - .form-inline .input-group > .form-control { - width: 100%; - } + .form-inline .input-group > .form-control { + width: 100%; + } - .form-inline .form-control-label { - margin-bottom: 0; - vertical-align: middle; - } + .form-inline .form-control-label { + margin-bottom: 0; + vertical-align: middle; + } - .form-inline .form-check { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } + .form-inline .form-check { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } - .form-inline .form-check-label { - padding-left: 0; - } + .form-inline .form-check-label { + padding-left: 0; + } - .form-inline .form-check-input { - position: relative; - margin-left: 0; - } + .form-inline .form-check-input { + position: relative; + margin-left: 0; + } - .form-inline .has-feedback .form-control-feedback { - top: 0; - } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } } .btn, .action-button { - display: inline-block; - font-weight: normal; - line-height: 1.25; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - user-select: none; - border: 1px solid transparent; - padding: 0.5rem 1rem; - font-size: 1rem; - border-radius: 0.25rem; + display: inline-block; + font-weight: normal; + line-height: 1.25; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + user-select: none; + border: 1px solid transparent; + padding: 0.5rem 1rem; + font-size: 1rem; + border-radius: 0.25rem; } - .btn:focus, .action-button:focus, .btn.focus, .focus.action-button, .btn:active:focus, .action-button:active:focus, .btn:active.focus, .action-button:active.focus, .btn.active:focus, .active.action-button:focus, .btn.active.focus, .active.focus.action-button { - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } + .btn:focus, .action-button:focus, .btn.focus, .focus.action-button, .btn:active:focus, .action-button:active:focus, .btn:active.focus, .action-button:active.focus, .btn.active:focus, .active.action-button:focus, .btn.active.focus, .active.focus.action-button { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; + } - .btn:focus, .action-button:focus, .btn:hover, .action-button:hover { - text-decoration: none; - } + .btn:focus, .action-button:focus, .btn:hover, .action-button:hover { + text-decoration: none; + } - .btn.focus, .focus.action-button { - text-decoration: none; - } + .btn.focus, .focus.action-button { + text-decoration: none; + } - .btn:active, .action-button:active, .btn.active, .active.action-button { - background-image: none; - outline: 0; - } + .btn:active, .action-button:active, .btn.active, .active.action-button { + background-image: none; + outline: 0; + } - .btn.disabled, .disabled.action-button, .btn:disabled, .action-button:disabled { - cursor: not-allowed; - opacity: .65; - } + .btn.disabled, .disabled.action-button, .btn:disabled, .action-button:disabled { + cursor: not-allowed; + opacity: .65; + } a.btn.disabled, a.disabled.action-button, fieldset[disabled] a.btn, fieldset[disabled] a.action-button { - pointer-events: none; + pointer-events: none; } .btn-primary { - color: #fff; - background-color: #214497; - border-color: #214497; + color: #fff; + background-color: #214497; + border-color: #214497; } - .btn-primary:hover { - color: #fff; - background-color: #18316d; - border-color: #162d65; - } + .btn-primary:hover { + color: #fff; + background-color: #18316d; + border-color: #162d65; + } - .btn-primary:focus, .btn-primary.focus { - color: #fff; - background-color: #18316d; - border-color: #162d65; - } + .btn-primary:focus, .btn-primary.focus { + color: #fff; + background-color: #18316d; + border-color: #162d65; + } - .btn-primary:active, .btn-primary.active, - .open > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #18316d; - border-color: #162d65; - background-image: none; - } + .btn-primary:active, .btn-primary.active, + .open > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #18316d; + border-color: #162d65; + background-image: none; + } - .btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, - .open > .btn-primary.dropdown-toggle:hover, - .open > .btn-primary.dropdown-toggle:focus, - .open > .btn-primary.dropdown-toggle.focus { - color: #fff; - background-color: #112450; - border-color: #0a152e; - } + .btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, + .open > .btn-primary.dropdown-toggle:hover, + .open > .btn-primary.dropdown-toggle:focus, + .open > .btn-primary.dropdown-toggle.focus { + color: #fff; + background-color: #112450; + border-color: #0a152e; + } - .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary:disabled:focus, .btn-primary:disabled.focus { - background-color: #214497; - border-color: #214497; - } + .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary:disabled:focus, .btn-primary:disabled.focus { + background-color: #214497; + border-color: #214497; + } - .btn-primary.disabled:hover, .btn-primary:disabled:hover { - background-color: #214497; - border-color: #214497; - } + .btn-primary.disabled:hover, .btn-primary:disabled:hover { + background-color: #214497; + border-color: #214497; + } .btn-secondary { - color: #373a3c; - background-color: #fff; - border-color: #ccc; + color: #373a3c; + background-color: #fff; + border-color: #ccc; } - .btn-secondary:hover { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - } + .btn-secondary:hover { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + } - .btn-secondary:focus, .btn-secondary.focus { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - } + .btn-secondary:focus, .btn-secondary.focus { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + } - .btn-secondary:active, .btn-secondary.active, - .open > .btn-secondary.dropdown-toggle { - color: #373a3c; - background-color: #e6e6e6; - border-color: #adadad; - background-image: none; - } + .btn-secondary:active, .btn-secondary.active, + .open > .btn-secondary.dropdown-toggle { + color: #373a3c; + background-color: #e6e6e6; + border-color: #adadad; + background-image: none; + } - .btn-secondary:active:hover, .btn-secondary:active:focus, .btn-secondary:active.focus, .btn-secondary.active:hover, .btn-secondary.active:focus, .btn-secondary.active.focus, - .open > .btn-secondary.dropdown-toggle:hover, - .open > .btn-secondary.dropdown-toggle:focus, - .open > .btn-secondary.dropdown-toggle.focus { - color: #373a3c; - background-color: #d4d4d4; - border-color: #8c8c8c; - } + .btn-secondary:active:hover, .btn-secondary:active:focus, .btn-secondary:active.focus, .btn-secondary.active:hover, .btn-secondary.active:focus, .btn-secondary.active.focus, + .open > .btn-secondary.dropdown-toggle:hover, + .open > .btn-secondary.dropdown-toggle:focus, + .open > .btn-secondary.dropdown-toggle.focus { + color: #373a3c; + background-color: #d4d4d4; + border-color: #8c8c8c; + } - .btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus { - background-color: #fff; - border-color: #ccc; - } + .btn-secondary.disabled:focus, .btn-secondary.disabled.focus, .btn-secondary:disabled:focus, .btn-secondary:disabled.focus { + background-color: #fff; + border-color: #ccc; + } - .btn-secondary.disabled:hover, .btn-secondary:disabled:hover { - background-color: #fff; - border-color: #ccc; - } + .btn-secondary.disabled:hover, .btn-secondary:disabled:hover { + background-color: #fff; + border-color: #ccc; + } .btn-info { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; } - .btn-info:hover { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - } + .btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + } - .btn-info:focus, .btn-info.focus { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - } + .btn-info:focus, .btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + } - .btn-info:active, .btn-info.active, - .open > .btn-info.dropdown-toggle { - color: #fff; - background-color: #31b0d5; - border-color: #2aabd2; - background-image: none; - } + .btn-info:active, .btn-info.active, + .open > .btn-info.dropdown-toggle { + color: #fff; + background-color: #31b0d5; + border-color: #2aabd2; + background-image: none; + } - .btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, - .open > .btn-info.dropdown-toggle:hover, - .open > .btn-info.dropdown-toggle:focus, - .open > .btn-info.dropdown-toggle.focus { - color: #fff; - background-color: #269abc; - border-color: #1f7e9a; - } + .btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, + .open > .btn-info.dropdown-toggle:hover, + .open > .btn-info.dropdown-toggle:focus, + .open > .btn-info.dropdown-toggle.focus { + color: #fff; + background-color: #269abc; + border-color: #1f7e9a; + } - .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info:disabled:focus, .btn-info:disabled.focus { - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info:disabled:focus, .btn-info:disabled.focus { + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-info.disabled:hover, .btn-info:disabled:hover { - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-info.disabled:hover, .btn-info:disabled:hover { + background-color: #5bc0de; + border-color: #5bc0de; + } .btn-success { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; } - .btn-success:hover { - color: #fff; - background-color: #449d44; - border-color: #419641; - } + .btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #419641; + } - .btn-success:focus, .btn-success.focus { - color: #fff; - background-color: #449d44; - border-color: #419641; - } + .btn-success:focus, .btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #419641; + } - .btn-success:active, .btn-success.active, - .open > .btn-success.dropdown-toggle { - color: #fff; - background-color: #449d44; - border-color: #419641; - background-image: none; - } + .btn-success:active, .btn-success.active, + .open > .btn-success.dropdown-toggle { + color: #fff; + background-color: #449d44; + border-color: #419641; + background-image: none; + } - .btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, - .open > .btn-success.dropdown-toggle:hover, - .open > .btn-success.dropdown-toggle:focus, - .open > .btn-success.dropdown-toggle.focus { - color: #fff; - background-color: #398439; - border-color: #2d672d; - } + .btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, + .open > .btn-success.dropdown-toggle:hover, + .open > .btn-success.dropdown-toggle:focus, + .open > .btn-success.dropdown-toggle.focus { + color: #fff; + background-color: #398439; + border-color: #2d672d; + } - .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success:disabled:focus, .btn-success:disabled.focus { - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success:disabled:focus, .btn-success:disabled.focus { + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-success.disabled:hover, .btn-success:disabled:hover { - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-success.disabled:hover, .btn-success:disabled:hover { + background-color: #5cb85c; + border-color: #5cb85c; + } .btn-warning { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; } - .btn-warning:hover { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - } + .btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + } - .btn-warning:focus, .btn-warning.focus { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - } + .btn-warning:focus, .btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + } - .btn-warning:active, .btn-warning.active, - .open > .btn-warning.dropdown-toggle { - color: #fff; - background-color: #ec971f; - border-color: #eb9316; - background-image: none; - } + .btn-warning:active, .btn-warning.active, + .open > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #ec971f; + border-color: #eb9316; + background-image: none; + } - .btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, - .open > .btn-warning.dropdown-toggle:hover, - .open > .btn-warning.dropdown-toggle:focus, - .open > .btn-warning.dropdown-toggle.focus { - color: #fff; - background-color: #d58512; - border-color: #b06d0f; - } + .btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, + .open > .btn-warning.dropdown-toggle:hover, + .open > .btn-warning.dropdown-toggle:focus, + .open > .btn-warning.dropdown-toggle.focus { + color: #fff; + background-color: #d58512; + border-color: #b06d0f; + } - .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning:disabled:focus, .btn-warning:disabled.focus { - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning:disabled:focus, .btn-warning:disabled.focus { + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-warning.disabled:hover, .btn-warning:disabled:hover { - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-warning.disabled:hover, .btn-warning:disabled:hover { + background-color: #f0ad4e; + border-color: #f0ad4e; + } .btn-danger { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; + color: #fff; + background-color: #d9534f; + border-color: #d9534f; } - .btn-danger:hover { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - } + .btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + } - .btn-danger:focus, .btn-danger.focus { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - } + .btn-danger:focus, .btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + } - .btn-danger:active, .btn-danger.active, - .open > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #c9302c; - border-color: #c12e2a; - background-image: none; - } + .btn-danger:active, .btn-danger.active, + .open > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #c9302c; + border-color: #c12e2a; + background-image: none; + } - .btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, - .open > .btn-danger.dropdown-toggle:hover, - .open > .btn-danger.dropdown-toggle:focus, - .open > .btn-danger.dropdown-toggle.focus { - color: #fff; - background-color: #ac2925; - border-color: #8b211e; - } + .btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, + .open > .btn-danger.dropdown-toggle:hover, + .open > .btn-danger.dropdown-toggle:focus, + .open > .btn-danger.dropdown-toggle.focus { + color: #fff; + background-color: #ac2925; + border-color: #8b211e; + } - .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger:disabled:focus, .btn-danger:disabled.focus { - background-color: #d9534f; - border-color: #d9534f; - } + .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger:disabled:focus, .btn-danger:disabled.focus { + background-color: #d9534f; + border-color: #d9534f; + } - .btn-danger.disabled:hover, .btn-danger:disabled:hover { - background-color: #d9534f; - border-color: #d9534f; - } + .btn-danger.disabled:hover, .btn-danger:disabled:hover { + background-color: #d9534f; + border-color: #d9534f; + } .btn-outline-primary { - color: #214497; - background-image: none; - background-color: transparent; - border-color: #214497; + color: #214497; + background-image: none; + background-color: transparent; + border-color: #214497; } - .btn-outline-primary:hover { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:hover { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:focus, .btn-outline-primary.focus { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:focus, .btn-outline-primary.focus { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:active, .btn-outline-primary.active, - .open > .btn-outline-primary.dropdown-toggle { - color: #fff; - background-color: #214497; - border-color: #214497; - } + .btn-outline-primary:active, .btn-outline-primary.active, + .open > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #214497; + border-color: #214497; + } - .btn-outline-primary:active:hover, .btn-outline-primary:active:focus, .btn-outline-primary:active.focus, .btn-outline-primary.active:hover, .btn-outline-primary.active:focus, .btn-outline-primary.active.focus, - .open > .btn-outline-primary.dropdown-toggle:hover, - .open > .btn-outline-primary.dropdown-toggle:focus, - .open > .btn-outline-primary.dropdown-toggle.focus { - color: #fff; - background-color: #112450; - border-color: #0a152e; - } + .btn-outline-primary:active:hover, .btn-outline-primary:active:focus, .btn-outline-primary:active.focus, .btn-outline-primary.active:hover, .btn-outline-primary.active:focus, .btn-outline-primary.active.focus, + .open > .btn-outline-primary.dropdown-toggle:hover, + .open > .btn-outline-primary.dropdown-toggle:focus, + .open > .btn-outline-primary.dropdown-toggle.focus { + color: #fff; + background-color: #112450; + border-color: #0a152e; + } - .btn-outline-primary.disabled:focus, .btn-outline-primary.disabled.focus, .btn-outline-primary:disabled:focus, .btn-outline-primary:disabled.focus { - border-color: #4772d7; - } + .btn-outline-primary.disabled:focus, .btn-outline-primary.disabled.focus, .btn-outline-primary:disabled:focus, .btn-outline-primary:disabled.focus { + border-color: #4772d7; + } - .btn-outline-primary.disabled:hover, .btn-outline-primary:disabled:hover { - border-color: #4772d7; - } + .btn-outline-primary.disabled:hover, .btn-outline-primary:disabled:hover { + border-color: #4772d7; + } .btn-outline-secondary { - color: #ccc; - background-image: none; - background-color: transparent; - border-color: #ccc; + color: #ccc; + background-image: none; + background-color: transparent; + border-color: #ccc; } - .btn-outline-secondary:hover { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:hover { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:focus, .btn-outline-secondary.focus { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:focus, .btn-outline-secondary.focus { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:active, .btn-outline-secondary.active, - .open > .btn-outline-secondary.dropdown-toggle { - color: #fff; - background-color: #ccc; - border-color: #ccc; - } + .btn-outline-secondary:active, .btn-outline-secondary.active, + .open > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #ccc; + border-color: #ccc; + } - .btn-outline-secondary:active:hover, .btn-outline-secondary:active:focus, .btn-outline-secondary:active.focus, .btn-outline-secondary.active:hover, .btn-outline-secondary.active:focus, .btn-outline-secondary.active.focus, - .open > .btn-outline-secondary.dropdown-toggle:hover, - .open > .btn-outline-secondary.dropdown-toggle:focus, - .open > .btn-outline-secondary.dropdown-toggle.focus { - color: #fff; - background-color: #a1a1a1; - border-color: #8c8c8c; - } + .btn-outline-secondary:active:hover, .btn-outline-secondary:active:focus, .btn-outline-secondary:active.focus, .btn-outline-secondary.active:hover, .btn-outline-secondary.active:focus, .btn-outline-secondary.active.focus, + .open > .btn-outline-secondary.dropdown-toggle:hover, + .open > .btn-outline-secondary.dropdown-toggle:focus, + .open > .btn-outline-secondary.dropdown-toggle.focus { + color: #fff; + background-color: #a1a1a1; + border-color: #8c8c8c; + } - .btn-outline-secondary.disabled:focus, .btn-outline-secondary.disabled.focus, .btn-outline-secondary:disabled:focus, .btn-outline-secondary:disabled.focus { - border-color: white; - } + .btn-outline-secondary.disabled:focus, .btn-outline-secondary.disabled.focus, .btn-outline-secondary:disabled:focus, .btn-outline-secondary:disabled.focus { + border-color: white; + } - .btn-outline-secondary.disabled:hover, .btn-outline-secondary:disabled:hover { - border-color: white; - } + .btn-outline-secondary.disabled:hover, .btn-outline-secondary:disabled:hover { + border-color: white; + } .btn-outline-info { - color: #5bc0de; - background-image: none; - background-color: transparent; - border-color: #5bc0de; + color: #5bc0de; + background-image: none; + background-color: transparent; + border-color: #5bc0de; } - .btn-outline-info:hover { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:hover { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:focus, .btn-outline-info.focus { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:focus, .btn-outline-info.focus { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:active, .btn-outline-info.active, - .open > .btn-outline-info.dropdown-toggle { - color: #fff; - background-color: #5bc0de; - border-color: #5bc0de; - } + .btn-outline-info:active, .btn-outline-info.active, + .open > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; + } - .btn-outline-info:active:hover, .btn-outline-info:active:focus, .btn-outline-info:active.focus, .btn-outline-info.active:hover, .btn-outline-info.active:focus, .btn-outline-info.active.focus, - .open > .btn-outline-info.dropdown-toggle:hover, - .open > .btn-outline-info.dropdown-toggle:focus, - .open > .btn-outline-info.dropdown-toggle.focus { - color: #fff; - background-color: #269abc; - border-color: #1f7e9a; - } + .btn-outline-info:active:hover, .btn-outline-info:active:focus, .btn-outline-info:active.focus, .btn-outline-info.active:hover, .btn-outline-info.active:focus, .btn-outline-info.active.focus, + .open > .btn-outline-info.dropdown-toggle:hover, + .open > .btn-outline-info.dropdown-toggle:focus, + .open > .btn-outline-info.dropdown-toggle.focus { + color: #fff; + background-color: #269abc; + border-color: #1f7e9a; + } - .btn-outline-info.disabled:focus, .btn-outline-info.disabled.focus, .btn-outline-info:disabled:focus, .btn-outline-info:disabled.focus { - border-color: #b0e1ef; - } + .btn-outline-info.disabled:focus, .btn-outline-info.disabled.focus, .btn-outline-info:disabled:focus, .btn-outline-info:disabled.focus { + border-color: #b0e1ef; + } - .btn-outline-info.disabled:hover, .btn-outline-info:disabled:hover { - border-color: #b0e1ef; - } + .btn-outline-info.disabled:hover, .btn-outline-info:disabled:hover { + border-color: #b0e1ef; + } .btn-outline-success { - color: #5cb85c; - background-image: none; - background-color: transparent; - border-color: #5cb85c; + color: #5cb85c; + background-image: none; + background-color: transparent; + border-color: #5cb85c; } - .btn-outline-success:hover { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:hover { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:focus, .btn-outline-success.focus { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:focus, .btn-outline-success.focus { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:active, .btn-outline-success.active, - .open > .btn-outline-success.dropdown-toggle { - color: #fff; - background-color: #5cb85c; - border-color: #5cb85c; - } + .btn-outline-success:active, .btn-outline-success.active, + .open > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #5cb85c; + border-color: #5cb85c; + } - .btn-outline-success:active:hover, .btn-outline-success:active:focus, .btn-outline-success:active.focus, .btn-outline-success.active:hover, .btn-outline-success.active:focus, .btn-outline-success.active.focus, - .open > .btn-outline-success.dropdown-toggle:hover, - .open > .btn-outline-success.dropdown-toggle:focus, - .open > .btn-outline-success.dropdown-toggle.focus { - color: #fff; - background-color: #398439; - border-color: #2d672d; - } + .btn-outline-success:active:hover, .btn-outline-success:active:focus, .btn-outline-success:active.focus, .btn-outline-success.active:hover, .btn-outline-success.active:focus, .btn-outline-success.active.focus, + .open > .btn-outline-success.dropdown-toggle:hover, + .open > .btn-outline-success.dropdown-toggle:focus, + .open > .btn-outline-success.dropdown-toggle.focus { + color: #fff; + background-color: #398439; + border-color: #2d672d; + } - .btn-outline-success.disabled:focus, .btn-outline-success.disabled.focus, .btn-outline-success:disabled:focus, .btn-outline-success:disabled.focus { - border-color: #a3d7a3; - } + .btn-outline-success.disabled:focus, .btn-outline-success.disabled.focus, .btn-outline-success:disabled:focus, .btn-outline-success:disabled.focus { + border-color: #a3d7a3; + } - .btn-outline-success.disabled:hover, .btn-outline-success:disabled:hover { - border-color: #a3d7a3; - } + .btn-outline-success.disabled:hover, .btn-outline-success:disabled:hover { + border-color: #a3d7a3; + } .btn-outline-warning { - color: #f0ad4e; - background-image: none; - background-color: transparent; - border-color: #f0ad4e; + color: #f0ad4e; + background-image: none; + background-color: transparent; + border-color: #f0ad4e; } - .btn-outline-warning:hover { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:hover { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:focus, .btn-outline-warning.focus { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:focus, .btn-outline-warning.focus { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:active, .btn-outline-warning.active, - .open > .btn-outline-warning.dropdown-toggle { - color: #fff; - background-color: #f0ad4e; - border-color: #f0ad4e; - } + .btn-outline-warning:active, .btn-outline-warning.active, + .open > .btn-outline-warning.dropdown-toggle { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; + } - .btn-outline-warning:active:hover, .btn-outline-warning:active:focus, .btn-outline-warning:active.focus, .btn-outline-warning.active:hover, .btn-outline-warning.active:focus, .btn-outline-warning.active.focus, - .open > .btn-outline-warning.dropdown-toggle:hover, - .open > .btn-outline-warning.dropdown-toggle:focus, - .open > .btn-outline-warning.dropdown-toggle.focus { - color: #fff; - background-color: #d58512; - border-color: #b06d0f; - } + .btn-outline-warning:active:hover, .btn-outline-warning:active:focus, .btn-outline-warning:active.focus, .btn-outline-warning.active:hover, .btn-outline-warning.active:focus, .btn-outline-warning.active.focus, + .open > .btn-outline-warning.dropdown-toggle:hover, + .open > .btn-outline-warning.dropdown-toggle:focus, + .open > .btn-outline-warning.dropdown-toggle.focus { + color: #fff; + background-color: #d58512; + border-color: #b06d0f; + } - .btn-outline-warning.disabled:focus, .btn-outline-warning.disabled.focus, .btn-outline-warning:disabled:focus, .btn-outline-warning:disabled.focus { - border-color: #f8d9ac; - } + .btn-outline-warning.disabled:focus, .btn-outline-warning.disabled.focus, .btn-outline-warning:disabled:focus, .btn-outline-warning:disabled.focus { + border-color: #f8d9ac; + } - .btn-outline-warning.disabled:hover, .btn-outline-warning:disabled:hover { - border-color: #f8d9ac; - } + .btn-outline-warning.disabled:hover, .btn-outline-warning:disabled:hover { + border-color: #f8d9ac; + } .btn-outline-danger { - color: #d9534f; - background-image: none; - background-color: transparent; - border-color: #d9534f; + color: #d9534f; + background-image: none; + background-color: transparent; + border-color: #d9534f; } - .btn-outline-danger:hover { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:hover { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:focus, .btn-outline-danger.focus { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:focus, .btn-outline-danger.focus { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:active, .btn-outline-danger.active, - .open > .btn-outline-danger.dropdown-toggle { - color: #fff; - background-color: #d9534f; - border-color: #d9534f; - } + .btn-outline-danger:active, .btn-outline-danger.active, + .open > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; + } - .btn-outline-danger:active:hover, .btn-outline-danger:active:focus, .btn-outline-danger:active.focus, .btn-outline-danger.active:hover, .btn-outline-danger.active:focus, .btn-outline-danger.active.focus, - .open > .btn-outline-danger.dropdown-toggle:hover, - .open > .btn-outline-danger.dropdown-toggle:focus, - .open > .btn-outline-danger.dropdown-toggle.focus { - color: #fff; - background-color: #ac2925; - border-color: #8b211e; - } + .btn-outline-danger:active:hover, .btn-outline-danger:active:focus, .btn-outline-danger:active.focus, .btn-outline-danger.active:hover, .btn-outline-danger.active:focus, .btn-outline-danger.active.focus, + .open > .btn-outline-danger.dropdown-toggle:hover, + .open > .btn-outline-danger.dropdown-toggle:focus, + .open > .btn-outline-danger.dropdown-toggle.focus { + color: #fff; + background-color: #ac2925; + border-color: #8b211e; + } - .btn-outline-danger.disabled:focus, .btn-outline-danger.disabled.focus, .btn-outline-danger:disabled:focus, .btn-outline-danger:disabled.focus { - border-color: #eba5a3; - } + .btn-outline-danger.disabled:focus, .btn-outline-danger.disabled.focus, .btn-outline-danger:disabled:focus, .btn-outline-danger:disabled.focus { + border-color: #eba5a3; + } - .btn-outline-danger.disabled:hover, .btn-outline-danger:disabled:hover { - border-color: #eba5a3; - } + .btn-outline-danger.disabled:hover, .btn-outline-danger:disabled:hover { + border-color: #eba5a3; + } .btn-link { - font-weight: normal; - color: #214497; - border-radius: 0; + font-weight: normal; + color: #214497; + border-radius: 0; } - .btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled { - background-color: transparent; - } + .btn-link, .btn-link:active, .btn-link.active, .btn-link:disabled { + background-color: transparent; + } - .btn-link, .btn-link:focus, .btn-link:active { - border-color: transparent; - } + .btn-link, .btn-link:focus, .btn-link:active { + border-color: transparent; + } - .btn-link:hover { - border-color: transparent; - } + .btn-link:hover { + border-color: transparent; + } - .btn-link:focus, .btn-link:hover { - color: #132858; - text-decoration: underline; - background-color: transparent; - } + .btn-link:focus, .btn-link:hover { + color: #132858; + text-decoration: underline; + background-color: transparent; + } - .btn-link:disabled:focus, .btn-link:disabled:hover { - color: #818a91; - text-decoration: none; - } + .btn-link:disabled:focus, .btn-link:disabled:hover { + color: #818a91; + text-decoration: none; + } .btn-lg, .btn-group-lg > .btn, .btn-group-lg > .action-button { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; - border-radius: 0.3rem; + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + border-radius: 0.3rem; } .btn-sm, .btn-group-sm > .btn, .btn-group-sm > .action-button { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; } .btn-block, .action-button { - display: block; - width: 100%; + display: block; + width: 100%; } - .btn-block + .btn-block, .action-button + .btn-block, .btn-block + .action-button, .action-button + .action-button { - margin-top: 0.5rem; - } + .btn-block + .btn-block, .action-button + .btn-block, .btn-block + .action-button, .action-button + .action-button { + margin-top: 0.5rem; + } input[type="submit"].btn-block, input[type="submit"].action-button, input[type="reset"].btn-block, input[type="reset"].action-button, input[type="button"].btn-block, input[type="button"].action-button { - width: 100%; + width: 100%; } .fade { - opacity: 0; - transition: opacity .15s linear; + opacity: 0; + transition: opacity .15s linear; } - .fade.in { - opacity: 1; - } + .fade.in { + opacity: 1; + } .collapse { - display: none; + display: none; } - .collapse.in { - display: block; - } + .collapse.in { + display: block; + } tr.collapse.in { - display: table-row; + display: table-row; } tbody.collapse.in { - display: table-row-group; + display: table-row-group; } .collapsing { - position: relative; - height: 0; - overflow: hidden; - transition-timing-function: ease; - transition-duration: .35s; - transition-property: height; + position: relative; + height: 0; + overflow: hidden; + transition-timing-function: ease; + transition-duration: .35s; + transition-property: height; } .dropup, .dropdown { - position: relative; + position: relative; } .dropdown-toggle::after { - display: inline-block; - width: 0; - height: 0; - margin-left: 0.3em; - vertical-align: middle; - content: ""; - border-top: 0.3em solid; - border-right: 0.3em solid transparent; - border-left: 0.3em solid transparent; + display: inline-block; + width: 0; + height: 0; + margin-left: 0.3em; + vertical-align: middle; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-left: 0.3em solid transparent; } .dropdown-toggle:focus { - outline: 0; + outline: 0; } .dropup .dropdown-toggle::after { - border-top: 0; - border-bottom: 0.3em solid; + border-top: 0; + border-bottom: 0.3em solid; } .dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 10rem; - padding: 0.5rem 0; - margin: 0.125rem 0 0; - font-size: 1rem; - color: #373a3c; - text-align: left; - list-style: none; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #373a3c; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; } .dropdown-divider { - height: 1px; - margin: 0.5rem 0; - overflow: hidden; - background-color: #e5e5e5; + height: 1px; + margin: 0.5rem 0; + overflow: hidden; + background-color: #e5e5e5; } .dropdown-item { - display: block; - width: 100%; - padding: 3px 1.5rem; - clear: both; - font-weight: normal; - color: #373a3c; - text-align: inherit; - white-space: nowrap; - background: none; - border: 0; + display: block; + width: 100%; + padding: 3px 1.5rem; + clear: both; + font-weight: normal; + color: #373a3c; + text-align: inherit; + white-space: nowrap; + background: none; + border: 0; } - .dropdown-item:focus, .dropdown-item:hover { - color: #2b2d2f; - text-decoration: none; - background-color: #f5f5f5; - } + .dropdown-item:focus, .dropdown-item:hover { + color: #2b2d2f; + text-decoration: none; + background-color: #f5f5f5; + } - .dropdown-item.active, .dropdown-item.active:focus, .dropdown-item.active:hover { - color: #fff; - text-decoration: none; - background-color: #214497; - outline: 0; - } + .dropdown-item.active, .dropdown-item.active:focus, .dropdown-item.active:hover { + color: #fff; + text-decoration: none; + background-color: #214497; + outline: 0; + } - .dropdown-item.disabled, .dropdown-item.disabled:focus, .dropdown-item.disabled:hover { - color: #818a91; - } + .dropdown-item.disabled, .dropdown-item.disabled:focus, .dropdown-item.disabled:hover { + color: #818a91; + } - .dropdown-item.disabled:focus, .dropdown-item.disabled:hover { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: "progid:DXImageTransform.Microsoft.gradient(enabled = false)"; - } + .dropdown-item.disabled:focus, .dropdown-item.disabled: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; + display: block; } .open > a { - outline: 0; + outline: 0; } .dropdown-menu-right { - right: 0; - left: auto; + right: 0; + left: auto; } .dropdown-menu-left { - right: auto; - left: 0; + right: auto; + left: 0; } .dropdown-header { - display: block; - padding: 0.5rem 1.5rem; - margin-bottom: 0; - font-size: 0.875rem; - color: #818a91; - white-space: nowrap; + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #818a91; + white-space: nowrap; } .dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { - content: ""; - border-top: 0; - border-bottom: 0.3em solid; + content: ""; + border-top: 0; + border-bottom: 0.3em solid; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 0.125rem; + top: auto; + bottom: 100%; + margin-bottom: 0.125rem; } .btn-group, .btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; + position: relative; + display: inline-block; + vertical-align: middle; } - .btn-group > .btn, .btn-group > .action-button, - .btn-group-vertical > .btn, - .btn-group-vertical > .action-button { - position: relative; - float: left; - margin-bottom: 0; - } + .btn-group > .btn, .btn-group > .action-button, + .btn-group-vertical > .btn, + .btn-group-vertical > .action-button { + position: relative; + float: left; + margin-bottom: 0; + } - .btn-group > .btn:focus, .btn-group > .action-button:focus, .btn-group > .btn:active, .btn-group > .action-button:active, .btn-group > .btn.active, .btn-group > .active.action-button, - .btn-group-vertical > .btn:focus, - .btn-group-vertical > .action-button:focus, - .btn-group-vertical > .btn:active, - .btn-group-vertical > .action-button:active, - .btn-group-vertical > .btn.active, - .btn-group-vertical > .active.action-button { - z-index: 2; - } + .btn-group > .btn:focus, .btn-group > .action-button:focus, .btn-group > .btn:active, .btn-group > .action-button:active, .btn-group > .btn.active, .btn-group > .active.action-button, + .btn-group-vertical > .btn:focus, + .btn-group-vertical > .action-button:focus, + .btn-group-vertical > .btn:active, + .btn-group-vertical > .action-button:active, + .btn-group-vertical > .btn.active, + .btn-group-vertical > .active.action-button { + z-index: 2; + } - .btn-group > .btn:hover, .btn-group > .action-button:hover, - .btn-group-vertical > .btn:hover, - .btn-group-vertical > .action-button:hover { - z-index: 2; - } + .btn-group > .btn:hover, .btn-group > .action-button:hover, + .btn-group-vertical > .btn:hover, + .btn-group-vertical > .action-button:hover { + z-index: 2; + } - .btn-group .btn + .btn, .btn-group .action-button + .btn, .btn-group .btn + .action-button, .btn-group .action-button + .action-button, - .btn-group .btn + .btn-group, - .btn-group .action-button + .btn-group, - .btn-group .btn-group + .btn, - .btn-group .btn-group + .action-button, - .btn-group .btn-group + .btn-group { - margin-left: -1px; - } + .btn-group .btn + .btn, .btn-group .action-button + .btn, .btn-group .btn + .action-button, .btn-group .action-button + .action-button, + .btn-group .btn + .btn-group, + .btn-group .action-button + .btn-group, + .btn-group .btn-group + .btn, + .btn-group .btn-group + .action-button, + .btn-group .btn-group + .btn-group { + margin-left: -1px; + } .btn-toolbar { - margin-left: -0.5rem; + margin-left: -0.5rem; } - .btn-toolbar::after { - content: ""; - display: table; - clear: both; - } + .btn-toolbar::after { + content: ""; + display: table; + clear: both; + } - .btn-toolbar .btn-group, - .btn-toolbar .input-group { - float: left; - } + .btn-toolbar .btn-group, + .btn-toolbar .input-group { + float: left; + } - .btn-toolbar > .btn, .btn-toolbar > .action-button, - .btn-toolbar > .btn-group, - .btn-toolbar > .input-group { - margin-left: 0.5rem; - } + .btn-toolbar > .btn, .btn-toolbar > .action-button, + .btn-toolbar > .btn-group, + .btn-toolbar > .input-group { + margin-left: 0.5rem; + } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle), .btn-group > .action-button:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; + border-radius: 0; } .btn-group > .btn:first-child, .btn-group > .action-button:first-child { - margin-left: 0; + margin-left: 0; } - .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle), .btn-group > .action-button:first-child:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } + .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle), .btn-group > .action-button:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } .btn-group > .btn:last-child:not(:first-child), .btn-group > .action-button:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; } .btn-group > .btn-group { - float: left; + float: left; } - .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn, .btn-group > .btn-group:not(:first-child):not(:last-child) > .action-button { - border-radius: 0; - } + .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn, .btn-group > .btn-group:not(:first-child):not(:last-child) > .action-button { + border-radius: 0; + } - .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .action-button:last-child, - .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } + .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .action-button:last-child, + .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } - .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child, .btn-group > .btn-group:last-child:not(:first-child) > .action-button:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } + .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child, .btn-group > .btn-group:last-child:not(:first-child) > .action-button:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { - outline: 0; + outline: 0; } .btn + .dropdown-toggle-split, .action-button + .dropdown-toggle-split { - padding-right: 0.75rem; - padding-left: 0.75rem; + padding-right: 0.75rem; + padding-left: 0.75rem; } - .btn + .dropdown-toggle-split::after, .action-button + .dropdown-toggle-split::after { - margin-left: 0; - } + .btn + .dropdown-toggle-split::after, .action-button + .dropdown-toggle-split::after { + margin-left: 0; + } .btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split, .btn-group-sm > .action-button + .dropdown-toggle-split { - padding-right: 0.375rem; - padding-left: 0.375rem; + padding-right: 0.375rem; + padding-left: 0.375rem; } .btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split, .btn-group-lg > .action-button + .dropdown-toggle-split { - padding-right: 1.125rem; - padding-left: 1.125rem; + padding-right: 1.125rem; + padding-left: 1.125rem; } .btn .caret, .action-button .caret { - margin-left: 0; + margin-left: 0; } .btn-lg .caret, .btn-group-lg > .btn .caret, .btn-group-lg > .action-button .caret { - border-width: 0.3em 0.3em 0; - border-bottom-width: 0; + border-width: 0.3em 0.3em 0; + border-bottom-width: 0; } .dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret, .dropup .btn-group-lg > .action-button .caret { - border-width: 0 0.3em 0.3em; + border-width: 0 0.3em 0.3em; } .btn-group-vertical > .btn, .btn-group-vertical > .action-button, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn, .btn-group-vertical > .btn-group > .action-button { - display: block; - float: none; - width: 100%; - max-width: 100%; + display: block; + float: none; + width: 100%; + max-width: 100%; } - .btn-group-vertical > .btn-group::after { - content: ""; - display: table; - clear: both; - } + .btn-group-vertical > .btn-group::after { + content: ""; + display: table; + clear: both; + } - .btn-group-vertical > .btn-group > .btn, .btn-group-vertical > .btn-group > .action-button { - float: none; - } + .btn-group-vertical > .btn-group > .btn, .btn-group-vertical > .btn-group > .action-button { + float: none; + } - .btn-group-vertical > .btn + .btn, .btn-group-vertical > .action-button + .btn, .btn-group-vertical > .btn + .action-button, .btn-group-vertical > .action-button + .action-button, - .btn-group-vertical > .btn + .btn-group, - .btn-group-vertical > .action-button + .btn-group, - .btn-group-vertical > .btn-group + .btn, - .btn-group-vertical > .btn-group + .action-button, - .btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; - } + .btn-group-vertical > .btn + .btn, .btn-group-vertical > .action-button + .btn, .btn-group-vertical > .btn + .action-button, .btn-group-vertical > .action-button + .action-button, + .btn-group-vertical > .btn + .btn-group, + .btn-group-vertical > .action-button + .btn-group, + .btn-group-vertical > .btn-group + .btn, + .btn-group-vertical > .btn-group + .action-button, + .btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; + } - .btn-group-vertical > .btn:not(:first-child):not(:last-child), .btn-group-vertical > .action-button:not(:first-child):not(:last-child) { - border-radius: 0; - } + .btn-group-vertical > .btn:not(:first-child):not(:last-child), .btn-group-vertical > .action-button:not(:first-child):not(:last-child) { + border-radius: 0; + } - .btn-group-vertical > .btn:first-child:not(:last-child), .btn-group-vertical > .action-button:first-child:not(:last-child) { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - } + .btn-group-vertical > .btn:first-child:not(:last-child), .btn-group-vertical > .action-button:first-child:not(:last-child) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } - .btn-group-vertical > .btn:last-child:not(:first-child), .btn-group-vertical > .action-button:last-child:not(:first-child) { - border-top-right-radius: 0; - border-top-left-radius: 0; - } + .btn-group-vertical > .btn:last-child:not(:first-child), .btn-group-vertical > .action-button:last-child:not(:first-child) { + border-top-right-radius: 0; + border-top-left-radius: 0; + } - .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn, .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .action-button { - border-radius: 0; - } + .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn, .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .action-button { + 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) > .action-button: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:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .action-button: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, .btn-group-vertical > .btn-group:last-child:not(:first-child) > .action-button:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; - } + .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child, .btn-group-vertical > .btn-group:last-child:not(:first-child) > .action-button:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; + } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .action-button input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], @@ -4770,5349 +4770,5349 @@ tbody.collapse.in { [data-toggle="buttons"] > .btn-group > .action-button input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .action-button input[type="checkbox"] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; } .input-group { - position: relative; - width: 100%; - display: table; - border-collapse: separate; + position: relative; + width: 100%; + display: table; + border-collapse: separate; } - .input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0; - } + .input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; + } - .input-group .form-control:focus, .input-group .form-control:active, .input-group .form-control:hover { - z-index: 3; - } + .input-group .form-control:focus, .input-group .form-control:active, .input-group .form-control:hover { + z-index: 3; + } - .input-group-addon, - .input-group-btn, - .input-group .form-control { - display: table-cell; - } + .input-group-addon, + .input-group-btn, + .input-group .form-control { + display: table-cell; + } - .input-group-addon:not(:first-child):not(:last-child), - .input-group-btn:not(:first-child):not(:last-child), - .input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; - } + .input-group-addon:not(:first-child):not(:last-child), + .input-group-btn:not(:first-child):not(:last-child), + .input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; + } .input-group-addon, .input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; + width: 1%; + white-space: nowrap; + vertical-align: middle; } .input-group-addon { - padding: 0.5rem 0.75rem; - margin-bottom: 0; - font-size: 1rem; - font-weight: normal; - line-height: 1.25; - color: #55595c; - text-align: center; - background-color: #eceeef; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: normal; + line-height: 1.25; + color: #55595c; + text-align: center; + background-color: #eceeef; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; } - .input-group-addon.form-control-sm, - .input-group-sm > .input-group-addon, - .input-group-sm > .input-group-btn > .input-group-addon.btn, - .input-group-sm > .input-group-btn > .input-group-addon.action-button { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; - } + .input-group-addon.form-control-sm, + .input-group-sm > .input-group-addon, + .input-group-sm > .input-group-btn > .input-group-addon.btn, + .input-group-sm > .input-group-btn > .input-group-addon.action-button { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; + } - .input-group-addon.form-control-lg, - .input-group-lg > .input-group-addon, - .input-group-lg > .input-group-btn > .input-group-addon.btn, - .input-group-lg > .input-group-btn > .input-group-addon.action-button { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; - border-radius: 0.3rem; - } + .input-group-addon.form-control-lg, + .input-group-lg > .input-group-addon, + .input-group-lg > .input-group-btn > .input-group-addon.btn, + .input-group-lg > .input-group-btn > .input-group-addon.action-button { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + border-radius: 0.3rem; + } - .input-group-addon input[type="radio"], - .input-group-addon input[type="checkbox"] { - margin-top: 0; - } + .input-group-addon input[type="radio"], + .input-group-addon input[type="checkbox"] { + margin-top: 0; + } - .input-group .form-control:not(:last-child), - .input-group-addon:not(:last-child), - .input-group-btn:not(:last-child) > .btn, - .input-group-btn:not(:last-child) > .action-button, - .input-group-btn:not(:last-child) > .btn-group > .btn, - .input-group-btn:not(:last-child) > .btn-group > .action-button, - .input-group-btn:not(:last-child) > .dropdown-toggle, - .input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle), - .input-group-btn:not(:first-child) > .action-button:not(:last-child):not(.dropdown-toggle), - .input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn, - .input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .action-button { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } + .input-group .form-control:not(:last-child), + .input-group-addon:not(:last-child), + .input-group-btn:not(:last-child) > .btn, + .input-group-btn:not(:last-child) > .action-button, + .input-group-btn:not(:last-child) > .btn-group > .btn, + .input-group-btn:not(:last-child) > .btn-group > .action-button, + .input-group-btn:not(:last-child) > .dropdown-toggle, + .input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle), + .input-group-btn:not(:first-child) > .action-button:not(:last-child):not(.dropdown-toggle), + .input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn, + .input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .action-button { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } - .input-group-addon:not(:last-child) { - border-right: 0; - } + .input-group-addon:not(:last-child) { + border-right: 0; + } - .input-group .form-control:not(:first-child), - .input-group-addon:not(:first-child), - .input-group-btn:not(:first-child) > .btn, - .input-group-btn:not(:first-child) > .action-button, - .input-group-btn:not(:first-child) > .btn-group > .btn, - .input-group-btn:not(:first-child) > .btn-group > .action-button, - .input-group-btn:not(:first-child) > .dropdown-toggle, - .input-group-btn:not(:last-child) > .btn:not(:first-child), - .input-group-btn:not(:last-child) > .action-button:not(:first-child), - .input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn, - .input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .action-button { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } + .input-group .form-control:not(:first-child), + .input-group-addon:not(:first-child), + .input-group-btn:not(:first-child) > .btn, + .input-group-btn:not(:first-child) > .action-button, + .input-group-btn:not(:first-child) > .btn-group > .btn, + .input-group-btn:not(:first-child) > .btn-group > .action-button, + .input-group-btn:not(:first-child) > .dropdown-toggle, + .input-group-btn:not(:last-child) > .btn:not(:first-child), + .input-group-btn:not(:last-child) > .action-button:not(:first-child), + .input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn, + .input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .action-button { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } .form-control + .input-group-addon:not(:first-child) { - border-left: 0; + border-left: 0; } .input-group-btn { - position: relative; - font-size: 0; - white-space: nowrap; + position: relative; + font-size: 0; + white-space: nowrap; } - .input-group-btn > .btn, .input-group-btn > .action-button { - position: relative; - } + .input-group-btn > .btn, .input-group-btn > .action-button { + position: relative; + } - .input-group-btn > .btn + .btn, .input-group-btn > .action-button + .btn, .input-group-btn > .btn + .action-button, .input-group-btn > .action-button + .action-button { - margin-left: -1px; - } + .input-group-btn > .btn + .btn, .input-group-btn > .action-button + .btn, .input-group-btn > .btn + .action-button, .input-group-btn > .action-button + .action-button { + margin-left: -1px; + } - .input-group-btn > .btn:focus, .input-group-btn > .action-button:focus, .input-group-btn > .btn:active, .input-group-btn > .action-button:active, .input-group-btn > .btn:hover, .input-group-btn > .action-button:hover { - z-index: 3; - } + .input-group-btn > .btn:focus, .input-group-btn > .action-button:focus, .input-group-btn > .btn:active, .input-group-btn > .action-button:active, .input-group-btn > .btn:hover, .input-group-btn > .action-button:hover { + z-index: 3; + } - .input-group-btn:not(:last-child) > .btn, .input-group-btn:not(:last-child) > .action-button, - .input-group-btn:not(:last-child) > .btn-group { - margin-right: -1px; - } + .input-group-btn:not(:last-child) > .btn, .input-group-btn:not(:last-child) > .action-button, + .input-group-btn:not(:last-child) > .btn-group { + margin-right: -1px; + } - .input-group-btn:not(:first-child) > .btn, .input-group-btn:not(:first-child) > .action-button, - .input-group-btn:not(:first-child) > .btn-group { - z-index: 2; - margin-left: -1px; - } + .input-group-btn:not(:first-child) > .btn, .input-group-btn:not(:first-child) > .action-button, + .input-group-btn:not(:first-child) > .btn-group { + z-index: 2; + margin-left: -1px; + } - .input-group-btn:not(:first-child) > .btn:focus, .input-group-btn:not(:first-child) > .action-button:focus, .input-group-btn:not(:first-child) > .btn:active, .input-group-btn:not(:first-child) > .action-button:active, .input-group-btn:not(:first-child) > .btn:hover, .input-group-btn:not(:first-child) > .action-button:hover, - .input-group-btn:not(:first-child) > .btn-group:focus, - .input-group-btn:not(:first-child) > .btn-group:active, - .input-group-btn:not(:first-child) > .btn-group:hover { - z-index: 3; - } + .input-group-btn:not(:first-child) > .btn:focus, .input-group-btn:not(:first-child) > .action-button:focus, .input-group-btn:not(:first-child) > .btn:active, .input-group-btn:not(:first-child) > .action-button:active, .input-group-btn:not(:first-child) > .btn:hover, .input-group-btn:not(:first-child) > .action-button:hover, + .input-group-btn:not(:first-child) > .btn-group:focus, + .input-group-btn:not(:first-child) > .btn-group:active, + .input-group-btn:not(:first-child) > .btn-group:hover { + z-index: 3; + } .custom-control { - position: relative; - display: inline-block; - padding-left: 1.5rem; - cursor: pointer; + position: relative; + display: inline-block; + padding-left: 1.5rem; + cursor: pointer; } - .custom-control + .custom-control { - margin-left: 1rem; - } + .custom-control + .custom-control { + margin-left: 1rem; + } .custom-control-input { - position: absolute; - z-index: -1; - opacity: 0; + position: absolute; + z-index: -1; + opacity: 0; } - .custom-control-input:checked ~ .custom-control-indicator { - color: #fff; - background-color: #0074d9; - } + .custom-control-input:checked ~ .custom-control-indicator { + color: #fff; + background-color: #0074d9; + } - .custom-control-input:focus ~ .custom-control-indicator { - box-shadow: 0 0 0 0.075rem #fff, 0 0 0 0.2rem #0074d9; - } + .custom-control-input:focus ~ .custom-control-indicator { + box-shadow: 0 0 0 0.075rem #fff, 0 0 0 0.2rem #0074d9; + } - .custom-control-input:active ~ .custom-control-indicator { - color: #fff; - background-color: #84c6ff; - } + .custom-control-input:active ~ .custom-control-indicator { + color: #fff; + background-color: #84c6ff; + } - .custom-control-input:disabled ~ .custom-control-indicator { - cursor: not-allowed; - background-color: #eee; - } + .custom-control-input:disabled ~ .custom-control-indicator { + cursor: not-allowed; + background-color: #eee; + } - .custom-control-input:disabled ~ .custom-control-description { - color: #767676; - cursor: not-allowed; - } + .custom-control-input:disabled ~ .custom-control-description { + color: #767676; + cursor: not-allowed; + } .custom-control-indicator { - position: absolute; - top: .25rem; - left: 0; - display: block; - width: 1rem; - height: 1rem; - pointer-events: none; - user-select: none; - background-color: #ddd; - background-repeat: no-repeat; - background-position: center center; - background-size: 50% 50%; + position: absolute; + top: .25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + user-select: none; + background-color: #ddd; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; } .custom-checkbox .custom-control-indicator { - border-radius: 0.25rem; + border-radius: 0.25rem; } .custom-checkbox .custom-control-input:checked ~ .custom-control-indicator { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); } .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-indicator { - background-color: #0074d9; - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#fff' d='M0 2h4'/%3E%3C/svg%3E"); + background-color: #0074d9; + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#fff' d='M0 2h4'/%3E%3C/svg%3E"); } .custom-radio .custom-control-indicator { - border-radius: 50%; + border-radius: 50%; } .custom-radio .custom-control-input:checked ~ .custom-control-indicator { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#fff'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#fff'/%3E%3C/svg%3E"); } .custom-controls-stacked .custom-control { - float: left; - clear: left; + float: left; + clear: left; } - .custom-controls-stacked .custom-control + .custom-control { - margin-left: 0; - } + .custom-controls-stacked .custom-control + .custom-control { + margin-left: 0; + } .custom-select { - display: inline-block; - max-width: 100%; - height: calc(2.5rem - 2px); - padding: 0.375rem 1.75rem 0.375rem 0.75rem; - padding-right: 0.75rem \9; - color: #55595c; - vertical-align: middle; - background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; - background-image: none \9; - background-size: 8px 10px; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; - -moz-appearance: none; - -webkit-appearance: none; + display: inline-block; + max-width: 100%; + height: calc(2.5rem - 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + padding-right: 0.75rem \9; + color: #55595c; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; + background-image: none \9; + background-size: 8px 10px; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + -moz-appearance: none; + -webkit-appearance: none; } - .custom-select:focus { - border-color: #51a7e8; - outline: none; - } + .custom-select:focus { + border-color: #51a7e8; + outline: none; + } - .custom-select:focus::-ms-value { - color: #55595c; - background-color: #fff; - } + .custom-select:focus::-ms-value { + color: #55595c; + background-color: #fff; + } - .custom-select:disabled { - color: #818a91; - cursor: not-allowed; - background-color: #eceeef; - } + .custom-select:disabled { + color: #818a91; + cursor: not-allowed; + background-color: #eceeef; + } - .custom-select::-ms-expand { - opacity: 0; - } + .custom-select::-ms-expand { + opacity: 0; + } .custom-select-sm { - padding-top: 0.375rem; - padding-bottom: 0.375rem; - font-size: 75%; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 75%; } .custom-file { - position: relative; - display: inline-block; - max-width: 100%; - height: 2.5rem; - cursor: pointer; + position: relative; + display: inline-block; + max-width: 100%; + height: 2.5rem; + cursor: pointer; } .custom-file-input { - min-width: 14rem; - max-width: 100%; - margin: 0; - filter: alpha(opacity=0); - opacity: 0; + min-width: 14rem; + max-width: 100%; + margin: 0; + filter: alpha(opacity=0); + opacity: 0; } .custom-file-control { - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 5; - height: 2.5rem; - padding: 0.5rem 1rem; - line-height: 1.5; - color: #555; - user-select: none; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 0.25rem; + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 5; + height: 2.5rem; + padding: 0.5rem 1rem; + line-height: 1.5; + color: #555; + user-select: none; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0.25rem; } - .custom-file-control:lang(en)::after { - content: "Choose file..."; - } + .custom-file-control:lang(en)::after { + content: "Choose file..."; + } - .custom-file-control::before { - position: absolute; - top: -1px; - right: -1px; - bottom: -1px; - z-index: 6; - display: block; - height: 2.5rem; - padding: 0.5rem 1rem; - line-height: 1.5; - color: #555; - background-color: #eee; - border: 1px solid #ddd; - border-radius: 0 0.25rem 0.25rem 0; - } + .custom-file-control::before { + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + z-index: 6; + display: block; + height: 2.5rem; + padding: 0.5rem 1rem; + line-height: 1.5; + color: #555; + background-color: #eee; + border: 1px solid #ddd; + border-radius: 0 0.25rem 0.25rem 0; + } - .custom-file-control:lang(en)::before { - content: "Browse"; - } + .custom-file-control:lang(en)::before { + content: "Browse"; + } .nav { - padding-left: 0; - margin-bottom: 0; - list-style: none; + padding-left: 0; + margin-bottom: 0; + list-style: none; } .nav-link { - display: inline-block; + display: inline-block; } - .nav-link:focus, .nav-link:hover { - text-decoration: none; - } + .nav-link:focus, .nav-link:hover { + text-decoration: none; + } - .nav-link.disabled { - color: #818a91; - } + .nav-link.disabled { + color: #818a91; + } - .nav-link.disabled, .nav-link.disabled:focus, .nav-link.disabled:hover { - color: #818a91; - cursor: not-allowed; - background-color: transparent; - } + .nav-link.disabled, .nav-link.disabled:focus, .nav-link.disabled:hover { + color: #818a91; + cursor: not-allowed; + background-color: transparent; + } .nav-inline .nav-item { - display: inline-block; + display: inline-block; } - .nav-inline .nav-item + .nav-item, - .nav-inline .nav-link + .nav-link { - margin-left: 1rem; - } + .nav-inline .nav-item + .nav-item, + .nav-inline .nav-link + .nav-link { + margin-left: 1rem; + } .nav-tabs { - border-bottom: 1px solid #ddd; + border-bottom: 1px solid #ddd; } - .nav-tabs::after { - content: ""; - display: table; - clear: both; - } + .nav-tabs::after { + content: ""; + display: table; + clear: both; + } - .nav-tabs .nav-item { - float: left; - margin-bottom: -1px; - } + .nav-tabs .nav-item { + float: left; + margin-bottom: -1px; + } - .nav-tabs .nav-item + .nav-item { - margin-left: 0.2rem; - } + .nav-tabs .nav-item + .nav-item { + margin-left: 0.2rem; + } - .nav-tabs .nav-link { - display: block; - padding: 0.5em 1em; - border: 1px solid transparent; - border-top-right-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .nav-tabs .nav-link { + display: block; + padding: 0.5em 1em; + border: 1px solid transparent; + border-top-right-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { - border-color: #eceeef #eceeef #ddd; - } + .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + border-color: #eceeef #eceeef #ddd; + } - .nav-tabs .nav-link.disabled, .nav-tabs .nav-link.disabled:focus, .nav-tabs .nav-link.disabled:hover { - color: #818a91; - background-color: transparent; - border-color: transparent; - } + .nav-tabs .nav-link.disabled, .nav-tabs .nav-link.disabled:focus, .nav-tabs .nav-link.disabled:hover { + color: #818a91; + background-color: transparent; + border-color: transparent; + } - .nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover, - .nav-tabs .nav-item.open .nav-link, - .nav-tabs .nav-item.open .nav-link:focus, - .nav-tabs .nav-item.open .nav-link:hover { - color: #55595c; - background-color: #fff; - border-color: #ddd #ddd transparent; - } + .nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover, + .nav-tabs .nav-item.open .nav-link, + .nav-tabs .nav-item.open .nav-link:focus, + .nav-tabs .nav-item.open .nav-link:hover { + color: #55595c; + background-color: #fff; + border-color: #ddd #ddd transparent; + } - .nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; - } + .nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; + } .nav-pills::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } .nav-pills .nav-item { - float: left; + float: left; } - .nav-pills .nav-item + .nav-item { - margin-left: 0.2rem; - } + .nav-pills .nav-item + .nav-item { + margin-left: 0.2rem; + } .nav-pills .nav-link { - display: block; - padding: 0.5em 1em; - border-radius: 0.25rem; + display: block; + padding: 0.5em 1em; + border-radius: 0.25rem; } - .nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover, - .nav-pills .nav-item.open .nav-link, - .nav-pills .nav-item.open .nav-link:focus, - .nav-pills .nav-item.open .nav-link:hover { - color: #fff; - cursor: default; - background-color: #214497; - } + .nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover, + .nav-pills .nav-item.open .nav-link, + .nav-pills .nav-item.open .nav-link:focus, + .nav-pills .nav-item.open .nav-link:hover { + color: #fff; + cursor: default; + background-color: #214497; + } .nav-stacked .nav-item { - display: block; - float: none; + display: block; + float: none; } - .nav-stacked .nav-item + .nav-item { - margin-top: 0.2rem; - margin-left: 0; - } + .nav-stacked .nav-item + .nav-item { + margin-top: 0.2rem; + margin-left: 0; + } .tab-content > .tab-pane { - display: none; + display: none; } .tab-content > .active { - display: block; + display: block; } .navbar { - position: relative; - padding: 0.5rem 1rem; + position: relative; + padding: 0.5rem 1rem; } - .navbar::after { - content: ""; - display: table; - clear: both; - } + .navbar::after { + content: ""; + display: table; + clear: both; + } @media (min-width: 576px) { - .navbar { - border-radius: 0.25rem; - } + .navbar { + border-radius: 0.25rem; + } } .navbar-full { - z-index: 1000; + z-index: 1000; } @media (min-width: 576px) { - .navbar-full { - border-radius: 0; - } + .navbar-full { + border-radius: 0; + } } .navbar-fixed-top, .navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; + position: fixed; + right: 0; + left: 0; + z-index: 1030; } @media (min-width: 576px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } } .navbar-fixed-top { - top: 0; + top: 0; } .navbar-fixed-bottom { - bottom: 0; + bottom: 0; } .navbar-sticky-top { - position: sticky; - top: 0; - z-index: 1030; - width: 100%; + position: sticky; + top: 0; + z-index: 1030; + width: 100%; } @media (min-width: 576px) { - .navbar-sticky-top { - border-radius: 0; - } + .navbar-sticky-top { + border-radius: 0; + } } .navbar-brand { - float: left; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - margin-right: 1rem; - font-size: 1.25rem; - line-height: inherit; + float: left; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; } - .navbar-brand:focus, .navbar-brand:hover { - text-decoration: none; - } + .navbar-brand:focus, .navbar-brand:hover { + text-decoration: none; + } .navbar-divider { - float: left; - width: 1px; - padding-top: 0.425rem; - padding-bottom: 0.425rem; - margin-right: 1rem; - margin-left: 1rem; - overflow: hidden; + float: left; + width: 1px; + padding-top: 0.425rem; + padding-bottom: 0.425rem; + margin-right: 1rem; + margin-left: 1rem; + overflow: hidden; } - .navbar-divider::before { - content: "\A0"; - } + .navbar-divider::before { + content: "\A0"; + } .navbar-text { - display: inline-block; - padding-top: .425rem; - padding-bottom: .425rem; + display: inline-block; + padding-top: .425rem; + padding-bottom: .425rem; } .navbar-toggler { - width: 2.5em; - height: 2em; - padding: 0.5rem 0.75rem; - font-size: 1.25rem; - line-height: 1; - background: transparent no-repeat center center; - background-size: 24px 24px; - border: 1px solid transparent; - border-radius: 0.25rem; + width: 2.5em; + height: 2em; + padding: 0.5rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background: transparent no-repeat center center; + background-size: 24px 24px; + border: 1px solid transparent; + border-radius: 0.25rem; } - .navbar-toggler:focus, .navbar-toggler:hover { - text-decoration: none; - } + .navbar-toggler:focus, .navbar-toggler:hover { + text-decoration: none; + } .navbar-toggleable-xs::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 575px) { - .navbar-toggleable-xs .navbar-brand { - display: block; - float: none; - margin-top: .5rem; - margin-right: 0; - } + .navbar-toggleable-xs .navbar-brand { + display: block; + float: none; + margin-top: .5rem; + margin-right: 0; + } - .navbar-toggleable-xs .navbar-nav { - margin-top: .5rem; - margin-bottom: .5rem; - } + .navbar-toggleable-xs .navbar-nav { + margin-top: .5rem; + margin-bottom: .5rem; + } - .navbar-toggleable-xs .navbar-nav .dropdown-menu { - position: static; - float: none; - } + .navbar-toggleable-xs .navbar-nav .dropdown-menu { + position: static; + float: none; + } } @media (min-width: 576px) { - .navbar-toggleable-xs { - display: block; - } + .navbar-toggleable-xs { + display: block; + } } .navbar-toggleable-sm::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 767px) { - .navbar-toggleable-sm .navbar-brand { - display: block; - float: none; - margin-top: .5rem; - margin-right: 0; - } + .navbar-toggleable-sm .navbar-brand { + display: block; + float: none; + margin-top: .5rem; + margin-right: 0; + } - .navbar-toggleable-sm .navbar-nav { - margin-top: .5rem; - margin-bottom: .5rem; - } + .navbar-toggleable-sm .navbar-nav { + margin-top: .5rem; + margin-bottom: .5rem; + } - .navbar-toggleable-sm .navbar-nav .dropdown-menu { - position: static; - float: none; - } + .navbar-toggleable-sm .navbar-nav .dropdown-menu { + position: static; + float: none; + } } @media (min-width: 768px) { - .navbar-toggleable-sm { - display: block; - } + .navbar-toggleable-sm { + display: block; + } } .navbar-toggleable-md::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 991px) { - .navbar-toggleable-md .navbar-brand { - display: block; - float: none; - margin-top: .5rem; - margin-right: 0; - } + .navbar-toggleable-md .navbar-brand { + display: block; + float: none; + margin-top: .5rem; + margin-right: 0; + } - .navbar-toggleable-md .navbar-nav { - margin-top: .5rem; - margin-bottom: .5rem; - } + .navbar-toggleable-md .navbar-nav { + margin-top: .5rem; + margin-bottom: .5rem; + } - .navbar-toggleable-md .navbar-nav .dropdown-menu { - position: static; - float: none; - } + .navbar-toggleable-md .navbar-nav .dropdown-menu { + position: static; + float: none; + } } @media (min-width: 992px) { - .navbar-toggleable-md { - display: block; - } + .navbar-toggleable-md { + display: block; + } } .navbar-toggleable-lg::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 1199px) { - .navbar-toggleable-lg .navbar-brand { - display: block; - float: none; - margin-top: .5rem; - margin-right: 0; - } + .navbar-toggleable-lg .navbar-brand { + display: block; + float: none; + margin-top: .5rem; + margin-right: 0; + } - .navbar-toggleable-lg .navbar-nav { - margin-top: .5rem; - margin-bottom: .5rem; - } + .navbar-toggleable-lg .navbar-nav { + margin-top: .5rem; + margin-bottom: .5rem; + } - .navbar-toggleable-lg .navbar-nav .dropdown-menu { - position: static; - float: none; - } + .navbar-toggleable-lg .navbar-nav .dropdown-menu { + position: static; + float: none; + } } @media (min-width: 1200px) { - .navbar-toggleable-lg { - display: block; - } + .navbar-toggleable-lg { + display: block; + } } .navbar-toggleable-xl { - display: block; + display: block; } - .navbar-toggleable-xl::after { - content: ""; - display: table; - clear: both; - } + .navbar-toggleable-xl::after { + content: ""; + display: table; + clear: both; + } - .navbar-toggleable-xl .navbar-brand { - display: block; - float: none; - margin-top: .5rem; - margin-right: 0; - } + .navbar-toggleable-xl .navbar-brand { + display: block; + float: none; + margin-top: .5rem; + margin-right: 0; + } - .navbar-toggleable-xl .navbar-nav { - margin-top: .5rem; - margin-bottom: .5rem; - } + .navbar-toggleable-xl .navbar-nav { + margin-top: .5rem; + margin-bottom: .5rem; + } - .navbar-toggleable-xl .navbar-nav .dropdown-menu { - position: static; - float: none; - } + .navbar-toggleable-xl .navbar-nav .dropdown-menu { + position: static; + float: none; + } .navbar-nav .nav-item { - float: left; + float: left; } .navbar-nav .nav-link { - display: block; - padding-top: .425rem; - padding-bottom: .425rem; + display: block; + padding-top: .425rem; + padding-bottom: .425rem; } - .navbar-nav .nav-link + .nav-link { - margin-left: 1rem; - } + .navbar-nav .nav-link + .nav-link { + margin-left: 1rem; + } .navbar-nav .nav-item + .nav-item { - margin-left: 1rem; + margin-left: 1rem; } .navbar-light .navbar-brand, .navbar-light .navbar-toggler { - color: rgba(0, 0, 0, 0.9); + color: rgba(0, 0, 0, 0.9); } - .navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover, - .navbar-light .navbar-toggler:focus, - .navbar-light .navbar-toggler:hover { - color: rgba(0, 0, 0, 0.9); - } + .navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover, + .navbar-light .navbar-toggler:focus, + .navbar-light .navbar-toggler:hover { + color: rgba(0, 0, 0, 0.9); + } .navbar-light .navbar-nav .nav-link { - color: rgba(0, 0, 0, 0.5); + color: rgba(0, 0, 0, 0.5); } - .navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { - color: rgba(0, 0, 0, 0.7); - } + .navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { + color: rgba(0, 0, 0, 0.7); + } - .navbar-light .navbar-nav .open > .nav-link, .navbar-light .navbar-nav .open > .nav-link:focus, .navbar-light .navbar-nav .open > .nav-link:hover, - .navbar-light .navbar-nav .active > .nav-link, - .navbar-light .navbar-nav .active > .nav-link:focus, - .navbar-light .navbar-nav .active > .nav-link:hover, - .navbar-light .navbar-nav .nav-link.open, - .navbar-light .navbar-nav .nav-link.open:focus, - .navbar-light .navbar-nav .nav-link.open:hover, - .navbar-light .navbar-nav .nav-link.active, - .navbar-light .navbar-nav .nav-link.active:focus, - .navbar-light .navbar-nav .nav-link.active:hover { - color: rgba(0, 0, 0, 0.9); - } + .navbar-light .navbar-nav .open > .nav-link, .navbar-light .navbar-nav .open > .nav-link:focus, .navbar-light .navbar-nav .open > .nav-link:hover, + .navbar-light .navbar-nav .active > .nav-link, + .navbar-light .navbar-nav .active > .nav-link:focus, + .navbar-light .navbar-nav .active > .nav-link:hover, + .navbar-light .navbar-nav .nav-link.open, + .navbar-light .navbar-nav .nav-link.open:focus, + .navbar-light .navbar-nav .nav-link.open:hover, + .navbar-light .navbar-nav .nav-link.active, + .navbar-light .navbar-nav .nav-link.active:focus, + .navbar-light .navbar-nav .nav-link.active:hover { + color: rgba(0, 0, 0, 0.9); + } .navbar-light .navbar-toggler { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E"); - border-color: rgba(0, 0, 0, 0.1); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E"); + border-color: rgba(0, 0, 0, 0.1); } .navbar-light .navbar-divider { - background-color: rgba(0, 0, 0, 0.075); + background-color: rgba(0, 0, 0, 0.075); } .navbar-dark .navbar-brand, .navbar-dark .navbar-toggler { - color: white; + color: white; } - .navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover, - .navbar-dark .navbar-toggler:focus, - .navbar-dark .navbar-toggler:hover { - color: white; - } + .navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover, + .navbar-dark .navbar-toggler:focus, + .navbar-dark .navbar-toggler:hover { + color: white; + } .navbar-dark .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.5); + color: rgba(255, 255, 255, 0.5); } - .navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { - color: rgba(255, 255, 255, 0.75); - } + .navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { + color: rgba(255, 255, 255, 0.75); + } - .navbar-dark .navbar-nav .open > .nav-link, .navbar-dark .navbar-nav .open > .nav-link:focus, .navbar-dark .navbar-nav .open > .nav-link:hover, - .navbar-dark .navbar-nav .active > .nav-link, - .navbar-dark .navbar-nav .active > .nav-link:focus, - .navbar-dark .navbar-nav .active > .nav-link:hover, - .navbar-dark .navbar-nav .nav-link.open, - .navbar-dark .navbar-nav .nav-link.open:focus, - .navbar-dark .navbar-nav .nav-link.open:hover, - .navbar-dark .navbar-nav .nav-link.active, - .navbar-dark .navbar-nav .nav-link.active:focus, - .navbar-dark .navbar-nav .nav-link.active:hover { - color: white; - } + .navbar-dark .navbar-nav .open > .nav-link, .navbar-dark .navbar-nav .open > .nav-link:focus, .navbar-dark .navbar-nav .open > .nav-link:hover, + .navbar-dark .navbar-nav .active > .nav-link, + .navbar-dark .navbar-nav .active > .nav-link:focus, + .navbar-dark .navbar-nav .active > .nav-link:hover, + .navbar-dark .navbar-nav .nav-link.open, + .navbar-dark .navbar-nav .nav-link.open:focus, + .navbar-dark .navbar-nav .nav-link.open:hover, + .navbar-dark .navbar-nav .nav-link.active, + .navbar-dark .navbar-nav .nav-link.active:focus, + .navbar-dark .navbar-nav .nav-link.active:hover { + color: white; + } .navbar-dark .navbar-toggler { - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E"); - border-color: rgba(255, 255, 255, 0.1); + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E"); + border-color: rgba(255, 255, 255, 0.1); } .navbar-dark .navbar-divider { - background-color: rgba(255, 255, 255, 0.075); + background-color: rgba(255, 255, 255, 0.075); } .navbar-toggleable-xs::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 575px) { - .navbar-toggleable-xs .navbar-nav .nav-item { - float: none; - margin-left: 0; - } + .navbar-toggleable-xs .navbar-nav .nav-item { + float: none; + margin-left: 0; + } } @media (min-width: 576px) { - .navbar-toggleable-xs { - display: block !important; - } + .navbar-toggleable-xs { + display: block !important; + } } .navbar-toggleable-sm::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 767px) { - .navbar-toggleable-sm .navbar-nav .nav-item { - float: none; - margin-left: 0; - } + .navbar-toggleable-sm .navbar-nav .nav-item { + float: none; + margin-left: 0; + } } @media (min-width: 768px) { - .navbar-toggleable-sm { - display: block !important; - } + .navbar-toggleable-sm { + display: block !important; + } } .navbar-toggleable-md::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } @media (max-width: 991px) { - .navbar-toggleable-md .navbar-nav .nav-item { - float: none; - margin-left: 0; - } + .navbar-toggleable-md .navbar-nav .nav-item { + float: none; + margin-left: 0; + } } @media (min-width: 992px) { - .navbar-toggleable-md { - display: block !important; - } + .navbar-toggleable-md { + display: block !important; + } } .card { - position: relative; - display: block; - margin-bottom: 0.75rem; - background-color: #fff; - border-radius: 0.25rem; - border: 1px solid rgba(0, 0, 0, 0.125); + position: relative; + display: block; + margin-bottom: 0.75rem; + background-color: #fff; + border-radius: 0.25rem; + border: 1px solid rgba(0, 0, 0, 0.125); } .card-block { - padding: 1.25rem; + padding: 1.25rem; } - .card-block::after { - content: ""; - display: table; - clear: both; - } + .card-block::after { + content: ""; + display: table; + clear: both; + } .card-title { - margin-bottom: 0.75rem; + margin-bottom: 0.75rem; } .card-subtitle { - margin-top: -0.375rem; - margin-bottom: 0; + margin-top: -0.375rem; + margin-bottom: 0; } .card-text:last-child { - margin-bottom: 0; + margin-bottom: 0; } .card-link:hover { - text-decoration: none; + text-decoration: none; } .card-link + .card-link { - margin-left: 1.25rem; + margin-left: 1.25rem; } .card > .list-group:first-child .list-group-item:first-child { - border-top-right-radius: 0.25rem; - border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + border-top-left-radius: 0.25rem; } .card > .list-group:last-child .list-group-item:last-child { - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; } .card-header { - padding: 0.75rem 1.25rem; - margin-bottom: 0; - background-color: #f5f5f5; - border-bottom: 1px solid rgba(0, 0, 0, 0.125); + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: #f5f5f5; + border-bottom: 1px solid rgba(0, 0, 0, 0.125); } - .card-header::after { - content: ""; - display: table; - clear: both; - } + .card-header::after { + content: ""; + display: table; + clear: both; + } - .card-header:first-child { - border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; - } + .card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; + } .card-footer { - padding: 0.75rem 1.25rem; - background-color: #f5f5f5; - border-top: 1px solid rgba(0, 0, 0, 0.125); + padding: 0.75rem 1.25rem; + background-color: #f5f5f5; + border-top: 1px solid rgba(0, 0, 0, 0.125); } - .card-footer::after { - content: ""; - display: table; - clear: both; - } + .card-footer::after { + content: ""; + display: table; + clear: both; + } - .card-footer:last-child { - border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); - } + .card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); + } .card-header-tabs { - margin-right: -0.625rem; - margin-bottom: -0.75rem; - margin-left: -0.625rem; - border-bottom: 0; + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; } .card-header-pills { - margin-right: -0.625rem; - margin-left: -0.625rem; + margin-right: -0.625rem; + margin-left: -0.625rem; } .card-primary { - background-color: #214497; - border-color: #214497; + background-color: #214497; + border-color: #214497; } - .card-primary .card-header, - .card-primary .card-footer { - background-color: transparent; - } + .card-primary .card-header, + .card-primary .card-footer { + background-color: transparent; + } .card-success { - background-color: #5cb85c; - border-color: #5cb85c; + background-color: #5cb85c; + border-color: #5cb85c; } - .card-success .card-header, - .card-success .card-footer { - background-color: transparent; - } + .card-success .card-header, + .card-success .card-footer { + background-color: transparent; + } .card-info { - background-color: #5bc0de; - border-color: #5bc0de; + background-color: #5bc0de; + border-color: #5bc0de; } - .card-info .card-header, - .card-info .card-footer { - background-color: transparent; - } + .card-info .card-header, + .card-info .card-footer { + background-color: transparent; + } .card-warning { - background-color: #f0ad4e; - border-color: #f0ad4e; + background-color: #f0ad4e; + border-color: #f0ad4e; } - .card-warning .card-header, - .card-warning .card-footer { - background-color: transparent; - } + .card-warning .card-header, + .card-warning .card-footer { + background-color: transparent; + } .card-danger { - background-color: #d9534f; - border-color: #d9534f; + background-color: #d9534f; + border-color: #d9534f; } - .card-danger .card-header, - .card-danger .card-footer { - background-color: transparent; - } + .card-danger .card-header, + .card-danger .card-footer { + background-color: transparent; + } .card-outline-primary { - background-color: transparent; - border-color: #214497; + background-color: transparent; + border-color: #214497; } .card-outline-secondary { - background-color: transparent; - border-color: #ccc; + background-color: transparent; + border-color: #ccc; } .card-outline-info { - background-color: transparent; - border-color: #5bc0de; + background-color: transparent; + border-color: #5bc0de; } .card-outline-success { - background-color: transparent; - border-color: #5cb85c; + background-color: transparent; + border-color: #5cb85c; } .card-outline-warning { - background-color: transparent; - border-color: #f0ad4e; + background-color: transparent; + border-color: #f0ad4e; } .card-outline-danger { - background-color: transparent; - border-color: #d9534f; + background-color: transparent; + border-color: #d9534f; } .card-inverse .card-header, .card-inverse .card-footer { - border-color: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.2); } .card-inverse .card-header, .card-inverse .card-footer, .card-inverse .card-title, .card-inverse .card-blockquote { - color: #fff; + color: #fff; } - .card-inverse .card-link, - .card-inverse .card-text, - .card-inverse .card-subtitle, - .card-inverse .card-blockquote .blockquote-footer { - color: rgba(255, 255, 255, 0.65); - } + .card-inverse .card-link, + .card-inverse .card-text, + .card-inverse .card-subtitle, + .card-inverse .card-blockquote .blockquote-footer { + color: rgba(255, 255, 255, 0.65); + } - .card-inverse .card-link:focus, .card-inverse .card-link:hover { - color: #fff; - } + .card-inverse .card-link:focus, .card-inverse .card-link:hover { + color: #fff; + } .card-blockquote { - padding: 0; - margin-bottom: 0; - border-left: 0; + padding: 0; + margin-bottom: 0; + border-left: 0; } .card-img { - border-radius: calc(0.25rem - 1px); + border-radius: calc(0.25rem - 1px); } .card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 1.25rem; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; } .card-img-top { - border-top-right-radius: calc(0.25rem - 1px); - border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); + border-top-left-radius: calc(0.25rem - 1px); } .card-img-bottom { - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); } @media (min-width: 576px) { - .card-deck { - display: table; - width: 100%; - margin-bottom: 0.75rem; - table-layout: fixed; - border-spacing: 1.25rem 0; - } + .card-deck { + display: table; + width: 100%; + margin-bottom: 0.75rem; + table-layout: fixed; + border-spacing: 1.25rem 0; + } - .card-deck .card { - display: table-cell; - margin-bottom: 0; - vertical-align: top; - } + .card-deck .card { + display: table-cell; + margin-bottom: 0; + vertical-align: top; + } - .card-deck-wrapper { - margin-right: -1.25rem; - margin-left: -1.25rem; - } + .card-deck-wrapper { + margin-right: -1.25rem; + margin-left: -1.25rem; + } } @media (min-width: 576px) { - .card-group { - display: table; - width: 100%; - table-layout: fixed; - } + .card-group { + display: table; + width: 100%; + table-layout: fixed; + } - .card-group .card { - display: table-cell; - vertical-align: top; - } + .card-group .card { + display: table-cell; + vertical-align: top; + } - .card-group .card + .card { - margin-left: 0; - border-left: 0; - } + .card-group .card + .card { + margin-left: 0; + border-left: 0; + } - .card-group .card:first-child { - border-bottom-right-radius: 0; - border-top-right-radius: 0; - } + .card-group .card:first-child { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } - .card-group .card:first-child .card-img-top { - border-top-right-radius: 0; - } + .card-group .card:first-child .card-img-top { + border-top-right-radius: 0; + } - .card-group .card:first-child .card-img-bottom { - border-bottom-right-radius: 0; - } + .card-group .card:first-child .card-img-bottom { + border-bottom-right-radius: 0; + } - .card-group .card:last-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } + .card-group .card:last-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } - .card-group .card:last-child .card-img-top { - border-top-left-radius: 0; - } + .card-group .card:last-child .card-img-top { + border-top-left-radius: 0; + } - .card-group .card:last-child .card-img-bottom { - border-bottom-left-radius: 0; - } + .card-group .card:last-child .card-img-bottom { + border-bottom-left-radius: 0; + } - .card-group .card:not(:first-child):not(:last-child) { - border-radius: 0; - } + .card-group .card:not(:first-child):not(:last-child) { + border-radius: 0; + } - .card-group .card:not(:first-child):not(:last-child) .card-img-top, - .card-group .card:not(:first-child):not(:last-child) .card-img-bottom { - border-radius: 0; - } + .card-group .card:not(:first-child):not(:last-child) .card-img-top, + .card-group .card:not(:first-child):not(:last-child) .card-img-bottom { + border-radius: 0; + } } @media (min-width: 576px) { - .card-columns { - column-count: 3; - column-gap: 1.25rem; - } + .card-columns { + column-count: 3; + column-gap: 1.25rem; + } - .card-columns .card { - display: inline-block; - width: 100%; - } + .card-columns .card { + display: inline-block; + width: 100%; + } } .breadcrumb { - padding: 0.75rem 1rem; - margin-bottom: 1rem; - list-style: none; - background-color: #eceeef; - border-radius: 0.25rem; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #eceeef; + border-radius: 0.25rem; } - .breadcrumb::after { - content: ""; - display: table; - clear: both; - } + .breadcrumb::after { + content: ""; + display: table; + clear: both; + } .breadcrumb-item { - float: left; + float: left; } - .breadcrumb-item + .breadcrumb-item::before { - display: inline-block; - padding-right: 0.5rem; - padding-left: 0.5rem; - color: #818a91; - content: "/"; - } + .breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + padding-left: 0.5rem; + color: #818a91; + content: "/"; + } - .breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: underline; - } + .breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; + } - .breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: none; - } + .breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; + } - .breadcrumb-item.active { - color: #818a91; - } + .breadcrumb-item.active { + color: #818a91; + } .pagination { - display: inline-block; - padding-left: 0; - margin-top: 1rem; - margin-bottom: 1rem; - border-radius: 0.25rem; + display: inline-block; + padding-left: 0; + margin-top: 1rem; + margin-bottom: 1rem; + border-radius: 0.25rem; } .page-item { - display: inline; + display: inline; } - .page-item:first-child .page-link { - margin-left: 0; - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .page-item:first-child .page-link { + margin-left: 0; + border-bottom-left-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .page-item:last-child .page-link { - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - } + .page-item:last-child .page-link { + border-bottom-right-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } - .page-item.active .page-link, .page-item.active .page-link:focus, .page-item.active .page-link:hover { - z-index: 2; - color: #fff; - cursor: default; - background-color: #214497; - border-color: #214497; - } + .page-item.active .page-link, .page-item.active .page-link:focus, .page-item.active .page-link:hover { + z-index: 2; + color: #fff; + cursor: default; + background-color: #214497; + border-color: #214497; + } - .page-item.disabled .page-link, .page-item.disabled .page-link:focus, .page-item.disabled .page-link:hover { - color: #818a91; - pointer-events: none; - cursor: not-allowed; - background-color: #fff; - border-color: #ddd; - } + .page-item.disabled .page-link, .page-item.disabled .page-link:focus, .page-item.disabled .page-link:hover { + color: #818a91; + pointer-events: none; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; + } .page-link { - position: relative; - float: left; - padding: 0.5rem 0.75rem; - margin-left: -1px; - color: #214497; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd; + position: relative; + float: left; + padding: 0.5rem 0.75rem; + margin-left: -1px; + color: #214497; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; } - .page-link:focus, .page-link:hover { - color: #132858; - background-color: #eceeef; - border-color: #ddd; - } + .page-link:focus, .page-link:hover { + color: #132858; + background-color: #eceeef; + border-color: #ddd; + } .pagination-lg .page-link { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; + padding: 0.75rem 1.5rem; + font-size: 1.25rem; } .pagination-lg .page-item:first-child .page-link { - border-bottom-left-radius: 0.3rem; - border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; + border-top-left-radius: 0.3rem; } .pagination-lg .page-item:last-child .page-link { - border-bottom-right-radius: 0.3rem; - border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; + border-top-right-radius: 0.3rem; } .pagination-sm .page-link { - padding: 0.275rem 0.75rem; - font-size: 0.875rem; + padding: 0.275rem 0.75rem; + font-size: 0.875rem; } .pagination-sm .page-item:first-child .page-link { - border-bottom-left-radius: 0.2rem; - border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-top-left-radius: 0.2rem; } .pagination-sm .page-item:last-child .page-link { - border-bottom-right-radius: 0.2rem; - border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; + border-top-right-radius: 0.2rem; } .tag { - display: inline-block; - padding: 0.25em 0.4em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 0.25rem; + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; } - .tag:empty { - display: none; - } + .tag:empty { + display: none; + } .btn .tag, .action-button .tag { - position: relative; - top: -1px; + position: relative; + top: -1px; } a.tag:focus, a.tag:hover { - color: #fff; - text-decoration: none; - cursor: pointer; + color: #fff; + text-decoration: none; + cursor: pointer; } .tag-pill { - padding-right: 0.6em; - padding-left: 0.6em; - border-radius: 10rem; + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; } .tag-default { - background-color: #818a91; + background-color: #818a91; } - .tag-default[href]:focus, .tag-default[href]:hover { - background-color: #687077; - } + .tag-default[href]:focus, .tag-default[href]:hover { + background-color: #687077; + } .tag-primary { - background-color: #214497; + background-color: #214497; } - .tag-primary[href]:focus, .tag-primary[href]:hover { - background-color: #18316d; - } + .tag-primary[href]:focus, .tag-primary[href]:hover { + background-color: #18316d; + } .tag-success { - background-color: #5cb85c; + background-color: #5cb85c; } - .tag-success[href]:focus, .tag-success[href]:hover { - background-color: #449d44; - } + .tag-success[href]:focus, .tag-success[href]:hover { + background-color: #449d44; + } .tag-info { - background-color: #5bc0de; + background-color: #5bc0de; } - .tag-info[href]:focus, .tag-info[href]:hover { - background-color: #31b0d5; - } + .tag-info[href]:focus, .tag-info[href]:hover { + background-color: #31b0d5; + } .tag-warning { - background-color: #f0ad4e; + background-color: #f0ad4e; } - .tag-warning[href]:focus, .tag-warning[href]:hover { - background-color: #ec971f; - } + .tag-warning[href]:focus, .tag-warning[href]:hover { + background-color: #ec971f; + } .tag-danger { - background-color: #d9534f; + background-color: #d9534f; } - .tag-danger[href]:focus, .tag-danger[href]:hover { - background-color: #c9302c; - } + .tag-danger[href]:focus, .tag-danger[href]:hover { + background-color: #c9302c; + } .jumbotron { - padding: 2rem 1rem; - margin-bottom: 2rem; - background-color: #eceeef; - border-radius: 0.3rem; + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #eceeef; + border-radius: 0.3rem; } @media (min-width: 576px) { - .jumbotron { - padding: 4rem 2rem; - } + .jumbotron { + padding: 4rem 2rem; + } } .jumbotron-hr { - border-top-color: #d0d5d8; + border-top-color: #d0d5d8; } .jumbotron-fluid { - padding-right: 0; - padding-left: 0; - border-radius: 0; + padding-right: 0; + padding-left: 0; + border-radius: 0; } .alert { - padding: 0.75rem 1.25rem; - margin-bottom: 1rem; - border: 1px solid transparent; - border-radius: 0.25rem; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; } .alert-heading { - color: inherit; + color: inherit; } .alert-link { - font-weight: bold; + font-weight: bold; } .alert-dismissible { - padding-right: 2.5rem; + padding-right: 2.5rem; } - .alert-dismissible .close { - position: relative; - top: -.125rem; - right: -1.25rem; - color: inherit; - } + .alert-dismissible .close { + position: relative; + top: -.125rem; + right: -1.25rem; + color: inherit; + } .alert-success { - background-color: #dff0d8; - border-color: #d0e9c6; - color: #3c763d; + background-color: #dff0d8; + border-color: #d0e9c6; + color: #3c763d; } - .alert-success hr { - border-top-color: #c1e2b3; - } + .alert-success hr { + border-top-color: #c1e2b3; + } - .alert-success .alert-link { - color: #2b542c; - } + .alert-success .alert-link { + color: #2b542c; + } .alert-info { - background-color: #d9edf7; - border-color: #bcdff1; - color: #31708f; + background-color: #d9edf7; + border-color: #bcdff1; + color: #31708f; } - .alert-info hr { - border-top-color: #a6d5ec; - } + .alert-info hr { + border-top-color: #a6d5ec; + } - .alert-info .alert-link { - color: #245269; - } + .alert-info .alert-link { + color: #245269; + } .alert-warning { - background-color: #fcf8e3; - border-color: #faf2cc; - color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faf2cc; + color: #8a6d3b; } - .alert-warning hr { - border-top-color: #f7ecb5; - } + .alert-warning hr { + border-top-color: #f7ecb5; + } - .alert-warning .alert-link { - color: #66512c; - } + .alert-warning .alert-link { + color: #66512c; + } .alert-danger { - background-color: #f2dede; - border-color: #ebcccc; - color: #a94442; + background-color: #f2dede; + border-color: #ebcccc; + color: #a94442; } - .alert-danger hr { - border-top-color: #e4b9b9; - } + .alert-danger hr { + border-top-color: #e4b9b9; + } - .alert-danger .alert-link { - color: #843534; - } + .alert-danger .alert-link { + color: #843534; + } @keyframes progress-bar-stripes { - from { - background-position: 1rem 0; - } + from { + background-position: 1rem 0; + } - to { - background-position: 0 0; - } + to { + background-position: 0 0; + } } .progress { - display: block; - width: 100%; - height: 1rem; - margin-bottom: 1rem; + display: block; + width: 100%; + height: 1rem; + margin-bottom: 1rem; } - .progress[value] { - background-color: #eee; - border: 0; - appearance: none; - border-radius: 0.25rem; - } + .progress[value] { + background-color: #eee; + border: 0; + appearance: none; + border-radius: 0.25rem; + } - .progress[value]::-ms-fill { - background-color: #0074d9; - border: 0; - } + .progress[value]::-ms-fill { + background-color: #0074d9; + border: 0; + } - .progress[value]::-moz-progress-bar { - background-color: #0074d9; - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .progress[value]::-moz-progress-bar { + background-color: #0074d9; + border-bottom-left-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .progress[value]::-webkit-progress-value { - background-color: #0074d9; - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .progress[value]::-webkit-progress-value { + background-color: #0074d9; + border-bottom-left-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .progress[value="100"]::-moz-progress-bar { - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - } + .progress[value="100"]::-moz-progress-bar { + border-bottom-right-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } - .progress[value="100"]::-webkit-progress-value { - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - } + .progress[value="100"]::-webkit-progress-value { + border-bottom-right-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } - .progress[value]::-webkit-progress-bar { - background-color: #eee; - border-radius: 0.25rem; - } + .progress[value]::-webkit-progress-bar { + background-color: #eee; + border-radius: 0.25rem; + } - base::-moz-progress-bar, - .progress[value] { - background-color: #eee; - border-radius: 0.25rem; - } + base::-moz-progress-bar, + .progress[value] { + background-color: #eee; + border-radius: 0.25rem; + } @media screen and (min-width: 0\0) { - .progress { - background-color: #eee; - border-radius: 0.25rem; - } + .progress { + background-color: #eee; + border-radius: 0.25rem; + } - .progress-bar { - display: inline-block; - height: 1rem; - text-indent: -999rem; - background-color: #0074d9; - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .progress-bar { + display: inline-block; + height: 1rem; + text-indent: -999rem; + background-color: #0074d9; + border-bottom-left-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .progress[width="100%"] { - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - } + .progress[width="100%"] { + border-bottom-right-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } } .progress-striped[value]::-webkit-progress-value { - 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); - background-size: 1rem 1rem; + 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); + background-size: 1rem 1rem; } .progress-striped[value]::-moz-progress-bar { - 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); - background-size: 1rem 1rem; + 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); + background-size: 1rem 1rem; } .progress-striped[value]::-ms-fill { - 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); - background-size: 1rem 1rem; + 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); + background-size: 1rem 1rem; } @media screen and (min-width: 0\0) { - .progress-bar-striped { - 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); - background-size: 1rem 1rem; - } + .progress-bar-striped { + 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); + background-size: 1rem 1rem; + } } .progress-animated[value]::-webkit-progress-value { - animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } .progress-animated[value]::-moz-progress-bar { - animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } @media screen and (min-width: 0\0) { - .progress-animated .progress-bar-striped { - animation: progress-bar-stripes 2s linear infinite; - } + .progress-animated .progress-bar-striped { + animation: progress-bar-stripes 2s linear infinite; + } } .progress-success[value]::-webkit-progress-value { - background-color: #5cb85c; + background-color: #5cb85c; } .progress-success[value]::-moz-progress-bar { - background-color: #5cb85c; + background-color: #5cb85c; } .progress-success[value]::-ms-fill { - background-color: #5cb85c; + background-color: #5cb85c; } @media screen and (min-width: 0\0) { - .progress-success .progress-bar { - background-color: #5cb85c; - } + .progress-success .progress-bar { + background-color: #5cb85c; + } } .progress-info[value]::-webkit-progress-value { - background-color: #5bc0de; + background-color: #5bc0de; } .progress-info[value]::-moz-progress-bar { - background-color: #5bc0de; + background-color: #5bc0de; } .progress-info[value]::-ms-fill { - background-color: #5bc0de; + background-color: #5bc0de; } @media screen and (min-width: 0\0) { - .progress-info .progress-bar { - background-color: #5bc0de; - } + .progress-info .progress-bar { + background-color: #5bc0de; + } } .progress-warning[value]::-webkit-progress-value { - background-color: #f0ad4e; + background-color: #f0ad4e; } .progress-warning[value]::-moz-progress-bar { - background-color: #f0ad4e; + background-color: #f0ad4e; } .progress-warning[value]::-ms-fill { - background-color: #f0ad4e; + background-color: #f0ad4e; } @media screen and (min-width: 0\0) { - .progress-warning .progress-bar { - background-color: #f0ad4e; - } + .progress-warning .progress-bar { + background-color: #f0ad4e; + } } .progress-danger[value]::-webkit-progress-value { - background-color: #d9534f; + background-color: #d9534f; } .progress-danger[value]::-moz-progress-bar { - background-color: #d9534f; + background-color: #d9534f; } .progress-danger[value]::-ms-fill { - background-color: #d9534f; + background-color: #d9534f; } @media screen and (min-width: 0\0) { - .progress-danger .progress-bar { - background-color: #d9534f; - } + .progress-danger .progress-bar { + background-color: #d9534f; + } } .media, .media-body { - overflow: hidden; + overflow: hidden; } .media-body { - width: 10000px; + width: 10000px; } .media-left, .media-right, .media-body { - display: table-cell; - vertical-align: top; + display: table-cell; + vertical-align: top; } .media-middle { - vertical-align: middle; + vertical-align: middle; } .media-bottom { - vertical-align: bottom; + vertical-align: bottom; } .media-object { - display: block; + display: block; } - .media-object.img-thumbnail { - max-width: none; - } + .media-object.img-thumbnail { + max-width: none; + } .media-right { - padding-left: 10px; + padding-left: 10px; } .media-left { - padding-right: 10px; + padding-right: 10px; } .media-heading { - margin-top: 0; - margin-bottom: 5px; + margin-top: 0; + margin-bottom: 5px; } .media-list { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } .list-group { - padding-left: 0; - margin-bottom: 0; + padding-left: 0; + margin-bottom: 0; } .list-group-item { - position: relative; - display: block; - padding: 0.75rem 1.25rem; - margin-bottom: -1px; - background-color: #fff; - border: 1px solid #ddd; + position: relative; + display: block; + padding: 0.75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; } - .list-group-item:first-child { - border-top-right-radius: 0.25rem; - border-top-left-radius: 0.25rem; - } + .list-group-item:first-child { + border-top-right-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } - .list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; - } + .list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } - .list-group-item.disabled, .list-group-item.disabled:focus, .list-group-item.disabled:hover { - color: #818a91; - cursor: not-allowed; - background-color: #eceeef; - } + .list-group-item.disabled, .list-group-item.disabled:focus, .list-group-item.disabled:hover { + color: #818a91; + cursor: not-allowed; + background-color: #eceeef; + } - .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-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: #818a91; - } + .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: #818a91; + } - .list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover { - z-index: 2; - color: #fff; - text-decoration: none; - background-color: #214497; - border-color: #214497; - } + .list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover { + z-index: 2; + color: #fff; + text-decoration: none; + background-color: #214497; + border-color: #214497; + } - .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-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: #9bb2e9; - } + .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: #9bb2e9; + } .list-group-flush .list-group-item { - border-right: 0; - border-left: 0; - border-radius: 0; + border-right: 0; + border-left: 0; + border-radius: 0; } .list-group-item-action { - width: 100%; - color: #555; - text-align: inherit; + width: 100%; + color: #555; + text-align: inherit; } - .list-group-item-action .list-group-item-heading { - color: #333; - } + .list-group-item-action .list-group-item-heading { + color: #333; + } - .list-group-item-action:focus, .list-group-item-action:hover { - color: #555; - text-decoration: none; - background-color: #f5f5f5; - } + .list-group-item-action:focus, .list-group-item-action:hover { + color: #555; + text-decoration: none; + background-color: #f5f5f5; + } .list-group-item-success { - color: #3c763d; - background-color: #dff0d8; + color: #3c763d; + background-color: #dff0d8; } a.list-group-item-success, button.list-group-item-success { - color: #3c763d; + 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 .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: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; - } + 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; + color: #31708f; + background-color: #d9edf7; } a.list-group-item-info, button.list-group-item-info { - color: #31708f; + 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 .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: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; - } + 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; + color: #8a6d3b; + background-color: #fcf8e3; } a.list-group-item-warning, button.list-group-item-warning { - color: #8a6d3b; + 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 .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: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; - } + 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; + color: #a94442; + background-color: #f2dede; } a.list-group-item-danger, button.list-group-item-danger { - color: #a94442; + 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 .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: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; - } + 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; + margin-top: 0; + margin-bottom: 5px; } .list-group-item-text { - margin-bottom: 0; - line-height: 1.3; + margin-bottom: 0; + line-height: 1.3; } .embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden; + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; } - .embed-responsive .embed-responsive-item, - .embed-responsive iframe, - .embed-responsive embed, - .embed-responsive object, - .embed-responsive video { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - border: 0; - } + .embed-responsive .embed-responsive-item, + .embed-responsive iframe, + .embed-responsive embed, + .embed-responsive object, + .embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; + } .embed-responsive-21by9 { - padding-bottom: 42.85714%; + padding-bottom: 42.85714%; } .embed-responsive-16by9 { - padding-bottom: 56.25%; + padding-bottom: 56.25%; } .embed-responsive-4by3 { - padding-bottom: 75%; + padding-bottom: 75%; } .embed-responsive-1by1 { - padding-bottom: 100%; + padding-bottom: 100%; } .close { - float: right; - font-size: 1.5rem; - font-weight: bold; - line-height: 1; - color: #000; - text-shadow: 0 1px 0 #fff; - opacity: .2; + float: right; + font-size: 1.5rem; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .2; } - .close:focus, .close:hover { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: .5; - } + .close:focus, .close:hover { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: .5; + } button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; } .modal-open { - overflow: hidden; + overflow: hidden; } .modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - display: none; - overflow: hidden; - outline: 0; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; } - .modal.fade .modal-dialog { - transition: transform .3s ease-out; - transform: translate(0, -25%); - } + .modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0, -25%); + } - .modal.in .modal-dialog { - transform: translate(0, 0); - } + .modal.in .modal-dialog { + transform: translate(0, 0); + } .modal-open .modal { - overflow-x: hidden; - overflow-y: auto; + overflow-x: hidden; + overflow-y: auto; } .modal-dialog { - position: relative; - width: auto; - margin: 10px; + position: relative; + width: auto; + margin: 10px; } .modal-content { - position: relative; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; - outline: 0; + position: relative; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; } .modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; } - .modal-backdrop.fade { - opacity: 0; - } + .modal-backdrop.fade { + opacity: 0; + } - .modal-backdrop.in { - opacity: 0.5; - } + .modal-backdrop.in { + opacity: 0.5; + } .modal-header { - padding: 15px; - border-bottom: 1px solid #e5e5e5; + padding: 15px; + border-bottom: 1px solid #e5e5e5; } - .modal-header::after { - content: ""; - display: table; - clear: both; - } + .modal-header::after { + content: ""; + display: table; + clear: both; + } - .modal-header .close { - margin-top: -2px; - } + .modal-header .close { + margin-top: -2px; + } .modal-title { - margin: 0; - line-height: 1.5; + margin: 0; + line-height: 1.5; } .modal-body { - position: relative; - padding: 15px; + position: relative; + padding: 15px; } .modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; } - .modal-footer::after { - content: ""; - display: table; - clear: both; - } + .modal-footer::after { + content: ""; + display: table; + clear: both; + } .modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; } @media (min-width: 576px) { - .modal-dialog { - max-width: 600px; - margin: 30px auto; - } + .modal-dialog { + max-width: 600px; + margin: 30px auto; + } - .modal-sm { - max-width: 300px; - } + .modal-sm { + max-width: 300px; + } } @media (min-width: 992px) { - .modal-lg { - max-width: 900px; - } + .modal-lg { + max-width: 900px; + } } .tooltip { - position: absolute; - z-index: 1070; - display: block; - font-family: "Roboto", "Helvetica", sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - font-size: 0.875rem; - word-wrap: break-word; - opacity: 0; + position: absolute; + z-index: 1070; + display: block; + font-family: "Roboto", "Helvetica", sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; } - .tooltip.in { - opacity: 0.9; - } + .tooltip.in { + opacity: 0.9; + } - .tooltip.tooltip-top, .tooltip.bs-tether-element-attached-bottom { - padding: 5px 0; - margin-top: -3px; - } + .tooltip.tooltip-top, .tooltip.bs-tether-element-attached-bottom { + padding: 5px 0; + margin-top: -3px; + } - .tooltip.tooltip-top .tooltip-inner::before, .tooltip.bs-tether-element-attached-bottom .tooltip-inner::before { - bottom: 0; - left: 50%; - margin-left: -5px; - content: ""; - border-width: 5px 5px 0; - border-top-color: #000; - } + .tooltip.tooltip-top .tooltip-inner::before, .tooltip.bs-tether-element-attached-bottom .tooltip-inner::before { + bottom: 0; + left: 50%; + margin-left: -5px; + content: ""; + border-width: 5px 5px 0; + border-top-color: #000; + } - .tooltip.tooltip-right, .tooltip.bs-tether-element-attached-left { - padding: 0 5px; - margin-left: 3px; - } + .tooltip.tooltip-right, .tooltip.bs-tether-element-attached-left { + padding: 0 5px; + margin-left: 3px; + } - .tooltip.tooltip-right .tooltip-inner::before, .tooltip.bs-tether-element-attached-left .tooltip-inner::before { - top: 50%; - left: 0; - margin-top: -5px; - content: ""; - border-width: 5px 5px 5px 0; - border-right-color: #000; - } + .tooltip.tooltip-right .tooltip-inner::before, .tooltip.bs-tether-element-attached-left .tooltip-inner::before { + top: 50%; + left: 0; + margin-top: -5px; + content: ""; + border-width: 5px 5px 5px 0; + border-right-color: #000; + } - .tooltip.tooltip-bottom, .tooltip.bs-tether-element-attached-top { - padding: 5px 0; - margin-top: 3px; - } + .tooltip.tooltip-bottom, .tooltip.bs-tether-element-attached-top { + padding: 5px 0; + margin-top: 3px; + } - .tooltip.tooltip-bottom .tooltip-inner::before, .tooltip.bs-tether-element-attached-top .tooltip-inner::before { - top: 0; - left: 50%; - margin-left: -5px; - content: ""; - border-width: 0 5px 5px; - border-bottom-color: #000; - } + .tooltip.tooltip-bottom .tooltip-inner::before, .tooltip.bs-tether-element-attached-top .tooltip-inner::before { + top: 0; + left: 50%; + margin-left: -5px; + content: ""; + border-width: 0 5px 5px; + border-bottom-color: #000; + } - .tooltip.tooltip-left, .tooltip.bs-tether-element-attached-right { - padding: 0 5px; - margin-left: -3px; - } + .tooltip.tooltip-left, .tooltip.bs-tether-element-attached-right { + padding: 0 5px; + margin-left: -3px; + } - .tooltip.tooltip-left .tooltip-inner::before, .tooltip.bs-tether-element-attached-right .tooltip-inner::before { - top: 50%; - right: 0; - margin-top: -5px; - content: ""; - border-width: 5px 0 5px 5px; - border-left-color: #000; - } + .tooltip.tooltip-left .tooltip-inner::before, .tooltip.bs-tether-element-attached-right .tooltip-inner::before { + top: 50%; + right: 0; + margin-top: -5px; + content: ""; + border-width: 5px 0 5px 5px; + border-left-color: #000; + } .tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 0.25rem; + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; } - .tooltip-inner::before { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - } + .tooltip-inner::before { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } .popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: block; - max-width: 276px; - padding: 1px; - font-family: "Roboto", "Helvetica", sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - font-size: 0.875rem; - word-wrap: break-word; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + padding: 1px; + font-family: "Roboto", "Helvetica", sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; } - .popover.popover-top, .popover.bs-tether-element-attached-bottom { - margin-top: -10px; - } + .popover.popover-top, .popover.bs-tether-element-attached-bottom { + margin-top: -10px; + } - .popover.popover-top::before, .popover.popover-top::after, .popover.bs-tether-element-attached-bottom::before, .popover.bs-tether-element-attached-bottom::after { - left: 50%; - border-bottom-width: 0; - } + .popover.popover-top::before, .popover.popover-top::after, .popover.bs-tether-element-attached-bottom::before, .popover.bs-tether-element-attached-bottom::after { + left: 50%; + border-bottom-width: 0; + } - .popover.popover-top::before, .popover.bs-tether-element-attached-bottom::before { - bottom: -11px; - margin-left: -11px; - border-top-color: rgba(0, 0, 0, 0.25); - } + .popover.popover-top::before, .popover.bs-tether-element-attached-bottom::before { + bottom: -11px; + margin-left: -11px; + border-top-color: rgba(0, 0, 0, 0.25); + } - .popover.popover-top::after, .popover.bs-tether-element-attached-bottom::after { - bottom: -10px; - margin-left: -10px; - border-top-color: #fff; - } + .popover.popover-top::after, .popover.bs-tether-element-attached-bottom::after { + bottom: -10px; + margin-left: -10px; + border-top-color: #fff; + } - .popover.popover-right, .popover.bs-tether-element-attached-left { - margin-left: 10px; - } + .popover.popover-right, .popover.bs-tether-element-attached-left { + margin-left: 10px; + } - .popover.popover-right::before, .popover.popover-right::after, .popover.bs-tether-element-attached-left::before, .popover.bs-tether-element-attached-left::after { - top: 50%; - border-left-width: 0; - } + .popover.popover-right::before, .popover.popover-right::after, .popover.bs-tether-element-attached-left::before, .popover.bs-tether-element-attached-left::after { + top: 50%; + border-left-width: 0; + } - .popover.popover-right::before, .popover.bs-tether-element-attached-left::before { - left: -11px; - margin-top: -11px; - border-right-color: rgba(0, 0, 0, 0.25); - } + .popover.popover-right::before, .popover.bs-tether-element-attached-left::before { + left: -11px; + margin-top: -11px; + border-right-color: rgba(0, 0, 0, 0.25); + } - .popover.popover-right::after, .popover.bs-tether-element-attached-left::after { - left: -10px; - margin-top: -10px; - border-right-color: #fff; - } + .popover.popover-right::after, .popover.bs-tether-element-attached-left::after { + left: -10px; + margin-top: -10px; + border-right-color: #fff; + } - .popover.popover-bottom, .popover.bs-tether-element-attached-top { - margin-top: 10px; - } + .popover.popover-bottom, .popover.bs-tether-element-attached-top { + margin-top: 10px; + } - .popover.popover-bottom::before, .popover.popover-bottom::after, .popover.bs-tether-element-attached-top::before, .popover.bs-tether-element-attached-top::after { - left: 50%; - border-top-width: 0; - } + .popover.popover-bottom::before, .popover.popover-bottom::after, .popover.bs-tether-element-attached-top::before, .popover.bs-tether-element-attached-top::after { + left: 50%; + border-top-width: 0; + } - .popover.popover-bottom::before, .popover.bs-tether-element-attached-top::before { - top: -11px; - margin-left: -11px; - border-bottom-color: rgba(0, 0, 0, 0.25); - } + .popover.popover-bottom::before, .popover.bs-tether-element-attached-top::before { + top: -11px; + margin-left: -11px; + border-bottom-color: rgba(0, 0, 0, 0.25); + } - .popover.popover-bottom::after, .popover.bs-tether-element-attached-top::after { - top: -10px; - margin-left: -10px; - border-bottom-color: #f7f7f7; - } + .popover.popover-bottom::after, .popover.bs-tether-element-attached-top::after { + top: -10px; + margin-left: -10px; + border-bottom-color: #f7f7f7; + } - .popover.popover-bottom .popover-title::before, .popover.bs-tether-element-attached-top .popover-title::before { - position: absolute; - top: 0; - left: 50%; - display: block; - width: 20px; - margin-left: -10px; - content: ""; - border-bottom: 1px solid #f7f7f7; - } + .popover.popover-bottom .popover-title::before, .popover.bs-tether-element-attached-top .popover-title::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 20px; + margin-left: -10px; + content: ""; + border-bottom: 1px solid #f7f7f7; + } - .popover.popover-left, .popover.bs-tether-element-attached-right { - margin-left: -10px; - } + .popover.popover-left, .popover.bs-tether-element-attached-right { + margin-left: -10px; + } - .popover.popover-left::before, .popover.popover-left::after, .popover.bs-tether-element-attached-right::before, .popover.bs-tether-element-attached-right::after { - top: 50%; - border-right-width: 0; - } + .popover.popover-left::before, .popover.popover-left::after, .popover.bs-tether-element-attached-right::before, .popover.bs-tether-element-attached-right::after { + top: 50%; + border-right-width: 0; + } - .popover.popover-left::before, .popover.bs-tether-element-attached-right::before { - right: -11px; - margin-top: -11px; - border-left-color: rgba(0, 0, 0, 0.25); - } + .popover.popover-left::before, .popover.bs-tether-element-attached-right::before { + right: -11px; + margin-top: -11px; + border-left-color: rgba(0, 0, 0, 0.25); + } - .popover.popover-left::after, .popover.bs-tether-element-attached-right::after { - right: -10px; - margin-top: -10px; - border-left-color: #fff; - } + .popover.popover-left::after, .popover.bs-tether-element-attached-right::after { + right: -10px; + margin-top: -10px; + border-left-color: #fff; + } .popover-title { - padding: 8px 14px; - margin: 0; - font-size: 1rem; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 0.2375rem 0.2375rem 0 0; + padding: 8px 14px; + margin: 0; + font-size: 1rem; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 0.2375rem 0.2375rem 0 0; } - .popover-title:empty { - display: none; - } + .popover-title:empty { + display: none; + } .popover-content { - padding: 9px 14px; + padding: 9px 14px; } .popover::before, .popover::after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } .popover::before { - content: ""; - border-width: 11px; + content: ""; + border-width: 11px; } .popover::after { - content: ""; - border-width: 10px; + content: ""; + border-width: 10px; } .carousel { - position: relative; + position: relative; } .carousel-inner { - position: relative; - width: 100%; - overflow: hidden; + position: relative; + width: 100%; + overflow: hidden; } - .carousel-inner > .carousel-item { - position: relative; - display: none; - transition: .6s ease-in-out left; - } + .carousel-inner > .carousel-item { + position: relative; + display: none; + transition: .6s ease-in-out left; + } - .carousel-inner > .carousel-item > img, - .carousel-inner > .carousel-item > a > img { - line-height: 1; - } + .carousel-inner > .carousel-item > img, + .carousel-inner > .carousel-item > a > img { + line-height: 1; + } @media all and (transform-3d), (-webkit-transform-3d) { - .carousel-inner > .carousel-item { - transition: transform .6s ease-in-out; - backface-visibility: hidden; - perspective: 1000px; - } + .carousel-inner > .carousel-item { + transition: transform .6s ease-in-out; + backface-visibility: hidden; + perspective: 1000px; + } - .carousel-inner > .carousel-item.next, .carousel-inner > .carousel-item.active.right { - left: 0; - transform: translate3d(100%, 0, 0); - } + .carousel-inner > .carousel-item.next, .carousel-inner > .carousel-item.active.right { + left: 0; + transform: translate3d(100%, 0, 0); + } - .carousel-inner > .carousel-item.prev, .carousel-inner > .carousel-item.active.left { - left: 0; - transform: translate3d(-100%, 0, 0); - } + .carousel-inner > .carousel-item.prev, .carousel-inner > .carousel-item.active.left { + left: 0; + transform: translate3d(-100%, 0, 0); + } - .carousel-inner > .carousel-item.next.left, .carousel-inner > .carousel-item.prev.right, .carousel-inner > .carousel-item.active { - left: 0; - transform: translate3d(0, 0, 0); - } + .carousel-inner > .carousel-item.next.left, .carousel-inner > .carousel-item.prev.right, .carousel-inner > .carousel-item.active { + left: 0; + transform: translate3d(0, 0, 0); + } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { - display: block; + display: block; } .carousel-inner > .active { - left: 0; + left: 0; } .carousel-inner > .next, .carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; + position: absolute; + top: 0; + width: 100%; } .carousel-inner > .next { - left: 100%; + left: 100%; } .carousel-inner > .prev { - left: -100%; + left: -100%; } - .carousel-inner > .next.left, - .carousel-inner > .prev.right { - left: 0; - } + .carousel-inner > .next.left, + .carousel-inner > .prev.right { + left: 0; + } .carousel-inner > .active.left { - left: -100%; + left: -100%; } .carousel-inner > .active.right { - left: 100%; + 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, 0.6); - opacity: 0.5; + 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, 0.6); + opacity: 0.5; } - .carousel-control.left { - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); - } + .carousel-control.left { + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + } - .carousel-control.right { - right: 0; - left: auto; - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); - } + .carousel-control.right { + right: 0; + left: auto; + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + } - .carousel-control:focus, .carousel-control:hover { - color: #fff; - text-decoration: none; - outline: 0; - opacity: .9; - } + .carousel-control:focus, .carousel-control:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; + } - .carousel-control .icon-prev, - .carousel-control .icon-next { - position: absolute; - top: 50%; - z-index: 5; - display: inline-block; - width: 20px; - height: 20px; - margin-top: -10px; - font-family: serif; - line-height: 1; - } + .carousel-control .icon-prev, + .carousel-control .icon-next { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; + line-height: 1; + } - .carousel-control .icon-prev { - left: 50%; - margin-left: -10px; - } + .carousel-control .icon-prev { + left: 50%; + margin-left: -10px; + } - .carousel-control .icon-next { - right: 50%; - margin-right: -10px; - } + .carousel-control .icon-next { + right: 50%; + margin-right: -10px; + } - .carousel-control .icon-prev::before { - content: "\2039"; - } + .carousel-control .icon-prev::before { + content: "\2039"; + } - .carousel-control .icon-next::before { - content: "\203A"; - } + .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; + 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: transparent; - border: 1px solid #fff; - border-radius: 10px; - } + .carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: transparent; + border: 1px solid #fff; + border-radius: 10px; + } - .carousel-indicators .active { - width: 12px; - height: 12px; - margin: 0; - background-color: #fff; - } + .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, 0.6); + 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, 0.6); } - .carousel-caption .btn, .carousel-caption .action-button { - text-shadow: none; - } + .carousel-caption .btn, .carousel-caption .action-button { + text-shadow: none; + } @media (min-width: 576px) { - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - font-size: 30px; - } + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } - .carousel-control .icon-prev { - margin-left: -15px; - } + .carousel-control .icon-prev { + margin-left: -15px; + } - .carousel-control .icon-next { - margin-right: -15px; - } + .carousel-control .icon-next { + margin-right: -15px; + } - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px; - } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } - .carousel-indicators { - bottom: 20px; - } + .carousel-indicators { + bottom: 20px; + } } .align-baseline { - vertical-align: baseline !important; + vertical-align: baseline !important; } .align-top { - vertical-align: top !important; + vertical-align: top !important; } .align-middle { - vertical-align: middle !important; + vertical-align: middle !important; } .align-bottom { - vertical-align: bottom !important; + vertical-align: bottom !important; } .align-text-bottom { - vertical-align: text-bottom !important; + vertical-align: text-bottom !important; } .align-text-top { - vertical-align: text-top !important; + vertical-align: text-top !important; } .bg-faded { - background-color: #f7f7f9; + background-color: #f7f7f9; } .bg-primary { - background-color: #214497 !important; + background-color: #214497 !important; } a.bg-primary:focus, a.bg-primary:hover { - background-color: #18316d !important; + background-color: #18316d !important; } .bg-success { - background-color: #5cb85c !important; + background-color: #5cb85c !important; } a.bg-success:focus, a.bg-success:hover { - background-color: #449d44 !important; + background-color: #449d44 !important; } .bg-info { - background-color: #5bc0de !important; + background-color: #5bc0de !important; } a.bg-info:focus, a.bg-info:hover { - background-color: #31b0d5 !important; + background-color: #31b0d5 !important; } .bg-warning { - background-color: #f0ad4e !important; + background-color: #f0ad4e !important; } a.bg-warning:focus, a.bg-warning:hover { - background-color: #ec971f !important; + background-color: #ec971f !important; } .bg-danger { - background-color: #d9534f !important; + background-color: #d9534f !important; } a.bg-danger:focus, a.bg-danger:hover { - background-color: #c9302c !important; + background-color: #c9302c !important; } .bg-inverse { - background-color: #373a3c !important; + background-color: #373a3c !important; } a.bg-inverse:focus, a.bg-inverse:hover { - background-color: #1f2021 !important; + background-color: #1f2021 !important; } .rounded { - border-radius: 0.25rem; + border-radius: 0.25rem; } .rounded-top { - border-top-right-radius: 0.25rem; - border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + border-top-left-radius: 0.25rem; } .rounded-right { - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + border-top-right-radius: 0.25rem; } .rounded-bottom { - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; } .rounded-left { - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + border-top-left-radius: 0.25rem; } .rounded-circle { - border-radius: 50%; + border-radius: 50%; } .clearfix::after { - content: ""; - display: table; - clear: both; + content: ""; + display: table; + clear: both; } .d-block { - display: block !important; + display: block !important; } .d-inline-block { - display: inline-block !important; + display: inline-block !important; } .d-inline { - display: inline !important; + display: inline !important; } .float-xs-left { - float: left !important; + float: left !important; } .float-xs-right { - float: right !important; + float: right !important; } .float-xs-none { - float: none !important; + float: none !important; } @media (min-width: 576px) { - .float-sm-left { - float: left !important; - } + .float-sm-left { + float: left !important; + } - .float-sm-right { - float: right !important; - } + .float-sm-right { + float: right !important; + } - .float-sm-none { - float: none !important; - } + .float-sm-none { + float: none !important; + } } @media (min-width: 768px) { - .float-md-left { - float: left !important; - } + .float-md-left { + float: left !important; + } - .float-md-right { - float: right !important; - } + .float-md-right { + float: right !important; + } - .float-md-none { - float: none !important; - } + .float-md-none { + float: none !important; + } } @media (min-width: 992px) { - .float-lg-left { - float: left !important; - } + .float-lg-left { + float: left !important; + } - .float-lg-right { - float: right !important; - } + .float-lg-right { + float: right !important; + } - .float-lg-none { - float: none !important; - } + .float-lg-none { + float: none !important; + } } @media (min-width: 1200px) { - .float-xl-left { - float: left !important; - } + .float-xl-left { + float: left !important; + } - .float-xl-right { - float: right !important; - } + .float-xl-right { + float: right !important; + } - .float-xl-none { - float: none !important; - } + .float-xl-none { + float: none !important; + } } .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; + 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; + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; } .w-100 { - width: 100% !important; + width: 100% !important; } .h-100 { - height: 100% !important; + height: 100% !important; } .mx-auto { - margin-right: auto !important; - margin-left: auto !important; + margin-right: auto !important; + margin-left: auto !important; } .m-0 { - margin: 0 0 !important; + margin: 0 0 !important; } .mt-0 { - margin-top: 0 !important; + margin-top: 0 !important; } .mr-0 { - margin-right: 0 !important; + margin-right: 0 !important; } .mb-0 { - margin-bottom: 0 !important; + margin-bottom: 0 !important; } .ml-0 { - margin-left: 0 !important; + margin-left: 0 !important; } .mx-0 { - margin-right: 0 !important; - margin-left: 0 !important; + margin-right: 0 !important; + margin-left: 0 !important; } .my-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; + margin-top: 0 !important; + margin-bottom: 0 !important; } .m-1 { - margin: 1rem 1rem !important; + margin: 1rem 1rem !important; } .mt-1 { - margin-top: 1rem !important; + margin-top: 1rem !important; } .mr-1 { - margin-right: 1rem !important; + margin-right: 1rem !important; } .mb-1 { - margin-bottom: 1rem !important; + margin-bottom: 1rem !important; } .ml-1 { - margin-left: 1rem !important; + margin-left: 1rem !important; } .mx-1 { - margin-right: 1rem !important; - margin-left: 1rem !important; + margin-right: 1rem !important; + margin-left: 1rem !important; } .my-1 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; + margin-top: 1rem !important; + margin-bottom: 1rem !important; } .m-2 { - margin: 1.5rem 1.5rem !important; + margin: 1.5rem 1.5rem !important; } .mt-2 { - margin-top: 1.5rem !important; + margin-top: 1.5rem !important; } .mr-2 { - margin-right: 1.5rem !important; + margin-right: 1.5rem !important; } .mb-2 { - margin-bottom: 1.5rem !important; + margin-bottom: 1.5rem !important; } .ml-2 { - margin-left: 1.5rem !important; + margin-left: 1.5rem !important; } .mx-2 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; } .my-2 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; } .m-3 { - margin: 3rem 3rem !important; + margin: 3rem 3rem !important; } .mt-3 { - margin-top: 3rem !important; + margin-top: 3rem !important; } .mr-3 { - margin-right: 3rem !important; + margin-right: 3rem !important; } .mb-3 { - margin-bottom: 3rem !important; + margin-bottom: 3rem !important; } .ml-3 { - margin-left: 3rem !important; + margin-left: 3rem !important; } .mx-3 { - margin-right: 3rem !important; - margin-left: 3rem !important; + margin-right: 3rem !important; + margin-left: 3rem !important; } .my-3 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; + margin-top: 3rem !important; + margin-bottom: 3rem !important; } .p-0 { - padding: 0 0 !important; + padding: 0 0 !important; } .pt-0 { - padding-top: 0 !important; + padding-top: 0 !important; } .pr-0 { - padding-right: 0 !important; + padding-right: 0 !important; } .pb-0 { - padding-bottom: 0 !important; + padding-bottom: 0 !important; } .pl-0 { - padding-left: 0 !important; + padding-left: 0 !important; } .px-0 { - padding-right: 0 !important; - padding-left: 0 !important; + padding-right: 0 !important; + padding-left: 0 !important; } .py-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; + padding-top: 0 !important; + padding-bottom: 0 !important; } .p-1 { - padding: 1rem 1rem !important; + padding: 1rem 1rem !important; } .pt-1 { - padding-top: 1rem !important; + padding-top: 1rem !important; } .pr-1 { - padding-right: 1rem !important; + padding-right: 1rem !important; } .pb-1 { - padding-bottom: 1rem !important; + padding-bottom: 1rem !important; } .pl-1 { - padding-left: 1rem !important; + padding-left: 1rem !important; } .px-1 { - padding-right: 1rem !important; - padding-left: 1rem !important; + padding-right: 1rem !important; + padding-left: 1rem !important; } .py-1 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; + padding-top: 1rem !important; + padding-bottom: 1rem !important; } .p-2 { - padding: 1.5rem 1.5rem !important; + padding: 1.5rem 1.5rem !important; } .pt-2 { - padding-top: 1.5rem !important; + padding-top: 1.5rem !important; } .pr-2 { - padding-right: 1.5rem !important; + padding-right: 1.5rem !important; } .pb-2 { - padding-bottom: 1.5rem !important; + padding-bottom: 1.5rem !important; } .pl-2 { - padding-left: 1.5rem !important; + padding-left: 1.5rem !important; } .px-2 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; } .py-2 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; } .p-3 { - padding: 3rem 3rem !important; + padding: 3rem 3rem !important; } .pt-3 { - padding-top: 3rem !important; + padding-top: 3rem !important; } .pr-3 { - padding-right: 3rem !important; + padding-right: 3rem !important; } .pb-3 { - padding-bottom: 3rem !important; + padding-bottom: 3rem !important; } .pl-3 { - padding-left: 3rem !important; + padding-left: 3rem !important; } .px-3 { - padding-right: 3rem !important; - padding-left: 3rem !important; + padding-right: 3rem !important; + padding-left: 3rem !important; } .py-3 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; + padding-top: 3rem !important; + padding-bottom: 3rem !important; } .pos-f-t { - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; } .text-justify { - text-align: justify !important; + text-align: justify !important; } .text-nowrap { - white-space: nowrap !important; + white-space: nowrap !important; } .text-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .text-xs-left { - text-align: left !important; + text-align: left !important; } .text-xs-right { - text-align: right !important; + text-align: right !important; } .text-xs-center { - text-align: center !important; + text-align: center !important; } @media (min-width: 576px) { - .text-sm-left { - text-align: left !important; - } + .text-sm-left { + text-align: left !important; + } - .text-sm-right { - text-align: right !important; - } + .text-sm-right { + text-align: right !important; + } - .text-sm-center { - text-align: center !important; - } + .text-sm-center { + text-align: center !important; + } } @media (min-width: 768px) { - .text-md-left { - text-align: left !important; - } + .text-md-left { + text-align: left !important; + } - .text-md-right { - text-align: right !important; - } + .text-md-right { + text-align: right !important; + } - .text-md-center { - text-align: center !important; - } + .text-md-center { + text-align: center !important; + } } @media (min-width: 992px) { - .text-lg-left { - text-align: left !important; - } + .text-lg-left { + text-align: left !important; + } - .text-lg-right { - text-align: right !important; - } + .text-lg-right { + text-align: right !important; + } - .text-lg-center { - text-align: center !important; - } + .text-lg-center { + text-align: center !important; + } } @media (min-width: 1200px) { - .text-xl-left { - text-align: left !important; - } + .text-xl-left { + text-align: left !important; + } - .text-xl-right { - text-align: right !important; - } + .text-xl-right { + text-align: right !important; + } - .text-xl-center { - text-align: center !important; - } + .text-xl-center { + text-align: center !important; + } } .text-lowercase { - text-transform: lowercase !important; + text-transform: lowercase !important; } .text-uppercase { - text-transform: uppercase !important; + text-transform: uppercase !important; } .text-capitalize { - text-transform: capitalize !important; + text-transform: capitalize !important; } .font-weight-normal { - font-weight: normal; + font-weight: normal; } .font-weight-bold { - font-weight: bold; + font-weight: bold; } .font-italic { - font-style: italic; + font-style: italic; } .text-white { - color: #fff !important; + color: #fff !important; } .text-muted { - color: #818a91 !important; + color: #818a91 !important; } a.text-muted:focus, a.text-muted:hover { - color: #687077 !important; + color: #687077 !important; } .text-primary { - color: #214497 !important; + color: #214497 !important; } a.text-primary:focus, a.text-primary:hover { - color: #18316d !important; + color: #18316d !important; } .text-success { - color: #5cb85c !important; + color: #5cb85c !important; } a.text-success:focus, a.text-success:hover { - color: #449d44 !important; + color: #449d44 !important; } .text-info { - color: #5bc0de !important; + color: #5bc0de !important; } a.text-info:focus, a.text-info:hover { - color: #31b0d5 !important; + color: #31b0d5 !important; } .text-warning { - color: #f0ad4e !important; + color: #f0ad4e !important; } a.text-warning:focus, a.text-warning:hover { - color: #ec971f !important; + color: #ec971f !important; } .text-danger { - color: #d9534f !important; + color: #d9534f !important; } a.text-danger:focus, a.text-danger:hover { - color: #c9302c !important; + color: #c9302c !important; } .text-gray-dark { - color: #373a3c !important; + color: #373a3c !important; } a.text-gray-dark:focus, a.text-gray-dark:hover { - color: #1f2021 !important; + color: #1f2021 !important; } .text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; } .invisible { - visibility: hidden !important; + visibility: hidden !important; } .hidden-xs-up { - display: none !important; + display: none !important; } @media (max-width: 575px) { - .hidden-xs-down { - display: none !important; - } + .hidden-xs-down { + display: none !important; + } } @media (min-width: 576px) { - .hidden-sm-up { - display: none !important; - } + .hidden-sm-up { + display: none !important; + } } @media (max-width: 767px) { - .hidden-sm-down { - display: none !important; - } + .hidden-sm-down { + display: none !important; + } } @media (min-width: 768px) { - .hidden-md-up { - display: none !important; - } + .hidden-md-up { + display: none !important; + } } @media (max-width: 991px) { - .hidden-md-down { - display: none !important; - } + .hidden-md-down { + display: none !important; + } } @media (min-width: 992px) { - .hidden-lg-up { - display: none !important; - } + .hidden-lg-up { + display: none !important; + } } @media (max-width: 1199px) { - .hidden-lg-down { - display: none !important; - } + .hidden-lg-down { + display: none !important; + } } @media (min-width: 1200px) { - .hidden-xl-up { - display: none !important; - } + .hidden-xl-up { + display: none !important; + } } .hidden-xl-down { - display: none !important; + display: none !important; } .visible-print-block { - display: none !important; + display: none !important; } @media print { - .visible-print-block { - display: block !important; - } + .visible-print-block { + display: block !important; + } } .visible-print-inline { - display: none !important; + display: none !important; } @media print { - .visible-print-inline { - display: inline !important; - } + .visible-print-inline { + display: inline !important; + } } .visible-print-inline-block { - display: none !important; + display: none !important; } @media print { - .visible-print-inline-block { - display: inline-block !important; - } + .visible-print-inline-block { + display: inline-block !important; + } } @media print { - .hidden-print { - display: none !important; - } + .hidden-print { + display: none !important; + } } button { - background-color: transparent; - border: 0; - cursor: pointer; - padding: 0; + background-color: transparent; + border: 0; + cursor: pointer; + padding: 0; } a:hover { - text-decoration: none; + text-decoration: none; } .action-button { - color: #fff; - background-color: #329F80; - border-color: #329F80; - padding: 15px; - word-break: normal; - font-size: 13.5px; - min-width: 185px; - font-weight: 300; - letter-spacing: .7px; - box-shadow: 0 7px 13px 0 rgba(0, 0, 0, 0.19); - width: 100%; - text-overflow: ellipsis; - overflow: hidden; + color: #fff; + background-color: #329F80; + border-color: #329F80; + padding: 15px; + word-break: normal; + font-size: 13.5px; + min-width: 185px; + font-weight: 300; + letter-spacing: .7px; + box-shadow: 0 7px 13px 0 rgba(0, 0, 0, 0.19); + width: 100%; + text-overflow: ellipsis; + overflow: hidden; } - .action-button:hover { - color: #fff; - background-color: #24725B; - border-color: #24725B; - } + .action-button:hover { + color: #fff; + background-color: #24725B; + border-color: #24725B; + } - .action-button:focus, .action-button.focus { - color: #fff; - background-color: #24725B; - border-color: #24725B; - } + .action-button:focus, .action-button.focus { + color: #fff; + background-color: #24725B; + border-color: #24725B; + } - .action-button:active, .action-button.active, - .open > .action-button.dropdown-toggle { - color: #fff; - background-color: #24725B; - border-color: #24725B; - background-image: none; - } + .action-button:active, .action-button.active, + .open > .action-button.dropdown-toggle { + color: #fff; + background-color: #24725B; + border-color: #24725B; + background-image: none; + } - .action-button:active:hover, .action-button:active:focus, .action-button:active.focus, .action-button.active:hover, .action-button.active:focus, .action-button.active.focus, - .open > .action-button.dropdown-toggle:hover, - .open > .action-button.dropdown-toggle:focus, - .open > .action-button.dropdown-toggle.focus { - color: #fff; - background-color: #24725B; - border-color: #24725B; - } + .action-button:active:hover, .action-button:active:focus, .action-button:active.focus, .action-button.active:hover, .action-button.active:focus, .action-button.active.focus, + .open > .action-button.dropdown-toggle:hover, + .open > .action-button.dropdown-toggle:focus, + .open > .action-button.dropdown-toggle.focus { + color: #fff; + background-color: #24725B; + border-color: #24725B; + } - .action-button.disabled:focus, .action-button.disabled.focus, .action-button:disabled:focus, .action-button:disabled.focus { - background-color: #4582E8; - border-color: #4582E8; - } + .action-button.disabled:focus, .action-button.disabled.focus, .action-button:disabled:focus, .action-button:disabled.focus { + background-color: #4582E8; + border-color: #4582E8; + } - .action-button.disabled:hover, .action-button:disabled:hover { - background-color: #4582E8; - border-color: #4582E8; - } + .action-button.disabled:hover, .action-button:disabled:hover { + background-color: #4582E8; + border-color: #4582E8; + } - .action-button:hover { - background-color: #24725B; - border-color: rgba(28, 100, 222, 0); - opacity: .95; - } + .action-button:hover { + background-color: #24725B; + border-color: rgba(28, 100, 222, 0); + opacity: .95; + } - .action-button > span { - opacity: 1; - } + .action-button > span { + opacity: 1; + } - .action-button.finished { - background: #3c65c7; - border-color: #3c65c7; - } + .action-button.finished { + background: #3c65c7; + border-color: #3c65c7; + } .action-button--secondary { - background: #e7e7e7; - border: 0; - box-shadow: none; - color: #4A4A4A; - margin-bottom: .75rem; - padding: 17px; + background: #e7e7e7; + border: 0; + box-shadow: none; + color: #4A4A4A; + margin-bottom: .75rem; + padding: 17px; } - .action-button--secondary:hover, .action-button--secondary:active:hover, .action-button--secondary:active:focus, .action-button--secondary:focus { - background: #e4e4e4; - color: #4A4A4A; - } + .action-button--secondary:hover, .action-button--secondary:active:hover, .action-button--secondary:active:focus, .action-button--secondary:focus { + background: #e4e4e4; + color: #4A4A4A; + } strong { - font-weight: bold; + font-weight: bold; } .content-faded, .manual__step-one__instructions, .manual__step-two__instructions { - text-align: center; - font-size: 13px; - padding: 20px 20px; - color: #515664; - font-weight: 300; - opacity: .7; + text-align: center; + font-size: 13px; + padding: 20px 20px; + color: #515664; + font-weight: 300; + opacity: .7; } .modal-content { - box-shadow: 0 2px 32px 0 rgba(0, 0, 0, 0.85); - background: #F5F5F7; - z-index: 999999; - border-radius: 0; + box-shadow: 0 2px 32px 0 rgba(0, 0, 0, 0.85); + background: #F5F5F7; + z-index: 999999; + border-radius: 0; } @media (min-width: 576px) { - .modal-content { - border-radius: 7px 7px 6px 6px; - } + .modal-content { + border-radius: 7px 7px 6px 6px; + } } .opened .modal-content { - z-index: 0; + z-index: 0; } .modal { - display: block; - overflow-y: scroll; + display: block; + overflow-y: scroll; } - .modal.page { - overflow-y: hidden; - position: relative; - z-index: 105111; - } + .modal.page { + overflow-y: hidden; + position: relative; + z-index: 105111; + } .content { - display: block; - margin-left: auto; - margin-right: auto; + display: block; + margin-left: auto; + margin-right: auto; } .top-header { - color: #fff; - background-color: #329F80; - font-weight: 500; - letter-spacing: .5px; + color: #fff; + background-color: #329F80; + font-weight: 500; + letter-spacing: .5px; } @media (min-width: 576px) { - .top-header { - border-top-left-radius: 5px; - border-top-right-radius: 5px; - } + .top-header { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + } } .top-header .header { - display: flex; + display: flex; } .top-header .header__icon { - display: inline-block; - vertical-align: middle; - position: relative; - width: 100px; - height: 50px; - margin-left: 10px; - margin-top: 10px; + display: inline-block; + vertical-align: middle; + position: relative; + width: 100px; + height: 50px; + margin-left: 10px; + margin-top: 10px; } .top-header .timer-row { - background: #CEDC21; - display: flex; - align-items: center; - padding: 3px 14px; - position: relative; - transition: background 1s ease; + background: #CEDC21; + display: flex; + align-items: center; + padding: 3px 14px; + position: relative; + transition: background 1s ease; } - .top-header .timer-row.expiring-soon { - background: #D3051E; - } + .top-header .timer-row.expiring-soon { + background: #D3051E; + } - .top-header .timer-row.expiring-soon .timer-row__message { - opacity: 1; - } + .top-header .timer-row.expiring-soon .timer-row__message { + opacity: 1; + } .top-header .timer-row__spinner { - display: flex; - margin-left: -5px; - margin-right: 8px; + display: flex; + margin-left: -5px; + margin-right: 8px; } - .top-header .timer-row__spinner svg { - width: 17px; - height: 17px; - fill: #4681e2; - animation: spin 0.5s linear infinite; - margin-top: -2px; - transition: fill .5s ease; - } + .top-header .timer-row__spinner svg { + width: 17px; + height: 17px; + fill: #4681e2; + animation: spin 0.5s linear infinite; + margin-top: -2px; + transition: fill .5s ease; + } - .top-header .timer-row__spinner.white svg { - fill: #fff; - } + .top-header .timer-row__spinner.white svg { + fill: #fff; + } @keyframes spin { - 0% { - transform: rotate(0deg); - } + 0% { + transform: rotate(0deg); + } - 100% { - transform: rotate(360deg); - } + 100% { + transform: rotate(360deg); + } } .top-header .timer-row__message { - flex-grow: 1; - font-size: 13.5px; - z-index: 1; + flex-grow: 1; + font-size: 13.5px; + z-index: 1; } .top-header .timer-row__time-left { - font-size: 13.5px; - z-index: 1; + font-size: 13.5px; + z-index: 1; } .top-header .timer-row__progress-bar { - position: absolute; - height: 100%; - width: 0%; - top: 0; - left: 0; - background: rgba(0, 0, 0, 0.2); + position: absolute; + height: 100%; + width: 0%; + top: 0; + left: 0; + background: rgba(0, 0, 0, 0.2); } .subheader { - padding: 1rem !important; - font-size: 13px; + padding: 1rem !important; + font-size: 13px; } - .subheader::after { - content: ""; - display: table; - clear: both; - } + .subheader::after { + content: ""; + display: table; + clear: both; + } .subheader__bill > :first-child { - float: left; + float: left; } .subheader__bill > :last-child { - float: right; + float: right; } .single-item-order { - position: relative; - padding: 15px; - display: flex; - font-weight: 300; - color: #565D6E; - letter-spacing: .45px; - background: #fff; - min-height: 67px; + position: relative; + padding: 15px; + display: flex; + font-weight: 300; + color: #565D6E; + letter-spacing: .45px; + background: #fff; + min-height: 67px; } .single-item-order__left { - display: flex; - flex-direction: column; - justify-content: center; - font-size: 11.5px; + display: flex; + flex-direction: column; + justify-content: center; + font-size: 11.5px; } .single-item-order__left__name { - font-weight: 600; - margin-bottom: 4px; + font-weight: 600; + margin-bottom: 4px; } - .single-item-order__left__name.no-description { - margin-bottom: 0; - } + .single-item-order__left__name.no-description { + margin-bottom: 0; + } .single-item-order__left__description { - line-height: 16px; + line-height: 16px; } .single-item-order__right { - flex-grow: 1; - flex-shrink: 0; - padding-left: 20px; - text-align: right; - display: flex; - flex-direction: column; - justify-content: center; + flex-grow: 1; + flex-shrink: 0; + padding-left: 20px; + text-align: right; + display: flex; + flex-direction: column; + justify-content: center; } .single-item-order__right__fiat-price { - font-size: 14px; - margin-bottom: 3px; - font-weight: 400; + font-size: 14px; + margin-bottom: 3px; + font-weight: 400; } .single-item-order__right__ex-rate { - font-style: italic; - font-size: 11px; + font-style: italic; + font-size: 11px; } .single-item-order__right__btc-price { - font-size: 14px; + font-size: 14px; } - .single-item-order__right__btc-price.clickable { - cursor: pointer; - } + .single-item-order__right__btc-price.clickable { + cursor: pointer; + } .single-item-order__right__btc-price__chevron { - height: 8px; - margin-top: -1px; - transform: rotateZ(-90deg); - transition: transform 250ms ease; - opacity: .6; - margin-left: 3px; + height: 8px; + margin-top: -1px; + transform: rotateZ(-90deg); + transition: transform 250ms ease; + opacity: .6; + margin-left: 3px; } - .single-item-order__right__btc-price__chevron.expanded { - transform: rotateZ(-270deg); - } + .single-item-order__right__btc-price__chevron.expanded { + transform: rotateZ(-270deg); + } .payment-tabs { - position: relative; - background: #fff; - border-top: 1px solid #E9E9E9; - display: flex; - font-size: 13.5px; - box-shadow: 0px 5px 7px 0px rgba(0, 0, 0, 0.09); - color: #818EA9; - font-weight: 300; + position: relative; + background: #fff; + border-top: 1px solid #E9E9E9; + display: flex; + font-size: 13.5px; + box-shadow: 0px 5px 7px 0px rgba(0, 0, 0, 0.09); + color: #818EA9; + font-weight: 300; } .payment-tabs__tab { - text-align: center; - flex: 1; - padding: 12px; - outline: none; - letter-spacing: .8px; - cursor: pointer; + text-align: center; + flex: 1; + padding: 12px; + outline: none; + letter-spacing: .8px; + cursor: pointer; } - .payment-tabs__tab.active { - color: #214497; - font-weight: 400; - } + .payment-tabs__tab.active { + color: #214497; + font-weight: 400; + } .payment-tabs__slider { - position: absolute; - height: 5px; - width: 50%; - background: #329F80; - top: 0; - right: 50%; - transition: all .2s ease; + position: absolute; + height: 5px; + width: 50%; + background: #329F80; + top: 0; + right: 50%; + transition: all .2s ease; } - .payment-tabs__slider.slide-right { - right: 0; - } + .payment-tabs__slider.slide-right { + right: 0; + } .manual__step-one__header { - padding-top: 20px; - text-align: center; - font-size: 15px; + padding-top: 20px; + text-align: center; + font-size: 15px; } .paid-partial .manual__step-two { - padding-top: 1.4rem; + padding-top: 1.4rem; } .manual__step-two__instructions { - padding: 15px 10px 30px; + padding: 15px 10px 30px; } - .manual__step-two__instructions.compress { - padding-bottom: 20px; - padding-top: 0; - } + .manual__step-two__instructions.compress { + padding-bottom: 20px; + padding-top: 0; + } .manual__step-two__qr { - margin-top: 3px; - text-align: center; + margin-top: 3px; + text-align: center; } - .manual__step-two__qr > a { - cursor: pointer; - font-weight: 300; - color: #9B9B9B; - font-size: 11px; - text-align: center; - } + .manual__step-two__qr > a { + cursor: pointer; + font-weight: 300; + color: #9B9B9B; + font-size: 11px; + text-align: center; + } - .manual__step-two__qr > a:hover { - opacity: .8; - } + .manual__step-two__qr > a:hover { + opacity: .8; + } - .manual__step-two__qr canvas { - margin-top: 15px; - padding: 15px; - background-color: #ffffff; - border: 1px solid #E9E9E9; - border-radius: 5px; - width: 100%; - max-height: 300px; - } + .manual__step-two__qr canvas { + margin-top: 15px; + padding: 15px; + background-color: #ffffff; + border: 1px solid #E9E9E9; + border-radius: 5px; + width: 100%; + max-height: 300px; + } .copy-cursor { - cursor: copy; + cursor: copy; } .manual-box { - border-radius: 5px; - margin-left: calc(-40px + 10%); - margin-right: calc(-40px + 10%); - position: relative; + border-radius: 5px; + margin-left: calc(-40px + 10%); + margin-right: calc(-40px + 10%); + position: relative; } @media (min-width: 576px) { - .manual-box { - margin-left: 0; - margin-right: 0; - } + .manual-box { + margin-left: 0; + margin-right: 0; + } } .manual-box > * { - background: #fff; + background: #fff; } .manual-box .label { - text-transform: uppercase; - font-size: 10px; - color: #515664; - opacity: .5; - letter-spacing: .6px; - margin-bottom: 14px; + text-transform: uppercase; + font-size: 10px; + color: #515664; + opacity: .5; + letter-spacing: .6px; + margin-bottom: 14px; } - .manual-box .label > .initial-label { - opacity: 1; - transition: opacity 400ms ease; - } + .manual-box .label > .initial-label { + opacity: 1; + transition: opacity 400ms ease; + } - .manual-box .label > .final-label { - opacity: 0; - transition: opacity 400ms ease; - position: absolute; - width: 100%; - left: 0; - } + .manual-box .label > .final-label { + opacity: 0; + transition: opacity 400ms ease; + position: absolute; + width: 100%; + left: 0; + } - .manual-box .label.to-final-label > .initial-label { - opacity: 0; - } + .manual-box .label.to-final-label > .initial-label { + opacity: 0; + } - .manual-box .label.to-final-label > .final-label { - opacity: 1; - } + .manual-box .label.to-final-label > .final-label { + opacity: 1; + } .manual-box .copied .copied-label { - pointer-events: auto; - cursor: default; - transition: opacity .4s ease; + pointer-events: auto; + cursor: default; + transition: opacity .4s ease; } .manual-box .copied-label { - position: absolute; - width: 100%; - top: 0; - left: 0; - opacity: 0; - transition: opacity 1s ease; - pointer-events: none; + position: absolute; + width: 100%; + top: 0; + left: 0; + opacity: 0; + transition: opacity 1s ease; + pointer-events: none; } - .manual-box .copied-label span { - font-weight: 300; - font-size: 14px; - color: white; - background: #4A4A4A; - padding: 10px 40px; - border-radius: 3px; - letter-spacing: .5px; - } + .manual-box .copied-label span { + font-weight: 300; + font-size: 14px; + color: white; + background: #4A4A4A; + padding: 10px 40px; + border-radius: 3px; + letter-spacing: .5px; + } .manual-box.underpaid-expired { - margin-top: -.4rem; + margin-top: -.4rem; } - .manual-box.underpaid-expired > .manual-box__amount { - border-top-color: rgba(255, 255, 255, 0); - border-top-right-radius: 0; - border-top-left-radius: 0; - } + .manual-box.underpaid-expired > .manual-box__amount { + border-top-color: rgba(255, 255, 255, 0); + border-top-right-radius: 0; + border-top-left-radius: 0; + } .manual-box.underpaid-expired__refund-pending > .manual-box__amount { - transition: all 250ms cubic-bezier(0.4, 0, 1, 1); - border-top-color: #E9E9E9; - border-top-right-radius: 5px; - border-top-left-radius: 5px; + transition: all 250ms cubic-bezier(0.4, 0, 1, 1); + border-top-color: #E9E9E9; + border-top-right-radius: 5px; + border-top-left-radius: 5px; } .manual-box.underpaid-expired__refund-pending > .manual-box__underpaid-box { - opacity: 0; - transform: translateY(0); - max-height: 40px; - overflow: hidden; - transition: all 250ms ease-out; + opacity: 0; + transform: translateY(0); + max-height: 40px; + overflow: hidden; + transition: all 250ms ease-out; } .manual-box__underpaid-box { - text-align: center; - font-size: 14px; - font-weight: 300; - padding: 1.7rem; - padding-bottom: .7rem; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - border: 1px solid #E9E9E9; - border-bottom: 0; - max-height: 300px; + text-align: center; + font-size: 14px; + font-weight: 300; + padding: 1.7rem; + padding-bottom: .7rem; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border: 1px solid #E9E9E9; + border-bottom: 0; + max-height: 300px; } - .manual-box__underpaid-box img { - height: 100px; - margin-bottom: 1.2rem; - } + .manual-box__underpaid-box img { + height: 100px; + margin-bottom: 1.2rem; + } .manual-box__amount { - padding: 15px 10px 20px; - text-align: center; - position: relative; - border-radius: 5px; - border: 1px solid #E9E9E9; + padding: 15px 10px 20px; + text-align: center; + position: relative; + border-radius: 5px; + border: 1px solid #E9E9E9; } .flipped .manual-box__amount { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } .manual-box__amount.amount-only { - padding-bottom: 15px; + padding-bottom: 15px; } .manual-box__amount__value { - color: #4A4A4A; - font-size: 28px; - font-weight: 300; - letter-spacing: 1px; - margin-top: -10px; - position: relative; + color: #4A4A4A; + font-size: 28px; + font-weight: 300; + letter-spacing: 1px; + margin-top: -10px; + position: relative; } - .manual-box__amount__value > span { - transition: opacity 2s ease; - } + .manual-box__amount__value > span { + transition: opacity 2s ease; + } - .manual-box__amount__value.copied > span { - transition: opacity .4s ease; - opacity: 0; - } + .manual-box__amount__value.copied > span { + transition: opacity .4s ease; + opacity: 0; + } - .manual-box__amount__value.copied .copied-label { - opacity: 1; - } + .manual-box__amount__value.copied .copied-label { + opacity: 1; + } .manual-box__amount__arrow { - position: absolute; - height: 10px; - width: 10px; - left: 50%; - border-right: 1px solid #E9E9E9; - border-bottom: 1px solid #E9E9E9; - transform: rotate(45deg); - margin-left: -5px; - bottom: -6px; - background: #fff; + position: absolute; + height: 10px; + width: 10px; + left: 50%; + border-right: 1px solid #E9E9E9; + border-bottom: 1px solid #E9E9E9; + transform: rotate(45deg); + margin-left: -5px; + bottom: -6px; + background: #fff; } .amount-only .manual-box__amount__arrow { - display: none; + display: none; } .manual-box__address { - text-align: center; - perspective: 1000; - background: none; - height: 108px; + text-align: center; + perspective: 1000; + background: none; + height: 108px; } .manual-box__address__arrow { - position: absolute; - height: 10px; - width: 10px; - left: 50%; - border-right: 1px solid #E9E9E9; - border-bottom: 1px solid #E9E9E9; - transform: rotateZ(45deg); - margin-left: -5px; - top: -5px; - background: #329F80; - transform-style: preserve-3d; - backface-visibility: hidden; + position: absolute; + height: 10px; + width: 10px; + left: 50%; + border-right: 1px solid #E9E9E9; + border-bottom: 1px solid #E9E9E9; + transform: rotateZ(45deg); + margin-left: -5px; + top: -5px; + background: #329F80; + transform-style: preserve-3d; + backface-visibility: hidden; } .manual-box__address > .flipper { - backface-visibility: hidden; - height: 100%; - border: 1px solid #E9E9E9; - border-top: 0; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - transform-style: preserve-3d; - position: relative; - height: 108px; - transform: rotateX(-93deg); - transform-origin: top; - opacity: 0; - background: #fff; + backface-visibility: hidden; + height: 100%; + border: 1px solid #E9E9E9; + border-top: 0; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + transform-style: preserve-3d; + position: relative; + height: 108px; + transform: rotateX(-93deg); + transform-origin: top; + opacity: 0; + background: #fff; } - .manual-box__address > .flipper.flip { - opacity: 1; - animation-name: flip-in !important; - animation-duration: 1500ms; - animation-fill-mode: forwards; - transform: rotateX(0deg); - } + .manual-box__address > .flipper.flip { + opacity: 1; + animation-name: flip-in !important; + animation-duration: 1500ms; + animation-fill-mode: forwards; + transform: rotateX(0deg); + } - .manual-box__address > .flipper.flipped-initially { - animation-name: none; - transform: rotateX(0deg); - opacity: 1; - } + .manual-box__address > .flipper.flipped-initially { + animation-name: none; + transform: rotateX(0deg); + opacity: 1; + } - .manual-box__address > .flipper > .front, - .manual-box__address > .flipper > .back { - padding: 22px 5px 20px; - backface-visibility: hidden; - position: absolute; - top: 0; - left: 0; - width: 100%; - transform: translate3d(0, 0, 0); - } + .manual-box__address > .flipper > .front, + .manual-box__address > .flipper > .back { + padding: 22px 5px 20px; + backface-visibility: hidden; + position: absolute; + top: 0; + left: 0; + width: 100%; + transform: translate3d(0, 0, 0); + } .manual-box__address__value { - position: relative; + position: relative; } - .manual-box__address__value .manual-box__address__wrapper { - transition: opacity 2s ease; - } + .manual-box__address__value .manual-box__address__wrapper { + transition: opacity 2s ease; + } - .manual-box__address__value.copied .manual-box__address__wrapper { - transition: opacity .4s ease; - opacity: 0; - } + .manual-box__address__value.copied .manual-box__address__wrapper { + transition: opacity .4s ease; + opacity: 0; + } - .manual-box__address__value.copied .copied-label { - opacity: 1; - } + .manual-box__address__value.copied .copied-label { + opacity: 1; + } .manual-box__address__wrapper { - background: rgba(182, 182, 182, 0.13); - border: 1px solid rgba(77, 77, 77, 0.07); - border-radius: 4px; - display: inline-flex; - align-items: center; - padding: 6px 10px; - position: relative; + background: rgba(182, 182, 182, 0.13); + border: 1px solid rgba(77, 77, 77, 0.07); + border-radius: 4px; + display: inline-flex; + align-items: center; + padding: 6px 10px; + position: relative; } .manual-box__address__wrapper__logo { - margin-top: -1px; - padding-right: 7px; - border-right: 1px solid #E4E4E4; + margin-top: -1px; + padding-right: 7px; + border-right: 1px solid #E4E4E4; } .manual-box__address__wrapper__value { - padding-left: 9px; - font-size: 10.2px; - color: #4A4A4A; + padding-left: 9px; + font-size: 10.2px; + color: #4A4A4A; } .status-block { - position: relative; + position: relative; } - .status-block > .success-block { - position: relative; - opacity: 1; - } + .status-block > .success-block { + position: relative; + opacity: 1; + } - .status-block > .pending-block { - opacity: 0; - transition: transform 400ms ease, opacity 400ms ease-out; - transform: translate3d(0, 20px, 0); - } + .status-block > .pending-block { + opacity: 0; + transition: transform 400ms ease, opacity 400ms ease-out; + transform: translate3d(0, 20px, 0); + } .has-refund-address .status-block .success-block { - opacity: 0; + opacity: 0; } .has-refund-address .status-block .pending-block { - opacity: 1; - transform: translate3d(0, 0, 0); + opacity: 1; + transform: translate3d(0, 0, 0); } .pending-block { - position: absolute; - top: 0; - width: 100%; - text-align: center; + position: absolute; + top: 0; + width: 100%; + text-align: center; } .pending-block__header { - padding-top: 1.5rem; + padding-top: 1.5rem; } .pending-block__message { - padding-top: 10px; - font-weight: 100; - font-size: 14px; - color: rgba(111, 111, 111, 0.9); - text-align: center; - letter-spacing: .2px; + padding-top: 10px; + font-weight: 100; + font-size: 14px; + color: rgba(111, 111, 111, 0.9); + text-align: center; + letter-spacing: .2px; } @media (min-width: 576px) { - .pending-block__message { - padding-left: 1rem; - padding-right: 1rem; - font-size: 15px; - } + .pending-block__message { + padding-left: 1rem; + padding-right: 1rem; + font-size: 15px; + } } .refund-address-form-container { - transform: translate3d(0, -105px, 0); - transition: transform 250ms ease; - margin-left: calc(-40px + 10%); - margin-right: calc(-40px + 10%); + transform: translate3d(0, -105px, 0); + transition: transform 250ms ease; + margin-left: calc(-40px + 10%); + margin-right: calc(-40px + 10%); } @media (min-width: 576px) { - .refund-address-form-container { - margin-left: 0; - margin-right: 0; - } + .refund-address-form-container { + margin-left: 0; + margin-right: 0; + } } .has-refund-address .refund-address-form-container .input-wrapper { - transition: all 250ms ease; - transform: scale3d(0.1, 0.1, 1); - opacity: 0; + transition: all 250ms ease; + transform: scale3d(0.1, 0.1, 1); + opacity: 0; } .footer-button { - opacity: .9; - font-weight: 300; - position: absolute; - bottom: 0; - padding: 18px; - text-align: center; - width: 100%; - background: #E2E2E2; - font-size: 13.5px; - color: #4582E8; - letter-spacing: .5px; - border-bottom-left-radius: 9px; - border-bottom-right-radius: 9px; - cursor: pointer; - z-index: 9999; + opacity: .9; + font-weight: 300; + position: absolute; + bottom: 0; + padding: 18px; + text-align: center; + width: 100%; + background: #E2E2E2; + font-size: 13.5px; + color: #4582E8; + letter-spacing: .5px; + border-bottom-left-radius: 9px; + border-bottom-right-radius: 9px; + cursor: pointer; + z-index: 9999; } .edit-email-button { - text-align: left; - padding: 15px 2rem; - display: flex; + text-align: left; + padding: 15px 2rem; + display: flex; } .edit-email-button__label-box { - flex-grow: 1; + flex-grow: 1; } .edit-email-button__label-box__label { - color: #4A4A4A; - font-size: 12px; - margin-bottom: .15rem; - font-weight: 400; + color: #4A4A4A; + font-size: 12px; + margin-bottom: .15rem; + font-weight: 400; } .edit-email-button__label-box__email { - font-size: 14px; - font-weight: 300; + font-size: 14px; + font-weight: 300; } .payment-box { - padding-top: 15px; - position: relative; - margin-bottom: 1.5rem !important; - margin-bottom: 0 !important; - min-height: 393px; + padding-top: 15px; + position: relative; + margin-bottom: 1.5rem !important; + margin-bottom: 0 !important; + min-height: 393px; } .paypro { - padding: 10px; + padding: 10px; } .paypro__inner { - overflow: hidden; - display: block; - margin-left: auto; - margin-right: auto; - max-width: 320px; - border-radius: 5px; - border: 1px solid #214497; - position: relative; - height: 40px; + overflow: hidden; + display: block; + margin-left: auto; + margin-right: auto; + max-width: 320px; + border-radius: 5px; + border: 1px solid #214497; + position: relative; + height: 40px; } - .paypro__inner::after { - content: ""; - display: table; - clear: both; - } + .paypro__inner::after { + content: ""; + display: table; + clear: both; + } .paypro__button { - height: 40px; - display: inline-block; - width: 50%; - position: absolute; - color: #214497; + height: 40px; + display: inline-block; + width: 50%; + position: absolute; + color: #214497; } .paypro__button--selected { - background-color: #214497; - color: white; + background-color: #214497; + color: white; } .paypro__button:first-child { - left: 0; + left: 0; } .paypro__button:last-child { - right: 0; + right: 0; } .exrate { - flex-grow: 1; - display: flex; - justify-content: flex-end; - color: #ffffff; - padding: 13px; - font-size: 12px; + flex-grow: 1; + display: flex; + justify-content: flex-end; + color: #ffffff; + padding: 13px; + font-size: 12px; } .close-icon { - flex-grow: 1; - display: flex; - justify-content: flex-end; - padding: 13px; - transition: opacity 250ms ease; - opacity: 1; + flex-grow: 1; + display: flex; + justify-content: flex-end; + padding: 13px; + transition: opacity 250ms ease; + opacity: 1; } - .close-icon img { - height: 24px; - width: 14px; - cursor: pointer; - } + .close-icon img { + height: 24px; + width: 14px; + cursor: pointer; + } - .close-icon.fade-out { - opacity: 0; - pointer-events: none; - } + .close-icon.fade-out { + opacity: 0; + pointer-events: none; + } .email-receipt-form { - text-align: center; - font-weight: 300; + text-align: center; + font-weight: 300; } - .email-receipt-form input:focus { - outline: none; - } + .email-receipt-form input:focus { + outline: none; + } .email-receipt-form__label { - opacity: .68; - font-size: 13px; - margin-bottom: 7px; + opacity: .68; + font-size: 13px; + margin-bottom: 7px; } .email-input-wrapper { - margin-bottom: 15px; - font-size: 13px; - position: relative; + margin-bottom: 15px; + font-size: 13px; + position: relative; } - .email-input-wrapper .email-input { - position: relative; - text-align: left; - padding: 15px 20px; - z-index: 99; - } + .email-input-wrapper .email-input { + position: relative; + text-align: left; + padding: 15px 20px; + z-index: 99; + } - .email-input-wrapper .send-button { - position: absolute; - top: 0; - right: 0; - height: 100%; - display: block; - text-align: center; - background: rgba(237, 237, 237, 0.24); - width: 50px; - box-shadow: -1px 0 0 0 rgba(114, 114, 114, 0.06); - z-index: 99; - cursor: pointer; - } + .email-input-wrapper .send-button { + position: absolute; + top: 0; + right: 0; + height: 100%; + display: block; + text-align: center; + background: rgba(237, 237, 237, 0.24); + width: 50px; + box-shadow: -1px 0 0 0 rgba(114, 114, 114, 0.06); + z-index: 99; + cursor: pointer; + } - .email-input-wrapper .send-button:hover { - background: rgba(237, 237, 237, 0.44); - } + .email-input-wrapper .send-button:hover { + background: rgba(237, 237, 237, 0.44); + } - .email-input-wrapper .success-wrapper { - display: flex; - align-items: center; - justify-content: center; - position: absolute; - top: 0; - height: 100%; - width: 100%; - font-weight: 300; - color: rgba(111, 111, 111, 0.9); - } + .email-input-wrapper .success-wrapper { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 0; + height: 100%; + width: 100%; + font-weight: 300; + color: rgba(111, 111, 111, 0.9); + } - .email-input-wrapper .success-wrapper img { - margin-right: 8px; - } + .email-input-wrapper .success-wrapper img { + margin-right: 8px; + } .email-receipt-button { - margin-top: 15px; + margin-top: 15px; } .bp-input { - border: 1px solid #E9E9E9; - border-radius: 2px; - font-size: 15px; - font-weight: 400; - padding: 16px; - text-align: left; - min-width: 185px; - letter-spacing: .1px; - width: 100%; - line-height: normal; - -webkit-appearance: none; + border: 1px solid #E9E9E9; + border-radius: 2px; + font-size: 15px; + font-weight: 400; + padding: 16px; + text-align: left; + min-width: 185px; + letter-spacing: .1px; + width: 100%; + line-height: normal; + -webkit-appearance: none; } - .bp-input:disabled { - background: #EBEBEB; - border-color: rgba(212, 212, 212, 0.7); - color: rgba(61, 65, 76, 0.5); - } + .bp-input:disabled { + background: #EBEBEB; + border-color: rgba(212, 212, 212, 0.7); + color: rgba(61, 65, 76, 0.5); + } - .bp-input::-webkit-input-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - padding-top: 1px; - } + .bp-input::-webkit-input-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + padding-top: 1px; + } - .bp-input:-moz-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-input:-moz-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } - .bp-input::-moz-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-input::-moz-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } - .bp-input:-ms-input-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-input:-ms-input-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } .bp-view { - padding-top: 1em; - padding-bottom: 2em; - position: absolute; - padding-left: 30px; - padding-right: 30px; - width: 100%; + padding-top: 1em; + padding-bottom: 2em; + position: absolute; + padding-left: 30px; + padding-right: 30px; + width: 100%; } - .bp-view#paid { - padding-bottom: 0; - } + .bp-view#paid { + padding-bottom: 0; + } - .bp-view#paid.pad { - padding-bottom: 30px; - } + .bp-view#paid.pad { + padding-bottom: 30px; + } - .bp-view.enter-contact-email { - padding-left: 40px; - padding-right: 40px; - } + .bp-view.enter-contact-email { + padding-left: 40px; + padding-right: 40px; + } - .bp-view.scan { - padding-top: .9em !important; - } + .bp-view.scan { + padding-top: .9em !important; + } - .bp-view:not(.active) { - opacity: 0; - pointer-events: none; - } + .bp-view:not(.active) { + opacity: 0; + pointer-events: none; + } - .bp-view:not(.active) * { - cursor: default; - } + .bp-view:not(.active) * { + cursor: default; + } - .bp-view.active { - z-index: 9999; - } + .bp-view.active { + z-index: 9999; + } - .bp-view.paid-full { - padding-top: 30px; - padding-bottom: 0; - } + .bp-view.paid-full { + padding-top: 30px; + padding-bottom: 0; + } - .bp-view.paid-full .success-message { - padding-top: 27px; - padding-bottom: 40px; - } + .bp-view.paid-full .success-message { + padding-top: 27px; + padding-bottom: 40px; + } .success-message { - color: rgba(111, 111, 111, 0.9); - text-align: center; - font-size: 15px; - letter-spacing: .2px; - padding: 32px 0; + color: rgba(111, 111, 111, 0.9); + text-align: center; + font-size: 15px; + letter-spacing: .2px; + padding: 32px 0; } .success-message__explanation { - font-size: 13px; - margin-top: 15px; - font-weight: 300; + font-size: 13px; + margin-top: 15px; + font-weight: 300; } .status-icon { - position: relative; - text-align: center; + position: relative; + text-align: center; } .status-icon--error .status-icon__wrapper__outline { - border-color: #E5465A; + border-color: #E5465A; } .status-icon--error .status-icon__wrapper__icon { - margin-top: -5px; + margin-top: -5px; } .status-icon__wrapper { - display: flex; - justify-content: center; - text-align: center; - width: 100%; - z-index: 9999999; + display: flex; + justify-content: center; + text-align: center; + width: 100%; + z-index: 9999999; } - .status-icon__wrapper .inner-wrapper { - position: relative; - padding: 1px; - } + .status-icon__wrapper .inner-wrapper { + position: relative; + padding: 1px; + } .status-icon__wrapper__outline { - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - height: 154px; - width: 154px; - border: 2px solid #13E5B6; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + height: 154px; + width: 154px; + border: 2px solid #13E5B6; } .status-icon__wrapper__icon { - height: 100%; - width: 100%; - position: absolute; - display: flex; - align-items: center; - justify-content: center; + height: 100%; + width: 100%; + position: absolute; + display: flex; + align-items: center; + justify-content: center; } .payment { - padding-top: 1rem !important; + padding-top: 1rem !important; } .payment--expired { - padding: 3rem !important; - text-align: center; + padding: 3rem !important; + text-align: center; } .payment--expired__explaination { - margin-bottom: 1rem !important; + margin-bottom: 1rem !important; } .payment__details { - margin-bottom: 0 !important; + margin-bottom: 0 !important; } .payment__details__exception { - color: #FF9405; - font-weight: 500; + color: #FF9405; + font-weight: 500; } @media (max-width: 767px) { - .payment__details__exception { - text-align: center; - } + .payment__details__exception { + text-align: center; + } } .payment__details__instruction { - text-align: center; + text-align: center; } @media (min-width: 768px) { - .payment__details__instruction { - text-align: left; - margin-bottom: 1.5rem !important; - margin-top: 1rem !important; - } + .payment__details__instruction { + text-align: left; + margin-bottom: 1.5rem !important; + margin-top: 1rem !important; + } } .payment__details__instruction__btc-amount { - border-bottom: 1px dotted; + border-bottom: 1px dotted; } .payment__details__instruction__btc-address { - padding: 0 !important; - word-break: break-all; - margin-top: 0.4em; - display: inline-block; - color: #373a3c; - background-color: #ffffff; - font-size: 0.8em; - border-bottom: 1px dotted; + padding: 0 !important; + word-break: break-all; + margin-top: 0.4em; + display: inline-block; + color: #373a3c; + background-color: #ffffff; + font-size: 0.8em; + border-bottom: 1px dotted; } .payment__details__instruction__open-wallet { - display: block; - margin-left: auto; - margin-right: auto; - margin: 15px 15px 18px; - text-align: center; + display: block; + margin-left: auto; + margin-right: auto; + margin: 15px 15px 18px; + text-align: center; } .payment__details__instruction__open-wallet__btn__external-link { - height: 14px; - width: 14px; - opacity: .85; - margin-left: 10px; - margin-top: -5px; + height: 14px; + width: 14px; + opacity: .85; + margin-left: 10px; + margin-top: -5px; } .payment__details__title { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - font-weight: bold; - font-size: 1.25rem; + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + font-weight: bold; + font-size: 1.25rem; } .payment__scan { - position: relative; - text-align: center; + position: relative; + text-align: center; } .payment__scan__checkmark-wrapper { - display: flex; - justify-content: center; - text-align: center; - width: 100%; - z-index: 9999999; - padding: 20px; + display: flex; + justify-content: center; + text-align: center; + width: 100%; + z-index: 9999999; + padding: 20px; } - .payment__scan__checkmark-wrapper .inner-wrapper { - position: relative; - padding: 1px; - } + .payment__scan__checkmark-wrapper .inner-wrapper { + position: relative; + padding: 1px; + } .payment__scan__checkmark-wrapper__outline { - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - height: 154px; - width: 154px; - border: 2px solid #1DB670; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + height: 154px; + width: 154px; + border: 2px solid #1DB670; } .payment__scan__checkmark-wrapper__checkmark { - height: 100%; - width: 100%; - position: absolute; - display: flex; - align-items: center; - justify-content: center; + height: 100%; + width: 100%; + position: absolute; + display: flex; + align-items: center; + justify-content: center; } .payment__scan__qrcode img { - padding: 15px; - background-color: #ffffff; - border: 1px solid #E9E9E9; - border-radius: 5px; + padding: 15px; + background-color: #ffffff; + border: 1px solid #E9E9E9; + border-radius: 5px; } .payment__scan__help-text { - margin-top: -2px; - color: #AEC1D0; - font-size: 11px; - font-weight: 100; + margin-top: -2px; + color: #AEC1D0; + font-size: 11px; + font-weight: 100; } - .payment__scan__help-text > span { - cursor: pointer; - } + .payment__scan__help-text > span { + cursor: pointer; + } - .payment__scan__help-text > span:hover { - opacity: .8; - } + .payment__scan__help-text > span:hover { + opacity: .8; + } .payment__state-icon { - width: 5em; - margin-top: 1rem !important; - margin-bottom: 1rem !important; + width: 5em; + margin-top: 1rem !important; + margin-bottom: 1rem !important; } .payment__primary-btn { - border-radius: 2em; + border-radius: 2em; } .payment__secondary-btn { - text-decoration: underline; + text-decoration: underline; } .payment__btn-wrapper { - margin-top: 1rem !important; + margin-top: 1rem !important; } .payment--paid { - padding: 1rem !important; - text-align: center; + padding: 1rem !important; + text-align: center; } .payment--paid__statedesc { - color: #1DB670; - font-weight: 500; + color: #1DB670; + font-weight: 500; } .payment--paid__exception { - color: #FF9405; - font-size: 1.1em; - font-weight: 500; + color: #FF9405; + font-size: 1.1em; + font-weight: 500; } .payment--paid__exception-amount { - color: #FF9405; - font-size: 1.1em; - font-weight: 500; + color: #FF9405; + font-size: 1.1em; + font-weight: 500; } .order { - font-size: 0.875rem; + font-size: 0.875rem; } .order__price { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - width: 100%; - border: .0625rem solid #ddd; - border-radius: 0.25em; - overflow: hidden; - border-collapse: separate; - padding: 0 !important; + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + width: 100%; + border: .0625rem solid #ddd; + border-radius: 0.25em; + overflow: hidden; + border-collapse: separate; + padding: 0 !important; } .order__price__total { - background-color: #214497; - color: #FFFFFF; + background-color: #214497; + color: #FFFFFF; } .order__price__currency-header { - opacity: 0.7; - text-align: right; + opacity: 0.7; + text-align: right; } .order__price__orderid { - font-weight: 700; + font-weight: 700; } .order__price__currency { - text-align: right; + text-align: right; } .order__price__qty { - text-align: center; + text-align: center; } .order__price__item-name { - max-width: 190px; - overflow: hidden; - text-overflow: ellipsis; + max-width: 190px; + overflow: hidden; + text-overflow: ellipsis; } .order__price tr:not(:last-child) > td { - border-bottom: .0625rem solid #ddd; - background-color: #fff; + border-bottom: .0625rem solid #ddd; + background-color: #fff; } .order__price tr > td { - padding: 1rem !important; + padding: 1rem !important; } #request-full-refund-button.bg-BG { - font-size: 11px; + font-size: 11px; } .expired__body { - padding: 14px 10px; - padding-top: 8px; + padding: 14px 10px; + padding-top: 8px; } .expired__header { - font-weight: 500; - font-size: 25px; + font-weight: 500; + font-size: 25px; } .expired__text { - margin-top: 20px; - font-weight: 100; - font-size: 14.5px; - opacity: .8; + margin-top: 20px; + font-weight: 100; + font-size: 14.5px; + opacity: .8; } .expired__text__bullet { - font-weight: 500; + font-weight: 500; } .expired__text__link { - color: #4582E8; - display: inline; - cursor: pointer; - text-decoration: none !important; + color: #4582E8; + display: inline; + cursor: pointer; + text-decoration: none !important; } - .expired__text__link:hover, .expired__text__link:active, .expired__text__link:focus { - opacity: .85; - color: #4582E8; - } + .expired__text__link:hover, .expired__text__link:active, .expired__text__link:focus { + opacity: .85; + color: #4582E8; + } .expired .timer-row__progress-bar, .archived .timer-row__progress-bar { - width: 0 !important; + width: 0 !important; } .expired__message, .archived__message { - color: #6F6F6F; - text-align: center; - font-size: 15.5px; - letter-spacing: .2px; - padding: 25px; + color: #6F6F6F; + text-align: center; + font-size: 15.5px; + letter-spacing: .2px; + padding: 25px; } .expired__message__link, .archived__message__link { - text-decoration: none !important; + text-decoration: none !important; } .expired .expired-icon, .archived .expired-icon { - padding-top: 15px; + padding-top: 15px; } - .expired .expired-icon > img, - .archived .expired-icon > img { - height: 140px; - width: 140px; - } + .expired .expired-icon > img, + .archived .expired-icon > img { + height: 140px; + width: 140px; + } .expired-icon { - text-align: center; + text-align: center; } .paid-partial .manual__step-two__qr, .archived .manual__step-two__qr { - display: none; + display: none; } .paid-partial .expired-icon, .archived .expired-icon { - padding-top: 0; - margin-top: -10px; + padding-top: 0; + margin-top: -10px; } - .paid-partial .expired-icon > img, - .archived .expired-icon > img { - height: auto; - width: auto; - } + .paid-partial .expired-icon > img, + .archived .expired-icon > img { + height: auto; + width: auto; + } .paid-partial .manual-box, .archived .manual-box { - margin-bottom: 25px; + margin-bottom: 25px; } .paid-partial__message, .archived__message { - padding: 20px 10px; - margin: 0; - font-weight: 300; - font-size: 13px; - text-align: center; + padding: 20px 10px; + margin: 0; + font-weight: 300; + font-size: 13px; + text-align: center; } .paid-partial__message__header, .archived__message__header { - font-size: 14px; - font-weight: 500; - margin-bottom: 16px; + font-size: 14px; + font-weight: 500; + margin-bottom: 16px; } .paid-partial > .expired-icon { - padding-top: 2rem; + padding-top: 2rem; } .paid-partial-box { - background: #fff; - padding: 30px 15px; - text-align: center; - border: 1px solid #E9E9E9; - border-radius: 5px; - margin: -5px 0 18px; - font-weight: 300; - color: #4A4A4A; - margin-left: calc(-40px + 10%); - margin-right: calc(-40px + 10%); + background: #fff; + padding: 30px 15px; + text-align: center; + border: 1px solid #E9E9E9; + border-radius: 5px; + margin: -5px 0 18px; + font-weight: 300; + color: #4A4A4A; + margin-left: calc(-40px + 10%); + margin-right: calc(-40px + 10%); } @media (min-width: 576px) { - .paid-partial-box { - margin-left: 0; - margin-right: 0; - } + .paid-partial-box { + margin-left: 0; + margin-right: 0; + } } .paid-partial-box__pie-chart { - padding: 5px; + padding: 5px; } .paid-partial-box__explanation { - font-size: 15px; - padding: 30px 5px 25px; + font-size: 15px; + padding: 30px 5px 25px; } .paid-partial-box__amount { - font-size: 28px; + font-size: 28px; } .footer { - margin-top: 10px; - font-weight: 300; - font-size: 10.5px; - letter-spacing: .75px; - display: flex; - opacity: .8; - justify-content: center; - z-index: -1; + margin-top: 10px; + font-weight: 300; + font-size: 10.5px; + letter-spacing: .75px; + display: flex; + opacity: .8; + justify-content: center; + z-index: -1; } @media (max-width: 575px) { - .footer { - padding: 0 1rem; - } + .footer { + padding: 0 1rem; + } } .footer__item { - padding: 2px 14px; - border-right: 1px solid rgba(255, 255, 255, 0.5); - color: white; - opacity: .8; + padding: 2px 14px; + border-right: 1px solid rgba(255, 255, 255, 0.5); + color: white; + opacity: .8; } .footer__item__caret { - margin-top: -4px; - margin-right: 8px; + margin-top: -4px; + margin-right: 8px; } .footer__item:first-child { - padding-left: 5px; + padding-left: 5px; } .footer__item:last-child { - padding-right: 5px; - border: 0; + padding-right: 5px; + border: 0; } .footer__item:hover, .footer__item:active, .footer__item:focus { - color: #fff; - text-decoration: none; - opacity: .85; + color: #fff; + text-decoration: none; + opacity: .85; } .footer__item.no-hover:hover, .footer__item.no-hover:active, .footer__item.no-hover:focus { - color: #fff; - text-decoration: none; - opacity: 1; + color: #fff; + text-decoration: none; + opacity: 1; } .footer__item.no-border { - border: 0; + border: 0; } .footer .how-to-pay { - padding-top: 1px; - color: #fff; - flex-grow: 1; - display: flex; - align-items: center; + padding-top: 1px; + color: #fff; + flex-grow: 1; + display: flex; + align-items: center; } .footer .how-to-pay__help-icon { - margin-top: -2px; - margin-right: 8px; + margin-top: -2px; + margin-right: 8px; } .contact-email-form { - padding-bottom: 3rem; + padding-bottom: 3rem; } .refund-address-form { - text-align: center; + text-align: center; } .refund-address-form__link { - font-size: 14px; - font-weight: 300; - color: #5a8fe8; - display: inline-block; - cursor: pointer; + font-size: 14px; + font-weight: 300; + color: #5a8fe8; + display: inline-block; + cursor: pointer; } - .refund-address-form__link:hover { - opacity: .7; - } + .refund-address-form__link:hover { + opacity: .7; + } .refund-address-form__cancel { - text-align: center; - opacity: .35; - font-size: 14px; - margin-top: -2px; + text-align: center; + opacity: .35; + font-size: 14px; + margin-top: -2px; } - .refund-address-form__cancel > span { - cursor: pointer; - } + .refund-address-form__cancel > span { + cursor: pointer; + } .refund-address-form .input-wrapper { - margin: 15px 0 18px; + margin: 15px 0 18px; } .refund-address-form input:focus { - outline: none; + outline: none; } .refund-address-form > button > .initial-text { - opacity: 1; - transition: opacity 650ms ease; - position: relative; - z-index: 9999; - width: 100%; + opacity: 1; + transition: opacity 650ms ease; + position: relative; + z-index: 9999; + width: 100%; } .refund-address-form > button > .final-text { - opacity: 0; - transition: opacity 650ms ease; - position: absolute; - z-index: 9999; - width: 100%; - left: 0; + opacity: 0; + transition: opacity 650ms ease; + position: absolute; + z-index: 9999; + width: 100%; + left: 0; } .has-refund-address .refund-address-form > button { - background: #3c65c7; - border-color: #3c65c7; + background: #3c65c7; + border-color: #3c65c7; } - .has-refund-address .refund-address-form > button > .initial-text { - opacity: 0; - } + .has-refund-address .refund-address-form > button > .initial-text { + opacity: 0; + } - .has-refund-address .refund-address-form > button > .final-text { - opacity: 1; - } + .has-refund-address .refund-address-form > button > .final-text { + opacity: 1; + } .refund-address-form__label { - text-align: center; - margin-bottom: .5rem; - color: rgba(81, 86, 100, 0.5); - font-size: 10.5px; - text-transform: uppercase; - letter-spacing: .7px; + text-align: center; + margin-bottom: .5rem; + color: rgba(81, 86, 100, 0.5); + font-size: 10.5px; + text-transform: uppercase; + letter-spacing: .7px; } .submission-error-label { - display: none; + display: none; } .refund-address-form.ng-invalid.ng-submitted input, .email-receipt-form.ng-invalid.ng-submitted input { - border: 1px solid #E15061; + border: 1px solid #E15061; } .refund-address-form.ng-invalid.ng-submitted button, .email-receipt-form.ng-invalid.ng-submitted button { - opacity: .7; - pointer-events: none; + opacity: .7; + pointer-events: none; } .refund-address-form.ng-invalid.ng-submitted .initial-label, .email-receipt-form.ng-invalid.ng-submitted .initial-label { - display: none; + display: none; } .refund-address-form.ng-invalid.ng-submitted .submission-error-label, .email-receipt-form.ng-invalid.ng-submitted .submission-error-label { - display: block; + display: block; } .bitcoin-logo { - display: flex; - justify-content: center; - align-items: center; - position: absolute; - height: 100%; - width: 35px; - margin-top: -1px; - margin-left: -30px; - opacity: 0; - transition: padding .2s ease-out; + display: flex; + justify-content: center; + align-items: center; + position: absolute; + height: 100%; + width: 35px; + margin-top: -1px; + margin-left: -30px; + opacity: 0; + transition: padding .2s ease-out; } - .bitcoin-logo div { - padding: 0 8px 0 6px; - border-right: 1px solid rgba(0, 0, 0, 0.1); - } + .bitcoin-logo div { + padding: 0 8px 0 6px; + border-right: 1px solid rgba(0, 0, 0, 0.1); + } /* Warning Page */ .manual__step-two--warning { - display: block; - margin-left: auto; - margin-right: auto; - text-align: center; + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; } .warning-header { - font-size: 1.25rem; - line-height: 1.9; + font-size: 1.25rem; + line-height: 1.9; } .warning-content { - padding: 5px 12px 16px 12px; - line-height: 1.25; - text-align: left; + padding: 5px 12px 16px 12px; + line-height: 1.25; + text-align: left; } .action-button--long-text { - margin-top: 20px; + margin-top: 20px; } .accept-copy-warning { - /*margin-top: 1.25rem;*/ - margin-bottom: 0; + /*margin-top: 1.25rem;*/ + margin-bottom: 0; } .m-qr-code-expand { - height: 10px; - transform: rotateZ(-90deg); - transition: transform 250ms ease; - opacity: .6; - margin-left: 3px; + height: 10px; + transform: rotateZ(-90deg); + transition: transform 250ms ease; + opacity: .6; + margin-left: 3px; } .hide { - left: -100em; - position: absolute; + left: -100em; + position: absolute; } /* Mobile styles start here All mobile class names should be prefixed by m- */ .m-qr-code-container { - background: #f5f5f7; - border-radius: 6px; - padding-bottom: 28px; - border: 1px solid #e1e1e1; - opacity: 0; + background: #f5f5f7; + border-radius: 6px; + padding-bottom: 28px; + border: 1px solid #e1e1e1; + opacity: 0; } .m-qr-code-header { - background: #f0f0f1; - padding: 12px 0; - color: #6c6c6c; - font-size: 16px; - cursor: pointer; + background: #f0f0f1; + padding: 12px 0; + color: #6c6c6c; + font-size: 16px; + cursor: pointer; } .m-qr-code-icon { - height: 14px; - width: 14px; - opacity: .85; - margin-left: 10px; - margin-top: -5px; + height: 14px; + width: 14px; + opacity: .85; + margin-left: 10px; + margin-top: -5px; } .modal-dialog { - margin: 0; + margin: 0; } @media (min-width: 576px) { - .modal-dialog { - margin: 60px auto; - width: 360px; - } + .modal-dialog { + margin: 60px auto; + width: 360px; + } } .modal-backdrop { - transition: background-color 200ms ease-in-out; - background-color: rgba(32, 36, 47, 0); - position: fixed; - height: 100%; - width: 100%; - top: 0; - left: 0; + transition: background-color 200ms ease-in-out; + background-color: rgba(32, 36, 47, 0); + position: fixed; + height: 100%; + width: 100%; + top: 0; + left: 0; } .modal-body { - padding-bottom: 55px; + padding-bottom: 55px; } .fade-in { - background-color: rgba(32, 36, 47, 0.8); + background-color: rgba(32, 36, 47, 0.8); } .modal { - transition: all 10s ease-out !important; + transition: all 10s ease-out !important; } .modal-content { - opacity: 0; - border: 0; + opacity: 0; + border: 0; } @media (max-width: 767px) { - .modal-content { - transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out !important; - transform: translate3d(0, 100%, 0); - } + .modal-content { + transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out !important; + transform: translate3d(0, 100%, 0); + } } @media (min-width: 576px) { - .modal-content { - transition: opacity 0.2s ease-out !important; - transform: translate3d(0, 0, 0); - } + .modal-content { + transition: opacity 0.2s ease-out !important; + transform: translate3d(0, 0, 0); + } } .long { - opacity: 1 !important; + opacity: 1 !important; } @media (min-width: 576px) { - .long { - animation: modalopenbounce 1000ms linear both; - } + .long { + animation: modalopenbounce 1000ms linear both; + } } @media (max-width: 767px) { - .long { - transform: translate3d(0, 0, 0) !important; - } + .long { + transform: translate3d(0, 0, 0) !important; + } } .page .modal-content, .page .modal-content.long { - transition: none !important; - transform: none !important; + transition: none !important; + transform: none !important; } .modal.in .modal-dialog { - transform: scale(1, 1) !important; + transform: scale(1, 1) !important; } .modal.fade .modal-dialog { - transform: translate(0, 0); + transform: translate(0, 0); } @keyframes modalopenbounce { - 0% { - transform: matrix3d(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 0% { + transform: matrix3d(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 3.7% { - transform: matrix3d(1, 0, 0, 0, 0, 0.489, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 3.7% { + transform: matrix3d(1, 0, 0, 0, 0, 0.489, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 7.31% { - transform: matrix3d(1, 0, 0, 0, 0, 0.875, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 7.31% { + transform: matrix3d(1, 0, 0, 0, 0, 0.875, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 11.01% { - transform: matrix3d(1, 0, 0, 0, 0, 1.085, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 11.01% { + transform: matrix3d(1, 0, 0, 0, 0, 1.085, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 14.61% { - transform: matrix3d(1, 0, 0, 0, 0, 1.138, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 14.61% { + transform: matrix3d(1, 0, 0, 0, 0, 1.138, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 23.72% { - transform: matrix3d(1, 0, 0, 0, 0, 1.032, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 23.72% { + transform: matrix3d(1, 0, 0, 0, 0, 1.032, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 32.83% { - transform: matrix3d(1, 0, 0, 0, 0, 0.985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 32.83% { + transform: matrix3d(1, 0, 0, 0, 0, 0.985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 51.05% { - transform: matrix3d(1, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 51.05% { + transform: matrix3d(1, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 69.27% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 69.27% { + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 87.49% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 87.49% { + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 100% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 100% { + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } } .payment__scan__checkmark-wrapper { - opacity: 0; + opacity: 0; } .payment__scan__qrcode img { - transform: scale3d(0.1, 0.1, 1); - transition: all .18s ease-out; + transform: scale3d(0.1, 0.1, 1); + transition: all .18s ease-out; } .payment__scan__help-text { - opacity: 0; - transition: opacity .25s ease; + opacity: 0; + transition: opacity .25s ease; } .success-message { - transition: all .5s ease; - opacity: 0; + transition: all .5s ease; + opacity: 0; } .payment__details__instruction__open-wallet__btn { - opacity: 0; - transition: all .15s ease-out; - transform: translate3d(0, -100px, 0); + opacity: 0; + transition: all .15s ease-out; + transform: translate3d(0, -100px, 0); } .footer { - transform: translate3d(0, -50px, 0); - opacity: 0; + transform: translate3d(0, -50px, 0); + opacity: 0; } .top-header { - max-height: 90px; - transition: all .2s ease-out; + max-height: 90px; + transition: all .2s ease-out; } .exrate { - opacity: 1; - transition: opacity .2s ease-out; + opacity: 1; + transition: opacity .2s ease-out; } .payment-tabs { - margin-top: 0; - transition: all .2s ease-out; + margin-top: 0; + transition: all .2s ease-out; } .email-receipt-form { - opacity: 0; - margin-bottom: -71px; - transform: translate3d(0, -130px, 0); - transition: all .2s ease-out; + opacity: 0; + margin-bottom: -71px; + transform: translate3d(0, -130px, 0); + transition: all .2s ease-out; } .email-receipt-button { - margin-top: -56px; - transform: translate3d(0, 70px, 0); - opacity: 0; - transition: all .2s ease-out; + margin-top: -56px; + transform: translate3d(0, 70px, 0); + opacity: 0; + transition: all .2s ease-out; } .manual-flow { - opacity: 0; - margin-top: -15px; - transition: all .3s ease-out; + opacity: 0; + margin-top: -15px; + transition: all .3s ease-out; } - .manual-flow.active { - margin-top: 0; - opacity: 1; - } + .manual-flow.active { + margin-top: 0; + opacity: 1; + } .open .payment__scan__qrcode img { - transform: scale3d(1, 1, 1); - max-height: 255px !important; + transform: scale3d(1, 1, 1); + max-height: 255px !important; } .open .payment__scan__help-text { - opacity: 1; + opacity: 1; } .open .payment__details__instruction__open-wallet__btn { - transform: scale3d(1, 1, 1) translate3d(0, 10px, 0); + transform: scale3d(1, 1, 1) translate3d(0, 10px, 0); } .open .footer { - transform: translate3d(0, 0, 0); - opacity: 1; - transition: all 550ms ease-out; + transform: translate3d(0, 0, 0); + opacity: 1; + transition: all 550ms ease-out; } .open .bp-view.scan.active .payment__details__instruction__open-wallet__btn { - opacity: 1; + opacity: 1; } .expired .timer-row__time-left { - visibility: hidden; + visibility: hidden; } .paid .top-header, @@ -10120,7 +10120,7 @@ All mobile class names should be prefixed by m- */ .paid-partial .top-header, .refund-complete .top-header, .archived .top-header { - max-height: 59px; + max-height: 59px; } .paid .timer-row, @@ -10128,7 +10128,7 @@ All mobile class names should be prefixed by m- */ .paid-partial .timer-row, .refund-complete .timer-row, .archived .timer-row { - opacity: 0; + opacity: 0; } .paid .exrate, @@ -10136,7 +10136,7 @@ All mobile class names should be prefixed by m- */ .paid-partial .exrate, .refund-complete .exrate, .archived .exrate { - opacity: 0; + opacity: 0; } .paid .payment-tabs, @@ -10144,8 +10144,8 @@ All mobile class names should be prefixed by m- */ .paid-partial .payment-tabs, .refund-complete .payment-tabs, .archived .payment-tabs { - z-index: -1; - margin-top: -50px !important; + z-index: -1; + margin-top: -50px !important; } .paid .payment__scan__qrcode img, @@ -10153,10 +10153,10 @@ All mobile class names should be prefixed by m- */ .paid-partial .payment__scan__qrcode img, .refund-complete .payment__scan__qrcode img, .archived .payment__scan__qrcode img { - transition: all .1s ease-out !important; - transform: scale3d(0, 0, 1); - opacity: 0; - max-height: 180px !important; + transition: all .1s ease-out !important; + transform: scale3d(0, 0, 1); + opacity: 0; + max-height: 180px !important; } .paid .payment__scan__help-text, @@ -10164,7 +10164,7 @@ All mobile class names should be prefixed by m- */ .paid-partial .payment__scan__help-text, .refund-complete .payment__scan__help-text, .archived .payment__scan__help-text { - opacity: 0; + opacity: 0; } .paid .payment__details__instruction__open-wallet__btn, @@ -10172,16 +10172,16 @@ All mobile class names should be prefixed by m- */ .paid-partial .payment__details__instruction__open-wallet__btn, .refund-complete .payment__details__instruction__open-wallet__btn, .archived .payment__details__instruction__open-wallet__btn { - transition: all .1s ease-out !important; + transition: all .1s ease-out !important; } .paid-partial .invoice { - min-height: 0; + min-height: 0; } .paid-partial .manual__step-two { - margin-top: -.1rem; - padding-top: 0; + margin-top: -.1rem; + padding-top: 0; } .paid .manual-flow, @@ -10190,16 +10190,16 @@ All mobile class names should be prefixed by m- */ .expired .payment, .archived .manual-flow, .archived .payment { - display: none; + display: none; } .opened .payment__scan__qrcode img { - transition: all .23s ease-out; + transition: all .23s ease-out; } .opened .payment__details__instruction__open-wallet__btn { - transition: all .4s ease-in-out; - margin-top: 0; + transition: all .4s ease-in-out; + margin-top: 0; } .manual .payment__scan__qrcode img, @@ -10208,9 +10208,9 @@ All mobile class names should be prefixed by m- */ .confirm-contact-email .payment__scan__qrcode img, .link-expired .payment__scan__qrcode img, .wrong-email .payment__scan__qrcode img { - transition: all .23s ease-out; - transform: scale3d(0, 0, 1); - opacity: 0; + transition: all .23s ease-out; + transform: scale3d(0, 0, 1); + opacity: 0; } .manual .payment__details__instruction__open-wallet__btn, @@ -10219,9 +10219,9 @@ All mobile class names should be prefixed by m- */ .confirm-contact-email .payment__details__instruction__open-wallet__btn, .link-expired .payment__details__instruction__open-wallet__btn, .wrong-email .payment__details__instruction__open-wallet__btn { - opacity: 0; - margin-top: 25px; - transition: all .23s ease-out; + opacity: 0; + margin-top: 25px; + transition: all .23s ease-out; } .manual .payment__scan__help-text, @@ -10230,19 +10230,19 @@ All mobile class names should be prefixed by m- */ .confirm-contact-email .payment__scan__help-text, .link-expired .payment__scan__help-text, .wrong-email .payment__scan__help-text { - opacity: 0; + opacity: 0; } .paid .status-icon { - padding-top: 15px; + padding-top: 15px; } .paid:not(.paid-over) .status-icon { - padding-top: 54px; + padding-top: 54px; } .paid:not(.paid-over) .button-wrapper { - margin-top: 68px; + margin-top: 68px; } .enter-purchaser-email .payment-tabs, @@ -10250,9 +10250,9 @@ All mobile class names should be prefixed by m- */ .confirm-contact-email .payment-tabs, .link-expired .payment-tabs, .wrong-email .payment-tabs { - pointer-events: none; - margin-top: -2.95rem; - margin-bottom: 1rem; + pointer-events: none; + margin-top: -2.95rem; + margin-bottom: 1rem; } .enter-purchaser-email .payment-tabs__slider, @@ -10260,944 +10260,944 @@ All mobile class names should be prefixed by m- */ .confirm-contact-email .payment-tabs__slider, .link-expired .payment-tabs__slider, .wrong-email .payment-tabs__slider { - display: none; + display: none; } .confirm-contact-email .payment-box { - min-height: 425px !important; + min-height: 425px !important; } .confirm-contact-email .footer-button { - display: none; + display: none; } .confirm-bitcoin-address .payment-box, .link-expired .payment-box { - min-height: 455px !important; + min-height: 455px !important; } .wrong-email .payment-box { - min-height: 465px !important; + min-height: 465px !important; } .wrong-email .footer-button { - display: none; + display: none; } .has-refund-address .order-details { - display: block !important; + display: block !important; } .has-refund-address .payment-box { - min-height: 581px !important; + min-height: 581px !important; } .has-refund-address .timer-row, .confirm-bitcoin-address .timer-row, .enter-refund-address .timer-row { - display: none; + display: none; } .enter-refund-address .payment-box { - min-height: 460px !important; + min-height: 460px !important; } .enter-refund-address .refund-address-form { - margin-top: 35px; + margin-top: 35px; } .enter-refund-address .refund-address-view { - opacity: 1; - transform: translateY(0); - transition: transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1); + opacity: 1; + transform: translateY(0); + transition: transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1); } .enter-refund-address .payment-tabs { - z-index: -1; - margin-top: -50px !important; + z-index: -1; + margin-top: -50px !important; } .confirm-bitcoin-address .confirm-bitcoin-address-view, .confirm-bitcoin-address .enter-different-address-button { - opacity: 1; - transition: opacity 300ms ease; - pointer-events: all; - z-index: 1; + opacity: 1; + transition: opacity 300ms ease; + pointer-events: all; + z-index: 1; } .confirm-bitcoin-address-view, .enter-different-address-button { - opacity: 0; - pointer-events: none; - z-index: -1; + opacity: 0; + pointer-events: none; + z-index: -1; } .refund-address-view { - transform: translateY(20px); + transform: translateY(20px); } .payment-tabs { - z-index: 1; + z-index: 1; } .single-item-order { - z-index: 2; + z-index: 2; } .paid .button-wrapper, .refund-complete .button-wrapper { - margin-top: 6px; + margin-top: 6px; } .paid .status-icon__wrapper, .refund-complete .status-icon__wrapper { - opacity: 1; + opacity: 1; } .paid .status-icon__wrapper__outline, .refund-complete .status-icon__wrapper__outline { - animation: checkmarkbounce 750ms linear both; + animation: checkmarkbounce 750ms linear both; } .paid .status-icon__wrapper__icon, .refund-complete .status-icon__wrapper__icon { - animation: checkbounce 750ms linear both; + animation: checkbounce 750ms linear both; } .paid .success-message, .refund-complete .success-message { - display: block; - opacity: 1; + display: block; + opacity: 1; } .paid .payment__details__instruction__open-wallet__btn, .refund-complete .payment__details__instruction__open-wallet__btn { - opacity: 0; - height: 0; - margin: 0; - padding: 0; - transform: scale3d(0, 0, 0); + opacity: 0; + height: 0; + margin: 0; + padding: 0; + transform: scale3d(0, 0, 0); } .paid .email-receipt-form, .refund-complete .email-receipt-form { - opacity: 1; - margin: 0; - transform: translate3d(0, 0, 0); + opacity: 1; + margin: 0; + transform: translate3d(0, 0, 0); } .paid .email-receipt-button, .refund-complete .email-receipt-button { - margin-top: 19px; - opacity: 1; - transform: translate3d(0, 0, 0); + margin-top: 19px; + opacity: 1; + transform: translate3d(0, 0, 0); } .paid .footer, .refund-complete .footer { - opacity: 0; - transition-duration: 100ms; + opacity: 0; + transition-duration: 100ms; } .paid-partial .top-header { - max-height: 100px; + max-height: 100px; } .paid-partial .timer-row { - opacity: 1; + opacity: 1; } .paid-over .status-icon { - padding-top: 0; + padding-top: 0; } .paid-over .payment-box { - min-height: 550px; + min-height: 550px; } .paid-over.show-refund-address-form .payment-box { - min-height: 645px; + min-height: 645px; } .paid-over.has-refund-address .payment-box { - min-height: 585px; + min-height: 585px; } .paid-over .button-wrapper { - margin-top: 0; + margin-top: 0; } .paid-over .button-wrapper { - margin-top: 0; + margin-top: 0; } .refund-complete .payment-box { - min-height: 546px; + min-height: 546px; } .expired .bp-view:not(.paid-partial) .expired-icon, .archived .bp-view:not(.paid-partial) .expired-icon { - padding-top: 30px; + padding-top: 30px; } .expired .payment-box, .archived .payment-box { - min-height: 550px; + min-height: 550px; } .expired.show-refund-address-form .payment-box, .archived.show-refund-address-form .payment-box { - min-height: 644px; + min-height: 644px; } .expired.has-refund-address .payment-box, .archived.has-refund-address .payment-box { - min-height: 575px; + min-height: 575px; } .expired .order-details, .archived .order-details { - display: none; + display: none; } .expired.open .footer__item, .archived.open .footer__item { - opacity: .8; + opacity: .8; } .opened .footer { - z-index: 1; + z-index: 1; } .expired.paid-partial .timer-row { - display: none; + display: none; } .expired.paid-partial .order-details { - display: block; + display: block; } .expired .top-header { - max-height: 100px; + max-height: 100px; } .expired .timer-row { - background: #E5465A; - opacity: 1; - z-index: 999; + background: #E5465A; + opacity: 1; + z-index: 999; } .expired .timer-row__message { - opacity: 1; + opacity: 1; } .expired.has-refund-address .payment-box { - min-height: 591px; + min-height: 591px; } .archived .invoice { - min-height: 400px; + min-height: 400px; } .archived .payment-box { - min-height: 0; + min-height: 0; } .archived .footer { - display: none; + display: none; } .email-receipt-form .success-wrapper { - transition: all .2s ease; - opacity: 0; - right: -100px; + transition: all .2s ease; + opacity: 0; + right: -100px; } .email-receipt-form.sent .email-input, .email-receipt-form.sent .send-button, .email-receipt-form.sent .email-receipt-form__label { - transition: all .2s ease; - transform: translate3d(0, 40px, 0); - opacity: 0; + transition: all .2s ease; + transform: translate3d(0, 40px, 0); + opacity: 0; } .email-receipt-form.sent .success-wrapper { - opacity: 1; - right: 0; + opacity: 1; + right: 0; } .fade-out-up { - animation-fill-mode: both; - animation-duration: 0.2s; - animation-name: fadeOutUp; + animation-fill-mode: both; + animation-duration: 0.2s; + animation-name: fadeOutUp; } .fade-in-up { - animation-fill-mode: both; - animation-duration: 0.35s; - animation-name: fadeInUp; + animation-fill-mode: both; + animation-duration: 0.35s; + animation-name: fadeInUp; } @keyframes checkmarkbounce { - 0% { - transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 0% { + transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 4.7% { - transform: matrix3d(1.55, 0, 0, 0, 0, 1.55, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 4.7% { + transform: matrix3d(1.55, 0, 0, 0, 0, 1.55, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 9.41% { - transform: matrix3d(1.117, 0, 0, 0, 0, 1.117, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 9.41% { + transform: matrix3d(1.117, 0, 0, 0, 0, 1.117, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 14.11% { - transform: matrix3d(0.859, 0, 0, 0, 0, 0.859, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 14.11% { + transform: matrix3d(0.859, 0, 0, 0, 0, 0.859, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 18.72% { - transform: matrix3d(0.788, 0, 0, 0, 0, 0.788, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 18.72% { + transform: matrix3d(0.788, 0, 0, 0, 0, 0.788, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 24.32% { - transform: matrix3d(0.849, 0, 0, 0, 0, 0.849, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 24.32% { + transform: matrix3d(0.849, 0, 0, 0, 0, 0.849, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 29.93% { - transform: matrix3d(0.952, 0, 0, 0, 0, 0.952, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 29.93% { + transform: matrix3d(0.952, 0, 0, 0, 0, 0.952, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 35.54% { - transform: matrix3d(1.021, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 35.54% { + transform: matrix3d(1.021, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 41.04% { - transform: matrix3d(1.039, 0, 0, 0, 0, 1.039, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 41.04% { + transform: matrix3d(1.039, 0, 0, 0, 0, 1.039, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 52.15% { - transform: matrix3d(1.009, 0, 0, 0, 0, 1.009, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 52.15% { + transform: matrix3d(1.009, 0, 0, 0, 0, 1.009, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 63.26% { - transform: matrix3d(0.993, 0, 0, 0, 0, 0.993, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 63.26% { + transform: matrix3d(0.993, 0, 0, 0, 0, 0.993, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 85.49% { - transform: matrix3d(1.001, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 85.49% { + transform: matrix3d(1.001, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 100% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 100% { + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } } @keyframes checkbounce { - 0% { - transform: matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 0% { + transform: matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 4.7% { - transform: matrix3d(0.45, 0, 0, 0, 0, 0.45, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 4.7% { + transform: matrix3d(0.45, 0, 0, 0, 0, 0.45, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 9.41% { - transform: matrix3d(0.883, 0, 0, 0, 0, 0.883, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 9.41% { + transform: matrix3d(0.883, 0, 0, 0, 0, 0.883, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 14.11% { - transform: matrix3d(1.141, 0, 0, 0, 0, 1.141, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 14.11% { + transform: matrix3d(1.141, 0, 0, 0, 0, 1.141, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 18.72% { - transform: matrix3d(1.212, 0, 0, 0, 0, 1.212, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 18.72% { + transform: matrix3d(1.212, 0, 0, 0, 0, 1.212, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 24.32% { - transform: matrix3d(1.151, 0, 0, 0, 0, 1.151, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 24.32% { + transform: matrix3d(1.151, 0, 0, 0, 0, 1.151, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 29.93% { - transform: matrix3d(1.048, 0, 0, 0, 0, 1.048, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 29.93% { + transform: matrix3d(1.048, 0, 0, 0, 0, 1.048, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 35.54% { - transform: matrix3d(0.979, 0, 0, 0, 0, 0.979, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 35.54% { + transform: matrix3d(0.979, 0, 0, 0, 0, 0.979, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 41.04% { - transform: matrix3d(0.961, 0, 0, 0, 0, 0.961, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 41.04% { + transform: matrix3d(0.961, 0, 0, 0, 0, 0.961, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 52.15% { - transform: matrix3d(0.991, 0, 0, 0, 0, 0.991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 52.15% { + transform: matrix3d(0.991, 0, 0, 0, 0, 0.991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 63.26% { - transform: matrix3d(1.007, 0, 0, 0, 0, 1.007, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 63.26% { + transform: matrix3d(1.007, 0, 0, 0, 0, 1.007, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 85.49% { - transform: matrix3d(0.999, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 85.49% { + transform: matrix3d(0.999, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } - 100% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } + 100% { + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } } @keyframes flip-in { - 0% { - transform: rotateX(-93deg); - } + 0% { + transform: rotateX(-93deg); + } - 3% { - transform: rotateX(-71.05958deg); - } + 3% { + transform: rotateX(-71.05958deg); + } - 6% { - transform: rotateX(-51.04377deg); - } + 6% { + transform: rotateX(-51.04377deg); + } - 9% { - transform: rotateX(-34.03271deg); - } + 9% { + transform: rotateX(-34.03271deg); + } - 12% { - transform: rotateX(-20.4225deg); - } + 12% { + transform: rotateX(-20.4225deg); + } - 15% { - transform: rotateX(-10.15003deg); - } + 15% { + transform: rotateX(-10.15003deg); + } - 18% { - transform: rotateX(-2.87379deg); - } + 18% { + transform: rotateX(-2.87379deg); + } - 21% { - transform: rotateX(1.88904deg); - } + 21% { + transform: rotateX(1.88904deg); + } - 24% { - transform: rotateX(4.66502deg); - } + 24% { + transform: rotateX(4.66502deg); + } - 27% { - transform: rotateX(5.96deg); - } + 27% { + transform: rotateX(5.96deg); + } - 30% { - transform: rotateX(6.22122deg); - } + 30% { + transform: rotateX(6.22122deg); + } - 33% { - transform: rotateX(5.81909deg); - } + 33% { + transform: rotateX(5.81909deg); + } - 36% { - transform: rotateX(5.04293deg); - } + 36% { + transform: rotateX(5.04293deg); + } - 39% { - transform: rotateX(4.10566deg); - } + 39% { + transform: rotateX(4.10566deg); + } - 42% { - transform: rotateX(3.15364deg); - } + 42% { + transform: rotateX(3.15364deg); + } - 45% { - transform: rotateX(2.27876deg); - } + 45% { + transform: rotateX(2.27876deg); + } - 48% { - transform: rotateX(1.5309deg); - } + 48% { + transform: rotateX(1.5309deg); + } - 51% { - transform: rotateX(0.9294deg); - } + 51% { + transform: rotateX(0.9294deg); + } - 54% { - transform: rotateX(0.47298deg); - } + 54% { + transform: rotateX(0.47298deg); + } - 57% { - transform: rotateX(0.1477deg); - } + 57% { + transform: rotateX(0.1477deg); + } - 60% { - transform: rotateX(-0.06697deg); - } + 60% { + transform: rotateX(-0.06697deg); + } - 63% { - transform: rotateX(-0.19373deg); - } + 63% { + transform: rotateX(-0.19373deg); + } - 66% { - transform: rotateX(-0.25461deg); - } + 66% { + transform: rotateX(-0.25461deg); + } - 69% { - transform: rotateX(-0.26921deg); - } + 69% { + transform: rotateX(-0.26921deg); + } - 72% { - transform: rotateX(-0.25385deg); - } + 72% { + transform: rotateX(-0.25385deg); + } - 75% { - transform: rotateX(-0.22134deg); - } + 75% { + transform: rotateX(-0.22134deg); + } - 78% { - transform: rotateX(-0.18117deg); - } + 78% { + transform: rotateX(-0.18117deg); + } - 81% { - transform: rotateX(-0.13989deg); - } + 81% { + transform: rotateX(-0.13989deg); + } - 84% { - transform: rotateX(-0.10167deg); - } + 84% { + transform: rotateX(-0.10167deg); + } - 87% { - transform: rotateX(-0.06881deg); - } + 87% { + transform: rotateX(-0.06881deg); + } - 90% { - transform: rotateX(-0.04224deg); - } + 90% { + transform: rotateX(-0.04224deg); + } - 93% { - transform: rotateX(-0.02197deg); - } + 93% { + transform: rotateX(-0.02197deg); + } - 96% { - transform: rotateX(-0.00744deg); - } + 96% { + transform: rotateX(-0.00744deg); + } - 99% { - transform: rotateX(0.00223deg); - } + 99% { + transform: rotateX(0.00223deg); + } } @keyframes fadeOutUp { - from { - opacity: 1; - } + from { + opacity: 1; + } - to { - opacity: 0; - transform: translate3d(0, -5%, 0); - } + to { + opacity: 0; + transform: translate3d(0, -5%, 0); + } } @keyframes fadeInUp { - from { - opacity: 0; - transform: translate3d(0, 10%, 0); - } + from { + opacity: 0; + transform: translate3d(0, 10%, 0); + } - to { - opacity: 1; - } + to { + opacity: 1; + } } bp-loading-button button { - position: relative; + position: relative; } - bp-loading-button button.loading { - opacity: .7 !important; - pointer-events: none; - } + bp-loading-button button.loading { + opacity: .7 !important; + pointer-events: none; + } - bp-loading-button button.loading .button-text { - opacity: 0; - transition: opacity 250ms ease; - } + bp-loading-button button.loading .button-text { + opacity: 0; + transition: opacity 250ms ease; + } - bp-loading-button button.loading .loader-wrapper { - opacity: 1; - transition: opacity 250ms ease; - } + bp-loading-button button.loading .loader-wrapper { + opacity: 1; + transition: opacity 250ms ease; + } - bp-loading-button button .loader-wrapper { - height: 100%; - width: 100%; - position: absolute; - top: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; - opacity: 0; - } + bp-loading-button button .loader-wrapper { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + } - bp-loading-button button .loader-wrapper > bp-spinner > svg { - height: 23px; - width: 23px; - fill: white; - animation: spin 0.55s linear infinite; - opacity: .85; - } + bp-loading-button button .loader-wrapper > bp-spinner > svg { + height: 23px; + width: 23px; + fill: white; + animation: spin 0.55s linear infinite; + opacity: .85; + } bp-spinner { - display: flex; + display: flex; } bp-refund-address.ng-valid .bitcoin-logo { - opacity: 1; - margin-left: 0; - transition: all .2s ease; + opacity: 1; + margin-left: 0; + transition: all .2s ease; } bp-refund-address.ng-valid input { - font-size: 10.6px; - padding-left: 36px; - padding-right: 8px; - text-align: center; + font-size: 10.6px; + padding-left: 36px; + padding-right: 8px; + text-align: center; } .bp-refund-address { - position: relative; + position: relative; } - .bp-refund-address input { - height: 56px; - transition: padding .2s ease; - text-align: left; - } + .bp-refund-address input { + height: 56px; + transition: padding .2s ease; + text-align: left; + } - .bp-refund-address input:focus { - font-size: 10.6px; - } + .bp-refund-address input:focus { + font-size: 10.6px; + } - .bp-refund-address input.not-empty { - font-size: 10.6px; - } + .bp-refund-address input.not-empty { + font-size: 10.6px; + } - .bp-refund-address input::-webkit-input-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-refund-address input::-webkit-input-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } - .bp-refund-address input:-moz-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-refund-address input:-moz-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } - .bp-refund-address input::-moz-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-refund-address input::-moz-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } - .bp-refund-address input:-ms-input-placeholder { - color: rgba(81, 86, 100, 0.5); - font-weight: 300; - font-size: 13px; - } + .bp-refund-address input:-ms-input-placeholder { + color: rgba(81, 86, 100, 0.5); + font-weight: 300; + font-size: 13px; + } .bp-resend { - text-align: center; + text-align: center; } .bp-resend__link { - font-size: 14px; - font-weight: 300; - color: #5a8fe8; - display: inline-block; - position: relative; + font-size: 14px; + font-weight: 300; + color: #5a8fe8; + display: inline-block; + position: relative; } - .bp-resend__link > .link-text { - opacity: 1; - cursor: pointer; - transform: scale3d(1, 1, 1); - } + .bp-resend__link > .link-text { + opacity: 1; + cursor: pointer; + transform: scale3d(1, 1, 1); + } - .bp-resend__link > .link-text > .resending { - color: #515664; - opacity: .7; - } + .bp-resend__link > .link-text > .resending { + color: #515664; + opacity: .7; + } - .bp-resend__link > .link-text > span { - transform: translate3d(0, 0, 0); - } + .bp-resend__link > .link-text > span { + transform: translate3d(0, 0, 0); + } - .bp-resend__link > .link-text:hover { - opacity: .8; - } + .bp-resend__link > .link-text:hover { + opacity: .8; + } - .bp-resend__link > .success-text { - color: #515664; - display: flex; - margin-left: auto; - margin-right: auto; - top: 0; - transform: translateX(100px); - opacity: 0; - pointer-events: none; - left: 50%; - white-space: nowrap; - position: absolute; - } + .bp-resend__link > .success-text { + color: #515664; + display: flex; + margin-left: auto; + margin-right: auto; + top: 0; + transform: translateX(100px); + opacity: 0; + pointer-events: none; + left: 50%; + white-space: nowrap; + position: absolute; + } - .bp-resend__link > .success-text img { - margin-right: .5rem; - } + .bp-resend__link > .success-text img { + margin-right: .5rem; + } .bp-resend__link__sent > .link-text { - transition: all 250ms ease; - opacity: 0; - pointer-events: none; - transform: scale3d(0.1, 0.1, 0.1); + transition: all 250ms ease; + opacity: 0; + pointer-events: none; + transform: scale3d(0.1, 0.1, 0.1); } - .bp-resend__link__sent > .link-text.fade { - opacity: 1; - transition: opacity 1000ms ease; - } + .bp-resend__link__sent > .link-text.fade { + opacity: 1; + transition: opacity 1000ms ease; + } - .bp-resend__link__sent > .link-text:hover { - opacity: 0; - } + .bp-resend__link__sent > .link-text:hover { + opacity: 0; + } .bp-resend__link__sent > .success-text { - opacity: .7; - transition: all 250ms ease; - transition-delay: 100ms; - transform: translateX(-50%); + opacity: .7; + transition: all 250ms ease; + transition-delay: 100ms; + transform: translateX(-50%); } - .bp-resend__link__sent > .success-text.fade { - opacity: 0; - transition: opacity 1000ms ease; - } + .bp-resend__link__sent > .success-text.fade { + opacity: 0; + transition: opacity 1000ms ease; + } language-selector { - display: block; - position: relative; + display: block; + position: relative; } - language-selector .selector { - cursor: pointer; - z-index: 2; - position: relative; - opacity: .8; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - width: 85px; - text-align: right; - } + language-selector .selector { + cursor: pointer; + z-index: 2; + position: relative; + opacity: .8; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 85px; + text-align: right; + } - language-selector .selector.open { - opacity: 1; - } + language-selector .selector.open { + opacity: 1; + } - language-selector .menu { - position: absolute; - z-index: 1; - bottom: -10px; - right: -42px; - background: black; - padding-bottom: 1rem; - border-radius: 3px; - height: 35px; - opacity: 0; - pointer-events: none; - transition: opacity 200ms ease, height 250ms cubic-bezier(0.4, 0, 0.2, 1); - } + language-selector .menu { + position: absolute; + z-index: 1; + bottom: -10px; + right: -42px; + background: black; + padding-bottom: 1rem; + border-radius: 3px; + height: 35px; + opacity: 0; + pointer-events: none; + transition: opacity 200ms ease, height 250ms cubic-bezier(0.4, 0, 0.2, 1); + } - language-selector .menu.reveal { - opacity: .9; - } + language-selector .menu.reveal { + opacity: .9; + } - language-selector .menu.stretch { - height: 488px; - pointer-events: all; - } + language-selector .menu.stretch { + height: 488px; + pointer-events: all; + } - language-selector .menu__scroll { - overflow-y: scroll; - max-height: 440px; - padding: 1.2rem 2rem; - margin-bottom: 2rem; - opacity: 0; - transition: opacity 250ms ease; - } + language-selector .menu__scroll { + overflow-y: scroll; + max-height: 440px; + padding: 1.2rem 2rem; + margin-bottom: 2rem; + opacity: 0; + transition: opacity 250ms ease; + } - language-selector .menu__scroll.fade-in-langs { - opacity: 1; - } + language-selector .menu__scroll.fade-in-langs { + opacity: 1; + } - language-selector .menu__item { - padding: 3px; - font-size: 13px; - font-weight: 400; - cursor: pointer; - opacity: .8; - } + language-selector .menu__item { + padding: 3px; + font-size: 13px; + font-weight: 400; + cursor: pointer; + opacity: .8; + } - language-selector .menu__item.selected, language-selector .menu__item:hover { - opacity: 1; - } + language-selector .menu__item.selected, language-selector .menu__item:hover { + opacity: 1; + } - language-selector .menu.open { - opacity: 1; - } + language-selector .menu.open { + opacity: 1; + } line-items { - background: #FBFBFB; - height: 25px; - border-top: 0; - z-index: 2; - position: relative; - display: block; - overflow: hidden; - height: 0; - transition: height 250ms ease; + background: #FBFBFB; + height: 25px; + border-top: 0; + z-index: 2; + position: relative; + display: block; + overflow: hidden; + height: 0; + transition: height 250ms ease; } - line-items.expanded { - height: 120px; - border-top: 1px solid rgba(238, 238, 238, 0.5); - } + line-items.expanded { + height: 120px; + border-top: 1px solid rgba(238, 238, 238, 0.5); + } - line-items.expanded.paid-over { - height: 295px; - } + line-items.expanded.paid-over { + height: 295px; + } - line-items.expanded.paid-partial-expired, line-items.expanded.paid-full { - height: 272px; - } + line-items.expanded.paid-partial-expired, line-items.expanded.paid-full { + height: 272px; + } - line-items .line-items { - padding: 1rem; - color: #565D6E; - } + line-items .line-items { + padding: 1rem; + color: #565D6E; + } - line-items .line-items__header { - border-top: 1px dashed rgba(151, 151, 151, 0.3); - padding-top: .75rem; - padding-bottom: .5rem; - margin-top: .75rem; - margin-bottom: 3px; - font-size: 16px; - font-weight: 400; - } + line-items .line-items__header { + border-top: 1px dashed rgba(151, 151, 151, 0.3); + padding-top: .75rem; + padding-bottom: .5rem; + margin-top: .75rem; + margin-bottom: 3px; + font-size: 16px; + font-weight: 400; + } - line-items .line-items__header--first { - border: 0; - padding-top: 0; - margin-top: 0; - margin-top: -.25rem; - } + line-items .line-items__header--first { + border: 0; + padding-top: 0; + margin-top: 0; + margin-top: -.25rem; + } - line-items .line-items__item { - display: flex; - font-size: 12px; - font-weight: 100; - padding: 2px 0; - } + line-items .line-items__item { + display: flex; + font-size: 12px; + font-weight: 100; + padding: 2px 0; + } - line-items .line-items__item__label { - flex-grow: 1; - display: flex; - align-items: center; - } + line-items .line-items__item__label { + flex-grow: 1; + display: flex; + align-items: center; + } - line-items .line-items__item__label > a { - display: block; - margin-top: -2px; - margin-left: 5px; - } + line-items .line-items__item__label > a { + display: block; + margin-top: -2px; + margin-left: 5px; + } - line-items .line-items__item--total { - font-weight: 600; - margin-top: 2px; - margin-top: 10px; - } + line-items .line-items__item--total { + font-weight: 600; + margin-top: 2px; + margin-top: 10px; + } - line-items .line-items__item--success { - color: #1DB670; - } + line-items .line-items__item--success { + color: #1DB670; + } - line-items .line-items__item--warn { - color: #FF9405; - } + line-items .line-items__item--warn { + color: #FF9405; + } low-fee-timeline { - display: block; - padding: 1rem 0; + display: block; + padding: 1rem 0; } - low-fee-timeline .timeline__item { - align-items: center; - display: flex; - font-size: 14px; - padding: 1rem 0; - color: #4A4A4A; - } + low-fee-timeline .timeline__item { + align-items: center; + display: flex; + font-size: 14px; + padding: 1rem 0; + color: #4A4A4A; + } - low-fee-timeline .timeline__item__icon { - width: 25px; - height: 25px; - min-width: 25px; - margin-right: 1rem; - border-radius: 50%; - border: 1px solid #D8D8D8; - position: relative; - background: #f5f5f7; - display: flex; - justify-content: center; - align-items: center; - opacity: 1; - } + low-fee-timeline .timeline__item__icon { + width: 25px; + height: 25px; + min-width: 25px; + margin-right: 1rem; + border-radius: 50%; + border: 1px solid #D8D8D8; + position: relative; + background: #f5f5f7; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + } - low-fee-timeline .timeline__item__icon--complete { - background: #50E3C2; - border-color: #50E3C2; - } + low-fee-timeline .timeline__item__icon--complete { + background: #50E3C2; + border-color: #50E3C2; + } - low-fee-timeline .timeline__item__icon--complete:after { - content: ''; - position: absolute; - height: 240%; - width: 1px; - left: 11px; - top: 24px; - background: #50E3C2; - } + low-fee-timeline .timeline__item__icon--complete:after { + content: ''; + position: absolute; + height: 240%; + width: 1px; + left: 11px; + top: 24px; + background: #50E3C2; + } - low-fee-timeline .timeline__item__icon--pending:after { - content: ''; - position: absolute; - height: 240%; - width: 1px; - left: 11px; - top: 24px; - background: #D8D8D8; - } + low-fee-timeline .timeline__item__icon--pending:after { + content: ''; + position: absolute; + height: 240%; + width: 1px; + left: 11px; + top: 24px; + background: #D8D8D8; + } - low-fee-timeline .timeline__item__name { - opacity: .8; - } + low-fee-timeline .timeline__item__name { + opacity: .8; + } .no-animate * { - transition: none !important; - animation: none !important; + transition: none !important; + animation: none !important; } .no-bounce * .long, .no-bounce * .status-icon__wrapper__icon, .no-bounce * .status-icon__wrapper__outline { - animation: none !important; + animation: none !important; } diff --git a/BTCPayServer/wwwroot/css/site.min.css b/BTCPayServer/wwwroot/css/site.min.css index 5e93e30ae..ee28be335 100644 --- a/BTCPayServer/wwwroot/css/site.min.css +++ b/BTCPayServer/wwwroot/css/site.min.css @@ -1 +1,28 @@ -body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} \ No newline at end of file +body { + padding-top: 50px; + padding-bottom: 20px +} + +.body-content { + padding-left: 15px; + padding-right: 15px +} + +.carousel-caption p { + font-size: 20px; + line-height: 1.4 +} + +.carousel-inner .item img[src$=".svg"] { + width: 100% +} + +#qrCode { + margin: 15px +} + +@media screen and (max-width:767px) { + .carousel-caption { + display: none + } +} diff --git a/BTCPayServer/wwwroot/js/creative.js b/BTCPayServer/wwwroot/js/creative.js index d8d66a719..5bba36185 100644 --- a/BTCPayServer/wwwroot/js/creative.js +++ b/BTCPayServer/wwwroot/js/creative.js @@ -1,73 +1,73 @@ -(function($) { - "use strict"; // Start of use strict +(function ($) { + "use strict"; // Start of use strict - // Smooth scrolling using jQuery easing - $('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function() { - if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { - var target = $(this.hash); - target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); - if (target.length) { - $('html, body').animate({ - scrollTop: (target.offset().top - 48) - }, 1000, "easeInOutExpo"); - return false; - } - } - }); + // Smooth scrolling using jQuery easing + $('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function () { + if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { + var target = $(this.hash); + target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); + if (target.length) { + $('html, body').animate({ + scrollTop: (target.offset().top - 48) + }, 1000, "easeInOutExpo"); + return false; + } + } + }); - // Closes responsive menu when a scroll trigger link is clicked - $('.js-scroll-trigger').click(function() { - $('.navbar-collapse').collapse('hide'); - }); + // Closes responsive menu when a scroll trigger link is clicked + $('.js-scroll-trigger').click(function () { + $('.navbar-collapse').collapse('hide'); + }); - // Activate scrollspy to add active class to navbar items on scroll - $('body').scrollspy({ - target: '#mainNav', - offset: 48 - }); + // Activate scrollspy to add active class to navbar items on scroll + $('body').scrollspy({ + target: '#mainNav', + offset: 48 + }); - // Collapse the navbar when page is scrolled - $(window).scroll(function () { - if ($("#mainNav").is(".always-shrinked")) - return; - if ($("#mainNav").offset().top > 100) { - $("#mainNav").addClass("navbar-shrink"); - } else { - $("#mainNav").removeClass("navbar-shrink"); - } - }); + // Collapse the navbar when page is scrolled + $(window).scroll(function () { + if ($("#mainNav").is(".always-shrinked")) + return; + if ($("#mainNav").offset().top > 100) { + $("#mainNav").addClass("navbar-shrink"); + } else { + $("#mainNav").removeClass("navbar-shrink"); + } + }); - // Scroll reveal calls - window.sr = ScrollReveal(); - sr.reveal('.sr-icons', { - duration: 600, - scale: 0.3, - distance: '0px' - }, 200); - sr.reveal('.sr-button', { - duration: 1000, - delay: 200 - }); - sr.reveal('.sr-contact', { - duration: 600, - scale: 0.3, - distance: '0px' - }, 300); + // Scroll reveal calls + window.sr = ScrollReveal(); + sr.reveal('.sr-icons', { + duration: 600, + scale: 0.3, + distance: '0px' + }, 200); + sr.reveal('.sr-button', { + duration: 1000, + delay: 200 + }); + sr.reveal('.sr-contact', { + duration: 600, + scale: 0.3, + distance: '0px' + }, 300); - // Magnific popup calls - $('.popup-gallery').magnificPopup({ - delegate: 'a', - type: 'image', - tLoading: 'Loading image #%curr%...', - mainClass: 'mfp-img-mobile', - gallery: { - enabled: true, - navigateByImgClick: true, - preload: [0, 1] - }, - image: { - tError: 'The image #%curr% could not be loaded.' - } - }); + // Magnific popup calls + $('.popup-gallery').magnificPopup({ + delegate: 'a', + type: 'image', + tLoading: 'Loading image #%curr%...', + mainClass: 'mfp-img-mobile', + gallery: { + enabled: true, + navigateByImgClick: true, + preload: [0, 1] + }, + image: { + tError: 'The image #%curr% could not be loaded.' + } + }); })(jQuery); // End of use strict diff --git a/BTCPayServer/wwwroot/js/vue-qrcode.js b/BTCPayServer/wwwroot/js/vue-qrcode.js index f90d89734..919117d43 100644 --- a/BTCPayServer/wwwroot/js/vue-qrcode.js +++ b/BTCPayServer/wwwroot/js/vue-qrcode.js @@ -1,14 +1,14 @@ (function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["VueQr"] = factory(); - else - root["VueQr"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap + if (typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if (typeof define === 'function' && define.amd) + define([], factory); + else if (typeof exports === 'object') + exports["VueQr"] = factory(); + else + root["VueQr"] = factory(); +})(this, function () { + return /******/ (function (modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ @@ -16,7 +16,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) +/******/ if (installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) @@ -24,7 +24,8 @@ return /******/ (function(modules) { // webpackBootstrap /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false -/******/ }; + /******/ +}; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); @@ -34,7 +35,8 @@ return /******/ (function(modules) { // webpackBootstrap /******/ /******/ // Return the exports of the module /******/ return module.exports; -/******/ } + /******/ +} /******/ /******/ /******/ // expose the modules object (__webpack_modules__) @@ -48,1425 +50,1443 @@ return /******/ (function(modules) { // webpackBootstrap /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); -/******/ }) + /******/ +}) /************************************************************************/ -/******/ ([ +/******/([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - 'use strict'; - - var _Qrcode = __webpack_require__(1); - - var _Qrcode2 = _interopRequireDefault(_Qrcode); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - module.exports = _Qrcode2.default; + 'use strict'; -/***/ }, + var _Qrcode = __webpack_require__(1); + + var _Qrcode2 = _interopRequireDefault(_Qrcode); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + module.exports = _Qrcode2.default; + + /***/ +}, /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var __vue_script__, __vue_template__ - __vue_script__ = __webpack_require__(2) - __vue_template__ = __webpack_require__(13) - module.exports = __vue_script__ || {} - if (module.exports.__esModule) module.exports = module.exports.default - if (__vue_template__) { (typeof module.exports === "function" ? module.exports.options : module.exports).template = __vue_template__ } - if (false) {(function () { module.hot.accept() - var hotAPI = require("vue-hot-reload-api") - hotAPI.install(require("vue"), true) - if (!hotAPI.compatible) return - var id = "/home/vixi_n/Documents/Github/vue-qrcode/src/Qrcode.vue" - if (!module.hot.data) { - hotAPI.createRecord(id, module.exports) - } else { - hotAPI.update(id, module.exports, __vue_template__) - } - })()} + var __vue_script__, __vue_template__ + __vue_script__ = __webpack_require__(2) + __vue_template__ = __webpack_require__(13) + module.exports = __vue_script__ || {} + if (module.exports.__esModule) module.exports = module.exports.default + if (__vue_template__) { (typeof module.exports === "function" ? module.exports.options : module.exports).template = __vue_template__ } + if (false) { + (function () { + module.hot.accept() + var hotAPI = require("vue-hot-reload-api") + hotAPI.install(require("vue"), true) + if (!hotAPI.compatible) return + var id = "/home/vixi_n/Documents/Github/vue-qrcode/src/Qrcode.vue" + if (!module.hot.data) { + hotAPI.createRecord(id, module.exports) + } else { + hotAPI.update(id, module.exports, __vue_template__) + } + })() + } -/***/ }, + /***/ +}, /* 2 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - 'use strict'; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - var _qr = __webpack_require__(3); - - var _qr2 = _interopRequireDefault(_qr); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - var update = function update() { - this.update(); - }; // - // - // - // - // - /* generated by vue-loader */ + Object.defineProperty(exports, "__esModule", { + value: true + }); -/***/ }, + var _qr = __webpack_require__(3); + + var _qr2 = _interopRequireDefault(_qr); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var update = function update() { + this.update(); + }; // + // + // + // + // + /* generated by vue-loader */ + + /***/ +}, /* 3 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var QRCode = __webpack_require__(4); - var ErrorCorrectLevel = __webpack_require__(8); - - var qrcode = function(data, opt) { - opt = opt || {}; - var qr = new QRCode(opt.typeNumber || -1, - opt.errorCorrectLevel || ErrorCorrectLevel.H); - qr.addData(data); - qr.make(); - - return qr; - }; - - qrcode.ErrorCorrectLevel = ErrorCorrectLevel; - - module.exports = qrcode; - + var QRCode = __webpack_require__(4); + var ErrorCorrectLevel = __webpack_require__(8); + + var qrcode = function (data, opt) { + opt = opt || {}; + var qr = new QRCode(opt.typeNumber || -1, + opt.errorCorrectLevel || ErrorCorrectLevel.H); + qr.addData(data); + qr.make(); + + return qr; + }; + + qrcode.ErrorCorrectLevel = ErrorCorrectLevel; + + module.exports = qrcode; -/***/ }, + + /***/ +}, /* 4 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var BitByte = __webpack_require__(5); - var RSBlock = __webpack_require__(7); - var BitBuffer = __webpack_require__(9); - var util = __webpack_require__(10); - var Polynomial = __webpack_require__(11); - - function QRCode(typeNumber, errorCorrectLevel) { - this.typeNumber = typeNumber; - this.errorCorrectLevel = errorCorrectLevel; - this.modules = null; - this.moduleCount = 0; - this.dataCache = null; - this.dataList = []; - } - - // for client side minification - var proto = QRCode.prototype; - - proto.addData = function(data) { - var newData = new BitByte(data); - this.dataList.push(newData); - this.dataCache = null; - }; - - proto.isDark = function(row, col) { - if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { - throw new Error(row + "," + col); - } - return this.modules[row][col]; - }; - - proto.getModuleCount = function() { - return this.moduleCount; - }; - - proto.make = function() { - // Calculate automatically typeNumber if provided is < 1 - if (this.typeNumber < 1 ){ - var typeNumber = 1; - for (typeNumber = 1; typeNumber < 40; typeNumber++) { - var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); - - var buffer = new BitBuffer(); - var totalDataCount = 0; - for (var i = 0; i < rsBlocks.length; i++) { - totalDataCount += rsBlocks[i].dataCount; - } - - for (var i = 0; i < this.dataList.length; i++) { - var data = this.dataList[i]; - buffer.put(data.mode, 4); - buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) ); - data.write(buffer); - } - if (buffer.getLengthInBits() <= totalDataCount * 8) - break; - } - this.typeNumber = typeNumber; - } - this.makeImpl(false, this.getBestMaskPattern() ); - }; - - proto.makeImpl = function(test, maskPattern) { - - this.moduleCount = this.typeNumber * 4 + 17; - this.modules = new Array(this.moduleCount); - - for (var row = 0; row < this.moduleCount; row++) { - - this.modules[row] = new Array(this.moduleCount); - - for (var col = 0; col < this.moduleCount; col++) { - this.modules[row][col] = null;//(col + row) % 3; - } - } - - this.setupPositionProbePattern(0, 0); - this.setupPositionProbePattern(this.moduleCount - 7, 0); - this.setupPositionProbePattern(0, this.moduleCount - 7); - this.setupPositionAdjustPattern(); - this.setupTimingPattern(); - this.setupTypeInfo(test, maskPattern); - - if (this.typeNumber >= 7) { - this.setupTypeNumber(test); - } - - if (this.dataCache == null) { - this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); - } - - this.mapData(this.dataCache, maskPattern); - }; - - proto.setupPositionProbePattern = function(row, col) { - - for (var r = -1; r <= 7; r++) { - - if (row + r <= -1 || this.moduleCount <= row + r) continue; - - for (var c = -1; c <= 7; c++) { - - if (col + c <= -1 || this.moduleCount <= col + c) continue; - - if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) - || (0 <= c && c <= 6 && (r == 0 || r == 6) ) - || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { - this.modules[row + r][col + c] = true; - } else { - this.modules[row + r][col + c] = false; - } - } - } - }; - - proto.getBestMaskPattern = function() { - - var minLostPoint = 0; - var pattern = 0; - - for (var i = 0; i < 8; i++) { - - this.makeImpl(true, i); - - var lostPoint = util.getLostPoint(this); - - if (i == 0 || minLostPoint > lostPoint) { - minLostPoint = lostPoint; - pattern = i; - } - } - - return pattern; - }; - - proto.createMovieClip = function(target_mc, instance_name, depth) { - - var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); - var cs = 1; - - this.make(); - - for (var row = 0; row < this.modules.length; row++) { - - var y = row * cs; - - for (var col = 0; col < this.modules[row].length; col++) { - - var x = col * cs; - var dark = this.modules[row][col]; - - if (dark) { - qr_mc.beginFill(0, 100); - qr_mc.moveTo(x, y); - qr_mc.lineTo(x + cs, y); - qr_mc.lineTo(x + cs, y + cs); - qr_mc.lineTo(x, y + cs); - qr_mc.endFill(); - } - } - } - - return qr_mc; - }; - - proto.setupTimingPattern = function() { - - for (var r = 8; r < this.moduleCount - 8; r++) { - if (this.modules[r][6] != null) { - continue; - } - this.modules[r][6] = (r % 2 == 0); - } - - for (var c = 8; c < this.moduleCount - 8; c++) { - if (this.modules[6][c] != null) { - continue; - } - this.modules[6][c] = (c % 2 == 0); - } - }; - - proto.setupPositionAdjustPattern = function() { - - var pos = util.getPatternPosition(this.typeNumber); - - for (var i = 0; i < pos.length; i++) { - - for (var j = 0; j < pos.length; j++) { - - var row = pos[i]; - var col = pos[j]; - - if (this.modules[row][col] != null) { - continue; - } - - for (var r = -2; r <= 2; r++) { - - for (var c = -2; c <= 2; c++) { - - if (r == -2 || r == 2 || c == -2 || c == 2 - || (r == 0 && c == 0) ) { - this.modules[row + r][col + c] = true; - } else { - this.modules[row + r][col + c] = false; - } - } - } - } - } - }; - - proto.setupTypeNumber = function(test) { - - var bits = util.getBCHTypeNumber(this.typeNumber); - - for (var i = 0; i < 18; i++) { - var mod = (!test && ( (bits >> i) & 1) == 1); - this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; - } - - for (var i = 0; i < 18; i++) { - var mod = (!test && ( (bits >> i) & 1) == 1); - this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; - } - }; - - proto.setupTypeInfo = function(test, maskPattern) { - - var data = (this.errorCorrectLevel << 3) | maskPattern; - var bits = util.getBCHTypeInfo(data); - - // vertical - for (var i = 0; i < 15; i++) { - - var mod = (!test && ( (bits >> i) & 1) == 1); - - if (i < 6) { - this.modules[i][8] = mod; - } else if (i < 8) { - this.modules[i + 1][8] = mod; - } else { - this.modules[this.moduleCount - 15 + i][8] = mod; - } - } - - // horizontal - for (var i = 0; i < 15; i++) { - - var mod = (!test && ( (bits >> i) & 1) == 1); - - if (i < 8) { - this.modules[8][this.moduleCount - i - 1] = mod; - } else if (i < 9) { - this.modules[8][15 - i - 1 + 1] = mod; - } else { - this.modules[8][15 - i - 1] = mod; - } - } - - // fixed module - this.modules[this.moduleCount - 8][8] = (!test); - }; - - proto.mapData = function(data, maskPattern) { - - var inc = -1; - var row = this.moduleCount - 1; - var bitIndex = 7; - var byteIndex = 0; - - for (var col = this.moduleCount - 1; col > 0; col -= 2) { - - if (col == 6) col--; - - while (true) { - - for (var c = 0; c < 2; c++) { - - if (this.modules[row][col - c] == null) { - - var dark = false; - - if (byteIndex < data.length) { - dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); - } - - var mask = util.getMask(maskPattern, row, col - c); - - if (mask) { - dark = !dark; - } - - this.modules[row][col - c] = dark; - bitIndex--; - - if (bitIndex == -1) { - byteIndex++; - bitIndex = 7; - } - } - } - - row += inc; - - if (row < 0 || this.moduleCount <= row) { - row -= inc; - inc = -inc; - break; - } - } - } - }; - - QRCode.PAD0 = 0xEC; - QRCode.PAD1 = 0x11; - - QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { - - var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel); - - var buffer = new BitBuffer(); - - for (var i = 0; i < dataList.length; i++) { - var data = dataList[i]; - buffer.put(data.mode, 4); - buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) ); - data.write(buffer); - } - - // calc num max data. - var totalDataCount = 0; - for (var i = 0; i < rsBlocks.length; i++) { - totalDataCount += rsBlocks[i].dataCount; - } - - if (buffer.getLengthInBits() > totalDataCount * 8) { - throw new Error("code length overflow. (" - + buffer.getLengthInBits() - + ">" - + totalDataCount * 8 - + ")"); - } - - // end code - if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { - buffer.put(0, 4); - } - - // padding - while (buffer.getLengthInBits() % 8 != 0) { - buffer.putBit(false); - } - - // padding - while (true) { - - if (buffer.getLengthInBits() >= totalDataCount * 8) { - break; - } - buffer.put(QRCode.PAD0, 8); - - if (buffer.getLengthInBits() >= totalDataCount * 8) { - break; - } - buffer.put(QRCode.PAD1, 8); - } - - return QRCode.createBytes(buffer, rsBlocks); - }; - - QRCode.createBytes = function(buffer, rsBlocks) { - - var offset = 0; - - var maxDcCount = 0; - var maxEcCount = 0; - - var dcdata = new Array(rsBlocks.length); - var ecdata = new Array(rsBlocks.length); - - for (var r = 0; r < rsBlocks.length; r++) { - - var dcCount = rsBlocks[r].dataCount; - var ecCount = rsBlocks[r].totalCount - dcCount; - - maxDcCount = Math.max(maxDcCount, dcCount); - maxEcCount = Math.max(maxEcCount, ecCount); - - dcdata[r] = new Array(dcCount); - - for (var i = 0; i < dcdata[r].length; i++) { - dcdata[r][i] = 0xff & buffer.buffer[i + offset]; - } - offset += dcCount; - - var rsPoly = util.getErrorCorrectPolynomial(ecCount); - var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1); - - var modPoly = rawPoly.mod(rsPoly); - ecdata[r] = new Array(rsPoly.getLength() - 1); - for (var i = 0; i < ecdata[r].length; i++) { - var modIndex = i + modPoly.getLength() - ecdata[r].length; - ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0; - } - - } - - var totalCodeCount = 0; - for (var i = 0; i < rsBlocks.length; i++) { - totalCodeCount += rsBlocks[i].totalCount; - } - - var data = new Array(totalCodeCount); - var index = 0; - - for (var i = 0; i < maxDcCount; i++) { - for (var r = 0; r < rsBlocks.length; r++) { - if (i < dcdata[r].length) { - data[index++] = dcdata[r][i]; - } - } - } - - for (var i = 0; i < maxEcCount; i++) { - for (var r = 0; r < rsBlocks.length; r++) { - if (i < ecdata[r].length) { - data[index++] = ecdata[r][i]; - } - } - } - - return data; - }; - - module.exports = QRCode; - + var BitByte = __webpack_require__(5); + var RSBlock = __webpack_require__(7); + var BitBuffer = __webpack_require__(9); + var util = __webpack_require__(10); + var Polynomial = __webpack_require__(11); + + function QRCode(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + // for client side minification + var proto = QRCode.prototype; + + proto.addData = function (data) { + var newData = new BitByte(data); + this.dataList.push(newData); + this.dataCache = null; + }; + + proto.isDark = function (row, col) { + if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { + throw new Error(row + "," + col); + } + return this.modules[row][col]; + }; + + proto.getModuleCount = function () { + return this.moduleCount; + }; + + proto.make = function () { + // Calculate automatically typeNumber if provided is < 1 + if (this.typeNumber < 1) { + var typeNumber = 1; + for (typeNumber = 1; typeNumber < 40; typeNumber++) { + var rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); + + var buffer = new BitBuffer(); + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + for (var i = 0; i < this.dataList.length; i++) { + var data = this.dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + if (buffer.getLengthInBits() <= totalDataCount * 8) + break; + } + this.typeNumber = typeNumber; + } + this.makeImpl(false, this.getBestMaskPattern()); + }; + + proto.makeImpl = function (test, maskPattern) { + + this.moduleCount = this.typeNumber * 4 + 17; + this.modules = new Array(this.moduleCount); + + for (var row = 0; row < this.moduleCount; row++) { + + this.modules[row] = new Array(this.moduleCount); + + for (var col = 0; col < this.moduleCount; col++) { + this.modules[row][col] = null;//(col + row) % 3; + } + } + + this.setupPositionProbePattern(0, 0); + this.setupPositionProbePattern(this.moduleCount - 7, 0); + this.setupPositionProbePattern(0, this.moduleCount - 7); + this.setupPositionAdjustPattern(); + this.setupTimingPattern(); + this.setupTypeInfo(test, maskPattern); + + if (this.typeNumber >= 7) { + this.setupTypeNumber(test); + } + + if (this.dataCache == null) { + this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); + } + + this.mapData(this.dataCache, maskPattern); + }; + + proto.setupPositionProbePattern = function (row, col) { + + for (var r = -1; r <= 7; r++) { + + if (row + r <= -1 || this.moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c++) { + + if (col + c <= -1 || this.moduleCount <= col + c) continue; + + if ((0 <= r && r <= 6 && (c == 0 || c == 6)) + || (0 <= c && c <= 6 && (r == 0 || r == 6)) + || (2 <= r && r <= 4 && 2 <= c && c <= 4)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + }; + + proto.getBestMaskPattern = function () { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i++) { + + this.makeImpl(true, i); + + var lostPoint = util.getLostPoint(this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }; + + proto.createMovieClip = function (target_mc, instance_name, depth) { + + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); + var cs = 1; + + this.make(); + + for (var row = 0; row < this.modules.length; row++) { + + var y = row * cs; + + for (var col = 0; col < this.modules[row].length; col++) { + + var x = col * cs; + var dark = this.modules[row][col]; + + if (dark) { + qr_mc.beginFill(0, 100); + qr_mc.moveTo(x, y); + qr_mc.lineTo(x + cs, y); + qr_mc.lineTo(x + cs, y + cs); + qr_mc.lineTo(x, y + cs); + qr_mc.endFill(); + } + } + } + + return qr_mc; + }; + + proto.setupTimingPattern = function () { + + for (var r = 8; r < this.moduleCount - 8; r++) { + if (this.modules[r][6] != null) { + continue; + } + this.modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < this.moduleCount - 8; c++) { + if (this.modules[6][c] != null) { + continue; + } + this.modules[6][c] = (c % 2 == 0); + } + }; + + proto.setupPositionAdjustPattern = function () { + + var pos = util.getPatternPosition(this.typeNumber); + + for (var i = 0; i < pos.length; i++) { + + for (var j = 0; j < pos.length; j++) { + + var row = pos[i]; + var col = pos[j]; + + if (this.modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r++) { + + for (var c = -2; c <= 2; c++) { + + if (r == -2 || r == 2 || c == -2 || c == 2 + || (r == 0 && c == 0)) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + } + } + }; + + proto.setupTypeNumber = function (test) { + + var bits = util.getBCHTypeNumber(this.typeNumber); + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i++) { + var mod = (!test && ((bits >> i) & 1) == 1); + this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }; + + proto.setupTypeInfo = function (test, maskPattern) { + + var data = (this.errorCorrectLevel << 3) | maskPattern; + var bits = util.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 6) { + this.modules[i][8] = mod; + } else if (i < 8) { + this.modules[i + 1][8] = mod; + } else { + this.modules[this.moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i++) { + + var mod = (!test && ((bits >> i) & 1) == 1); + + if (i < 8) { + this.modules[8][this.moduleCount - i - 1] = mod; + } else if (i < 9) { + this.modules[8][15 - i - 1 + 1] = mod; + } else { + this.modules[8][15 - i - 1] = mod; + } + } + + // fixed module + this.modules[this.moduleCount - 8][8] = (!test); + }; + + proto.mapData = function (data, maskPattern) { + + var inc = -1; + var row = this.moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + + for (var col = this.moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col--; + + while (true) { + + for (var c = 0; c < 2; c++) { + + if (this.modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = util.getMask(maskPattern, row, col - c); + + if (mask) { + dark = !dark; + } + + this.modules[row][col - c] = dark; + bitIndex--; + + if (bitIndex == -1) { + byteIndex++; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || this.moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + }; + + QRCode.PAD0 = 0xEC; + QRCode.PAD1 = 0x11; + + QRCode.createData = function (typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = new BitBuffer(); + + for (var i = 0; i < dataList.length; i++) { + var data = dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber)); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error("code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + + ")"); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD1, 8); + } + + return QRCode.createBytes(buffer, rsBlocks); + }; + + QRCode.createBytes = function (buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r++) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i++) { + dcdata[r][i] = 0xff & buffer.buffer[i + offset]; + } + offset += dcCount; + + var rsPoly = util.getErrorCorrectPolynomial(ecCount); + var rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i++) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; + } + + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < dcdata[r].length) { + data[index++] = dcdata[r][i]; + } + } + } + + for (var i = 0; i < maxEcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < ecdata[r].length) { + data[index++] = ecdata[r][i]; + } + } + } + + return data; + }; + + module.exports = QRCode; -/***/ }, + + /***/ +}, /* 5 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var mode = __webpack_require__(6); - - function QR8bitByte(data) { - this.mode = mode.MODE_8BIT_BYTE; - this.data = data; - } - - QR8bitByte.prototype = { - - getLength : function(buffer) { - return this.data.length; - }, - - write : function(buffer) { - for (var i = 0; i < this.data.length; i++) { - // not JIS ... - buffer.put(this.data.charCodeAt(i), 8); - } - } - }; - - module.exports = QR8bitByte; - + var mode = __webpack_require__(6); + + function QR8bitByte(data) { + this.mode = mode.MODE_8BIT_BYTE; + this.data = data; + } + + QR8bitByte.prototype = { + + getLength: function (buffer) { + return this.data.length; + }, + + write: function (buffer) { + for (var i = 0; i < this.data.length; i++) { + // not JIS ... + buffer.put(this.data.charCodeAt(i), 8); + } + } + }; + + module.exports = QR8bitByte; -/***/ }, + + /***/ +}, /* 6 */ -/***/ function(module, exports) { +/***/ function (module, exports) { - module.exports = { - MODE_NUMBER : 1 << 0, - MODE_ALPHA_NUM : 1 << 1, - MODE_8BIT_BYTE : 1 << 2, - MODE_KANJI : 1 << 3 - }; + module.exports = { + MODE_NUMBER: 1 << 0, + MODE_ALPHA_NUM: 1 << 1, + MODE_8BIT_BYTE: 1 << 2, + MODE_KANJI: 1 << 3 + }; -/***/ }, + /***/ +}, /* 7 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - // ErrorCorrectLevel - var ECL = __webpack_require__(8); - - function QRRSBlock(totalCount, dataCount) { - this.totalCount = totalCount; - this.dataCount = dataCount; - } - - QRRSBlock.RS_BLOCK_TABLE = [ - - // L - // M - // Q - // H - - // 1 - [1, 26, 19], - [1, 26, 16], - [1, 26, 13], - [1, 26, 9], - - // 2 - [1, 44, 34], - [1, 44, 28], - [1, 44, 22], - [1, 44, 16], - - // 3 - [1, 70, 55], - [1, 70, 44], - [2, 35, 17], - [2, 35, 13], - - // 4 - [1, 100, 80], - [2, 50, 32], - [2, 50, 24], - [4, 25, 9], - - // 5 - [1, 134, 108], - [2, 67, 43], - [2, 33, 15, 2, 34, 16], - [2, 33, 11, 2, 34, 12], - - // 6 - [2, 86, 68], - [4, 43, 27], - [4, 43, 19], - [4, 43, 15], - - // 7 - [2, 98, 78], - [4, 49, 31], - [2, 32, 14, 4, 33, 15], - [4, 39, 13, 1, 40, 14], - - // 8 - [2, 121, 97], - [2, 60, 38, 2, 61, 39], - [4, 40, 18, 2, 41, 19], - [4, 40, 14, 2, 41, 15], - - // 9 - [2, 146, 116], - [3, 58, 36, 2, 59, 37], - [4, 36, 16, 4, 37, 17], - [4, 36, 12, 4, 37, 13], - - // 10 - [2, 86, 68, 2, 87, 69], - [4, 69, 43, 1, 70, 44], - [6, 43, 19, 2, 44, 20], - [6, 43, 15, 2, 44, 16], - - // 11 - [4, 101, 81], - [1, 80, 50, 4, 81, 51], - [4, 50, 22, 4, 51, 23], - [3, 36, 12, 8, 37, 13], - - // 12 - [2, 116, 92, 2, 117, 93], - [6, 58, 36, 2, 59, 37], - [4, 46, 20, 6, 47, 21], - [7, 42, 14, 4, 43, 15], - - // 13 - [4, 133, 107], - [8, 59, 37, 1, 60, 38], - [8, 44, 20, 4, 45, 21], - [12, 33, 11, 4, 34, 12], - - // 14 - [3, 145, 115, 1, 146, 116], - [4, 64, 40, 5, 65, 41], - [11, 36, 16, 5, 37, 17], - [11, 36, 12, 5, 37, 13], - - // 15 - [5, 109, 87, 1, 110, 88], - [5, 65, 41, 5, 66, 42], - [5, 54, 24, 7, 55, 25], - [11, 36, 12], - - // 16 - [5, 122, 98, 1, 123, 99], - [7, 73, 45, 3, 74, 46], - [15, 43, 19, 2, 44, 20], - [3, 45, 15, 13, 46, 16], - - // 17 - [1, 135, 107, 5, 136, 108], - [10, 74, 46, 1, 75, 47], - [1, 50, 22, 15, 51, 23], - [2, 42, 14, 17, 43, 15], - - // 18 - [5, 150, 120, 1, 151, 121], - [9, 69, 43, 4, 70, 44], - [17, 50, 22, 1, 51, 23], - [2, 42, 14, 19, 43, 15], - - // 19 - [3, 141, 113, 4, 142, 114], - [3, 70, 44, 11, 71, 45], - [17, 47, 21, 4, 48, 22], - [9, 39, 13, 16, 40, 14], - - // 20 - [3, 135, 107, 5, 136, 108], - [3, 67, 41, 13, 68, 42], - [15, 54, 24, 5, 55, 25], - [15, 43, 15, 10, 44, 16], - - // 21 - [4, 144, 116, 4, 145, 117], - [17, 68, 42], - [17, 50, 22, 6, 51, 23], - [19, 46, 16, 6, 47, 17], - - // 22 - [2, 139, 111, 7, 140, 112], - [17, 74, 46], - [7, 54, 24, 16, 55, 25], - [34, 37, 13], - - // 23 - [4, 151, 121, 5, 152, 122], - [4, 75, 47, 14, 76, 48], - [11, 54, 24, 14, 55, 25], - [16, 45, 15, 14, 46, 16], - - // 24 - [6, 147, 117, 4, 148, 118], - [6, 73, 45, 14, 74, 46], - [11, 54, 24, 16, 55, 25], - [30, 46, 16, 2, 47, 17], - - // 25 - [8, 132, 106, 4, 133, 107], - [8, 75, 47, 13, 76, 48], - [7, 54, 24, 22, 55, 25], - [22, 45, 15, 13, 46, 16], - - // 26 - [10, 142, 114, 2, 143, 115], - [19, 74, 46, 4, 75, 47], - [28, 50, 22, 6, 51, 23], - [33, 46, 16, 4, 47, 17], - - // 27 - [8, 152, 122, 4, 153, 123], - [22, 73, 45, 3, 74, 46], - [8, 53, 23, 26, 54, 24], - [12, 45, 15, 28, 46, 16], - - // 28 - [3, 147, 117, 10, 148, 118], - [3, 73, 45, 23, 74, 46], - [4, 54, 24, 31, 55, 25], - [11, 45, 15, 31, 46, 16], - - // 29 - [7, 146, 116, 7, 147, 117], - [21, 73, 45, 7, 74, 46], - [1, 53, 23, 37, 54, 24], - [19, 45, 15, 26, 46, 16], - - // 30 - [5, 145, 115, 10, 146, 116], - [19, 75, 47, 10, 76, 48], - [15, 54, 24, 25, 55, 25], - [23, 45, 15, 25, 46, 16], - - // 31 - [13, 145, 115, 3, 146, 116], - [2, 74, 46, 29, 75, 47], - [42, 54, 24, 1, 55, 25], - [23, 45, 15, 28, 46, 16], - - // 32 - [17, 145, 115], - [10, 74, 46, 23, 75, 47], - [10, 54, 24, 35, 55, 25], - [19, 45, 15, 35, 46, 16], - - // 33 - [17, 145, 115, 1, 146, 116], - [14, 74, 46, 21, 75, 47], - [29, 54, 24, 19, 55, 25], - [11, 45, 15, 46, 46, 16], - - // 34 - [13, 145, 115, 6, 146, 116], - [14, 74, 46, 23, 75, 47], - [44, 54, 24, 7, 55, 25], - [59, 46, 16, 1, 47, 17], - - // 35 - [12, 151, 121, 7, 152, 122], - [12, 75, 47, 26, 76, 48], - [39, 54, 24, 14, 55, 25], - [22, 45, 15, 41, 46, 16], - - // 36 - [6, 151, 121, 14, 152, 122], - [6, 75, 47, 34, 76, 48], - [46, 54, 24, 10, 55, 25], - [2, 45, 15, 64, 46, 16], - - // 37 - [17, 152, 122, 4, 153, 123], - [29, 74, 46, 14, 75, 47], - [49, 54, 24, 10, 55, 25], - [24, 45, 15, 46, 46, 16], - - // 38 - [4, 152, 122, 18, 153, 123], - [13, 74, 46, 32, 75, 47], - [48, 54, 24, 14, 55, 25], - [42, 45, 15, 32, 46, 16], - - // 39 - [20, 147, 117, 4, 148, 118], - [40, 75, 47, 7, 76, 48], - [43, 54, 24, 22, 55, 25], - [10, 45, 15, 67, 46, 16], - - // 40 - [19, 148, 118, 6, 149, 119], - [18, 75, 47, 31, 76, 48], - [34, 54, 24, 34, 55, 25], - [20, 45, 15, 61, 46, 16] - ]; - - QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { - - var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); - - if (rsBlock == undefined) { - throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); - } - - var length = rsBlock.length / 3; - - var list = new Array(); - - for (var i = 0; i < length; i++) { - - var count = rsBlock[i * 3 + 0]; - var totalCount = rsBlock[i * 3 + 1]; - var dataCount = rsBlock[i * 3 + 2]; - - for (var j = 0; j < count; j++) { - list.push(new QRRSBlock(totalCount, dataCount) ); - } - } - - return list; - } - - QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { - - switch(errorCorrectLevel) { - case ECL.L : - return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; - case ECL.M : - return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; - case ECL.Q : - return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; - case ECL.H : - return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; - default : - return undefined; - } - } - - module.exports = QRRSBlock; + // ErrorCorrectLevel + var ECL = __webpack_require__(8); + + function QRRSBlock(totalCount, dataCount) { + this.totalCount = totalCount; + this.dataCount = dataCount; + } + + QRRSBlock.RS_BLOCK_TABLE = [ + + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ]; + + QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) { + + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); + + if (rsBlock == undefined) { + throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i++) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j++) { + list.push(new QRRSBlock(totalCount, dataCount)); + } + } + + return list; + } + + QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) { + + switch (errorCorrectLevel) { + case ECL.L: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case ECL.M: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case ECL.Q: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case ECL.H: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default: + return undefined; + } + } + + module.exports = QRRSBlock; -/***/ }, + /***/ +}, /* 8 */ -/***/ function(module, exports) { +/***/ function (module, exports) { - module.exports = { - L : 1, - M : 0, - Q : 3, - H : 2 - }; - + module.exports = { + L: 1, + M: 0, + Q: 3, + H: 2 + }; -/***/ }, + + /***/ +}, /* 9 */ -/***/ function(module, exports) { +/***/ function (module, exports) { - function QRBitBuffer() { - this.buffer = new Array(); - this.length = 0; - } - - QRBitBuffer.prototype = { - - get : function(index) { - var bufIndex = Math.floor(index / 8); - return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; - }, - - put : function(num, length) { - for (var i = 0; i < length; i++) { - this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); - } - }, - - getLengthInBits : function() { - return this.length; - }, - - putBit : function(bit) { - - var bufIndex = Math.floor(this.length / 8); - if (this.buffer.length <= bufIndex) { - this.buffer.push(0); - } - - if (bit) { - this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) ); - } - - this.length++; - } - }; - - module.exports = QRBitBuffer; + function QRBitBuffer() { + this.buffer = new Array(); + this.length = 0; + } + + QRBitBuffer.prototype = { + + get: function (index) { + var bufIndex = Math.floor(index / 8); + return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1; + }, + + put: function (num, length) { + for (var i = 0; i < length; i++) { + this.putBit(((num >>> (length - i - 1)) & 1) == 1); + } + }, + + getLengthInBits: function () { + return this.length; + }, + + putBit: function (bit) { + + var bufIndex = Math.floor(this.length / 8); + if (this.buffer.length <= bufIndex) { + this.buffer.push(0); + } + + if (bit) { + this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); + } + + this.length++; + } + }; + + module.exports = QRBitBuffer; -/***/ }, + /***/ +}, /* 10 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var Mode = __webpack_require__(6); - var Polynomial = __webpack_require__(11); - var math = __webpack_require__(12); - - var QRMaskPattern = { - PATTERN000 : 0, - PATTERN001 : 1, - PATTERN010 : 2, - PATTERN011 : 3, - PATTERN100 : 4, - PATTERN101 : 5, - PATTERN110 : 6, - PATTERN111 : 7 - }; - - var QRUtil = { - - PATTERN_POSITION_TABLE : [ - [], - [6, 18], - [6, 22], - [6, 26], - [6, 30], - [6, 34], - [6, 22, 38], - [6, 24, 42], - [6, 26, 46], - [6, 28, 50], - [6, 30, 54], - [6, 32, 58], - [6, 34, 62], - [6, 26, 46, 66], - [6, 26, 48, 70], - [6, 26, 50, 74], - [6, 30, 54, 78], - [6, 30, 56, 82], - [6, 30, 58, 86], - [6, 34, 62, 90], - [6, 28, 50, 72, 94], - [6, 26, 50, 74, 98], - [6, 30, 54, 78, 102], - [6, 28, 54, 80, 106], - [6, 32, 58, 84, 110], - [6, 30, 58, 86, 114], - [6, 34, 62, 90, 118], - [6, 26, 50, 74, 98, 122], - [6, 30, 54, 78, 102, 126], - [6, 26, 52, 78, 104, 130], - [6, 30, 56, 82, 108, 134], - [6, 34, 60, 86, 112, 138], - [6, 30, 58, 86, 114, 142], - [6, 34, 62, 90, 118, 146], - [6, 30, 54, 78, 102, 126, 150], - [6, 24, 50, 76, 102, 128, 154], - [6, 28, 54, 80, 106, 132, 158], - [6, 32, 58, 84, 110, 136, 162], - [6, 26, 54, 82, 110, 138, 166], - [6, 30, 58, 86, 114, 142, 170] - ], - - G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), - G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), - G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), - - getBCHTypeInfo : function(data) { - var d = data << 10; - while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { - d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); - } - return ( (data << 10) | d) ^ QRUtil.G15_MASK; - }, - - getBCHTypeNumber : function(data) { - var d = data << 12; - while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { - d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); - } - return (data << 12) | d; - }, - - getBCHDigit : function(data) { - - var digit = 0; - - while (data != 0) { - digit++; - data >>>= 1; - } - - return digit; - }, - - getPatternPosition : function(typeNumber) { - return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; - }, - - getMask : function(maskPattern, i, j) { - - switch (maskPattern) { - - case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0; - case QRMaskPattern.PATTERN001 : return i % 2 == 0; - case QRMaskPattern.PATTERN010 : return j % 3 == 0; - case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0; - case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; - case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0; - case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; - case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; - - default : - throw new Error("bad maskPattern:" + maskPattern); - } - }, - - getErrorCorrectPolynomial : function(errorCorrectLength) { - - var a = new Polynomial([1], 0); - - for (var i = 0; i < errorCorrectLength; i++) { - a = a.multiply(new Polynomial([1, math.gexp(i)], 0) ); - } - - return a; - }, - - getLengthInBits : function(mode, type) { - - if (1 <= type && type < 10) { - - // 1 - 9 - - switch(mode) { - case Mode.MODE_NUMBER : return 10; - case Mode.MODE_ALPHA_NUM : return 9; - case Mode.MODE_8BIT_BYTE : return 8; - case Mode.MODE_KANJI : return 8; - default : - throw new Error("mode:" + mode); - } - - } else if (type < 27) { - - // 10 - 26 - - switch(mode) { - case Mode.MODE_NUMBER : return 12; - case Mode.MODE_ALPHA_NUM : return 11; - case Mode.MODE_8BIT_BYTE : return 16; - case Mode.MODE_KANJI : return 10; - default : - throw new Error("mode:" + mode); - } - - } else if (type < 41) { - - // 27 - 40 - - switch(mode) { - case Mode.MODE_NUMBER : return 14; - case Mode.MODE_ALPHA_NUM : return 13; - case Mode.MODE_8BIT_BYTE : return 16; - case Mode.MODE_KANJI : return 12; - default : - throw new Error("mode:" + mode); - } - - } else { - throw new Error("type:" + type); - } - }, - - getLostPoint : function(qrCode) { - - var moduleCount = qrCode.getModuleCount(); - - var lostPoint = 0; - - // LEVEL1 - - for (var row = 0; row < moduleCount; row++) { - - for (var col = 0; col < moduleCount; col++) { - - var sameCount = 0; - var dark = qrCode.isDark(row, col); - - for (var r = -1; r <= 1; r++) { - - if (row + r < 0 || moduleCount <= row + r) { - continue; - } - - for (var c = -1; c <= 1; c++) { - - if (col + c < 0 || moduleCount <= col + c) { - continue; - } - - if (r == 0 && c == 0) { - continue; - } - - if (dark == qrCode.isDark(row + r, col + c) ) { - sameCount++; - } - } - } - - if (sameCount > 5) { - lostPoint += (3 + sameCount - 5); - } - } - } - - // LEVEL2 - - for (var row = 0; row < moduleCount - 1; row++) { - for (var col = 0; col < moduleCount - 1; col++) { - var count = 0; - if (qrCode.isDark(row, col ) ) count++; - if (qrCode.isDark(row + 1, col ) ) count++; - if (qrCode.isDark(row, col + 1) ) count++; - if (qrCode.isDark(row + 1, col + 1) ) count++; - if (count == 0 || count == 4) { - lostPoint += 3; - } - } - } - - // LEVEL3 - - for (var row = 0; row < moduleCount; row++) { - for (var col = 0; col < moduleCount - 6; col++) { - if (qrCode.isDark(row, col) - && !qrCode.isDark(row, col + 1) - && qrCode.isDark(row, col + 2) - && qrCode.isDark(row, col + 3) - && qrCode.isDark(row, col + 4) - && !qrCode.isDark(row, col + 5) - && qrCode.isDark(row, col + 6) ) { - lostPoint += 40; - } - } - } - - for (var col = 0; col < moduleCount; col++) { - for (var row = 0; row < moduleCount - 6; row++) { - if (qrCode.isDark(row, col) - && !qrCode.isDark(row + 1, col) - && qrCode.isDark(row + 2, col) - && qrCode.isDark(row + 3, col) - && qrCode.isDark(row + 4, col) - && !qrCode.isDark(row + 5, col) - && qrCode.isDark(row + 6, col) ) { - lostPoint += 40; - } - } - } - - // LEVEL4 - - var darkCount = 0; - - for (var col = 0; col < moduleCount; col++) { - for (var row = 0; row < moduleCount; row++) { - if (qrCode.isDark(row, col) ) { - darkCount++; - } - } - } - - var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; - lostPoint += ratio * 10; - - return lostPoint; - } - }; - - module.exports = QRUtil; + var Mode = __webpack_require__(6); + var Polynomial = __webpack_require__(11); + var math = __webpack_require__(12); + + var QRMaskPattern = { + PATTERN000: 0, + PATTERN001: 1, + PATTERN010: 2, + PATTERN011: 3, + PATTERN100: 4, + PATTERN101: 5, + PATTERN110: 6, + PATTERN111: 7 + }; + + var QRUtil = { + + PATTERN_POSITION_TABLE: [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ], + + G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), + G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), + G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), + + getBCHTypeInfo: function (data) { + var d = data << 10; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { + d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); + } + return ((data << 10) | d) ^ QRUtil.G15_MASK; + }, + + getBCHTypeNumber: function (data) { + var d = data << 12; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { + d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); + } + return (data << 12) | d; + }, + + getBCHDigit: function (data) { + + var digit = 0; + + while (data != 0) { + digit++; + data >>>= 1; + } + + return digit; + }, + + getPatternPosition: function (typeNumber) { + return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; + }, + + getMask: function (maskPattern, i, j) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000: return (i + j) % 2 == 0; + case QRMaskPattern.PATTERN001: return i % 2 == 0; + case QRMaskPattern.PATTERN010: return j % 3 == 0; + case QRMaskPattern.PATTERN011: return (i + j) % 3 == 0; + case QRMaskPattern.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; + case QRMaskPattern.PATTERN101: return (i * j) % 2 + (i * j) % 3 == 0; + case QRMaskPattern.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 == 0; + case QRMaskPattern.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 == 0; + + default: + throw new Error("bad maskPattern:" + maskPattern); + } + }, + + getErrorCorrectPolynomial: function (errorCorrectLength) { + + var a = new Polynomial([1], 0); + + for (var i = 0; i < errorCorrectLength; i++) { + a = a.multiply(new Polynomial([1, math.gexp(i)], 0)); + } + + return a; + }, + + getLengthInBits: function (mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch (mode) { + case Mode.MODE_NUMBER: return 10; + case Mode.MODE_ALPHA_NUM: return 9; + case Mode.MODE_8BIT_BYTE: return 8; + case Mode.MODE_KANJI: return 8; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch (mode) { + case Mode.MODE_NUMBER: return 12; + case Mode.MODE_ALPHA_NUM: return 11; + case Mode.MODE_8BIT_BYTE: return 16; + case Mode.MODE_KANJI: return 10; + default: + throw new Error("mode:" + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch (mode) { + case Mode.MODE_NUMBER: return 14; + case Mode.MODE_ALPHA_NUM: return 13; + case Mode.MODE_8BIT_BYTE: return 16; + case Mode.MODE_KANJI: return 12; + default: + throw new Error("mode:" + mode); + } + + } else { + throw new Error("type:" + type); + } + }, + + getLostPoint: function (qrCode) { + + var moduleCount = qrCode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row++) { + + for (var col = 0; col < moduleCount; col++) { + + var sameCount = 0; + var dark = qrCode.isDark(row, col); + + for (var r = -1; r <= 1; r++) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c++) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrCode.isDark(row + r, col + c)) { + sameCount++; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + } + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row++) { + for (var col = 0; col < moduleCount - 1; col++) { + var count = 0; + if (qrCode.isDark(row, col)) count++; + if (qrCode.isDark(row + 1, col)) count++; + if (qrCode.isDark(row, col + 1)) count++; + if (qrCode.isDark(row + 1, col + 1)) count++; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount - 6; col++) { + if (qrCode.isDark(row, col) + && !qrCode.isDark(row, col + 1) + && qrCode.isDark(row, col + 2) + && qrCode.isDark(row, col + 3) + && qrCode.isDark(row, col + 4) + && !qrCode.isDark(row, col + 5) + && qrCode.isDark(row, col + 6)) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount - 6; row++) { + if (qrCode.isDark(row, col) + && !qrCode.isDark(row + 1, col) + && qrCode.isDark(row + 2, col) + && qrCode.isDark(row + 3, col) + && qrCode.isDark(row + 4, col) + && !qrCode.isDark(row + 5, col) + && qrCode.isDark(row + 6, col)) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount; row++) { + if (qrCode.isDark(row, col)) { + darkCount++; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + } + }; + + module.exports = QRUtil; -/***/ }, + /***/ +}, /* 11 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function (module, exports, __webpack_require__) { - var math = __webpack_require__(12); - - function QRPolynomial(num, shift) { - - if (num.length == undefined) { - throw new Error(num.length + "/" + shift); - } - - var offset = 0; - - while (offset < num.length && num[offset] == 0) { - offset++; - } - - this.num = new Array(num.length - offset + shift); - for (var i = 0; i < num.length - offset; i++) { - this.num[i] = num[i + offset]; - } - } - - QRPolynomial.prototype = { - - get : function(index) { - return this.num[index]; - }, - - getLength : function() { - return this.num.length; - }, - - multiply : function(e) { - - var num = new Array(this.getLength() + e.getLength() - 1); - - for (var i = 0; i < this.getLength(); i++) { - for (var j = 0; j < e.getLength(); j++) { - num[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) ); - } - } - - return new QRPolynomial(num, 0); - }, - - mod : function(e) { - - if (this.getLength() - e.getLength() < 0) { - return this; - } - - var ratio = math.glog(this.get(0) ) - math.glog(e.get(0) ); - - var num = new Array(this.getLength() ); - - for (var i = 0; i < this.getLength(); i++) { - num[i] = this.get(i); - } - - for (var i = 0; i < e.getLength(); i++) { - num[i] ^= math.gexp(math.glog(e.get(i) ) + ratio); - } - - // recursive call - return new QRPolynomial(num, 0).mod(e); - } - }; - - module.exports = QRPolynomial; + var math = __webpack_require__(12); + + function QRPolynomial(num, shift) { + + if (num.length == undefined) { + throw new Error(num.length + "/" + shift); + } + + var offset = 0; + + while (offset < num.length && num[offset] == 0) { + offset++; + } + + this.num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i++) { + this.num[i] = num[i + offset]; + } + } + + QRPolynomial.prototype = { + + get: function (index) { + return this.num[index]; + }, + + getLength: function () { + return this.num.length; + }, + + multiply: function (e) { + + var num = new Array(this.getLength() + e.getLength() - 1); + + for (var i = 0; i < this.getLength(); i++) { + for (var j = 0; j < e.getLength(); j++) { + num[i + j] ^= math.gexp(math.glog(this.get(i)) + math.glog(e.get(j))); + } + } + + return new QRPolynomial(num, 0); + }, + + mod: function (e) { + + if (this.getLength() - e.getLength() < 0) { + return this; + } + + var ratio = math.glog(this.get(0)) - math.glog(e.get(0)); + + var num = new Array(this.getLength()); + + for (var i = 0; i < this.getLength(); i++) { + num[i] = this.get(i); + } + + for (var i = 0; i < e.getLength(); i++) { + num[i] ^= math.gexp(math.glog(e.get(i)) + ratio); + } + + // recursive call + return new QRPolynomial(num, 0).mod(e); + } + }; + + module.exports = QRPolynomial; -/***/ }, + /***/ +}, /* 12 */ -/***/ function(module, exports) { +/***/ function (module, exports) { - var QRMath = { - - glog : function(n) { - - if (n < 1) { - throw new Error("glog(" + n + ")"); - } - - return QRMath.LOG_TABLE[n]; - }, - - gexp : function(n) { - - while (n < 0) { - n += 255; - } - - while (n >= 256) { - n -= 255; - } - - return QRMath.EXP_TABLE[n]; - }, - - EXP_TABLE : new Array(256), - - LOG_TABLE : new Array(256) - - }; - - for (var i = 0; i < 8; i++) { - QRMath.EXP_TABLE[i] = 1 << i; - } - for (var i = 8; i < 256; i++) { - QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] - ^ QRMath.EXP_TABLE[i - 5] - ^ QRMath.EXP_TABLE[i - 6] - ^ QRMath.EXP_TABLE[i - 8]; - } - for (var i = 0; i < 255; i++) { - QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i; - } - - module.exports = QRMath; + var QRMath = { + + glog: function (n) { + + if (n < 1) { + throw new Error("glog(" + n + ")"); + } + + return QRMath.LOG_TABLE[n]; + }, + + gexp: function (n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return QRMath.EXP_TABLE[n]; + }, + + EXP_TABLE: new Array(256), + + LOG_TABLE: new Array(256) + + }; + + for (var i = 0; i < 8; i++) { + QRMath.EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i++) { + QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] + ^ QRMath.EXP_TABLE[i - 5] + ^ QRMath.EXP_TABLE[i - 6] + ^ QRMath.EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i++) { + QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; + } + + module.exports = QRMath; -/***/ }, + /***/ +}, /* 13 */ -/***/ function(module, exports) { +/***/ function (module, exports) { - module.exports = "\n
\n \n \n
\n"; + module.exports = "\n
\n \n \n
\n"; -/***/ } -/******/ ]) + /***/ +} +/******/]) }); ; -//# sourceMappingURL=vue-qrcode.js.map \ No newline at end of file +//# sourceMappingURL=vue-qrcode.js.map diff --git a/BTCPayServer/wwwroot/js/vue-qrcode.js.map b/BTCPayServer/wwwroot/js/vue-qrcode.js.map index 255504d57..f37f88c2f 100644 --- a/BTCPayServer/wwwroot/js/vue-qrcode.js.map +++ b/BTCPayServer/wwwroot/js/vue-qrcode.js.map @@ -1 +1,9 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 4d0ca69ab3f3eb801054","webpack:///./src/index.js","webpack:///./src/Qrcode.vue","webpack:///Qrcode.vue","webpack:///./~/qr.js/index.js","webpack:///./~/qr.js/lib/QRCode.js","webpack:///./~/qr.js/lib/8BitByte.js","webpack:///./~/qr.js/lib/mode.js","webpack:///./~/qr.js/lib/RSBlock.js","webpack:///./~/qr.js/lib/ErrorCorrectLevel.js","webpack:///./~/qr.js/lib/BitBuffer.js","webpack:///./~/qr.js/lib/util.js","webpack:///./~/qr.js/lib/Polynomial.js","webpack:///./~/qr.js/lib/math.js","webpack:///./src/Qrcode.vue?ba49"],"names":["module","exports"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;ACtCA;;;;;;AAGAA,QAAOC,OAAP,oB;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB,aAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,EAAC,I;;;;;;;;;;;;ACDD;;;;;;AAEA,gCACA;QACA;AAEA;;;;;;;;;;;;;;;;;;aAIA;iBAEA;AAHA;;aAKA;gBAEA;AAHA;AAIA;YACA;;aAEA;gBAEA;AAHA;;aAKA;gBAGA;AAJA;AAfA;iBAoBA;YACA;;+BAEA;uBACA;0BACA;0BACA;4BAEA;;2CAEA;;gCACA;0BACA;gCACA;gCACA;8EAEA;;uCACA;wBAEA;;yCACA;0CACA;4CACA;mEACA;mEACA;6EACA;AACA;AACA;AAEA;AA3BA;AAvBA;;;AAoDA,yCACA;AACA,cACA,oCACA,iCACA,gCACA,+BACA,0BAEA;;;;;;;;;;;ACnFA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;;;;;;;ACfA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAsB,iBAAiB;AACvC;;AAEA;AACA;AACA,mBAAkB,qBAAqB;AACvC;AACA;;AAEA,mBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,mBAAkB,wBAAwB;;AAE1C;;AAEA,oBAAmB,wBAAwB;AAC3C,kCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,kBAAiB,QAAQ;;AAEzB;;AAEA,mBAAkB,QAAQ;;AAE1B;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,I;AACA,G;AACA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,OAAO;;AAEvB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,2BAA2B;;AAE7C;;AAEA,oBAAmB,gCAAgC;;AAEnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,iBAAgB,0BAA0B;AAC1C;AACA;AACA;AACA;AACA;;AAEA,iBAAgB,0BAA0B;AAC1C;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,gBAAgB;;AAEhC,kBAAiB,gBAAgB;;AAEjC;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB,QAAQ;;AAE3B,qBAAoB,QAAQ;;AAE5B;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,QAAQ;AACxB;AACA;AACA;;AAEA,iBAAgB,QAAQ;AACxB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,iBAAgB,QAAQ;;AAExB;;AAEA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA,iBAAgB,QAAQ;;AAExB;;AAEA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,sCAAqC,SAAS;;AAE9C;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAgB,qBAAqB;AACrC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;AACA;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kBAAiB,sBAAsB;AACvC;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,qBAAqB;AACrC;AACA;;AAEA;AACA;;AAEA,iBAAgB,gBAAgB;AAChC,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;;AAEA,iBAAgB,gBAAgB;AAChC,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;ACpbA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA,kBAAiB,sBAAsB;AACvC;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;AACA;AACA;;AAEA,kBAAiB,WAAW;AAC5B,qD;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1SA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACLA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA,kBAAiB,YAAY;AAC7B;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;ACrCA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,uF;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,uF;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA,qBAAoB,wBAAwB;AAC5C;AACA;;AAEA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;AACN;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB,mBAAmB;;AAEzC,wBAAuB,mBAAmB;;AAE1C;AACA;;AAEA,qBAAoB,QAAQ;;AAE5B;AACA;AACA;;AAEA,yBAAwB,QAAQ;;AAEhC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uBAAsB,uBAAuB;AAC7C,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,mBAAmB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,uB;AACA;AACA;;AAEA;;;;;;;ACtRA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAgB,yBAAyB;AACzC;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC,mBAAkB,mBAAmB;AACrC;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC;AACA;;AAEA,kBAAiB,mBAAmB;AACpC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;AClEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,gBAAe,OAAO;AACtB;AACA;AACA,gBAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB;AACA;;AAEA;;;;;;;AC3CA,wJAAuJ,wCAAwC,qH","file":"./dist/vue-qrcode.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VueQr\"] = factory();\n\telse\n\t\troot[\"VueQr\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4d0ca69ab3f3eb801054","import Qrcode from './Qrcode.vue'\n\n\nmodule.exports = Qrcode\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","var __vue_script__, __vue_template__\n__vue_script__ = require(\"-!babel-loader!./../node_modules/vue-loader/lib/selector.js?type=script&index=0!./Qrcode.vue\")\n__vue_template__ = require(\"-!vue-html-loader!./../node_modules/vue-loader/lib/selector.js?type=template&index=0!./Qrcode.vue\")\nmodule.exports = __vue_script__ || {}\nif (module.exports.__esModule) module.exports = module.exports.default\nif (__vue_template__) { (typeof module.exports === \"function\" ? module.exports.options : module.exports).template = __vue_template__ }\nif (module.hot) {(function () { module.hot.accept()\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), true)\n if (!hotAPI.compatible) return\n var id = \"/home/vixi_n/Documents/Github/vue-qrcode/src/Qrcode.vue\"\n if (!module.hot.data) {\n hotAPI.createRecord(id, module.exports)\n } else {\n hotAPI.update(id, module.exports, __vue_template__)\n }\n})()}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/Qrcode.vue\n// module id = 1\n// module chunks = 0","\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// Qrcode.vue?34bfdd1a","var QRCode = require('./lib/QRCode');\r\nvar ErrorCorrectLevel = require('./lib/ErrorCorrectLevel');\r\n\r\nvar qrcode = function(data, opt) {\r\n\topt = opt || {};\r\n\tvar qr = new QRCode(opt.typeNumber || -1,\r\n\t\t\t\t\t\topt.errorCorrectLevel || ErrorCorrectLevel.H);\r\n\tqr.addData(data);\r\n\tqr.make();\r\n\r\n\treturn qr;\r\n};\r\n\r\nqrcode.ErrorCorrectLevel = ErrorCorrectLevel;\r\n\r\nmodule.exports = qrcode;\r\n\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/index.js\n// module id = 3\n// module chunks = 0","var BitByte = require('./8BitByte');\nvar RSBlock = require('./RSBlock');\nvar BitBuffer = require('./BitBuffer');\nvar util = require('./util');\nvar Polynomial = require('./Polynomial');\n\nfunction QRCode(typeNumber, errorCorrectLevel) {\n\tthis.typeNumber = typeNumber;\n\tthis.errorCorrectLevel = errorCorrectLevel;\n\tthis.modules = null;\n\tthis.moduleCount = 0;\n\tthis.dataCache = null;\n\tthis.dataList = [];\n}\n\n// for client side minification\nvar proto = QRCode.prototype;\n\nproto.addData = function(data) {\n\tvar newData = new BitByte(data);\n\tthis.dataList.push(newData);\n\tthis.dataCache = null;\n};\n\nproto.isDark = function(row, col) {\n\tif (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {\n\t\tthrow new Error(row + \",\" + col);\n\t}\n\treturn this.modules[row][col];\n};\n\nproto.getModuleCount = function() {\n\treturn this.moduleCount;\n};\n\nproto.make = function() {\n\t// Calculate automatically typeNumber if provided is < 1\n\tif (this.typeNumber < 1 ){\n\t\tvar typeNumber = 1;\n\t\tfor (typeNumber = 1; typeNumber < 40; typeNumber++) {\n\t\t\tvar rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);\n\n\t\t\tvar buffer = new BitBuffer();\n\t\t\tvar totalDataCount = 0;\n\t\t\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\t\t\ttotalDataCount += rsBlocks[i].dataCount;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < this.dataList.length; i++) {\n\t\t\t\tvar data = this.dataList[i];\n\t\t\t\tbuffer.put(data.mode, 4);\n\t\t\t\tbuffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );\n\t\t\t\tdata.write(buffer);\n\t\t\t}\n\t\t\tif (buffer.getLengthInBits() <= totalDataCount * 8)\n\t\t\t\tbreak;\n\t\t}\n\t\tthis.typeNumber = typeNumber;\n\t}\n\tthis.makeImpl(false, this.getBestMaskPattern() );\n};\n\nproto.makeImpl = function(test, maskPattern) {\n\t\n\tthis.moduleCount = this.typeNumber * 4 + 17;\n\tthis.modules = new Array(this.moduleCount);\n\t\n\tfor (var row = 0; row < this.moduleCount; row++) {\n\t\t\n\t\tthis.modules[row] = new Array(this.moduleCount);\n\t\t\n\t\tfor (var col = 0; col < this.moduleCount; col++) {\n\t\t\tthis.modules[row][col] = null;//(col + row) % 3;\n\t\t}\n\t}\n\n\tthis.setupPositionProbePattern(0, 0);\n\tthis.setupPositionProbePattern(this.moduleCount - 7, 0);\n\tthis.setupPositionProbePattern(0, this.moduleCount - 7);\n\tthis.setupPositionAdjustPattern();\n\tthis.setupTimingPattern();\n\tthis.setupTypeInfo(test, maskPattern);\n\t\n\tif (this.typeNumber >= 7) {\n\t\tthis.setupTypeNumber(test);\n\t}\n\n\tif (this.dataCache == null) {\n\t\tthis.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);\n\t}\n\n\tthis.mapData(this.dataCache, maskPattern);\n};\n\nproto.setupPositionProbePattern = function(row, col) {\n\t\n\tfor (var r = -1; r <= 7; r++) {\n\t\t\n\t\tif (row + r <= -1 || this.moduleCount <= row + r) continue;\n\t\t\n\t\tfor (var c = -1; c <= 7; c++) {\n\t\t\t\n\t\t\tif (col + c <= -1 || this.moduleCount <= col + c) continue;\n\t\t\t\n\t\t\tif ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n\t\t\t\t\t|| (0 <= c && c <= 6 && (r == 0 || r == 6) )\n\t\t\t\t\t|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n\t\t\t\tthis.modules[row + r][col + c] = true;\n\t\t\t} else {\n\t\t\t\tthis.modules[row + r][col + c] = false;\n\t\t\t}\n\t\t}\t\t\n\t}\t\t\n};\n\nproto.getBestMaskPattern = function() {\n\n\tvar minLostPoint = 0;\n\tvar pattern = 0;\n\n\tfor (var i = 0; i < 8; i++) {\n\t\t\n\t\tthis.makeImpl(true, i);\n\n\t\tvar lostPoint = util.getLostPoint(this);\n\n\t\tif (i == 0 || minLostPoint > lostPoint) {\n\t\t\tminLostPoint = lostPoint;\n\t\t\tpattern = i;\n\t\t}\n\t}\n\n\treturn pattern;\n};\n\nproto.createMovieClip = function(target_mc, instance_name, depth) {\n\n\tvar qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);\n\tvar cs = 1;\n\n\tthis.make();\n\n\tfor (var row = 0; row < this.modules.length; row++) {\n\t\t\n\t\tvar y = row * cs;\n\t\t\n\t\tfor (var col = 0; col < this.modules[row].length; col++) {\n\n\t\t\tvar x = col * cs;\n\t\t\tvar dark = this.modules[row][col];\n\t\t\n\t\t\tif (dark) {\n\t\t\t\tqr_mc.beginFill(0, 100);\n\t\t\t\tqr_mc.moveTo(x, y);\n\t\t\t\tqr_mc.lineTo(x + cs, y);\n\t\t\t\tqr_mc.lineTo(x + cs, y + cs);\n\t\t\t\tqr_mc.lineTo(x, y + cs);\n\t\t\t\tqr_mc.endFill();\n\t\t\t}\n\t\t}\n\t}\n\t\n\treturn qr_mc;\n};\n\nproto.setupTimingPattern = function() {\n\t\n\tfor (var r = 8; r < this.moduleCount - 8; r++) {\n\t\tif (this.modules[r][6] != null) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.modules[r][6] = (r % 2 == 0);\n\t}\n\n\tfor (var c = 8; c < this.moduleCount - 8; c++) {\n\t\tif (this.modules[6][c] != null) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.modules[6][c] = (c % 2 == 0);\n\t}\n};\n\nproto.setupPositionAdjustPattern = function() {\n\n\tvar pos = util.getPatternPosition(this.typeNumber);\n\t\n\tfor (var i = 0; i < pos.length; i++) {\n\t\n\t\tfor (var j = 0; j < pos.length; j++) {\n\t\t\n\t\t\tvar row = pos[i];\n\t\t\tvar col = pos[j];\n\t\t\t\n\t\t\tif (this.modules[row][col] != null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tfor (var r = -2; r <= 2; r++) {\n\t\t\t\n\t\t\t\tfor (var c = -2; c <= 2; c++) {\n\t\t\t\t\n\t\t\t\t\tif (r == -2 || r == 2 || c == -2 || c == 2\n\t\t\t\t\t\t\t|| (r == 0 && c == 0) ) {\n\t\t\t\t\t\tthis.modules[row + r][col + c] = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.modules[row + r][col + c] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nproto.setupTypeNumber = function(test) {\n\n\tvar bits = util.getBCHTypeNumber(this.typeNumber);\n\n\tfor (var i = 0; i < 18; i++) {\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\tthis.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;\n\t}\n\n\tfor (var i = 0; i < 18; i++) {\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\tthis.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;\n\t}\n};\n\nproto.setupTypeInfo = function(test, maskPattern) {\n\n\tvar data = (this.errorCorrectLevel << 3) | maskPattern;\n\tvar bits = util.getBCHTypeInfo(data);\n\n\t// vertical\t\t\n\tfor (var i = 0; i < 15; i++) {\n\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\n\t\tif (i < 6) {\n\t\t\tthis.modules[i][8] = mod;\n\t\t} else if (i < 8) {\n\t\t\tthis.modules[i + 1][8] = mod;\n\t\t} else {\n\t\t\tthis.modules[this.moduleCount - 15 + i][8] = mod;\n\t\t}\n\t}\n\n\t// horizontal\n\tfor (var i = 0; i < 15; i++) {\n\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\t\n\t\tif (i < 8) {\n\t\t\tthis.modules[8][this.moduleCount - i - 1] = mod;\n\t\t} else if (i < 9) {\n\t\t\tthis.modules[8][15 - i - 1 + 1] = mod;\n\t\t} else {\n\t\t\tthis.modules[8][15 - i - 1] = mod;\n\t\t}\n\t}\n\n\t// fixed module\n\tthis.modules[this.moduleCount - 8][8] = (!test);\n};\n\nproto.mapData = function(data, maskPattern) {\n\t\n\tvar inc = -1;\n\tvar row = this.moduleCount - 1;\n\tvar bitIndex = 7;\n\tvar byteIndex = 0;\n\t\n\tfor (var col = this.moduleCount - 1; col > 0; col -= 2) {\n\n\t\tif (col == 6) col--;\n\n\t\twhile (true) {\n\n\t\t\tfor (var c = 0; c < 2; c++) {\n\t\t\t\t\n\t\t\t\tif (this.modules[row][col - c] == null) {\n\t\t\t\t\t\n\t\t\t\t\tvar dark = false;\n\n\t\t\t\t\tif (byteIndex < data.length) {\n\t\t\t\t\t\tdark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar mask = util.getMask(maskPattern, row, col - c);\n\n\t\t\t\t\tif (mask) {\n\t\t\t\t\t\tdark = !dark;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthis.modules[row][col - c] = dark;\n\t\t\t\t\tbitIndex--;\n\n\t\t\t\t\tif (bitIndex == -1) {\n\t\t\t\t\t\tbyteIndex++;\n\t\t\t\t\t\tbitIndex = 7;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\trow += inc;\n\n\t\t\tif (row < 0 || this.moduleCount <= row) {\n\t\t\t\trow -= inc;\n\t\t\t\tinc = -inc;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n};\n\nQRCode.PAD0 = 0xEC;\nQRCode.PAD1 = 0x11;\n\nQRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {\n\t\n\tvar rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);\n\t\n\tvar buffer = new BitBuffer();\n\t\n\tfor (var i = 0; i < dataList.length; i++) {\n\t\tvar data = dataList[i];\n\t\tbuffer.put(data.mode, 4);\n\t\tbuffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );\n\t\tdata.write(buffer);\n\t}\n\n\t// calc num max data.\n\tvar totalDataCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\ttotalDataCount += rsBlocks[i].dataCount;\n\t}\n\n\tif (buffer.getLengthInBits() > totalDataCount * 8) {\n\t\tthrow new Error(\"code length overflow. (\"\n\t\t\t+ buffer.getLengthInBits()\n\t\t\t+ \">\"\n\t\t\t+ totalDataCount * 8\n\t\t\t+ \")\");\n\t}\n\n\t// end code\n\tif (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n\t\tbuffer.put(0, 4);\n\t}\n\n\t// padding\n\twhile (buffer.getLengthInBits() % 8 != 0) {\n\t\tbuffer.putBit(false);\n\t}\n\n\t// padding\n\twhile (true) {\n\t\t\n\t\tif (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\t\tbreak;\n\t\t}\n\t\tbuffer.put(QRCode.PAD0, 8);\n\t\t\n\t\tif (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\t\tbreak;\n\t\t}\n\t\tbuffer.put(QRCode.PAD1, 8);\n\t}\n\n\treturn QRCode.createBytes(buffer, rsBlocks);\n};\n\nQRCode.createBytes = function(buffer, rsBlocks) {\n\n\tvar offset = 0;\n\t\n\tvar maxDcCount = 0;\n\tvar maxEcCount = 0;\n\t\n\tvar dcdata = new Array(rsBlocks.length);\n\tvar ecdata = new Array(rsBlocks.length);\n\t\n\tfor (var r = 0; r < rsBlocks.length; r++) {\n\n\t\tvar dcCount = rsBlocks[r].dataCount;\n\t\tvar ecCount = rsBlocks[r].totalCount - dcCount;\n\n\t\tmaxDcCount = Math.max(maxDcCount, dcCount);\n\t\tmaxEcCount = Math.max(maxEcCount, ecCount);\n\t\t\n\t\tdcdata[r] = new Array(dcCount);\n\t\t\n\t\tfor (var i = 0; i < dcdata[r].length; i++) {\n\t\t\tdcdata[r][i] = 0xff & buffer.buffer[i + offset];\n\t\t}\n\t\toffset += dcCount;\n\t\t\n\t\tvar rsPoly = util.getErrorCorrectPolynomial(ecCount);\n\t\tvar rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);\n\n\t\tvar modPoly = rawPoly.mod(rsPoly);\n\t\tecdata[r] = new Array(rsPoly.getLength() - 1);\n\t\tfor (var i = 0; i < ecdata[r].length; i++) {\n var modIndex = i + modPoly.getLength() - ecdata[r].length;\n\t\t\tecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;\n\t\t}\n\n\t}\n\t\n\tvar totalCodeCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\ttotalCodeCount += rsBlocks[i].totalCount;\n\t}\n\n\tvar data = new Array(totalCodeCount);\n\tvar index = 0;\n\n\tfor (var i = 0; i < maxDcCount; i++) {\n\t\tfor (var r = 0; r < rsBlocks.length; r++) {\n\t\t\tif (i < dcdata[r].length) {\n\t\t\t\tdata[index++] = dcdata[r][i];\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (var i = 0; i < maxEcCount; i++) {\n\t\tfor (var r = 0; r < rsBlocks.length; r++) {\n\t\t\tif (i < ecdata[r].length) {\n\t\t\t\tdata[index++] = ecdata[r][i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data;\n};\n\nmodule.exports = QRCode;\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/QRCode.js\n// module id = 4\n// module chunks = 0","var mode = require('./mode');\n\nfunction QR8bitByte(data) {\n\tthis.mode = mode.MODE_8BIT_BYTE;\n\tthis.data = data;\n}\n\nQR8bitByte.prototype = {\n\n\tgetLength : function(buffer) {\n\t\treturn this.data.length;\n\t},\n\t\n\twrite : function(buffer) {\n\t\tfor (var i = 0; i < this.data.length; i++) {\n\t\t\t// not JIS ...\n\t\t\tbuffer.put(this.data.charCodeAt(i), 8);\n\t\t}\n\t}\n};\n\nmodule.exports = QR8bitByte;\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/8BitByte.js\n// module id = 5\n// module chunks = 0","module.exports = {\n\tMODE_NUMBER :\t\t1 << 0,\n\tMODE_ALPHA_NUM : \t1 << 1,\n\tMODE_8BIT_BYTE : \t1 << 2,\n\tMODE_KANJI :\t\t1 << 3\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/mode.js\n// module id = 6\n// module chunks = 0","// ErrorCorrectLevel\nvar ECL = require('./ErrorCorrectLevel');\n\nfunction QRRSBlock(totalCount, dataCount) {\n\tthis.totalCount = totalCount;\n\tthis.dataCount = dataCount;\n}\n\nQRRSBlock.RS_BLOCK_TABLE = [\n\n\t// L\n\t// M\n\t// Q\n\t// H\n\n\t// 1\n\t[1, 26, 19],\n\t[1, 26, 16],\n\t[1, 26, 13],\n\t[1, 26, 9],\n\t\n\t// 2\n\t[1, 44, 34],\n\t[1, 44, 28],\n\t[1, 44, 22],\n\t[1, 44, 16],\n\n\t// 3\n\t[1, 70, 55],\n\t[1, 70, 44],\n\t[2, 35, 17],\n\t[2, 35, 13],\n\n\t// 4\t\t\n\t[1, 100, 80],\n\t[2, 50, 32],\n\t[2, 50, 24],\n\t[4, 25, 9],\n\t\n\t// 5\n\t[1, 134, 108],\n\t[2, 67, 43],\n\t[2, 33, 15, 2, 34, 16],\n\t[2, 33, 11, 2, 34, 12],\n\t\n\t// 6\n\t[2, 86, 68],\n\t[4, 43, 27],\n\t[4, 43, 19],\n\t[4, 43, 15],\n\t\n\t// 7\t\t\n\t[2, 98, 78],\n\t[4, 49, 31],\n\t[2, 32, 14, 4, 33, 15],\n\t[4, 39, 13, 1, 40, 14],\n\t\n\t// 8\n\t[2, 121, 97],\n\t[2, 60, 38, 2, 61, 39],\n\t[4, 40, 18, 2, 41, 19],\n\t[4, 40, 14, 2, 41, 15],\n\t\n\t// 9\n\t[2, 146, 116],\n\t[3, 58, 36, 2, 59, 37],\n\t[4, 36, 16, 4, 37, 17],\n\t[4, 36, 12, 4, 37, 13],\n\t\n\t// 10\t\t\n\t[2, 86, 68, 2, 87, 69],\n\t[4, 69, 43, 1, 70, 44],\n\t[6, 43, 19, 2, 44, 20],\n\t[6, 43, 15, 2, 44, 16],\n\n\t// 11\n\t[4, 101, 81],\n\t[1, 80, 50, 4, 81, 51],\n\t[4, 50, 22, 4, 51, 23],\n\t[3, 36, 12, 8, 37, 13],\n\n\t// 12\n\t[2, 116, 92, 2, 117, 93],\n\t[6, 58, 36, 2, 59, 37],\n\t[4, 46, 20, 6, 47, 21],\n\t[7, 42, 14, 4, 43, 15],\n\n\t// 13\n\t[4, 133, 107],\n\t[8, 59, 37, 1, 60, 38],\n\t[8, 44, 20, 4, 45, 21],\n\t[12, 33, 11, 4, 34, 12],\n\n\t// 14\n\t[3, 145, 115, 1, 146, 116],\n\t[4, 64, 40, 5, 65, 41],\n\t[11, 36, 16, 5, 37, 17],\n\t[11, 36, 12, 5, 37, 13],\n\n\t// 15\n\t[5, 109, 87, 1, 110, 88],\n\t[5, 65, 41, 5, 66, 42],\n\t[5, 54, 24, 7, 55, 25],\n\t[11, 36, 12],\n\n\t// 16\n\t[5, 122, 98, 1, 123, 99],\n\t[7, 73, 45, 3, 74, 46],\n\t[15, 43, 19, 2, 44, 20],\n\t[3, 45, 15, 13, 46, 16],\n\n\t// 17\n\t[1, 135, 107, 5, 136, 108],\n\t[10, 74, 46, 1, 75, 47],\n\t[1, 50, 22, 15, 51, 23],\n\t[2, 42, 14, 17, 43, 15],\n\n\t// 18\n\t[5, 150, 120, 1, 151, 121],\n\t[9, 69, 43, 4, 70, 44],\n\t[17, 50, 22, 1, 51, 23],\n\t[2, 42, 14, 19, 43, 15],\n\n\t// 19\n\t[3, 141, 113, 4, 142, 114],\n\t[3, 70, 44, 11, 71, 45],\n\t[17, 47, 21, 4, 48, 22],\n\t[9, 39, 13, 16, 40, 14],\n\n\t// 20\n\t[3, 135, 107, 5, 136, 108],\n\t[3, 67, 41, 13, 68, 42],\n\t[15, 54, 24, 5, 55, 25],\n\t[15, 43, 15, 10, 44, 16],\n\n\t// 21\n\t[4, 144, 116, 4, 145, 117],\n\t[17, 68, 42],\n\t[17, 50, 22, 6, 51, 23],\n\t[19, 46, 16, 6, 47, 17],\n\n\t// 22\n\t[2, 139, 111, 7, 140, 112],\n\t[17, 74, 46],\n\t[7, 54, 24, 16, 55, 25],\n\t[34, 37, 13],\n\n\t// 23\n\t[4, 151, 121, 5, 152, 122],\n\t[4, 75, 47, 14, 76, 48],\n\t[11, 54, 24, 14, 55, 25],\n\t[16, 45, 15, 14, 46, 16],\n\n\t// 24\n\t[6, 147, 117, 4, 148, 118],\n\t[6, 73, 45, 14, 74, 46],\n\t[11, 54, 24, 16, 55, 25],\n\t[30, 46, 16, 2, 47, 17],\n\n\t// 25\n\t[8, 132, 106, 4, 133, 107],\n\t[8, 75, 47, 13, 76, 48],\n\t[7, 54, 24, 22, 55, 25],\n\t[22, 45, 15, 13, 46, 16],\n\n\t// 26\n\t[10, 142, 114, 2, 143, 115],\n\t[19, 74, 46, 4, 75, 47],\n\t[28, 50, 22, 6, 51, 23],\n\t[33, 46, 16, 4, 47, 17],\n\n\t// 27\n\t[8, 152, 122, 4, 153, 123],\n\t[22, 73, 45, 3, 74, 46],\n\t[8, 53, 23, 26, 54, 24],\n\t[12, 45, 15, 28, 46, 16],\n\n\t// 28\n\t[3, 147, 117, 10, 148, 118],\n\t[3, 73, 45, 23, 74, 46],\n\t[4, 54, 24, 31, 55, 25],\n\t[11, 45, 15, 31, 46, 16],\n\n\t// 29\n\t[7, 146, 116, 7, 147, 117],\n\t[21, 73, 45, 7, 74, 46],\n\t[1, 53, 23, 37, 54, 24],\n\t[19, 45, 15, 26, 46, 16],\n\n\t// 30\n\t[5, 145, 115, 10, 146, 116],\n\t[19, 75, 47, 10, 76, 48],\n\t[15, 54, 24, 25, 55, 25],\n\t[23, 45, 15, 25, 46, 16],\n\n\t// 31\n\t[13, 145, 115, 3, 146, 116],\n\t[2, 74, 46, 29, 75, 47],\n\t[42, 54, 24, 1, 55, 25],\n\t[23, 45, 15, 28, 46, 16],\n\n\t// 32\n\t[17, 145, 115],\n\t[10, 74, 46, 23, 75, 47],\n\t[10, 54, 24, 35, 55, 25],\n\t[19, 45, 15, 35, 46, 16],\n\n\t// 33\n\t[17, 145, 115, 1, 146, 116],\n\t[14, 74, 46, 21, 75, 47],\n\t[29, 54, 24, 19, 55, 25],\n\t[11, 45, 15, 46, 46, 16],\n\n\t// 34\n\t[13, 145, 115, 6, 146, 116],\n\t[14, 74, 46, 23, 75, 47],\n\t[44, 54, 24, 7, 55, 25],\n\t[59, 46, 16, 1, 47, 17],\n\n\t// 35\n\t[12, 151, 121, 7, 152, 122],\n\t[12, 75, 47, 26, 76, 48],\n\t[39, 54, 24, 14, 55, 25],\n\t[22, 45, 15, 41, 46, 16],\n\n\t// 36\n\t[6, 151, 121, 14, 152, 122],\n\t[6, 75, 47, 34, 76, 48],\n\t[46, 54, 24, 10, 55, 25],\n\t[2, 45, 15, 64, 46, 16],\n\n\t// 37\n\t[17, 152, 122, 4, 153, 123],\n\t[29, 74, 46, 14, 75, 47],\n\t[49, 54, 24, 10, 55, 25],\n\t[24, 45, 15, 46, 46, 16],\n\n\t// 38\n\t[4, 152, 122, 18, 153, 123],\n\t[13, 74, 46, 32, 75, 47],\n\t[48, 54, 24, 14, 55, 25],\n\t[42, 45, 15, 32, 46, 16],\n\n\t// 39\n\t[20, 147, 117, 4, 148, 118],\n\t[40, 75, 47, 7, 76, 48],\n\t[43, 54, 24, 22, 55, 25],\n\t[10, 45, 15, 67, 46, 16],\n\n\t// 40\n\t[19, 148, 118, 6, 149, 119],\n\t[18, 75, 47, 31, 76, 48],\n\t[34, 54, 24, 34, 55, 25],\n\t[20, 45, 15, 61, 46, 16]\n];\n\nQRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {\n\t\n\tvar rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);\n\t\n\tif (rsBlock == undefined) {\n\t\tthrow new Error(\"bad rs block @ typeNumber:\" + typeNumber + \"/errorCorrectLevel:\" + errorCorrectLevel);\n\t}\n\n\tvar length = rsBlock.length / 3;\n\t\n\tvar list = new Array();\n\t\n\tfor (var i = 0; i < length; i++) {\n\n\t\tvar count = rsBlock[i * 3 + 0];\n\t\tvar totalCount = rsBlock[i * 3 + 1];\n\t\tvar dataCount = rsBlock[i * 3 + 2];\n\n\t\tfor (var j = 0; j < count; j++) {\n\t\t\tlist.push(new QRRSBlock(totalCount, dataCount) );\t\n\t\t}\n\t}\n\t\n\treturn list;\n}\n\nQRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {\n\n\tswitch(errorCorrectLevel) {\n\tcase ECL.L :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n\tcase ECL.M :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n\tcase ECL.Q :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n\tcase ECL.H :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n\tdefault :\n\t\treturn undefined;\n\t}\n}\n\nmodule.exports = QRRSBlock;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/RSBlock.js\n// module id = 7\n// module chunks = 0","module.exports = {\n\tL : 1,\n\tM : 0,\n\tQ : 3,\n\tH : 2\n};\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/ErrorCorrectLevel.js\n// module id = 8\n// module chunks = 0","function QRBitBuffer() {\n\tthis.buffer = new Array();\n\tthis.length = 0;\n}\n\nQRBitBuffer.prototype = {\n\n\tget : function(index) {\n\t\tvar bufIndex = Math.floor(index / 8);\n\t\treturn ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n\t},\n\t\n\tput : function(num, length) {\n\t\tfor (var i = 0; i < length; i++) {\n\t\t\tthis.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n\t\t}\n\t},\n\t\n\tgetLengthInBits : function() {\n\t\treturn this.length;\n\t},\n\t\n\tputBit : function(bit) {\n\t\n\t\tvar bufIndex = Math.floor(this.length / 8);\n\t\tif (this.buffer.length <= bufIndex) {\n\t\t\tthis.buffer.push(0);\n\t\t}\n\t\n\t\tif (bit) {\n\t\t\tthis.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );\n\t\t}\n\t\n\t\tthis.length++;\n\t}\n};\n\nmodule.exports = QRBitBuffer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/BitBuffer.js\n// module id = 9\n// module chunks = 0","var Mode = require('./mode');\nvar Polynomial = require('./Polynomial');\nvar math = require('./math');\n\nvar QRMaskPattern = {\n\tPATTERN000 : 0,\n\tPATTERN001 : 1,\n\tPATTERN010 : 2,\n\tPATTERN011 : 3,\n\tPATTERN100 : 4,\n\tPATTERN101 : 5,\n\tPATTERN110 : 6,\n\tPATTERN111 : 7\n};\n\nvar QRUtil = {\n\n PATTERN_POSITION_TABLE : [\n\t [],\n\t [6, 18],\n\t [6, 22],\n\t [6, 26],\n\t [6, 30],\n\t [6, 34],\n\t [6, 22, 38],\n\t [6, 24, 42],\n\t [6, 26, 46],\n\t [6, 28, 50],\n\t [6, 30, 54],\t\t\n\t [6, 32, 58],\n\t [6, 34, 62],\n\t [6, 26, 46, 66],\n\t [6, 26, 48, 70],\n\t [6, 26, 50, 74],\n\t [6, 30, 54, 78],\n\t [6, 30, 56, 82],\n\t [6, 30, 58, 86],\n\t [6, 34, 62, 90],\n\t [6, 28, 50, 72, 94],\n\t [6, 26, 50, 74, 98],\n\t [6, 30, 54, 78, 102],\n\t [6, 28, 54, 80, 106],\n\t [6, 32, 58, 84, 110],\n\t [6, 30, 58, 86, 114],\n\t [6, 34, 62, 90, 118],\n\t [6, 26, 50, 74, 98, 122],\n\t [6, 30, 54, 78, 102, 126],\n\t [6, 26, 52, 78, 104, 130],\n\t [6, 30, 56, 82, 108, 134],\n\t [6, 34, 60, 86, 112, 138],\n\t [6, 30, 58, 86, 114, 142],\n\t [6, 34, 62, 90, 118, 146],\n\t [6, 30, 54, 78, 102, 126, 150],\n\t [6, 24, 50, 76, 102, 128, 154],\n\t [6, 28, 54, 80, 106, 132, 158],\n\t [6, 32, 58, 84, 110, 136, 162],\n\t [6, 26, 54, 82, 110, 138, 166],\n\t [6, 30, 58, 86, 114, 142, 170]\n ],\n\n G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),\n G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),\n G15_MASK : (1 << 14) | (1 << 12) | (1 << 10)\t| (1 << 4) | (1 << 1),\n\n getBCHTypeInfo : function(data) {\n\t var d = data << 10;\n\t while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {\n\t\t d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); \t\n\t }\n\t return ( (data << 10) | d) ^ QRUtil.G15_MASK;\n },\n\n getBCHTypeNumber : function(data) {\n\t var d = data << 12;\n\t while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {\n\t\t d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); \t\n\t }\n\t return (data << 12) | d;\n },\n\n getBCHDigit : function(data) {\n\n\t var digit = 0;\n\n\t while (data != 0) {\n\t\t digit++;\n\t\t data >>>= 1;\n\t }\n\n\t return digit;\n },\n\n getPatternPosition : function(typeNumber) {\n\t return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];\n },\n\n getMask : function(maskPattern, i, j) {\n\t \n\t switch (maskPattern) {\n\t\t \n\t case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;\n\t case QRMaskPattern.PATTERN001 : return i % 2 == 0;\n\t case QRMaskPattern.PATTERN010 : return j % 3 == 0;\n\t case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;\n\t case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;\n\t case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;\n\t case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;\n\t case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;\n\n\t default :\n\t\t throw new Error(\"bad maskPattern:\" + maskPattern);\n\t }\n },\n\n getErrorCorrectPolynomial : function(errorCorrectLength) {\n\n\t var a = new Polynomial([1], 0);\n\n\t for (var i = 0; i < errorCorrectLength; i++) {\n\t\t a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );\n\t }\n\n\t return a;\n },\n\n getLengthInBits : function(mode, type) {\n\n\t if (1 <= type && type < 10) {\n\n\t\t // 1 - 9\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 10;\n\t\t case Mode.MODE_ALPHA_NUM \t: return 9;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 8;\n\t\t case Mode.MODE_KANJI \t: return 8;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else if (type < 27) {\n\n\t\t // 10 - 26\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 12;\n\t\t case Mode.MODE_ALPHA_NUM \t: return 11;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 16;\n\t\t case Mode.MODE_KANJI \t: return 10;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else if (type < 41) {\n\n\t\t // 27 - 40\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 14;\n\t\t case Mode.MODE_ALPHA_NUM\t: return 13;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 16;\n\t\t case Mode.MODE_KANJI \t: return 12;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else {\n\t\t throw new Error(\"type:\" + type);\n\t }\n },\n\n getLostPoint : function(qrCode) {\n\t \n\t var moduleCount = qrCode.getModuleCount();\n\t \n\t var lostPoint = 0;\n\t \n\t // LEVEL1\n\t \n\t for (var row = 0; row < moduleCount; row++) {\n\n\t\t for (var col = 0; col < moduleCount; col++) {\n\n\t\t\t var sameCount = 0;\n\t\t\t var dark = qrCode.isDark(row, col);\n\n\t\t\t\tfor (var r = -1; r <= 1; r++) {\n\n\t\t\t\t if (row + r < 0 || moduleCount <= row + r) {\n\t\t\t\t\t continue;\n\t\t\t\t }\n\n\t\t\t\t for (var c = -1; c <= 1; c++) {\n\n\t\t\t\t\t if (col + c < 0 || moduleCount <= col + c) {\n\t\t\t\t\t\t continue;\n\t\t\t\t\t }\n\n\t\t\t\t\t if (r == 0 && c == 0) {\n\t\t\t\t\t\t continue;\n\t\t\t\t\t }\n\n\t\t\t\t\t if (dark == qrCode.isDark(row + r, col + c) ) {\n\t\t\t\t\t\t sameCount++;\n\t\t\t\t\t }\n\t\t\t\t }\n\t\t\t }\n\n\t\t\t if (sameCount > 5) {\n\t\t\t\t lostPoint += (3 + sameCount - 5);\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL2\n\n\t for (var row = 0; row < moduleCount - 1; row++) {\n\t\t for (var col = 0; col < moduleCount - 1; col++) {\n\t\t\t var count = 0;\n\t\t\t if (qrCode.isDark(row, col ) ) count++;\n\t\t\t if (qrCode.isDark(row + 1, col ) ) count++;\n\t\t\t if (qrCode.isDark(row, col + 1) ) count++;\n\t\t\t if (qrCode.isDark(row + 1, col + 1) ) count++;\n\t\t\t if (count == 0 || count == 4) {\n\t\t\t\t lostPoint += 3;\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL3\n\n\t for (var row = 0; row < moduleCount; row++) {\n\t\t for (var col = 0; col < moduleCount - 6; col++) {\n\t\t\t if (qrCode.isDark(row, col)\n\t\t\t\t\t && !qrCode.isDark(row, col + 1)\n\t\t\t\t\t && qrCode.isDark(row, col + 2)\n\t\t\t\t\t && qrCode.isDark(row, col + 3)\n\t\t\t\t\t && qrCode.isDark(row, col + 4)\n\t\t\t\t\t && !qrCode.isDark(row, col + 5)\n\t\t\t\t\t && qrCode.isDark(row, col + 6) ) {\n\t\t\t\t lostPoint += 40;\n\t\t\t }\n\t\t }\n\t }\n\n\t for (var col = 0; col < moduleCount; col++) {\n\t\t for (var row = 0; row < moduleCount - 6; row++) {\n\t\t\t if (qrCode.isDark(row, col)\n\t\t\t\t\t && !qrCode.isDark(row + 1, col)\n\t\t\t\t\t && qrCode.isDark(row + 2, col)\n\t\t\t\t\t && qrCode.isDark(row + 3, col)\n\t\t\t\t\t && qrCode.isDark(row + 4, col)\n\t\t\t\t\t && !qrCode.isDark(row + 5, col)\n\t\t\t\t\t && qrCode.isDark(row + 6, col) ) {\n\t\t\t\t lostPoint += 40;\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL4\n\t \n\t var darkCount = 0;\n\n\t for (var col = 0; col < moduleCount; col++) {\n\t\t for (var row = 0; row < moduleCount; row++) {\n\t\t\t if (qrCode.isDark(row, col) ) {\n\t\t\t\t darkCount++;\n\t\t\t }\n\t\t }\n\t }\n\t \n\t var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;\n\t lostPoint += ratio * 10;\n\n\t return lostPoint;\t\t\n }\n};\n\nmodule.exports = QRUtil;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/util.js\n// module id = 10\n// module chunks = 0","var math = require('./math');\n\nfunction QRPolynomial(num, shift) {\n\n\tif (num.length == undefined) {\n\t\tthrow new Error(num.length + \"/\" + shift);\n\t}\n\n\tvar offset = 0;\n\n\twhile (offset < num.length && num[offset] == 0) {\n\t\toffset++;\n\t}\n\n\tthis.num = new Array(num.length - offset + shift);\n\tfor (var i = 0; i < num.length - offset; i++) {\n\t\tthis.num[i] = num[i + offset];\n\t}\n}\n\nQRPolynomial.prototype = {\n\n\tget : function(index) {\n\t\treturn this.num[index];\n\t},\n\t\n\tgetLength : function() {\n\t\treturn this.num.length;\n\t},\n\t\n\tmultiply : function(e) {\n\t\n\t\tvar num = new Array(this.getLength() + e.getLength() - 1);\n\t\n\t\tfor (var i = 0; i < this.getLength(); i++) {\n\t\t\tfor (var j = 0; j < e.getLength(); j++) {\n\t\t\t\tnum[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );\n\t\t\t}\n\t\t}\n\t\n\t\treturn new QRPolynomial(num, 0);\n\t},\n\t\n\tmod : function(e) {\n\t\n\t\tif (this.getLength() - e.getLength() < 0) {\n\t\t\treturn this;\n\t\t}\n\t\n\t\tvar ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );\n\t\n\t\tvar num = new Array(this.getLength() );\n\t\t\n\t\tfor (var i = 0; i < this.getLength(); i++) {\n\t\t\tnum[i] = this.get(i);\n\t\t}\n\t\t\n\t\tfor (var i = 0; i < e.getLength(); i++) {\n\t\t\tnum[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);\n\t\t}\n\t\n\t\t// recursive call\n\t\treturn new QRPolynomial(num, 0).mod(e);\n\t}\n};\n\nmodule.exports = QRPolynomial;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/Polynomial.js\n// module id = 11\n// module chunks = 0","var QRMath = {\n\n\tglog : function(n) {\n\t\n\t\tif (n < 1) {\n\t\t\tthrow new Error(\"glog(\" + n + \")\");\n\t\t}\n\t\t\n\t\treturn QRMath.LOG_TABLE[n];\n\t},\n\t\n\tgexp : function(n) {\n\t\n\t\twhile (n < 0) {\n\t\t\tn += 255;\n\t\t}\n\t\n\t\twhile (n >= 256) {\n\t\t\tn -= 255;\n\t\t}\n\t\n\t\treturn QRMath.EXP_TABLE[n];\n\t},\n\t\n\tEXP_TABLE : new Array(256),\n\t\n\tLOG_TABLE : new Array(256)\n\n};\n\t\nfor (var i = 0; i < 8; i++) {\n\tQRMath.EXP_TABLE[i] = 1 << i;\n}\nfor (var i = 8; i < 256; i++) {\n\tQRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]\n\t\t^ QRMath.EXP_TABLE[i - 5]\n\t\t^ QRMath.EXP_TABLE[i - 6]\n\t\t^ QRMath.EXP_TABLE[i - 8];\n}\nfor (var i = 0; i < 255; i++) {\n\tQRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;\n}\n\nmodule.exports = QRMath;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/math.js\n// module id = 12\n// module chunks = 0","module.exports = \"\\n
\\n \\n \\n
\\n\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Qrcode.vue\n// module id = 13\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{ + "version": 3, + "sources": [ "webpack:///webpack/universalModuleDefinition", "webpack:///webpack/bootstrap 4d0ca69ab3f3eb801054", "webpack:///./src/index.js", "webpack:///./src/Qrcode.vue", "webpack:///Qrcode.vue", "webpack:///./~/qr.js/index.js", "webpack:///./~/qr.js/lib/QRCode.js", "webpack:///./~/qr.js/lib/8BitByte.js", "webpack:///./~/qr.js/lib/mode.js", "webpack:///./~/qr.js/lib/RSBlock.js", "webpack:///./~/qr.js/lib/ErrorCorrectLevel.js", "webpack:///./~/qr.js/lib/BitBuffer.js", "webpack:///./~/qr.js/lib/util.js", "webpack:///./~/qr.js/lib/Polynomial.js", "webpack:///./~/qr.js/lib/math.js", "webpack:///./src/Qrcode.vue?ba49" ], + "names": [ "module", "exports" ], + "mappings": "AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;ACtCA;;;;;;AAGAA,QAAOC,OAAP,oB;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB,aAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,EAAC,I;;;;;;;;;;;;ACDD;;;;;;AAEA,gCACA;QACA;AAEA;;;;;;;;;;;;;;;;;;aAIA;iBAEA;AAHA;;aAKA;gBAEA;AAHA;AAIA;YACA;;aAEA;gBAEA;AAHA;;aAKA;gBAGA;AAJA;AAfA;iBAoBA;YACA;;+BAEA;uBACA;0BACA;0BACA;4BAEA;;2CAEA;;gCACA;0BACA;gCACA;gCACA;8EAEA;;uCACA;wBAEA;;yCACA;0CACA;4CACA;mEACA;mEACA;6EACA;AACA;AACA;AAEA;AA3BA;AAvBA;;;AAoDA,yCACA;AACA,cACA,oCACA,iCACA,gCACA,+BACA,0BAEA;;;;;;;;;;;ACnFA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;;;;;;;ACfA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,uBAAsB,iBAAiB;AACvC;;AAEA;AACA;AACA,mBAAkB,qBAAqB;AACvC;AACA;;AAEA,mBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,mBAAkB,wBAAwB;;AAE1C;;AAEA,oBAAmB,wBAAwB;AAC3C,kCAAiC;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,kBAAiB,QAAQ;;AAEzB;;AAEA,mBAAkB,QAAQ;;AAE1B;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,I;AACA,G;AACA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,OAAO;;AAEvB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,2BAA2B;;AAE7C;;AAEA,oBAAmB,gCAAgC;;AAEnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,iBAAgB,0BAA0B;AAC1C;AACA;AACA;AACA;AACA;;AAEA,iBAAgB,0BAA0B;AAC1C;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,gBAAgB;;AAEhC,kBAAiB,gBAAgB;;AAEjC;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB,QAAQ;;AAE3B,qBAAoB,QAAQ;;AAE5B;AACA;AACA;AACA,OAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,QAAQ;AACxB;AACA;AACA;;AAEA,iBAAgB,QAAQ;AACxB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,iBAAgB,QAAQ;;AAExB;;AAEA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA,iBAAgB,QAAQ;;AAExB;;AAEA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,sCAAqC,SAAS;;AAE9C;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAgB,qBAAqB;AACrC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;AACA;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kBAAiB,sBAAsB;AACvC;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,qBAAqB;AACrC;AACA;;AAEA;AACA;;AAEA,iBAAgB,gBAAgB;AAChC,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;;AAEA,iBAAgB,gBAAgB;AAChC,kBAAiB,qBAAqB;AACtC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;ACpbA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA,kBAAiB,sBAAsB;AACvC;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;AACA;AACA;;AAEA,kBAAiB,WAAW;AAC5B,qD;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1SA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACLA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA,kBAAiB,YAAY;AAC7B;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;ACrCA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,uF;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,uF;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA,qBAAoB,wBAAwB;AAC5C;AACA;;AAEA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAM;AACN;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB,mBAAmB;;AAEzC,wBAAuB,mBAAmB;;AAE1C;AACA;;AAEA,qBAAoB,QAAQ;;AAE5B;AACA;AACA;;AAEA,yBAAwB,QAAQ;;AAEhC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uBAAsB,uBAAuB;AAC7C,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uBAAsB,mBAAmB;AACzC,wBAAuB,mBAAmB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,uB;AACA;AACA;;AAEA;;;;;;;ACtRA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAgB,yBAAyB;AACzC;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC,mBAAkB,mBAAmB;AACrC;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,kBAAiB,sBAAsB;AACvC;AACA;;AAEA,kBAAiB,mBAAmB;AACpC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;AClEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,gBAAe,OAAO;AACtB;AACA;AACA,gBAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAe,SAAS;AACxB;AACA;;AAEA;;;;;;;AC3CA,wJAAuJ,wCAAwC,qH", + "file": "./dist/vue-qrcode.js", + "sourcesContent": [ "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VueQr\"] = factory();\n\telse\n\t\troot[\"VueQr\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition", " \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4d0ca69ab3f3eb801054", "import Qrcode from './Qrcode.vue'\n\n\nmodule.exports = Qrcode\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js", "var __vue_script__, __vue_template__\n__vue_script__ = require(\"-!babel-loader!./../node_modules/vue-loader/lib/selector.js?type=script&index=0!./Qrcode.vue\")\n__vue_template__ = require(\"-!vue-html-loader!./../node_modules/vue-loader/lib/selector.js?type=template&index=0!./Qrcode.vue\")\nmodule.exports = __vue_script__ || {}\nif (module.exports.__esModule) module.exports = module.exports.default\nif (__vue_template__) { (typeof module.exports === \"function\" ? module.exports.options : module.exports).template = __vue_template__ }\nif (module.hot) {(function () { module.hot.accept()\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), true)\n if (!hotAPI.compatible) return\n var id = \"/home/vixi_n/Documents/Github/vue-qrcode/src/Qrcode.vue\"\n if (!module.hot.data) {\n hotAPI.createRecord(id, module.exports)\n } else {\n hotAPI.update(id, module.exports, __vue_template__)\n }\n})()}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/Qrcode.vue\n// module id = 1\n// module chunks = 0", "\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// Qrcode.vue?34bfdd1a", "var QRCode = require('./lib/QRCode');\r\nvar ErrorCorrectLevel = require('./lib/ErrorCorrectLevel');\r\n\r\nvar qrcode = function(data, opt) {\r\n\topt = opt || {};\r\n\tvar qr = new QRCode(opt.typeNumber || -1,\r\n\t\t\t\t\t\topt.errorCorrectLevel || ErrorCorrectLevel.H);\r\n\tqr.addData(data);\r\n\tqr.make();\r\n\r\n\treturn qr;\r\n};\r\n\r\nqrcode.ErrorCorrectLevel = ErrorCorrectLevel;\r\n\r\nmodule.exports = qrcode;\r\n\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/index.js\n// module id = 3\n// module chunks = 0", "var BitByte = require('./8BitByte');\nvar RSBlock = require('./RSBlock');\nvar BitBuffer = require('./BitBuffer');\nvar util = require('./util');\nvar Polynomial = require('./Polynomial');\n\nfunction QRCode(typeNumber, errorCorrectLevel) {\n\tthis.typeNumber = typeNumber;\n\tthis.errorCorrectLevel = errorCorrectLevel;\n\tthis.modules = null;\n\tthis.moduleCount = 0;\n\tthis.dataCache = null;\n\tthis.dataList = [];\n}\n\n// for client side minification\nvar proto = QRCode.prototype;\n\nproto.addData = function(data) {\n\tvar newData = new BitByte(data);\n\tthis.dataList.push(newData);\n\tthis.dataCache = null;\n};\n\nproto.isDark = function(row, col) {\n\tif (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {\n\t\tthrow new Error(row + \",\" + col);\n\t}\n\treturn this.modules[row][col];\n};\n\nproto.getModuleCount = function() {\n\treturn this.moduleCount;\n};\n\nproto.make = function() {\n\t// Calculate automatically typeNumber if provided is < 1\n\tif (this.typeNumber < 1 ){\n\t\tvar typeNumber = 1;\n\t\tfor (typeNumber = 1; typeNumber < 40; typeNumber++) {\n\t\t\tvar rsBlocks = RSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);\n\n\t\t\tvar buffer = new BitBuffer();\n\t\t\tvar totalDataCount = 0;\n\t\t\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\t\t\ttotalDataCount += rsBlocks[i].dataCount;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < this.dataList.length; i++) {\n\t\t\t\tvar data = this.dataList[i];\n\t\t\t\tbuffer.put(data.mode, 4);\n\t\t\t\tbuffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );\n\t\t\t\tdata.write(buffer);\n\t\t\t}\n\t\t\tif (buffer.getLengthInBits() <= totalDataCount * 8)\n\t\t\t\tbreak;\n\t\t}\n\t\tthis.typeNumber = typeNumber;\n\t}\n\tthis.makeImpl(false, this.getBestMaskPattern() );\n};\n\nproto.makeImpl = function(test, maskPattern) {\n\t\n\tthis.moduleCount = this.typeNumber * 4 + 17;\n\tthis.modules = new Array(this.moduleCount);\n\t\n\tfor (var row = 0; row < this.moduleCount; row++) {\n\t\t\n\t\tthis.modules[row] = new Array(this.moduleCount);\n\t\t\n\t\tfor (var col = 0; col < this.moduleCount; col++) {\n\t\t\tthis.modules[row][col] = null;//(col + row) % 3;\n\t\t}\n\t}\n\n\tthis.setupPositionProbePattern(0, 0);\n\tthis.setupPositionProbePattern(this.moduleCount - 7, 0);\n\tthis.setupPositionProbePattern(0, this.moduleCount - 7);\n\tthis.setupPositionAdjustPattern();\n\tthis.setupTimingPattern();\n\tthis.setupTypeInfo(test, maskPattern);\n\t\n\tif (this.typeNumber >= 7) {\n\t\tthis.setupTypeNumber(test);\n\t}\n\n\tif (this.dataCache == null) {\n\t\tthis.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);\n\t}\n\n\tthis.mapData(this.dataCache, maskPattern);\n};\n\nproto.setupPositionProbePattern = function(row, col) {\n\t\n\tfor (var r = -1; r <= 7; r++) {\n\t\t\n\t\tif (row + r <= -1 || this.moduleCount <= row + r) continue;\n\t\t\n\t\tfor (var c = -1; c <= 7; c++) {\n\t\t\t\n\t\t\tif (col + c <= -1 || this.moduleCount <= col + c) continue;\n\t\t\t\n\t\t\tif ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n\t\t\t\t\t|| (0 <= c && c <= 6 && (r == 0 || r == 6) )\n\t\t\t\t\t|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n\t\t\t\tthis.modules[row + r][col + c] = true;\n\t\t\t} else {\n\t\t\t\tthis.modules[row + r][col + c] = false;\n\t\t\t}\n\t\t}\t\t\n\t}\t\t\n};\n\nproto.getBestMaskPattern = function() {\n\n\tvar minLostPoint = 0;\n\tvar pattern = 0;\n\n\tfor (var i = 0; i < 8; i++) {\n\t\t\n\t\tthis.makeImpl(true, i);\n\n\t\tvar lostPoint = util.getLostPoint(this);\n\n\t\tif (i == 0 || minLostPoint > lostPoint) {\n\t\t\tminLostPoint = lostPoint;\n\t\t\tpattern = i;\n\t\t}\n\t}\n\n\treturn pattern;\n};\n\nproto.createMovieClip = function(target_mc, instance_name, depth) {\n\n\tvar qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);\n\tvar cs = 1;\n\n\tthis.make();\n\n\tfor (var row = 0; row < this.modules.length; row++) {\n\t\t\n\t\tvar y = row * cs;\n\t\t\n\t\tfor (var col = 0; col < this.modules[row].length; col++) {\n\n\t\t\tvar x = col * cs;\n\t\t\tvar dark = this.modules[row][col];\n\t\t\n\t\t\tif (dark) {\n\t\t\t\tqr_mc.beginFill(0, 100);\n\t\t\t\tqr_mc.moveTo(x, y);\n\t\t\t\tqr_mc.lineTo(x + cs, y);\n\t\t\t\tqr_mc.lineTo(x + cs, y + cs);\n\t\t\t\tqr_mc.lineTo(x, y + cs);\n\t\t\t\tqr_mc.endFill();\n\t\t\t}\n\t\t}\n\t}\n\t\n\treturn qr_mc;\n};\n\nproto.setupTimingPattern = function() {\n\t\n\tfor (var r = 8; r < this.moduleCount - 8; r++) {\n\t\tif (this.modules[r][6] != null) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.modules[r][6] = (r % 2 == 0);\n\t}\n\n\tfor (var c = 8; c < this.moduleCount - 8; c++) {\n\t\tif (this.modules[6][c] != null) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.modules[6][c] = (c % 2 == 0);\n\t}\n};\n\nproto.setupPositionAdjustPattern = function() {\n\n\tvar pos = util.getPatternPosition(this.typeNumber);\n\t\n\tfor (var i = 0; i < pos.length; i++) {\n\t\n\t\tfor (var j = 0; j < pos.length; j++) {\n\t\t\n\t\t\tvar row = pos[i];\n\t\t\tvar col = pos[j];\n\t\t\t\n\t\t\tif (this.modules[row][col] != null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n\t\t\tfor (var r = -2; r <= 2; r++) {\n\t\t\t\n\t\t\t\tfor (var c = -2; c <= 2; c++) {\n\t\t\t\t\n\t\t\t\t\tif (r == -2 || r == 2 || c == -2 || c == 2\n\t\t\t\t\t\t\t|| (r == 0 && c == 0) ) {\n\t\t\t\t\t\tthis.modules[row + r][col + c] = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.modules[row + r][col + c] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\nproto.setupTypeNumber = function(test) {\n\n\tvar bits = util.getBCHTypeNumber(this.typeNumber);\n\n\tfor (var i = 0; i < 18; i++) {\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\tthis.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;\n\t}\n\n\tfor (var i = 0; i < 18; i++) {\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\tthis.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;\n\t}\n};\n\nproto.setupTypeInfo = function(test, maskPattern) {\n\n\tvar data = (this.errorCorrectLevel << 3) | maskPattern;\n\tvar bits = util.getBCHTypeInfo(data);\n\n\t// vertical\t\t\n\tfor (var i = 0; i < 15; i++) {\n\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\n\t\tif (i < 6) {\n\t\t\tthis.modules[i][8] = mod;\n\t\t} else if (i < 8) {\n\t\t\tthis.modules[i + 1][8] = mod;\n\t\t} else {\n\t\t\tthis.modules[this.moduleCount - 15 + i][8] = mod;\n\t\t}\n\t}\n\n\t// horizontal\n\tfor (var i = 0; i < 15; i++) {\n\n\t\tvar mod = (!test && ( (bits >> i) & 1) == 1);\n\t\t\n\t\tif (i < 8) {\n\t\t\tthis.modules[8][this.moduleCount - i - 1] = mod;\n\t\t} else if (i < 9) {\n\t\t\tthis.modules[8][15 - i - 1 + 1] = mod;\n\t\t} else {\n\t\t\tthis.modules[8][15 - i - 1] = mod;\n\t\t}\n\t}\n\n\t// fixed module\n\tthis.modules[this.moduleCount - 8][8] = (!test);\n};\n\nproto.mapData = function(data, maskPattern) {\n\t\n\tvar inc = -1;\n\tvar row = this.moduleCount - 1;\n\tvar bitIndex = 7;\n\tvar byteIndex = 0;\n\t\n\tfor (var col = this.moduleCount - 1; col > 0; col -= 2) {\n\n\t\tif (col == 6) col--;\n\n\t\twhile (true) {\n\n\t\t\tfor (var c = 0; c < 2; c++) {\n\t\t\t\t\n\t\t\t\tif (this.modules[row][col - c] == null) {\n\t\t\t\t\t\n\t\t\t\t\tvar dark = false;\n\n\t\t\t\t\tif (byteIndex < data.length) {\n\t\t\t\t\t\tdark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tvar mask = util.getMask(maskPattern, row, col - c);\n\n\t\t\t\t\tif (mask) {\n\t\t\t\t\t\tdark = !dark;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthis.modules[row][col - c] = dark;\n\t\t\t\t\tbitIndex--;\n\n\t\t\t\t\tif (bitIndex == -1) {\n\t\t\t\t\t\tbyteIndex++;\n\t\t\t\t\t\tbitIndex = 7;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\trow += inc;\n\n\t\t\tif (row < 0 || this.moduleCount <= row) {\n\t\t\t\trow -= inc;\n\t\t\t\tinc = -inc;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n};\n\nQRCode.PAD0 = 0xEC;\nQRCode.PAD1 = 0x11;\n\nQRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {\n\t\n\tvar rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel);\n\t\n\tvar buffer = new BitBuffer();\n\t\n\tfor (var i = 0; i < dataList.length; i++) {\n\t\tvar data = dataList[i];\n\t\tbuffer.put(data.mode, 4);\n\t\tbuffer.put(data.getLength(), util.getLengthInBits(data.mode, typeNumber) );\n\t\tdata.write(buffer);\n\t}\n\n\t// calc num max data.\n\tvar totalDataCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\ttotalDataCount += rsBlocks[i].dataCount;\n\t}\n\n\tif (buffer.getLengthInBits() > totalDataCount * 8) {\n\t\tthrow new Error(\"code length overflow. (\"\n\t\t\t+ buffer.getLengthInBits()\n\t\t\t+ \">\"\n\t\t\t+ totalDataCount * 8\n\t\t\t+ \")\");\n\t}\n\n\t// end code\n\tif (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n\t\tbuffer.put(0, 4);\n\t}\n\n\t// padding\n\twhile (buffer.getLengthInBits() % 8 != 0) {\n\t\tbuffer.putBit(false);\n\t}\n\n\t// padding\n\twhile (true) {\n\t\t\n\t\tif (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\t\tbreak;\n\t\t}\n\t\tbuffer.put(QRCode.PAD0, 8);\n\t\t\n\t\tif (buffer.getLengthInBits() >= totalDataCount * 8) {\n\t\t\tbreak;\n\t\t}\n\t\tbuffer.put(QRCode.PAD1, 8);\n\t}\n\n\treturn QRCode.createBytes(buffer, rsBlocks);\n};\n\nQRCode.createBytes = function(buffer, rsBlocks) {\n\n\tvar offset = 0;\n\t\n\tvar maxDcCount = 0;\n\tvar maxEcCount = 0;\n\t\n\tvar dcdata = new Array(rsBlocks.length);\n\tvar ecdata = new Array(rsBlocks.length);\n\t\n\tfor (var r = 0; r < rsBlocks.length; r++) {\n\n\t\tvar dcCount = rsBlocks[r].dataCount;\n\t\tvar ecCount = rsBlocks[r].totalCount - dcCount;\n\n\t\tmaxDcCount = Math.max(maxDcCount, dcCount);\n\t\tmaxEcCount = Math.max(maxEcCount, ecCount);\n\t\t\n\t\tdcdata[r] = new Array(dcCount);\n\t\t\n\t\tfor (var i = 0; i < dcdata[r].length; i++) {\n\t\t\tdcdata[r][i] = 0xff & buffer.buffer[i + offset];\n\t\t}\n\t\toffset += dcCount;\n\t\t\n\t\tvar rsPoly = util.getErrorCorrectPolynomial(ecCount);\n\t\tvar rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);\n\n\t\tvar modPoly = rawPoly.mod(rsPoly);\n\t\tecdata[r] = new Array(rsPoly.getLength() - 1);\n\t\tfor (var i = 0; i < ecdata[r].length; i++) {\n var modIndex = i + modPoly.getLength() - ecdata[r].length;\n\t\t\tecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;\n\t\t}\n\n\t}\n\t\n\tvar totalCodeCount = 0;\n\tfor (var i = 0; i < rsBlocks.length; i++) {\n\t\ttotalCodeCount += rsBlocks[i].totalCount;\n\t}\n\n\tvar data = new Array(totalCodeCount);\n\tvar index = 0;\n\n\tfor (var i = 0; i < maxDcCount; i++) {\n\t\tfor (var r = 0; r < rsBlocks.length; r++) {\n\t\t\tif (i < dcdata[r].length) {\n\t\t\t\tdata[index++] = dcdata[r][i];\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (var i = 0; i < maxEcCount; i++) {\n\t\tfor (var r = 0; r < rsBlocks.length; r++) {\n\t\t\tif (i < ecdata[r].length) {\n\t\t\t\tdata[index++] = ecdata[r][i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data;\n};\n\nmodule.exports = QRCode;\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/QRCode.js\n// module id = 4\n// module chunks = 0", "var mode = require('./mode');\n\nfunction QR8bitByte(data) {\n\tthis.mode = mode.MODE_8BIT_BYTE;\n\tthis.data = data;\n}\n\nQR8bitByte.prototype = {\n\n\tgetLength : function(buffer) {\n\t\treturn this.data.length;\n\t},\n\t\n\twrite : function(buffer) {\n\t\tfor (var i = 0; i < this.data.length; i++) {\n\t\t\t// not JIS ...\n\t\t\tbuffer.put(this.data.charCodeAt(i), 8);\n\t\t}\n\t}\n};\n\nmodule.exports = QR8bitByte;\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/8BitByte.js\n// module id = 5\n// module chunks = 0", "module.exports = {\n\tMODE_NUMBER :\t\t1 << 0,\n\tMODE_ALPHA_NUM : \t1 << 1,\n\tMODE_8BIT_BYTE : \t1 << 2,\n\tMODE_KANJI :\t\t1 << 3\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/mode.js\n// module id = 6\n// module chunks = 0", "// ErrorCorrectLevel\nvar ECL = require('./ErrorCorrectLevel');\n\nfunction QRRSBlock(totalCount, dataCount) {\n\tthis.totalCount = totalCount;\n\tthis.dataCount = dataCount;\n}\n\nQRRSBlock.RS_BLOCK_TABLE = [\n\n\t// L\n\t// M\n\t// Q\n\t// H\n\n\t// 1\n\t[1, 26, 19],\n\t[1, 26, 16],\n\t[1, 26, 13],\n\t[1, 26, 9],\n\t\n\t// 2\n\t[1, 44, 34],\n\t[1, 44, 28],\n\t[1, 44, 22],\n\t[1, 44, 16],\n\n\t// 3\n\t[1, 70, 55],\n\t[1, 70, 44],\n\t[2, 35, 17],\n\t[2, 35, 13],\n\n\t// 4\t\t\n\t[1, 100, 80],\n\t[2, 50, 32],\n\t[2, 50, 24],\n\t[4, 25, 9],\n\t\n\t// 5\n\t[1, 134, 108],\n\t[2, 67, 43],\n\t[2, 33, 15, 2, 34, 16],\n\t[2, 33, 11, 2, 34, 12],\n\t\n\t// 6\n\t[2, 86, 68],\n\t[4, 43, 27],\n\t[4, 43, 19],\n\t[4, 43, 15],\n\t\n\t// 7\t\t\n\t[2, 98, 78],\n\t[4, 49, 31],\n\t[2, 32, 14, 4, 33, 15],\n\t[4, 39, 13, 1, 40, 14],\n\t\n\t// 8\n\t[2, 121, 97],\n\t[2, 60, 38, 2, 61, 39],\n\t[4, 40, 18, 2, 41, 19],\n\t[4, 40, 14, 2, 41, 15],\n\t\n\t// 9\n\t[2, 146, 116],\n\t[3, 58, 36, 2, 59, 37],\n\t[4, 36, 16, 4, 37, 17],\n\t[4, 36, 12, 4, 37, 13],\n\t\n\t// 10\t\t\n\t[2, 86, 68, 2, 87, 69],\n\t[4, 69, 43, 1, 70, 44],\n\t[6, 43, 19, 2, 44, 20],\n\t[6, 43, 15, 2, 44, 16],\n\n\t// 11\n\t[4, 101, 81],\n\t[1, 80, 50, 4, 81, 51],\n\t[4, 50, 22, 4, 51, 23],\n\t[3, 36, 12, 8, 37, 13],\n\n\t// 12\n\t[2, 116, 92, 2, 117, 93],\n\t[6, 58, 36, 2, 59, 37],\n\t[4, 46, 20, 6, 47, 21],\n\t[7, 42, 14, 4, 43, 15],\n\n\t// 13\n\t[4, 133, 107],\n\t[8, 59, 37, 1, 60, 38],\n\t[8, 44, 20, 4, 45, 21],\n\t[12, 33, 11, 4, 34, 12],\n\n\t// 14\n\t[3, 145, 115, 1, 146, 116],\n\t[4, 64, 40, 5, 65, 41],\n\t[11, 36, 16, 5, 37, 17],\n\t[11, 36, 12, 5, 37, 13],\n\n\t// 15\n\t[5, 109, 87, 1, 110, 88],\n\t[5, 65, 41, 5, 66, 42],\n\t[5, 54, 24, 7, 55, 25],\n\t[11, 36, 12],\n\n\t// 16\n\t[5, 122, 98, 1, 123, 99],\n\t[7, 73, 45, 3, 74, 46],\n\t[15, 43, 19, 2, 44, 20],\n\t[3, 45, 15, 13, 46, 16],\n\n\t// 17\n\t[1, 135, 107, 5, 136, 108],\n\t[10, 74, 46, 1, 75, 47],\n\t[1, 50, 22, 15, 51, 23],\n\t[2, 42, 14, 17, 43, 15],\n\n\t// 18\n\t[5, 150, 120, 1, 151, 121],\n\t[9, 69, 43, 4, 70, 44],\n\t[17, 50, 22, 1, 51, 23],\n\t[2, 42, 14, 19, 43, 15],\n\n\t// 19\n\t[3, 141, 113, 4, 142, 114],\n\t[3, 70, 44, 11, 71, 45],\n\t[17, 47, 21, 4, 48, 22],\n\t[9, 39, 13, 16, 40, 14],\n\n\t// 20\n\t[3, 135, 107, 5, 136, 108],\n\t[3, 67, 41, 13, 68, 42],\n\t[15, 54, 24, 5, 55, 25],\n\t[15, 43, 15, 10, 44, 16],\n\n\t// 21\n\t[4, 144, 116, 4, 145, 117],\n\t[17, 68, 42],\n\t[17, 50, 22, 6, 51, 23],\n\t[19, 46, 16, 6, 47, 17],\n\n\t// 22\n\t[2, 139, 111, 7, 140, 112],\n\t[17, 74, 46],\n\t[7, 54, 24, 16, 55, 25],\n\t[34, 37, 13],\n\n\t// 23\n\t[4, 151, 121, 5, 152, 122],\n\t[4, 75, 47, 14, 76, 48],\n\t[11, 54, 24, 14, 55, 25],\n\t[16, 45, 15, 14, 46, 16],\n\n\t// 24\n\t[6, 147, 117, 4, 148, 118],\n\t[6, 73, 45, 14, 74, 46],\n\t[11, 54, 24, 16, 55, 25],\n\t[30, 46, 16, 2, 47, 17],\n\n\t// 25\n\t[8, 132, 106, 4, 133, 107],\n\t[8, 75, 47, 13, 76, 48],\n\t[7, 54, 24, 22, 55, 25],\n\t[22, 45, 15, 13, 46, 16],\n\n\t// 26\n\t[10, 142, 114, 2, 143, 115],\n\t[19, 74, 46, 4, 75, 47],\n\t[28, 50, 22, 6, 51, 23],\n\t[33, 46, 16, 4, 47, 17],\n\n\t// 27\n\t[8, 152, 122, 4, 153, 123],\n\t[22, 73, 45, 3, 74, 46],\n\t[8, 53, 23, 26, 54, 24],\n\t[12, 45, 15, 28, 46, 16],\n\n\t// 28\n\t[3, 147, 117, 10, 148, 118],\n\t[3, 73, 45, 23, 74, 46],\n\t[4, 54, 24, 31, 55, 25],\n\t[11, 45, 15, 31, 46, 16],\n\n\t// 29\n\t[7, 146, 116, 7, 147, 117],\n\t[21, 73, 45, 7, 74, 46],\n\t[1, 53, 23, 37, 54, 24],\n\t[19, 45, 15, 26, 46, 16],\n\n\t// 30\n\t[5, 145, 115, 10, 146, 116],\n\t[19, 75, 47, 10, 76, 48],\n\t[15, 54, 24, 25, 55, 25],\n\t[23, 45, 15, 25, 46, 16],\n\n\t// 31\n\t[13, 145, 115, 3, 146, 116],\n\t[2, 74, 46, 29, 75, 47],\n\t[42, 54, 24, 1, 55, 25],\n\t[23, 45, 15, 28, 46, 16],\n\n\t// 32\n\t[17, 145, 115],\n\t[10, 74, 46, 23, 75, 47],\n\t[10, 54, 24, 35, 55, 25],\n\t[19, 45, 15, 35, 46, 16],\n\n\t// 33\n\t[17, 145, 115, 1, 146, 116],\n\t[14, 74, 46, 21, 75, 47],\n\t[29, 54, 24, 19, 55, 25],\n\t[11, 45, 15, 46, 46, 16],\n\n\t// 34\n\t[13, 145, 115, 6, 146, 116],\n\t[14, 74, 46, 23, 75, 47],\n\t[44, 54, 24, 7, 55, 25],\n\t[59, 46, 16, 1, 47, 17],\n\n\t// 35\n\t[12, 151, 121, 7, 152, 122],\n\t[12, 75, 47, 26, 76, 48],\n\t[39, 54, 24, 14, 55, 25],\n\t[22, 45, 15, 41, 46, 16],\n\n\t// 36\n\t[6, 151, 121, 14, 152, 122],\n\t[6, 75, 47, 34, 76, 48],\n\t[46, 54, 24, 10, 55, 25],\n\t[2, 45, 15, 64, 46, 16],\n\n\t// 37\n\t[17, 152, 122, 4, 153, 123],\n\t[29, 74, 46, 14, 75, 47],\n\t[49, 54, 24, 10, 55, 25],\n\t[24, 45, 15, 46, 46, 16],\n\n\t// 38\n\t[4, 152, 122, 18, 153, 123],\n\t[13, 74, 46, 32, 75, 47],\n\t[48, 54, 24, 14, 55, 25],\n\t[42, 45, 15, 32, 46, 16],\n\n\t// 39\n\t[20, 147, 117, 4, 148, 118],\n\t[40, 75, 47, 7, 76, 48],\n\t[43, 54, 24, 22, 55, 25],\n\t[10, 45, 15, 67, 46, 16],\n\n\t// 40\n\t[19, 148, 118, 6, 149, 119],\n\t[18, 75, 47, 31, 76, 48],\n\t[34, 54, 24, 34, 55, 25],\n\t[20, 45, 15, 61, 46, 16]\n];\n\nQRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {\n\t\n\tvar rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);\n\t\n\tif (rsBlock == undefined) {\n\t\tthrow new Error(\"bad rs block @ typeNumber:\" + typeNumber + \"/errorCorrectLevel:\" + errorCorrectLevel);\n\t}\n\n\tvar length = rsBlock.length / 3;\n\t\n\tvar list = new Array();\n\t\n\tfor (var i = 0; i < length; i++) {\n\n\t\tvar count = rsBlock[i * 3 + 0];\n\t\tvar totalCount = rsBlock[i * 3 + 1];\n\t\tvar dataCount = rsBlock[i * 3 + 2];\n\n\t\tfor (var j = 0; j < count; j++) {\n\t\t\tlist.push(new QRRSBlock(totalCount, dataCount) );\t\n\t\t}\n\t}\n\t\n\treturn list;\n}\n\nQRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {\n\n\tswitch(errorCorrectLevel) {\n\tcase ECL.L :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n\tcase ECL.M :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n\tcase ECL.Q :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n\tcase ECL.H :\n\t\treturn QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n\tdefault :\n\t\treturn undefined;\n\t}\n}\n\nmodule.exports = QRRSBlock;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/RSBlock.js\n// module id = 7\n// module chunks = 0", "module.exports = {\n\tL : 1,\n\tM : 0,\n\tQ : 3,\n\tH : 2\n};\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/ErrorCorrectLevel.js\n// module id = 8\n// module chunks = 0", "function QRBitBuffer() {\n\tthis.buffer = new Array();\n\tthis.length = 0;\n}\n\nQRBitBuffer.prototype = {\n\n\tget : function(index) {\n\t\tvar bufIndex = Math.floor(index / 8);\n\t\treturn ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n\t},\n\t\n\tput : function(num, length) {\n\t\tfor (var i = 0; i < length; i++) {\n\t\t\tthis.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n\t\t}\n\t},\n\t\n\tgetLengthInBits : function() {\n\t\treturn this.length;\n\t},\n\t\n\tputBit : function(bit) {\n\t\n\t\tvar bufIndex = Math.floor(this.length / 8);\n\t\tif (this.buffer.length <= bufIndex) {\n\t\t\tthis.buffer.push(0);\n\t\t}\n\t\n\t\tif (bit) {\n\t\t\tthis.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );\n\t\t}\n\t\n\t\tthis.length++;\n\t}\n};\n\nmodule.exports = QRBitBuffer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/BitBuffer.js\n// module id = 9\n// module chunks = 0", "var Mode = require('./mode');\nvar Polynomial = require('./Polynomial');\nvar math = require('./math');\n\nvar QRMaskPattern = {\n\tPATTERN000 : 0,\n\tPATTERN001 : 1,\n\tPATTERN010 : 2,\n\tPATTERN011 : 3,\n\tPATTERN100 : 4,\n\tPATTERN101 : 5,\n\tPATTERN110 : 6,\n\tPATTERN111 : 7\n};\n\nvar QRUtil = {\n\n PATTERN_POSITION_TABLE : [\n\t [],\n\t [6, 18],\n\t [6, 22],\n\t [6, 26],\n\t [6, 30],\n\t [6, 34],\n\t [6, 22, 38],\n\t [6, 24, 42],\n\t [6, 26, 46],\n\t [6, 28, 50],\n\t [6, 30, 54],\t\t\n\t [6, 32, 58],\n\t [6, 34, 62],\n\t [6, 26, 46, 66],\n\t [6, 26, 48, 70],\n\t [6, 26, 50, 74],\n\t [6, 30, 54, 78],\n\t [6, 30, 56, 82],\n\t [6, 30, 58, 86],\n\t [6, 34, 62, 90],\n\t [6, 28, 50, 72, 94],\n\t [6, 26, 50, 74, 98],\n\t [6, 30, 54, 78, 102],\n\t [6, 28, 54, 80, 106],\n\t [6, 32, 58, 84, 110],\n\t [6, 30, 58, 86, 114],\n\t [6, 34, 62, 90, 118],\n\t [6, 26, 50, 74, 98, 122],\n\t [6, 30, 54, 78, 102, 126],\n\t [6, 26, 52, 78, 104, 130],\n\t [6, 30, 56, 82, 108, 134],\n\t [6, 34, 60, 86, 112, 138],\n\t [6, 30, 58, 86, 114, 142],\n\t [6, 34, 62, 90, 118, 146],\n\t [6, 30, 54, 78, 102, 126, 150],\n\t [6, 24, 50, 76, 102, 128, 154],\n\t [6, 28, 54, 80, 106, 132, 158],\n\t [6, 32, 58, 84, 110, 136, 162],\n\t [6, 26, 54, 82, 110, 138, 166],\n\t [6, 30, 58, 86, 114, 142, 170]\n ],\n\n G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),\n G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),\n G15_MASK : (1 << 14) | (1 << 12) | (1 << 10)\t| (1 << 4) | (1 << 1),\n\n getBCHTypeInfo : function(data) {\n\t var d = data << 10;\n\t while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {\n\t\t d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); \t\n\t }\n\t return ( (data << 10) | d) ^ QRUtil.G15_MASK;\n },\n\n getBCHTypeNumber : function(data) {\n\t var d = data << 12;\n\t while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {\n\t\t d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); \t\n\t }\n\t return (data << 12) | d;\n },\n\n getBCHDigit : function(data) {\n\n\t var digit = 0;\n\n\t while (data != 0) {\n\t\t digit++;\n\t\t data >>>= 1;\n\t }\n\n\t return digit;\n },\n\n getPatternPosition : function(typeNumber) {\n\t return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];\n },\n\n getMask : function(maskPattern, i, j) {\n\t \n\t switch (maskPattern) {\n\t\t \n\t case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;\n\t case QRMaskPattern.PATTERN001 : return i % 2 == 0;\n\t case QRMaskPattern.PATTERN010 : return j % 3 == 0;\n\t case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;\n\t case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;\n\t case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;\n\t case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;\n\t case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;\n\n\t default :\n\t\t throw new Error(\"bad maskPattern:\" + maskPattern);\n\t }\n },\n\n getErrorCorrectPolynomial : function(errorCorrectLength) {\n\n\t var a = new Polynomial([1], 0);\n\n\t for (var i = 0; i < errorCorrectLength; i++) {\n\t\t a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );\n\t }\n\n\t return a;\n },\n\n getLengthInBits : function(mode, type) {\n\n\t if (1 <= type && type < 10) {\n\n\t\t // 1 - 9\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 10;\n\t\t case Mode.MODE_ALPHA_NUM \t: return 9;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 8;\n\t\t case Mode.MODE_KANJI \t: return 8;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else if (type < 27) {\n\n\t\t // 10 - 26\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 12;\n\t\t case Mode.MODE_ALPHA_NUM \t: return 11;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 16;\n\t\t case Mode.MODE_KANJI \t: return 10;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else if (type < 41) {\n\n\t\t // 27 - 40\n\n\t\t switch(mode) {\n\t\t case Mode.MODE_NUMBER \t: return 14;\n\t\t case Mode.MODE_ALPHA_NUM\t: return 13;\n\t\t case Mode.MODE_8BIT_BYTE\t: return 16;\n\t\t case Mode.MODE_KANJI \t: return 12;\n\t\t default :\n\t\t\t throw new Error(\"mode:\" + mode);\n\t\t }\n\n\t } else {\n\t\t throw new Error(\"type:\" + type);\n\t }\n },\n\n getLostPoint : function(qrCode) {\n\t \n\t var moduleCount = qrCode.getModuleCount();\n\t \n\t var lostPoint = 0;\n\t \n\t // LEVEL1\n\t \n\t for (var row = 0; row < moduleCount; row++) {\n\n\t\t for (var col = 0; col < moduleCount; col++) {\n\n\t\t\t var sameCount = 0;\n\t\t\t var dark = qrCode.isDark(row, col);\n\n\t\t\t\tfor (var r = -1; r <= 1; r++) {\n\n\t\t\t\t if (row + r < 0 || moduleCount <= row + r) {\n\t\t\t\t\t continue;\n\t\t\t\t }\n\n\t\t\t\t for (var c = -1; c <= 1; c++) {\n\n\t\t\t\t\t if (col + c < 0 || moduleCount <= col + c) {\n\t\t\t\t\t\t continue;\n\t\t\t\t\t }\n\n\t\t\t\t\t if (r == 0 && c == 0) {\n\t\t\t\t\t\t continue;\n\t\t\t\t\t }\n\n\t\t\t\t\t if (dark == qrCode.isDark(row + r, col + c) ) {\n\t\t\t\t\t\t sameCount++;\n\t\t\t\t\t }\n\t\t\t\t }\n\t\t\t }\n\n\t\t\t if (sameCount > 5) {\n\t\t\t\t lostPoint += (3 + sameCount - 5);\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL2\n\n\t for (var row = 0; row < moduleCount - 1; row++) {\n\t\t for (var col = 0; col < moduleCount - 1; col++) {\n\t\t\t var count = 0;\n\t\t\t if (qrCode.isDark(row, col ) ) count++;\n\t\t\t if (qrCode.isDark(row + 1, col ) ) count++;\n\t\t\t if (qrCode.isDark(row, col + 1) ) count++;\n\t\t\t if (qrCode.isDark(row + 1, col + 1) ) count++;\n\t\t\t if (count == 0 || count == 4) {\n\t\t\t\t lostPoint += 3;\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL3\n\n\t for (var row = 0; row < moduleCount; row++) {\n\t\t for (var col = 0; col < moduleCount - 6; col++) {\n\t\t\t if (qrCode.isDark(row, col)\n\t\t\t\t\t && !qrCode.isDark(row, col + 1)\n\t\t\t\t\t && qrCode.isDark(row, col + 2)\n\t\t\t\t\t && qrCode.isDark(row, col + 3)\n\t\t\t\t\t && qrCode.isDark(row, col + 4)\n\t\t\t\t\t && !qrCode.isDark(row, col + 5)\n\t\t\t\t\t && qrCode.isDark(row, col + 6) ) {\n\t\t\t\t lostPoint += 40;\n\t\t\t }\n\t\t }\n\t }\n\n\t for (var col = 0; col < moduleCount; col++) {\n\t\t for (var row = 0; row < moduleCount - 6; row++) {\n\t\t\t if (qrCode.isDark(row, col)\n\t\t\t\t\t && !qrCode.isDark(row + 1, col)\n\t\t\t\t\t && qrCode.isDark(row + 2, col)\n\t\t\t\t\t && qrCode.isDark(row + 3, col)\n\t\t\t\t\t && qrCode.isDark(row + 4, col)\n\t\t\t\t\t && !qrCode.isDark(row + 5, col)\n\t\t\t\t\t && qrCode.isDark(row + 6, col) ) {\n\t\t\t\t lostPoint += 40;\n\t\t\t }\n\t\t }\n\t }\n\n\t // LEVEL4\n\t \n\t var darkCount = 0;\n\n\t for (var col = 0; col < moduleCount; col++) {\n\t\t for (var row = 0; row < moduleCount; row++) {\n\t\t\t if (qrCode.isDark(row, col) ) {\n\t\t\t\t darkCount++;\n\t\t\t }\n\t\t }\n\t }\n\t \n\t var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;\n\t lostPoint += ratio * 10;\n\n\t return lostPoint;\t\t\n }\n};\n\nmodule.exports = QRUtil;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/util.js\n// module id = 10\n// module chunks = 0", "var math = require('./math');\n\nfunction QRPolynomial(num, shift) {\n\n\tif (num.length == undefined) {\n\t\tthrow new Error(num.length + \"/\" + shift);\n\t}\n\n\tvar offset = 0;\n\n\twhile (offset < num.length && num[offset] == 0) {\n\t\toffset++;\n\t}\n\n\tthis.num = new Array(num.length - offset + shift);\n\tfor (var i = 0; i < num.length - offset; i++) {\n\t\tthis.num[i] = num[i + offset];\n\t}\n}\n\nQRPolynomial.prototype = {\n\n\tget : function(index) {\n\t\treturn this.num[index];\n\t},\n\t\n\tgetLength : function() {\n\t\treturn this.num.length;\n\t},\n\t\n\tmultiply : function(e) {\n\t\n\t\tvar num = new Array(this.getLength() + e.getLength() - 1);\n\t\n\t\tfor (var i = 0; i < this.getLength(); i++) {\n\t\t\tfor (var j = 0; j < e.getLength(); j++) {\n\t\t\t\tnum[i + j] ^= math.gexp(math.glog(this.get(i) ) + math.glog(e.get(j) ) );\n\t\t\t}\n\t\t}\n\t\n\t\treturn new QRPolynomial(num, 0);\n\t},\n\t\n\tmod : function(e) {\n\t\n\t\tif (this.getLength() - e.getLength() < 0) {\n\t\t\treturn this;\n\t\t}\n\t\n\t\tvar ratio = math.glog(this.get(0) ) - math.glog(e.get(0) );\n\t\n\t\tvar num = new Array(this.getLength() );\n\t\t\n\t\tfor (var i = 0; i < this.getLength(); i++) {\n\t\t\tnum[i] = this.get(i);\n\t\t}\n\t\t\n\t\tfor (var i = 0; i < e.getLength(); i++) {\n\t\t\tnum[i] ^= math.gexp(math.glog(e.get(i) ) + ratio);\n\t\t}\n\t\n\t\t// recursive call\n\t\treturn new QRPolynomial(num, 0).mod(e);\n\t}\n};\n\nmodule.exports = QRPolynomial;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/Polynomial.js\n// module id = 11\n// module chunks = 0", "var QRMath = {\n\n\tglog : function(n) {\n\t\n\t\tif (n < 1) {\n\t\t\tthrow new Error(\"glog(\" + n + \")\");\n\t\t}\n\t\t\n\t\treturn QRMath.LOG_TABLE[n];\n\t},\n\t\n\tgexp : function(n) {\n\t\n\t\twhile (n < 0) {\n\t\t\tn += 255;\n\t\t}\n\t\n\t\twhile (n >= 256) {\n\t\t\tn -= 255;\n\t\t}\n\t\n\t\treturn QRMath.EXP_TABLE[n];\n\t},\n\t\n\tEXP_TABLE : new Array(256),\n\t\n\tLOG_TABLE : new Array(256)\n\n};\n\t\nfor (var i = 0; i < 8; i++) {\n\tQRMath.EXP_TABLE[i] = 1 << i;\n}\nfor (var i = 8; i < 256; i++) {\n\tQRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]\n\t\t^ QRMath.EXP_TABLE[i - 5]\n\t\t^ QRMath.EXP_TABLE[i - 6]\n\t\t^ QRMath.EXP_TABLE[i - 8];\n}\nfor (var i = 0; i < 255; i++) {\n\tQRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;\n}\n\nmodule.exports = QRMath;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/qr.js/lib/math.js\n// module id = 12\n// module chunks = 0", "module.exports = \"\\n
\\n \\n \\n
\\n\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/Qrcode.vue\n// module id = 13\n// module chunks = 0" ], + "sourceRoot": "" +} diff --git a/BTCPayServer/wwwroot/js/vue.js b/BTCPayServer/wwwroot/js/vue.js index 36e01a473..a53e3f8ed 100644 --- a/BTCPayServer/wwwroot/js/vue.js +++ b/BTCPayServer/wwwroot/js/vue.js @@ -4,10514 +4,10519 @@ * Released under the MIT License. */ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.Vue = factory()); -}(this, (function () { 'use strict'; + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Vue = factory()); +}(this, (function () { + 'use strict'; -/* */ + /* */ -// these helpers produces better vm code in JS engines due to their -// explicitness and function inlining -function isUndef (v) { - return v === undefined || v === null -} - -function isDef (v) { - return v !== undefined && v !== null -} - -function isTrue (v) { - return v === true -} - -function isFalse (v) { - return v === false -} - -/** - * Check if value is primitive - */ -function isPrimitive (value) { - return ( - typeof value === 'string' || - typeof value === 'number' || - typeof value === 'boolean' - ) -} - -/** - * Quick object check - this is primarily used to tell - * Objects from primitive values when we know the value - * is a JSON-compliant type. - */ -function isObject (obj) { - return obj !== null && typeof obj === 'object' -} - -/** - * Get the raw type string of a value e.g. [object Object] - */ -var _toString = Object.prototype.toString; - -function toRawType (value) { - return _toString.call(value).slice(8, -1) -} - -/** - * Strict object type check. Only returns true - * for plain JavaScript objects. - */ -function isPlainObject (obj) { - return _toString.call(obj) === '[object Object]' -} - -function isRegExp (v) { - return _toString.call(v) === '[object RegExp]' -} - -/** - * Check if val is a valid array index. - */ -function isValidArrayIndex (val) { - var n = parseFloat(String(val)); - return n >= 0 && Math.floor(n) === n && isFinite(val) -} - -/** - * Convert a value to a string that is actually rendered. - */ -function toString (val) { - return val == null - ? '' - : typeof val === 'object' - ? JSON.stringify(val, null, 2) - : String(val) -} - -/** - * Convert a input value to a number for persistence. - * If the conversion fails, return original string. - */ -function toNumber (val) { - var n = parseFloat(val); - return isNaN(n) ? val : n -} - -/** - * Make a map and return a function for checking if a key - * is in that map. - */ -function makeMap ( - str, - expectsLowerCase -) { - var map = Object.create(null); - var list = str.split(','); - for (var i = 0; i < list.length; i++) { - map[list[i]] = true; - } - return expectsLowerCase - ? function (val) { return map[val.toLowerCase()]; } - : function (val) { return map[val]; } -} - -/** - * Check if a tag is a built-in tag. - */ -var isBuiltInTag = makeMap('slot,component', true); - -/** - * Check if a attribute is a reserved attribute. - */ -var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); - -/** - * Remove an item from an array - */ -function remove (arr, item) { - if (arr.length) { - var index = arr.indexOf(item); - if (index > -1) { - return arr.splice(index, 1) + // these helpers produces better vm code in JS engines due to their + // explicitness and function inlining + function isUndef(v) { + return v === undefined || v === null } - } -} -/** - * Check whether the object has the property. - */ -var hasOwnProperty = Object.prototype.hasOwnProperty; -function hasOwn (obj, key) { - return hasOwnProperty.call(obj, key) -} - -/** - * Create a cached version of a pure function. - */ -function cached (fn) { - var cache = Object.create(null); - return (function cachedFn (str) { - var hit = cache[str]; - return hit || (cache[str] = fn(str)) - }) -} - -/** - * Camelize a hyphen-delimited string. - */ -var camelizeRE = /-(\w)/g; -var camelize = cached(function (str) { - return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) -}); - -/** - * Capitalize a string. - */ -var capitalize = cached(function (str) { - return str.charAt(0).toUpperCase() + str.slice(1) -}); - -/** - * Hyphenate a camelCase string. - */ -var hyphenateRE = /\B([A-Z])/g; -var hyphenate = cached(function (str) { - return str.replace(hyphenateRE, '-$1').toLowerCase() -}); - -/** - * Simple bind, faster than native - */ -function bind (fn, ctx) { - function boundFn (a) { - var l = arguments.length; - return l - ? l > 1 - ? fn.apply(ctx, arguments) - : fn.call(ctx, a) - : fn.call(ctx) - } - // record original fn length - boundFn._length = fn.length; - return boundFn -} - -/** - * Convert an Array-like object to a real Array. - */ -function toArray (list, start) { - start = start || 0; - var i = list.length - start; - var ret = new Array(i); - while (i--) { - ret[i] = list[i + start]; - } - return ret -} - -/** - * Mix properties into target object. - */ -function extend (to, _from) { - for (var key in _from) { - to[key] = _from[key]; - } - return to -} - -/** - * Merge an Array of Objects into a single Object. - */ -function toObject (arr) { - var res = {}; - for (var i = 0; i < arr.length; i++) { - if (arr[i]) { - extend(res, arr[i]); + function isDef(v) { + return v !== undefined && v !== null } - } - return res -} -/** - * Perform no operation. - * Stubbing args to make Flow happy without leaving useless transpiled code - * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) - */ -function noop (a, b, c) {} + function isTrue(v) { + return v === true + } -/** - * Always return false. - */ -var no = function (a, b, c) { return false; }; + function isFalse(v) { + return v === false + } -/** - * Return same value - */ -var identity = function (_) { return _; }; + /** + * Check if value is primitive + */ + function isPrimitive(value) { + return ( + typeof value === 'string' || + typeof value === 'number' || + typeof value === 'boolean' + ) + } -/** - * Generate a static keys string from compiler modules. - */ -function genStaticKeys (modules) { - return modules.reduce(function (keys, m) { - return keys.concat(m.staticKeys || []) - }, []).join(',') -} + /** + * Quick object check - this is primarily used to tell + * Objects from primitive values when we know the value + * is a JSON-compliant type. + */ + function isObject(obj) { + return obj !== null && typeof obj === 'object' + } -/** - * Check if two values are loosely equal - that is, - * if they are plain objects, do they have the same shape? - */ -function looseEqual (a, b) { - if (a === b) { return true } - var isObjectA = isObject(a); - var isObjectB = isObject(b); - if (isObjectA && isObjectB) { - try { - var isArrayA = Array.isArray(a); - var isArrayB = Array.isArray(b); - if (isArrayA && isArrayB) { - return a.length === b.length && a.every(function (e, i) { - return looseEqual(e, b[i]) + /** + * Get the raw type string of a value e.g. [object Object] + */ + var _toString = Object.prototype.toString; + + function toRawType(value) { + return _toString.call(value).slice(8, -1) + } + + /** + * Strict object type check. Only returns true + * for plain JavaScript objects. + */ + function isPlainObject(obj) { + return _toString.call(obj) === '[object Object]' + } + + function isRegExp(v) { + return _toString.call(v) === '[object RegExp]' + } + + /** + * Check if val is a valid array index. + */ + function isValidArrayIndex(val) { + var n = parseFloat(String(val)); + return n >= 0 && Math.floor(n) === n && isFinite(val) + } + + /** + * Convert a value to a string that is actually rendered. + */ + function toString(val) { + return val == null + ? '' + : typeof val === 'object' + ? JSON.stringify(val, null, 2) + : String(val) + } + + /** + * Convert a input value to a number for persistence. + * If the conversion fails, return original string. + */ + function toNumber(val) { + var n = parseFloat(val); + return isNaN(n) ? val : n + } + + /** + * Make a map and return a function for checking if a key + * is in that map. + */ + function makeMap( + str, + expectsLowerCase + ) { + var map = Object.create(null); + var list = str.split(','); + for (var i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase + ? function (val) { return map[val.toLowerCase()]; } + : function (val) { return map[val]; } + } + + /** + * Check if a tag is a built-in tag. + */ + var isBuiltInTag = makeMap('slot,component', true); + + /** + * Check if a attribute is a reserved attribute. + */ + var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); + + /** + * Remove an item from an array + */ + function remove(arr, item) { + if (arr.length) { + var index = arr.indexOf(item); + if (index > -1) { + return arr.splice(index, 1) + } + } + } + + /** + * Check whether the object has the property. + */ + var hasOwnProperty = Object.prototype.hasOwnProperty; + function hasOwn(obj, key) { + return hasOwnProperty.call(obj, key) + } + + /** + * Create a cached version of a pure function. + */ + function cached(fn) { + var cache = Object.create(null); + return (function cachedFn(str) { + var hit = cache[str]; + return hit || (cache[str] = fn(str)) }) - } else if (!isArrayA && !isArrayB) { - var keysA = Object.keys(a); - var keysB = Object.keys(b); - return keysA.length === keysB.length && keysA.every(function (key) { - return looseEqual(a[key], b[key]) - }) - } else { + } + + /** + * Camelize a hyphen-delimited string. + */ + var camelizeRE = /-(\w)/g; + var camelize = cached(function (str) { + return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) + }); + + /** + * Capitalize a string. + */ + var capitalize = cached(function (str) { + return str.charAt(0).toUpperCase() + str.slice(1) + }); + + /** + * Hyphenate a camelCase string. + */ + var hyphenateRE = /\B([A-Z])/g; + var hyphenate = cached(function (str) { + return str.replace(hyphenateRE, '-$1').toLowerCase() + }); + + /** + * Simple bind, faster than native + */ + function bind(fn, ctx) { + function boundFn(a) { + var l = arguments.length; + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + // record original fn length + boundFn._length = fn.length; + return boundFn + } + + /** + * Convert an Array-like object to a real Array. + */ + function toArray(list, start) { + start = start || 0; + var i = list.length - start; + var ret = new Array(i); + while (i--) { + ret[i] = list[i + start]; + } + return ret + } + + /** + * Mix properties into target object. + */ + function extend(to, _from) { + for (var key in _from) { + to[key] = _from[key]; + } + return to + } + + /** + * Merge an Array of Objects into a single Object. + */ + function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res + } + + /** + * Perform no operation. + * Stubbing args to make Flow happy without leaving useless transpiled code + * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) + */ + function noop(a, b, c) { } + + /** + * Always return false. + */ + var no = function (a, b, c) { return false; }; + + /** + * Return same value + */ + var identity = function (_) { return _; }; + + /** + * Generate a static keys string from compiler modules. + */ + function genStaticKeys(modules) { + return modules.reduce(function (keys, m) { + return keys.concat(m.staticKeys || []) + }, []).join(',') + } + + /** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + */ + function looseEqual(a, b) { + if (a === b) { return true } + var isObjectA = isObject(a); + var isObjectB = isObject(b); + if (isObjectA && isObjectB) { + try { + var isArrayA = Array.isArray(a); + var isArrayB = Array.isArray(b); + if (isArrayA && isArrayB) { + return a.length === b.length && a.every(function (e, i) { + return looseEqual(e, b[i]) + }) + } else if (!isArrayA && !isArrayB) { + var keysA = Object.keys(a); + var keysB = Object.keys(b); + return keysA.length === keysB.length && keysA.every(function (key) { + return looseEqual(a[key], b[key]) + }) + } else { + /* istanbul ignore next */ + return false + } + } catch (e) { + /* istanbul ignore next */ + return false + } + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } + } + + function looseIndexOf(arr, val) { + for (var i = 0; i < arr.length; i++) { + if (looseEqual(arr[i], val)) { return i } + } + return -1 + } + + /** + * Ensure a function is called only once. + */ + function once(fn) { + var called = false; + return function () { + if (!called) { + called = true; + fn.apply(this, arguments); + } + } + } + + var SSR_ATTR = 'data-server-rendered'; + + var ASSET_TYPES = [ + 'component', + 'directive', + 'filter' + ]; + + var LIFECYCLE_HOOKS = [ + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'beforeDestroy', + 'destroyed', + 'activated', + 'deactivated', + 'errorCaptured' + ]; + + /* */ + + var config = ({ + /** + * Option merge strategies (used in core/util/options) + */ + optionMergeStrategies: Object.create(null), + + /** + * Whether to suppress warnings. + */ + silent: false, + + /** + * Show production mode tip message on boot? + */ + productionTip: "development" !== 'production', + + /** + * Whether to enable devtools + */ + devtools: "development" !== 'production', + + /** + * Whether to record perf + */ + performance: false, + + /** + * Error handler for watcher errors + */ + errorHandler: null, + + /** + * Warn handler for watcher warns + */ + warnHandler: null, + + /** + * Ignore certain custom elements + */ + ignoredElements: [], + + /** + * Custom user key aliases for v-on + */ + keyCodes: Object.create(null), + + /** + * Check if a tag is reserved so that it cannot be registered as a + * component. This is platform-dependent and may be overwritten. + */ + isReservedTag: no, + + /** + * Check if an attribute is reserved so that it cannot be used as a component + * prop. This is platform-dependent and may be overwritten. + */ + isReservedAttr: no, + + /** + * Check if a tag is an unknown element. + * Platform-dependent. + */ + isUnknownElement: no, + + /** + * Get the namespace of an element + */ + getTagNamespace: noop, + + /** + * Parse the real tag name for the specific platform. + */ + parsePlatformTagName: identity, + + /** + * Check if an attribute must be bound using property, e.g. value + * Platform-dependent. + */ + mustUseProp: no, + + /** + * Exposed for legacy reasons + */ + _lifecycleHooks: LIFECYCLE_HOOKS + }); + + /* */ + + var emptyObject = Object.freeze({}); + + /** + * Check if a string starts with $ or _ + */ + function isReserved(str) { + var c = (str + '').charCodeAt(0); + return c === 0x24 || c === 0x5F + } + + /** + * Define a property. + */ + function def(obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }); + } + + /** + * Parse simple path. + */ + var bailRE = /[^\w.$]/; + function parsePath(path) { + if (bailRE.test(path)) { + return + } + var segments = path.split('.'); + return function (obj) { + for (var i = 0; i < segments.length; i++) { + if (!obj) { return } + obj = obj[segments[i]]; + } + return obj + } + } + + /* */ + + var warn = noop; + var tip = noop; + var generateComponentTrace = (noop); // work around flow check + var formatComponentName = (noop); + + { + var hasConsole = typeof console !== 'undefined'; + var classifyRE = /(?:^|[-_])(\w)/g; + var classify = function (str) { + return str + .replace(classifyRE, function (c) { return c.toUpperCase(); }) + .replace(/[-_]/g, ''); + }; + + warn = function (msg, vm) { + var trace = vm ? generateComponentTrace(vm) : ''; + + if (config.warnHandler) { + config.warnHandler.call(null, msg, vm, trace); + } else if (hasConsole && (!config.silent)) { + console.error(("[Vue warn]: " + msg + trace)); + } + }; + + tip = function (msg, vm) { + if (hasConsole && (!config.silent)) { + console.warn("[Vue tip]: " + msg + ( + vm ? generateComponentTrace(vm) : '' + )); + } + }; + + formatComponentName = function (vm, includeFile) { + if (vm.$root === vm) { + return '' + } + var options = typeof vm === 'function' && vm.cid != null + ? vm.options + : vm._isVue + ? vm.$options || vm.constructor.options + : vm || {}; + var name = options.name || options._componentTag; + var file = options.__file; + if (!name && file) { + var match = file.match(/([^/\\]+)\.vue$/); + name = match && match[1]; + } + + return ( + (name ? ("<" + (classify(name)) + ">") : "") + + (file && includeFile !== false ? (" at " + file) : '') + ) + }; + + var repeat = function (str, n) { + var res = ''; + while (n) { + if (n % 2 === 1) { res += str; } + if (n > 1) { str += str; } + n >>= 1; + } + return res + }; + + generateComponentTrace = function (vm) { + if (vm._isVue && vm.$parent) { + var tree = []; + var currentRecursiveSequence = 0; + while (vm) { + if (tree.length > 0) { + var last = tree[tree.length - 1]; + if (last.constructor === vm.constructor) { + currentRecursiveSequence++; + vm = vm.$parent; + continue + } else if (currentRecursiveSequence > 0) { + tree[tree.length - 1] = [last, currentRecursiveSequence]; + currentRecursiveSequence = 0; + } + } + tree.push(vm); + vm = vm.$parent; + } + return '\n\nfound in\n\n' + tree + .map(function (vm, i) { + return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm) + ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)") + : formatComponentName(vm))); + }) + .join('\n') + } else { + return ("\n\n(found in " + (formatComponentName(vm)) + ")") + } + }; + } + + /* */ + + function handleError(err, vm, info) { + if (vm) { + var cur = vm; + while ((cur = cur.$parent)) { + var hooks = cur.$options.errorCaptured; + if (hooks) { + for (var i = 0; i < hooks.length; i++) { + try { + var capture = hooks[i].call(cur, err, vm, info) === false; + if (capture) { return } + } catch (e) { + globalHandleError(e, cur, 'errorCaptured hook'); + } + } + } + } + } + globalHandleError(err, vm, info); + } + + function globalHandleError(err, vm, info) { + if (config.errorHandler) { + try { + return config.errorHandler.call(null, err, vm, info) + } catch (e) { + logError(e, null, 'config.errorHandler'); + } + } + logError(err, vm, info); + } + + function logError(err, vm, info) { + { + warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); + } + /* istanbul ignore else */ + if (inBrowser && typeof console !== 'undefined') { + console.error(err); + } else { + throw err + } + } + + /* */ + /* globals MessageChannel */ + + // can we use __proto__? + var hasProto = '__proto__' in {}; + + // Browser environment sniffing + var inBrowser = typeof window !== 'undefined'; + var UA = inBrowser && window.navigator.userAgent.toLowerCase(); + var isIE = UA && /msie|trident/.test(UA); + var isIE9 = UA && UA.indexOf('msie 9.0') > 0; + var isEdge = UA && UA.indexOf('edge/') > 0; + var isAndroid = UA && UA.indexOf('android') > 0; + var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); + var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; + + // Firefox has a "watch" function on Object.prototype... + var nativeWatch = ({}).watch; + + var supportsPassive = false; + if (inBrowser) { + try { + var opts = {}; + Object.defineProperty(opts, 'passive', ({ + get: function get() { + /* istanbul ignore next */ + supportsPassive = true; + } + })); // https://github.com/facebook/flow/issues/285 + window.addEventListener('test-passive', null, opts); + } catch (e) { } + } + + // this needs to be lazy-evaled because vue may be required before + // vue-server-renderer can set VUE_ENV + var _isServer; + var isServerRendering = function () { + if (_isServer === undefined) { + /* istanbul ignore if */ + if (!inBrowser && typeof global !== 'undefined') { + // detect presence of vue-server-renderer and avoid + // Webpack shimming the process + _isServer = global['process'].env.VUE_ENV === 'server'; + } else { + _isServer = false; + } + } + return _isServer + }; + + // detect devtools + var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; + + /* istanbul ignore next */ + function isNative(Ctor) { + return typeof Ctor === 'function' && /native code/.test(Ctor.toString()) + } + + var hasSymbol = + typeof Symbol !== 'undefined' && isNative(Symbol) && + typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys); + + /** + * Defer a task to execute it asynchronously. + */ + var nextTick = (function () { + var callbacks = []; + var pending = false; + var timerFunc; + + function nextTickHandler() { + pending = false; + var copies = callbacks.slice(0); + callbacks.length = 0; + for (var i = 0; i < copies.length; i++) { + copies[i](); + } + } + + // An asynchronous deferring mechanism. + // In pre 2.4, we used to use microtasks (Promise/MutationObserver) + // but microtasks actually has too high a priority and fires in between + // supposedly sequential events (e.g. #4521, #6690) or even between + // bubbling of the same event (#6566). Technically setImmediate should be + // the ideal choice, but it's not available everywhere; and the only polyfill + // that consistently queues the callback after all DOM events triggered in the + // same loop is by using MessageChannel. + /* istanbul ignore if */ + if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { + timerFunc = function () { + setImmediate(nextTickHandler); + }; + } else if (typeof MessageChannel !== 'undefined' && ( + isNative(MessageChannel) || + // PhantomJS + MessageChannel.toString() === '[object MessageChannelConstructor]' + )) { + var channel = new MessageChannel(); + var port = channel.port2; + channel.port1.onmessage = nextTickHandler; + timerFunc = function () { + port.postMessage(1); + }; + } else + /* istanbul ignore next */ + if (typeof Promise !== 'undefined' && isNative(Promise)) { + // use microtask in non-DOM environments, e.g. Weex + var p = Promise.resolve(); + timerFunc = function () { + p.then(nextTickHandler); + }; + } else { + // fallback to setTimeout + timerFunc = function () { + setTimeout(nextTickHandler, 0); + }; + } + + return function queueNextTick(cb, ctx) { + var _resolve; + callbacks.push(function () { + if (cb) { + try { + cb.call(ctx); + } catch (e) { + handleError(e, ctx, 'nextTick'); + } + } else if (_resolve) { + _resolve(ctx); + } + }); + if (!pending) { + pending = true; + timerFunc(); + } + // $flow-disable-line + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve, reject) { + _resolve = resolve; + }) + } + } + })(); + + var _Set; + /* istanbul ignore if */ // $flow-disable-line + if (typeof Set !== 'undefined' && isNative(Set)) { + // use native Set when available. + _Set = Set; + } else { + // a non-standard Set polyfill that only works with primitive keys. + _Set = (function () { + function Set() { + this.set = Object.create(null); + } + Set.prototype.has = function has(key) { + return this.set[key] === true + }; + Set.prototype.add = function add(key) { + this.set[key] = true; + }; + Set.prototype.clear = function clear() { + this.set = Object.create(null); + }; + + return Set; + }()); + } + + /* */ + + + var uid = 0; + + /** + * A dep is an observable that can have multiple + * directives subscribing to it. + */ + var Dep = function Dep() { + this.id = uid++; + this.subs = []; + }; + + Dep.prototype.addSub = function addSub(sub) { + this.subs.push(sub); + }; + + Dep.prototype.removeSub = function removeSub(sub) { + remove(this.subs, sub); + }; + + Dep.prototype.depend = function depend() { + if (Dep.target) { + Dep.target.addDep(this); + } + }; + + Dep.prototype.notify = function notify() { + // stabilize the subscriber list first + var subs = this.subs.slice(); + for (var i = 0, l = subs.length; i < l; i++) { + subs[i].update(); + } + }; + + // the current target watcher being evaluated. + // this is globally unique because there could be only one + // watcher being evaluated at any time. + Dep.target = null; + var targetStack = []; + + function pushTarget(_target) { + if (Dep.target) { targetStack.push(Dep.target); } + Dep.target = _target; + } + + function popTarget() { + Dep.target = targetStack.pop(); + } + + /* */ + + var VNode = function VNode( + tag, + data, + children, + text, + elm, + context, + componentOptions, + asyncFactory + ) { + this.tag = tag; + this.data = data; + this.children = children; + this.text = text; + this.elm = elm; + this.ns = undefined; + this.context = context; + this.functionalContext = undefined; + this.functionalOptions = undefined; + this.functionalScopeId = undefined; + this.key = data && data.key; + this.componentOptions = componentOptions; + this.componentInstance = undefined; + this.parent = undefined; + this.raw = false; + this.isStatic = false; + this.isRootInsert = true; + this.isComment = false; + this.isCloned = false; + this.isOnce = false; + this.asyncFactory = asyncFactory; + this.asyncMeta = undefined; + this.isAsyncPlaceholder = false; + }; + + var prototypeAccessors = { child: { configurable: true } }; + + // DEPRECATED: alias for componentInstance for backwards compat. + /* istanbul ignore next */ + prototypeAccessors.child.get = function () { + return this.componentInstance + }; + + Object.defineProperties(VNode.prototype, prototypeAccessors); + + var createEmptyVNode = function (text) { + if (text === void 0) text = ''; + + var node = new VNode(); + node.text = text; + node.isComment = true; + return node + }; + + function createTextVNode(val) { + return new VNode(undefined, undefined, undefined, String(val)) + } + + // optimized shallow clone + // used for static nodes and slot nodes because they may be reused across + // multiple renders, cloning them avoids errors when DOM manipulations rely + // on their elm reference. + function cloneVNode(vnode, deep) { + var cloned = new VNode( + vnode.tag, + vnode.data, + vnode.children, + vnode.text, + vnode.elm, + vnode.context, + vnode.componentOptions, + vnode.asyncFactory + ); + cloned.ns = vnode.ns; + cloned.isStatic = vnode.isStatic; + cloned.key = vnode.key; + cloned.isComment = vnode.isComment; + cloned.isCloned = true; + if (deep && vnode.children) { + cloned.children = cloneVNodes(vnode.children); + } + return cloned + } + + function cloneVNodes(vnodes, deep) { + var len = vnodes.length; + var res = new Array(len); + for (var i = 0; i < len; i++) { + res[i] = cloneVNode(vnodes[i], deep); + } + return res + } + + /* + * not type checking this file because flow doesn't play well with + * dynamically accessing methods on Array prototype + */ + + var arrayProto = Array.prototype; + var arrayMethods = Object.create(arrayProto);[ + 'push', + 'pop', + 'shift', + 'unshift', + 'splice', + 'sort', + 'reverse' + ] + .forEach(function (method) { + // cache original method + var original = arrayProto[method]; + def(arrayMethods, method, function mutator() { + var args = [], len = arguments.length; + while (len--) args[len] = arguments[len]; + + var result = original.apply(this, args); + var ob = this.__ob__; + var inserted; + switch (method) { + case 'push': + case 'unshift': + inserted = args; + break + case 'splice': + inserted = args.slice(2); + break + } + if (inserted) { ob.observeArray(inserted); } + // notify change + ob.dep.notify(); + return result + }); + }); + + /* */ + + var arrayKeys = Object.getOwnPropertyNames(arrayMethods); + + /** + * By default, when a reactive property is set, the new value is + * also converted to become reactive. However when passing down props, + * we don't want to force conversion because the value may be a nested value + * under a frozen data structure. Converting it would defeat the optimization. + */ + var observerState = { + shouldConvert: true + }; + + /** + * Observer class that are attached to each observed + * object. Once attached, the observer converts target + * object's property keys into getter/setters that + * collect dependencies and dispatches updates. + */ + var Observer = function Observer(value) { + this.value = value; + this.dep = new Dep(); + this.vmCount = 0; + def(value, '__ob__', this); + if (Array.isArray(value)) { + var augment = hasProto + ? protoAugment + : copyAugment; + augment(value, arrayMethods, arrayKeys); + this.observeArray(value); + } else { + this.walk(value); + } + }; + + /** + * Walk through each property and convert them into + * getter/setters. This method should only be called when + * value type is Object. + */ + Observer.prototype.walk = function walk(obj) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + defineReactive(obj, keys[i], obj[keys[i]]); + } + }; + + /** + * Observe a list of Array items. + */ + Observer.prototype.observeArray = function observeArray(items) { + for (var i = 0, l = items.length; i < l; i++) { + observe(items[i]); + } + }; + + // helpers + + /** + * Augment an target Object or Array by intercepting + * the prototype chain using __proto__ + */ + function protoAugment(target, src, keys) { + /* eslint-disable no-proto */ + target.__proto__ = src; + /* eslint-enable no-proto */ + } + + /** + * Augment an target Object or Array by defining + * hidden properties. + */ + /* istanbul ignore next */ + function copyAugment(target, src, keys) { + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + def(target, key, src[key]); + } + } + + /** + * Attempt to create an observer instance for a value, + * returns the new observer if successfully observed, + * or the existing observer if the value already has one. + */ + function observe(value, asRootData) { + if (!isObject(value) || value instanceof VNode) { + return + } + var ob; + if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { + ob = value.__ob__; + } else if ( + observerState.shouldConvert && + !isServerRendering() && + (Array.isArray(value) || isPlainObject(value)) && + Object.isExtensible(value) && + !value._isVue + ) { + ob = new Observer(value); + } + if (asRootData && ob) { + ob.vmCount++; + } + return ob + } + + /** + * Define a reactive property on an Object. + */ + function defineReactive( + obj, + key, + val, + customSetter, + shallow + ) { + var dep = new Dep(); + + var property = Object.getOwnPropertyDescriptor(obj, key); + if (property && property.configurable === false) { + return + } + + // cater for pre-defined getter/setters + var getter = property && property.get; + var setter = property && property.set; + + var childOb = !shallow && observe(val); + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + get: function reactiveGetter() { + var value = getter ? getter.call(obj) : val; + if (Dep.target) { + dep.depend(); + if (childOb) { + childOb.dep.depend(); + if (Array.isArray(value)) { + dependArray(value); + } + } + } + return value + }, + set: function reactiveSetter(newVal) { + var value = getter ? getter.call(obj) : val; + /* eslint-disable no-self-compare */ + if (newVal === value || (newVal !== newVal && value !== value)) { + return + } + /* eslint-enable no-self-compare */ + if ("development" !== 'production' && customSetter) { + customSetter(); + } + if (setter) { + setter.call(obj, newVal); + } else { + val = newVal; + } + childOb = !shallow && observe(newVal); + dep.notify(); + } + }); + } + + /** + * Set a property on an object. Adds the new property and + * triggers change notification if the property doesn't + * already exist. + */ + function set(target, key, val) { + if (Array.isArray(target) && isValidArrayIndex(key)) { + target.length = Math.max(target.length, key); + target.splice(key, 1, val); + return val + } + if (hasOwn(target, key)) { + target[key] = val; + return val + } + var ob = (target).__ob__; + if (target._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid adding reactive properties to a Vue instance or its root $data ' + + 'at runtime - declare it upfront in the data option.' + ); + return val + } + if (!ob) { + target[key] = val; + return val + } + defineReactive(ob.value, key, val); + ob.dep.notify(); + return val + } + + /** + * Delete a property and trigger change if necessary. + */ + function del(target, key) { + if (Array.isArray(target) && isValidArrayIndex(key)) { + target.splice(key, 1); + return + } + var ob = (target).__ob__; + if (target._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid deleting properties on a Vue instance or its root $data ' + + '- just set it to null.' + ); + return + } + if (!hasOwn(target, key)) { + return + } + delete target[key]; + if (!ob) { + return + } + ob.dep.notify(); + } + + /** + * Collect dependencies on array elements when the array is touched, since + * we cannot intercept array element access like property getters. + */ + function dependArray(value) { + for (var e = (void 0), i = 0, l = value.length; i < l; i++) { + e = value[i]; + e && e.__ob__ && e.__ob__.dep.depend(); + if (Array.isArray(e)) { + dependArray(e); + } + } + } + + /* */ + + /** + * Option overwriting strategies are functions that handle + * how to merge a parent option value and a child option + * value into the final value. + */ + var strats = config.optionMergeStrategies; + + /** + * Options with restrictions + */ + { + strats.el = strats.propsData = function (parent, child, vm, key) { + if (!vm) { + warn( + "option \"" + key + "\" can only be used during instance " + + 'creation with the `new` keyword.' + ); + } + return defaultStrat(parent, child) + }; + } + + /** + * Helper that recursively merges two data objects together. + */ + function mergeData(to, from) { + if (!from) { return to } + var key, toVal, fromVal; + var keys = Object.keys(from); + for (var i = 0; i < keys.length; i++) { + key = keys[i]; + toVal = to[key]; + fromVal = from[key]; + if (!hasOwn(to, key)) { + set(to, key, fromVal); + } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { + mergeData(toVal, fromVal); + } + } + return to + } + + /** + * Data + */ + function mergeDataOrFn( + parentVal, + childVal, + vm + ) { + if (!vm) { + // in a Vue.extend merge, both should be functions + if (!childVal) { + return parentVal + } + if (!parentVal) { + return childVal + } + // when parentVal & childVal are both present, + // we need to return a function that returns the + // merged result of both functions... no need to + // check if parentVal is a function here because + // it has to be a function to pass previous merges. + return function mergedDataFn() { + return mergeData( + typeof childVal === 'function' ? childVal.call(this) : childVal, + typeof parentVal === 'function' ? parentVal.call(this) : parentVal + ) + } + } else if (parentVal || childVal) { + return function mergedInstanceDataFn() { + // instance merge + var instanceData = typeof childVal === 'function' + ? childVal.call(vm) + : childVal; + var defaultData = typeof parentVal === 'function' + ? parentVal.call(vm) + : parentVal; + if (instanceData) { + return mergeData(instanceData, defaultData) + } else { + return defaultData + } + } + } + } + + strats.data = function ( + parentVal, + childVal, + vm + ) { + if (!vm) { + if (childVal && typeof childVal !== 'function') { + "development" !== 'production' && warn( + 'The "data" option should be a function ' + + 'that returns a per-instance value in component ' + + 'definitions.', + vm + ); + + return parentVal + } + return mergeDataOrFn.call(this, parentVal, childVal) + } + + return mergeDataOrFn(parentVal, childVal, vm) + }; + + /** + * Hooks and props are merged as arrays. + */ + function mergeHook( + parentVal, + childVal + ) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : Array.isArray(childVal) + ? childVal + : [childVal] + : parentVal + } + + LIFECYCLE_HOOKS.forEach(function (hook) { + strats[hook] = mergeHook; + }); + + /** + * Assets + * + * When a vm is present (instance creation), we need to do + * a three-way merge between constructor options, instance + * options and parent options. + */ + function mergeAssets( + parentVal, + childVal, + vm, + key + ) { + var res = Object.create(parentVal || null); + if (childVal) { + "development" !== 'production' && assertObjectType(key, childVal, vm); + return extend(res, childVal) + } else { + return res + } + } + + ASSET_TYPES.forEach(function (type) { + strats[type + 's'] = mergeAssets; + }); + + /** + * Watchers. + * + * Watchers hashes should not overwrite one + * another, so we merge them as arrays. + */ + strats.watch = function ( + parentVal, + childVal, + vm, + key + ) { + // work around Firefox's Object.prototype.watch... + if (parentVal === nativeWatch) { parentVal = undefined; } + if (childVal === nativeWatch) { childVal = undefined; } + /* istanbul ignore if */ + if (!childVal) { return Object.create(parentVal || null) } + { + assertObjectType(key, childVal, vm); + } + if (!parentVal) { return childVal } + var ret = {}; + extend(ret, parentVal); + for (var key$1 in childVal) { + var parent = ret[key$1]; + var child = childVal[key$1]; + if (parent && !Array.isArray(parent)) { + parent = [parent]; + } + ret[key$1] = parent + ? parent.concat(child) + : Array.isArray(child) ? child : [child]; + } + return ret + }; + + /** + * Other object hashes. + */ + strats.props = + strats.methods = + strats.inject = + strats.computed = function ( + parentVal, + childVal, + vm, + key + ) { + if (childVal && "development" !== 'production') { + assertObjectType(key, childVal, vm); + } + if (!parentVal) { return childVal } + var ret = Object.create(null); + extend(ret, parentVal); + if (childVal) { extend(ret, childVal); } + return ret + }; + strats.provide = mergeDataOrFn; + + /** + * Default strategy. + */ + var defaultStrat = function (parentVal, childVal) { + return childVal === undefined + ? parentVal + : childVal + }; + + /** + * Validate component names + */ + function checkComponents(options) { + for (var key in options.components) { + var lower = key.toLowerCase(); + if (isBuiltInTag(lower) || config.isReservedTag(lower)) { + warn( + 'Do not use built-in or reserved HTML elements as component ' + + 'id: ' + key + ); + } + } + } + + /** + * Ensure all props option syntax are normalized into the + * Object-based format. + */ + function normalizeProps(options, vm) { + var props = options.props; + if (!props) { return } + var res = {}; + var i, val, name; + if (Array.isArray(props)) { + i = props.length; + while (i--) { + val = props[i]; + if (typeof val === 'string') { + name = camelize(val); + res[name] = { type: null }; + } else { + warn('props must be strings when using array syntax.'); + } + } + } else if (isPlainObject(props)) { + for (var key in props) { + val = props[key]; + name = camelize(key); + res[name] = isPlainObject(val) + ? val + : { type: val }; + } + } else { + warn( + "Invalid value for option \"props\": expected an Array or an Object, " + + "but got " + (toRawType(props)) + ".", + vm + ); + } + options.props = res; + } + + /** + * Normalize all injections into Object-based format + */ + function normalizeInject(options, vm) { + var inject = options.inject; + var normalized = options.inject = {}; + if (Array.isArray(inject)) { + for (var i = 0; i < inject.length; i++) { + normalized[inject[i]] = { from: inject[i] }; + } + } else if (isPlainObject(inject)) { + for (var key in inject) { + var val = inject[key]; + normalized[key] = isPlainObject(val) + ? extend({ from: key }, val) + : { from: val }; + } + } else if ("development" !== 'production' && inject) { + warn( + "Invalid value for option \"inject\": expected an Array or an Object, " + + "but got " + (toRawType(inject)) + ".", + vm + ); + } + } + + /** + * Normalize raw function directives into object format. + */ + function normalizeDirectives(options) { + var dirs = options.directives; + if (dirs) { + for (var key in dirs) { + var def = dirs[key]; + if (typeof def === 'function') { + dirs[key] = { bind: def, update: def }; + } + } + } + } + + function assertObjectType(name, value, vm) { + if (!isPlainObject(value)) { + warn( + "Invalid value for option \"" + name + "\": expected an Object, " + + "but got " + (toRawType(value)) + ".", + vm + ); + } + } + + /** + * Merge two option objects into a new one. + * Core utility used in both instantiation and inheritance. + */ + function mergeOptions( + parent, + child, + vm + ) { + { + checkComponents(child); + } + + if (typeof child === 'function') { + child = child.options; + } + + normalizeProps(child, vm); + normalizeInject(child, vm); + normalizeDirectives(child); + var extendsFrom = child.extends; + if (extendsFrom) { + parent = mergeOptions(parent, extendsFrom, vm); + } + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + parent = mergeOptions(parent, child.mixins[i], vm); + } + } + var options = {}; + var key; + for (key in parent) { + mergeField(key); + } + for (key in child) { + if (!hasOwn(parent, key)) { + mergeField(key); + } + } + function mergeField(key) { + var strat = strats[key] || defaultStrat; + options[key] = strat(parent[key], child[key], vm, key); + } + return options + } + + /** + * Resolve an asset. + * This function is used because child instances need access + * to assets defined in its ancestor chain. + */ + function resolveAsset( + options, + type, + id, + warnMissing + ) { + /* istanbul ignore if */ + if (typeof id !== 'string') { + return + } + var assets = options[type]; + // check local registration variations first + if (hasOwn(assets, id)) { return assets[id] } + var camelizedId = camelize(id); + if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } + var PascalCaseId = capitalize(camelizedId); + if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } + // fallback to prototype chain + var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; + if ("development" !== 'production' && warnMissing && !res) { + warn( + 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, + options + ); + } + return res + } + + /* */ + + function validateProp( + key, + propOptions, + propsData, + vm + ) { + var prop = propOptions[key]; + var absent = !hasOwn(propsData, key); + var value = propsData[key]; + // handle boolean props + if (isType(Boolean, prop.type)) { + if (absent && !hasOwn(prop, 'default')) { + value = false; + } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { + value = true; + } + } + // check default value + if (value === undefined) { + value = getPropDefaultValue(vm, prop, key); + // since the default value is a fresh copy, + // make sure to observe it. + var prevShouldConvert = observerState.shouldConvert; + observerState.shouldConvert = true; + observe(value); + observerState.shouldConvert = prevShouldConvert; + } + { + assertProp(prop, key, value, vm, absent); + } + return value + } + + /** + * Get the default value of a prop. + */ + function getPropDefaultValue(vm, prop, key) { + // no default, return undefined + if (!hasOwn(prop, 'default')) { + return undefined + } + var def = prop.default; + // warn against non-factory defaults for Object & Array + if ("development" !== 'production' && isObject(def)) { + warn( + 'Invalid default value for prop "' + key + '": ' + + 'Props with type Object/Array must use a factory function ' + + 'to return the default value.', + vm + ); + } + // the raw prop value was also undefined from previous render, + // return previous default value to avoid unnecessary watcher trigger + if (vm && vm.$options.propsData && + vm.$options.propsData[key] === undefined && + vm._props[key] !== undefined + ) { + return vm._props[key] + } + // call factory function for non-Function types + // a value is Function if its prototype is function even across different execution context + return typeof def === 'function' && getType(prop.type) !== 'Function' + ? def.call(vm) + : def + } + + /** + * Assert whether a prop is valid. + */ + function assertProp( + prop, + name, + value, + vm, + absent + ) { + if (prop.required && absent) { + warn( + 'Missing required prop: "' + name + '"', + vm + ); + return + } + if (value == null && !prop.required) { + return + } + var type = prop.type; + var valid = !type || type === true; + var expectedTypes = []; + if (type) { + if (!Array.isArray(type)) { + type = [type]; + } + for (var i = 0; i < type.length && !valid; i++) { + var assertedType = assertType(value, type[i]); + expectedTypes.push(assertedType.expectedType || ''); + valid = assertedType.valid; + } + } + if (!valid) { + warn( + "Invalid prop: type check failed for prop \"" + name + "\"." + + " Expected " + (expectedTypes.map(capitalize).join(', ')) + + ", got " + (toRawType(value)) + ".", + vm + ); + return + } + var validator = prop.validator; + if (validator) { + if (!validator(value)) { + warn( + 'Invalid prop: custom validator check failed for prop "' + name + '".', + vm + ); + } + } + } + + var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/; + + function assertType(value, type) { + var valid; + var expectedType = getType(type); + if (simpleCheckRE.test(expectedType)) { + var t = typeof value; + valid = t === expectedType.toLowerCase(); + // for primitive wrapper objects + if (!valid && t === 'object') { + valid = value instanceof type; + } + } else if (expectedType === 'Object') { + valid = isPlainObject(value); + } else if (expectedType === 'Array') { + valid = Array.isArray(value); + } else { + valid = value instanceof type; + } + return { + valid: valid, + expectedType: expectedType + } + } + + /** + * Use function string name to check built-in types, + * because a simple equality check will fail when running + * across different vms / iframes. + */ + function getType(fn) { + var match = fn && fn.toString().match(/^\s*function (\w+)/); + return match ? match[1] : '' + } + + function isType(type, fn) { + if (!Array.isArray(fn)) { + return getType(fn) === getType(type) + } + for (var i = 0, len = fn.length; i < len; i++) { + if (getType(fn[i]) === getType(type)) { + return true + } + } /* istanbul ignore next */ return false - } - } catch (e) { - /* istanbul ignore next */ - return false - } - } else if (!isObjectA && !isObjectB) { - return String(a) === String(b) - } else { - return false - } -} - -function looseIndexOf (arr, val) { - for (var i = 0; i < arr.length; i++) { - if (looseEqual(arr[i], val)) { return i } - } - return -1 -} - -/** - * Ensure a function is called only once. - */ -function once (fn) { - var called = false; - return function () { - if (!called) { - called = true; - fn.apply(this, arguments); - } - } -} - -var SSR_ATTR = 'data-server-rendered'; - -var ASSET_TYPES = [ - 'component', - 'directive', - 'filter' -]; - -var LIFECYCLE_HOOKS = [ - 'beforeCreate', - 'created', - 'beforeMount', - 'mounted', - 'beforeUpdate', - 'updated', - 'beforeDestroy', - 'destroyed', - 'activated', - 'deactivated', - 'errorCaptured' -]; - -/* */ - -var config = ({ - /** - * Option merge strategies (used in core/util/options) - */ - optionMergeStrategies: Object.create(null), - - /** - * Whether to suppress warnings. - */ - silent: false, - - /** - * Show production mode tip message on boot? - */ - productionTip: "development" !== 'production', - - /** - * Whether to enable devtools - */ - devtools: "development" !== 'production', - - /** - * Whether to record perf - */ - performance: false, - - /** - * Error handler for watcher errors - */ - errorHandler: null, - - /** - * Warn handler for watcher warns - */ - warnHandler: null, - - /** - * Ignore certain custom elements - */ - ignoredElements: [], - - /** - * Custom user key aliases for v-on - */ - keyCodes: Object.create(null), - - /** - * Check if a tag is reserved so that it cannot be registered as a - * component. This is platform-dependent and may be overwritten. - */ - isReservedTag: no, - - /** - * Check if an attribute is reserved so that it cannot be used as a component - * prop. This is platform-dependent and may be overwritten. - */ - isReservedAttr: no, - - /** - * Check if a tag is an unknown element. - * Platform-dependent. - */ - isUnknownElement: no, - - /** - * Get the namespace of an element - */ - getTagNamespace: noop, - - /** - * Parse the real tag name for the specific platform. - */ - parsePlatformTagName: identity, - - /** - * Check if an attribute must be bound using property, e.g. value - * Platform-dependent. - */ - mustUseProp: no, - - /** - * Exposed for legacy reasons - */ - _lifecycleHooks: LIFECYCLE_HOOKS -}); - -/* */ - -var emptyObject = Object.freeze({}); - -/** - * Check if a string starts with $ or _ - */ -function isReserved (str) { - var c = (str + '').charCodeAt(0); - return c === 0x24 || c === 0x5F -} - -/** - * Define a property. - */ -function def (obj, key, val, enumerable) { - Object.defineProperty(obj, key, { - value: val, - enumerable: !!enumerable, - writable: true, - configurable: true - }); -} - -/** - * Parse simple path. - */ -var bailRE = /[^\w.$]/; -function parsePath (path) { - if (bailRE.test(path)) { - return - } - var segments = path.split('.'); - return function (obj) { - for (var i = 0; i < segments.length; i++) { - if (!obj) { return } - obj = obj[segments[i]]; - } - return obj - } -} - -/* */ - -var warn = noop; -var tip = noop; -var generateComponentTrace = (noop); // work around flow check -var formatComponentName = (noop); - -{ - var hasConsole = typeof console !== 'undefined'; - var classifyRE = /(?:^|[-_])(\w)/g; - var classify = function (str) { return str - .replace(classifyRE, function (c) { return c.toUpperCase(); }) - .replace(/[-_]/g, ''); }; - - warn = function (msg, vm) { - var trace = vm ? generateComponentTrace(vm) : ''; - - if (config.warnHandler) { - config.warnHandler.call(null, msg, vm, trace); - } else if (hasConsole && (!config.silent)) { - console.error(("[Vue warn]: " + msg + trace)); - } - }; - - tip = function (msg, vm) { - if (hasConsole && (!config.silent)) { - console.warn("[Vue tip]: " + msg + ( - vm ? generateComponentTrace(vm) : '' - )); - } - }; - - formatComponentName = function (vm, includeFile) { - if (vm.$root === vm) { - return '' - } - var options = typeof vm === 'function' && vm.cid != null - ? vm.options - : vm._isVue - ? vm.$options || vm.constructor.options - : vm || {}; - var name = options.name || options._componentTag; - var file = options.__file; - if (!name && file) { - var match = file.match(/([^/\\]+)\.vue$/); - name = match && match[1]; } - return ( - (name ? ("<" + (classify(name)) + ">") : "") + - (file && includeFile !== false ? (" at " + file) : '') - ) - }; + /* */ - var repeat = function (str, n) { - var res = ''; - while (n) { - if (n % 2 === 1) { res += str; } - if (n > 1) { str += str; } - n >>= 1; - } - return res - }; + var mark; + var measure; - generateComponentTrace = function (vm) { - if (vm._isVue && vm.$parent) { - var tree = []; - var currentRecursiveSequence = 0; - while (vm) { - if (tree.length > 0) { - var last = tree[tree.length - 1]; - if (last.constructor === vm.constructor) { - currentRecursiveSequence++; - vm = vm.$parent; - continue - } else if (currentRecursiveSequence > 0) { - tree[tree.length - 1] = [last, currentRecursiveSequence]; - currentRecursiveSequence = 0; - } - } - tree.push(vm); - vm = vm.$parent; - } - return '\n\nfound in\n\n' + tree - .map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm) - ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)") - : formatComponentName(vm))); }) - .join('\n') - } else { - return ("\n\n(found in " + (formatComponentName(vm)) + ")") - } - }; -} - -/* */ - -function handleError (err, vm, info) { - if (vm) { - var cur = vm; - while ((cur = cur.$parent)) { - var hooks = cur.$options.errorCaptured; - if (hooks) { - for (var i = 0; i < hooks.length; i++) { - try { - var capture = hooks[i].call(cur, err, vm, info) === false; - if (capture) { return } - } catch (e) { - globalHandleError(e, cur, 'errorCaptured hook'); - } - } - } - } - } - globalHandleError(err, vm, info); -} - -function globalHandleError (err, vm, info) { - if (config.errorHandler) { - try { - return config.errorHandler.call(null, err, vm, info) - } catch (e) { - logError(e, null, 'config.errorHandler'); - } - } - logError(err, vm, info); -} - -function logError (err, vm, info) { - { - warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); - } - /* istanbul ignore else */ - if (inBrowser && typeof console !== 'undefined') { - console.error(err); - } else { - throw err - } -} - -/* */ -/* globals MessageChannel */ - -// can we use __proto__? -var hasProto = '__proto__' in {}; - -// Browser environment sniffing -var inBrowser = typeof window !== 'undefined'; -var UA = inBrowser && window.navigator.userAgent.toLowerCase(); -var isIE = UA && /msie|trident/.test(UA); -var isIE9 = UA && UA.indexOf('msie 9.0') > 0; -var isEdge = UA && UA.indexOf('edge/') > 0; -var isAndroid = UA && UA.indexOf('android') > 0; -var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); -var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; - -// Firefox has a "watch" function on Object.prototype... -var nativeWatch = ({}).watch; - -var supportsPassive = false; -if (inBrowser) { - try { - var opts = {}; - Object.defineProperty(opts, 'passive', ({ - get: function get () { - /* istanbul ignore next */ - supportsPassive = true; - } - })); // https://github.com/facebook/flow/issues/285 - window.addEventListener('test-passive', null, opts); - } catch (e) {} -} - -// this needs to be lazy-evaled because vue may be required before -// vue-server-renderer can set VUE_ENV -var _isServer; -var isServerRendering = function () { - if (_isServer === undefined) { - /* istanbul ignore if */ - if (!inBrowser && typeof global !== 'undefined') { - // detect presence of vue-server-renderer and avoid - // Webpack shimming the process - _isServer = global['process'].env.VUE_ENV === 'server'; - } else { - _isServer = false; - } - } - return _isServer -}; - -// detect devtools -var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; - -/* istanbul ignore next */ -function isNative (Ctor) { - return typeof Ctor === 'function' && /native code/.test(Ctor.toString()) -} - -var hasSymbol = - typeof Symbol !== 'undefined' && isNative(Symbol) && - typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys); - -/** - * Defer a task to execute it asynchronously. - */ -var nextTick = (function () { - var callbacks = []; - var pending = false; - var timerFunc; - - function nextTickHandler () { - pending = false; - var copies = callbacks.slice(0); - callbacks.length = 0; - for (var i = 0; i < copies.length; i++) { - copies[i](); - } - } - - // An asynchronous deferring mechanism. - // In pre 2.4, we used to use microtasks (Promise/MutationObserver) - // but microtasks actually has too high a priority and fires in between - // supposedly sequential events (e.g. #4521, #6690) or even between - // bubbling of the same event (#6566). Technically setImmediate should be - // the ideal choice, but it's not available everywhere; and the only polyfill - // that consistently queues the callback after all DOM events triggered in the - // same loop is by using MessageChannel. - /* istanbul ignore if */ - if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { - timerFunc = function () { - setImmediate(nextTickHandler); - }; - } else if (typeof MessageChannel !== 'undefined' && ( - isNative(MessageChannel) || - // PhantomJS - MessageChannel.toString() === '[object MessageChannelConstructor]' - )) { - var channel = new MessageChannel(); - var port = channel.port2; - channel.port1.onmessage = nextTickHandler; - timerFunc = function () { - port.postMessage(1); - }; - } else - /* istanbul ignore next */ - if (typeof Promise !== 'undefined' && isNative(Promise)) { - // use microtask in non-DOM environments, e.g. Weex - var p = Promise.resolve(); - timerFunc = function () { - p.then(nextTickHandler); - }; - } else { - // fallback to setTimeout - timerFunc = function () { - setTimeout(nextTickHandler, 0); - }; - } - - return function queueNextTick (cb, ctx) { - var _resolve; - callbacks.push(function () { - if (cb) { - try { - cb.call(ctx); - } catch (e) { - handleError(e, ctx, 'nextTick'); - } - } else if (_resolve) { - _resolve(ctx); - } - }); - if (!pending) { - pending = true; - timerFunc(); - } - // $flow-disable-line - if (!cb && typeof Promise !== 'undefined') { - return new Promise(function (resolve, reject) { - _resolve = resolve; - }) - } - } -})(); - -var _Set; -/* istanbul ignore if */ // $flow-disable-line -if (typeof Set !== 'undefined' && isNative(Set)) { - // use native Set when available. - _Set = Set; -} else { - // a non-standard Set polyfill that only works with primitive keys. - _Set = (function () { - function Set () { - this.set = Object.create(null); - } - Set.prototype.has = function has (key) { - return this.set[key] === true - }; - Set.prototype.add = function add (key) { - this.set[key] = true; - }; - Set.prototype.clear = function clear () { - this.set = Object.create(null); - }; - - return Set; - }()); -} - -/* */ - - -var uid = 0; - -/** - * A dep is an observable that can have multiple - * directives subscribing to it. - */ -var Dep = function Dep () { - this.id = uid++; - this.subs = []; -}; - -Dep.prototype.addSub = function addSub (sub) { - this.subs.push(sub); -}; - -Dep.prototype.removeSub = function removeSub (sub) { - remove(this.subs, sub); -}; - -Dep.prototype.depend = function depend () { - if (Dep.target) { - Dep.target.addDep(this); - } -}; - -Dep.prototype.notify = function notify () { - // stabilize the subscriber list first - var subs = this.subs.slice(); - for (var i = 0, l = subs.length; i < l; i++) { - subs[i].update(); - } -}; - -// the current target watcher being evaluated. -// this is globally unique because there could be only one -// watcher being evaluated at any time. -Dep.target = null; -var targetStack = []; - -function pushTarget (_target) { - if (Dep.target) { targetStack.push(Dep.target); } - Dep.target = _target; -} - -function popTarget () { - Dep.target = targetStack.pop(); -} - -/* */ - -var VNode = function VNode ( - tag, - data, - children, - text, - elm, - context, - componentOptions, - asyncFactory -) { - this.tag = tag; - this.data = data; - this.children = children; - this.text = text; - this.elm = elm; - this.ns = undefined; - this.context = context; - this.functionalContext = undefined; - this.functionalOptions = undefined; - this.functionalScopeId = undefined; - this.key = data && data.key; - this.componentOptions = componentOptions; - this.componentInstance = undefined; - this.parent = undefined; - this.raw = false; - this.isStatic = false; - this.isRootInsert = true; - this.isComment = false; - this.isCloned = false; - this.isOnce = false; - this.asyncFactory = asyncFactory; - this.asyncMeta = undefined; - this.isAsyncPlaceholder = false; -}; - -var prototypeAccessors = { child: { configurable: true } }; - -// DEPRECATED: alias for componentInstance for backwards compat. -/* istanbul ignore next */ -prototypeAccessors.child.get = function () { - return this.componentInstance -}; - -Object.defineProperties( VNode.prototype, prototypeAccessors ); - -var createEmptyVNode = function (text) { - if ( text === void 0 ) text = ''; - - var node = new VNode(); - node.text = text; - node.isComment = true; - return node -}; - -function createTextVNode (val) { - return new VNode(undefined, undefined, undefined, String(val)) -} - -// optimized shallow clone -// used for static nodes and slot nodes because they may be reused across -// multiple renders, cloning them avoids errors when DOM manipulations rely -// on their elm reference. -function cloneVNode (vnode, deep) { - var cloned = new VNode( - vnode.tag, - vnode.data, - vnode.children, - vnode.text, - vnode.elm, - vnode.context, - vnode.componentOptions, - vnode.asyncFactory - ); - cloned.ns = vnode.ns; - cloned.isStatic = vnode.isStatic; - cloned.key = vnode.key; - cloned.isComment = vnode.isComment; - cloned.isCloned = true; - if (deep && vnode.children) { - cloned.children = cloneVNodes(vnode.children); - } - return cloned -} - -function cloneVNodes (vnodes, deep) { - var len = vnodes.length; - var res = new Array(len); - for (var i = 0; i < len; i++) { - res[i] = cloneVNode(vnodes[i], deep); - } - return res -} - -/* - * not type checking this file because flow doesn't play well with - * dynamically accessing methods on Array prototype - */ - -var arrayProto = Array.prototype; -var arrayMethods = Object.create(arrayProto);[ - 'push', - 'pop', - 'shift', - 'unshift', - 'splice', - 'sort', - 'reverse' -] -.forEach(function (method) { - // cache original method - var original = arrayProto[method]; - def(arrayMethods, method, function mutator () { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - var result = original.apply(this, args); - var ob = this.__ob__; - var inserted; - switch (method) { - case 'push': - case 'unshift': - inserted = args; - break - case 'splice': - inserted = args.slice(2); - break - } - if (inserted) { ob.observeArray(inserted); } - // notify change - ob.dep.notify(); - return result - }); -}); - -/* */ - -var arrayKeys = Object.getOwnPropertyNames(arrayMethods); - -/** - * By default, when a reactive property is set, the new value is - * also converted to become reactive. However when passing down props, - * we don't want to force conversion because the value may be a nested value - * under a frozen data structure. Converting it would defeat the optimization. - */ -var observerState = { - shouldConvert: true -}; - -/** - * Observer class that are attached to each observed - * object. Once attached, the observer converts target - * object's property keys into getter/setters that - * collect dependencies and dispatches updates. - */ -var Observer = function Observer (value) { - this.value = value; - this.dep = new Dep(); - this.vmCount = 0; - def(value, '__ob__', this); - if (Array.isArray(value)) { - var augment = hasProto - ? protoAugment - : copyAugment; - augment(value, arrayMethods, arrayKeys); - this.observeArray(value); - } else { - this.walk(value); - } -}; - -/** - * Walk through each property and convert them into - * getter/setters. This method should only be called when - * value type is Object. - */ -Observer.prototype.walk = function walk (obj) { - var keys = Object.keys(obj); - for (var i = 0; i < keys.length; i++) { - defineReactive(obj, keys[i], obj[keys[i]]); - } -}; - -/** - * Observe a list of Array items. - */ -Observer.prototype.observeArray = function observeArray (items) { - for (var i = 0, l = items.length; i < l; i++) { - observe(items[i]); - } -}; - -// helpers - -/** - * Augment an target Object or Array by intercepting - * the prototype chain using __proto__ - */ -function protoAugment (target, src, keys) { - /* eslint-disable no-proto */ - target.__proto__ = src; - /* eslint-enable no-proto */ -} - -/** - * Augment an target Object or Array by defining - * hidden properties. - */ -/* istanbul ignore next */ -function copyAugment (target, src, keys) { - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - def(target, key, src[key]); - } -} - -/** - * Attempt to create an observer instance for a value, - * returns the new observer if successfully observed, - * or the existing observer if the value already has one. - */ -function observe (value, asRootData) { - if (!isObject(value) || value instanceof VNode) { - return - } - var ob; - if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { - ob = value.__ob__; - } else if ( - observerState.shouldConvert && - !isServerRendering() && - (Array.isArray(value) || isPlainObject(value)) && - Object.isExtensible(value) && - !value._isVue - ) { - ob = new Observer(value); - } - if (asRootData && ob) { - ob.vmCount++; - } - return ob -} - -/** - * Define a reactive property on an Object. - */ -function defineReactive ( - obj, - key, - val, - customSetter, - shallow -) { - var dep = new Dep(); - - var property = Object.getOwnPropertyDescriptor(obj, key); - if (property && property.configurable === false) { - return - } - - // cater for pre-defined getter/setters - var getter = property && property.get; - var setter = property && property.set; - - var childOb = !shallow && observe(val); - Object.defineProperty(obj, key, { - enumerable: true, - configurable: true, - get: function reactiveGetter () { - var value = getter ? getter.call(obj) : val; - if (Dep.target) { - dep.depend(); - if (childOb) { - childOb.dep.depend(); - if (Array.isArray(value)) { - dependArray(value); - } - } - } - return value - }, - set: function reactiveSetter (newVal) { - var value = getter ? getter.call(obj) : val; - /* eslint-disable no-self-compare */ - if (newVal === value || (newVal !== newVal && value !== value)) { - return - } - /* eslint-enable no-self-compare */ - if ("development" !== 'production' && customSetter) { - customSetter(); - } - if (setter) { - setter.call(obj, newVal); - } else { - val = newVal; - } - childOb = !shallow && observe(newVal); - dep.notify(); - } - }); -} - -/** - * Set a property on an object. Adds the new property and - * triggers change notification if the property doesn't - * already exist. - */ -function set (target, key, val) { - if (Array.isArray(target) && isValidArrayIndex(key)) { - target.length = Math.max(target.length, key); - target.splice(key, 1, val); - return val - } - if (hasOwn(target, key)) { - target[key] = val; - return val - } - var ob = (target).__ob__; - if (target._isVue || (ob && ob.vmCount)) { - "development" !== 'production' && warn( - 'Avoid adding reactive properties to a Vue instance or its root $data ' + - 'at runtime - declare it upfront in the data option.' - ); - return val - } - if (!ob) { - target[key] = val; - return val - } - defineReactive(ob.value, key, val); - ob.dep.notify(); - return val -} - -/** - * Delete a property and trigger change if necessary. - */ -function del (target, key) { - if (Array.isArray(target) && isValidArrayIndex(key)) { - target.splice(key, 1); - return - } - var ob = (target).__ob__; - if (target._isVue || (ob && ob.vmCount)) { - "development" !== 'production' && warn( - 'Avoid deleting properties on a Vue instance or its root $data ' + - '- just set it to null.' - ); - return - } - if (!hasOwn(target, key)) { - return - } - delete target[key]; - if (!ob) { - return - } - ob.dep.notify(); -} - -/** - * Collect dependencies on array elements when the array is touched, since - * we cannot intercept array element access like property getters. - */ -function dependArray (value) { - for (var e = (void 0), i = 0, l = value.length; i < l; i++) { - e = value[i]; - e && e.__ob__ && e.__ob__.dep.depend(); - if (Array.isArray(e)) { - dependArray(e); - } - } -} - -/* */ - -/** - * Option overwriting strategies are functions that handle - * how to merge a parent option value and a child option - * value into the final value. - */ -var strats = config.optionMergeStrategies; - -/** - * Options with restrictions - */ -{ - strats.el = strats.propsData = function (parent, child, vm, key) { - if (!vm) { - warn( - "option \"" + key + "\" can only be used during instance " + - 'creation with the `new` keyword.' - ); - } - return defaultStrat(parent, child) - }; -} - -/** - * Helper that recursively merges two data objects together. - */ -function mergeData (to, from) { - if (!from) { return to } - var key, toVal, fromVal; - var keys = Object.keys(from); - for (var i = 0; i < keys.length; i++) { - key = keys[i]; - toVal = to[key]; - fromVal = from[key]; - if (!hasOwn(to, key)) { - set(to, key, fromVal); - } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { - mergeData(toVal, fromVal); - } - } - return to -} - -/** - * Data - */ -function mergeDataOrFn ( - parentVal, - childVal, - vm -) { - if (!vm) { - // in a Vue.extend merge, both should be functions - if (!childVal) { - return parentVal - } - if (!parentVal) { - return childVal - } - // when parentVal & childVal are both present, - // we need to return a function that returns the - // merged result of both functions... no need to - // check if parentVal is a function here because - // it has to be a function to pass previous merges. - return function mergedDataFn () { - return mergeData( - typeof childVal === 'function' ? childVal.call(this) : childVal, - typeof parentVal === 'function' ? parentVal.call(this) : parentVal - ) - } - } else if (parentVal || childVal) { - return function mergedInstanceDataFn () { - // instance merge - var instanceData = typeof childVal === 'function' - ? childVal.call(vm) - : childVal; - var defaultData = typeof parentVal === 'function' - ? parentVal.call(vm) - : parentVal; - if (instanceData) { - return mergeData(instanceData, defaultData) - } else { - return defaultData - } - } - } -} - -strats.data = function ( - parentVal, - childVal, - vm -) { - if (!vm) { - if (childVal && typeof childVal !== 'function') { - "development" !== 'production' && warn( - 'The "data" option should be a function ' + - 'that returns a per-instance value in component ' + - 'definitions.', - vm - ); - - return parentVal - } - return mergeDataOrFn.call(this, parentVal, childVal) - } - - return mergeDataOrFn(parentVal, childVal, vm) -}; - -/** - * Hooks and props are merged as arrays. - */ -function mergeHook ( - parentVal, - childVal -) { - return childVal - ? parentVal - ? parentVal.concat(childVal) - : Array.isArray(childVal) - ? childVal - : [childVal] - : parentVal -} - -LIFECYCLE_HOOKS.forEach(function (hook) { - strats[hook] = mergeHook; -}); - -/** - * Assets - * - * When a vm is present (instance creation), we need to do - * a three-way merge between constructor options, instance - * options and parent options. - */ -function mergeAssets ( - parentVal, - childVal, - vm, - key -) { - var res = Object.create(parentVal || null); - if (childVal) { - "development" !== 'production' && assertObjectType(key, childVal, vm); - return extend(res, childVal) - } else { - return res - } -} - -ASSET_TYPES.forEach(function (type) { - strats[type + 's'] = mergeAssets; -}); - -/** - * Watchers. - * - * Watchers hashes should not overwrite one - * another, so we merge them as arrays. - */ -strats.watch = function ( - parentVal, - childVal, - vm, - key -) { - // work around Firefox's Object.prototype.watch... - if (parentVal === nativeWatch) { parentVal = undefined; } - if (childVal === nativeWatch) { childVal = undefined; } - /* istanbul ignore if */ - if (!childVal) { return Object.create(parentVal || null) } - { - assertObjectType(key, childVal, vm); - } - if (!parentVal) { return childVal } - var ret = {}; - extend(ret, parentVal); - for (var key$1 in childVal) { - var parent = ret[key$1]; - var child = childVal[key$1]; - if (parent && !Array.isArray(parent)) { - parent = [parent]; - } - ret[key$1] = parent - ? parent.concat(child) - : Array.isArray(child) ? child : [child]; - } - return ret -}; - -/** - * Other object hashes. - */ -strats.props = -strats.methods = -strats.inject = -strats.computed = function ( - parentVal, - childVal, - vm, - key -) { - if (childVal && "development" !== 'production') { - assertObjectType(key, childVal, vm); - } - if (!parentVal) { return childVal } - var ret = Object.create(null); - extend(ret, parentVal); - if (childVal) { extend(ret, childVal); } - return ret -}; -strats.provide = mergeDataOrFn; - -/** - * Default strategy. - */ -var defaultStrat = function (parentVal, childVal) { - return childVal === undefined - ? parentVal - : childVal -}; - -/** - * Validate component names - */ -function checkComponents (options) { - for (var key in options.components) { - var lower = key.toLowerCase(); - if (isBuiltInTag(lower) || config.isReservedTag(lower)) { - warn( - 'Do not use built-in or reserved HTML elements as component ' + - 'id: ' + key - ); - } - } -} - -/** - * Ensure all props option syntax are normalized into the - * Object-based format. - */ -function normalizeProps (options, vm) { - var props = options.props; - if (!props) { return } - var res = {}; - var i, val, name; - if (Array.isArray(props)) { - i = props.length; - while (i--) { - val = props[i]; - if (typeof val === 'string') { - name = camelize(val); - res[name] = { type: null }; - } else { - warn('props must be strings when using array syntax.'); - } - } - } else if (isPlainObject(props)) { - for (var key in props) { - val = props[key]; - name = camelize(key); - res[name] = isPlainObject(val) - ? val - : { type: val }; - } - } else { - warn( - "Invalid value for option \"props\": expected an Array or an Object, " + - "but got " + (toRawType(props)) + ".", - vm - ); - } - options.props = res; -} - -/** - * Normalize all injections into Object-based format - */ -function normalizeInject (options, vm) { - var inject = options.inject; - var normalized = options.inject = {}; - if (Array.isArray(inject)) { - for (var i = 0; i < inject.length; i++) { - normalized[inject[i]] = { from: inject[i] }; - } - } else if (isPlainObject(inject)) { - for (var key in inject) { - var val = inject[key]; - normalized[key] = isPlainObject(val) - ? extend({ from: key }, val) - : { from: val }; - } - } else if ("development" !== 'production' && inject) { - warn( - "Invalid value for option \"inject\": expected an Array or an Object, " + - "but got " + (toRawType(inject)) + ".", - vm - ); - } -} - -/** - * Normalize raw function directives into object format. - */ -function normalizeDirectives (options) { - var dirs = options.directives; - if (dirs) { - for (var key in dirs) { - var def = dirs[key]; - if (typeof def === 'function') { - dirs[key] = { bind: def, update: def }; - } - } - } -} - -function assertObjectType (name, value, vm) { - if (!isPlainObject(value)) { - warn( - "Invalid value for option \"" + name + "\": expected an Object, " + - "but got " + (toRawType(value)) + ".", - vm - ); - } -} - -/** - * Merge two option objects into a new one. - * Core utility used in both instantiation and inheritance. - */ -function mergeOptions ( - parent, - child, - vm -) { - { - checkComponents(child); - } - - if (typeof child === 'function') { - child = child.options; - } - - normalizeProps(child, vm); - normalizeInject(child, vm); - normalizeDirectives(child); - var extendsFrom = child.extends; - if (extendsFrom) { - parent = mergeOptions(parent, extendsFrom, vm); - } - if (child.mixins) { - for (var i = 0, l = child.mixins.length; i < l; i++) { - parent = mergeOptions(parent, child.mixins[i], vm); - } - } - var options = {}; - var key; - for (key in parent) { - mergeField(key); - } - for (key in child) { - if (!hasOwn(parent, key)) { - mergeField(key); - } - } - function mergeField (key) { - var strat = strats[key] || defaultStrat; - options[key] = strat(parent[key], child[key], vm, key); - } - return options -} - -/** - * Resolve an asset. - * This function is used because child instances need access - * to assets defined in its ancestor chain. - */ -function resolveAsset ( - options, - type, - id, - warnMissing -) { - /* istanbul ignore if */ - if (typeof id !== 'string') { - return - } - var assets = options[type]; - // check local registration variations first - if (hasOwn(assets, id)) { return assets[id] } - var camelizedId = camelize(id); - if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } - var PascalCaseId = capitalize(camelizedId); - if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } - // fallback to prototype chain - var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; - if ("development" !== 'production' && warnMissing && !res) { - warn( - 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, - options - ); - } - return res -} - -/* */ - -function validateProp ( - key, - propOptions, - propsData, - vm -) { - var prop = propOptions[key]; - var absent = !hasOwn(propsData, key); - var value = propsData[key]; - // handle boolean props - if (isType(Boolean, prop.type)) { - if (absent && !hasOwn(prop, 'default')) { - value = false; - } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { - value = true; - } - } - // check default value - if (value === undefined) { - value = getPropDefaultValue(vm, prop, key); - // since the default value is a fresh copy, - // make sure to observe it. - var prevShouldConvert = observerState.shouldConvert; - observerState.shouldConvert = true; - observe(value); - observerState.shouldConvert = prevShouldConvert; - } - { - assertProp(prop, key, value, vm, absent); - } - return value -} - -/** - * Get the default value of a prop. - */ -function getPropDefaultValue (vm, prop, key) { - // no default, return undefined - if (!hasOwn(prop, 'default')) { - return undefined - } - var def = prop.default; - // warn against non-factory defaults for Object & Array - if ("development" !== 'production' && isObject(def)) { - warn( - 'Invalid default value for prop "' + key + '": ' + - 'Props with type Object/Array must use a factory function ' + - 'to return the default value.', - vm - ); - } - // the raw prop value was also undefined from previous render, - // return previous default value to avoid unnecessary watcher trigger - if (vm && vm.$options.propsData && - vm.$options.propsData[key] === undefined && - vm._props[key] !== undefined - ) { - return vm._props[key] - } - // call factory function for non-Function types - // a value is Function if its prototype is function even across different execution context - return typeof def === 'function' && getType(prop.type) !== 'Function' - ? def.call(vm) - : def -} - -/** - * Assert whether a prop is valid. - */ -function assertProp ( - prop, - name, - value, - vm, - absent -) { - if (prop.required && absent) { - warn( - 'Missing required prop: "' + name + '"', - vm - ); - return - } - if (value == null && !prop.required) { - return - } - var type = prop.type; - var valid = !type || type === true; - var expectedTypes = []; - if (type) { - if (!Array.isArray(type)) { - type = [type]; - } - for (var i = 0; i < type.length && !valid; i++) { - var assertedType = assertType(value, type[i]); - expectedTypes.push(assertedType.expectedType || ''); - valid = assertedType.valid; - } - } - if (!valid) { - warn( - "Invalid prop: type check failed for prop \"" + name + "\"." + - " Expected " + (expectedTypes.map(capitalize).join(', ')) + - ", got " + (toRawType(value)) + ".", - vm - ); - return - } - var validator = prop.validator; - if (validator) { - if (!validator(value)) { - warn( - 'Invalid prop: custom validator check failed for prop "' + name + '".', - vm - ); - } - } -} - -var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/; - -function assertType (value, type) { - var valid; - var expectedType = getType(type); - if (simpleCheckRE.test(expectedType)) { - var t = typeof value; - valid = t === expectedType.toLowerCase(); - // for primitive wrapper objects - if (!valid && t === 'object') { - valid = value instanceof type; - } - } else if (expectedType === 'Object') { - valid = isPlainObject(value); - } else if (expectedType === 'Array') { - valid = Array.isArray(value); - } else { - valid = value instanceof type; - } - return { - valid: valid, - expectedType: expectedType - } -} - -/** - * Use function string name to check built-in types, - * because a simple equality check will fail when running - * across different vms / iframes. - */ -function getType (fn) { - var match = fn && fn.toString().match(/^\s*function (\w+)/); - return match ? match[1] : '' -} - -function isType (type, fn) { - if (!Array.isArray(fn)) { - return getType(fn) === getType(type) - } - for (var i = 0, len = fn.length; i < len; i++) { - if (getType(fn[i]) === getType(type)) { - return true - } - } - /* istanbul ignore next */ - return false -} - -/* */ - -var mark; -var measure; - -{ - var perf = inBrowser && window.performance; - /* istanbul ignore if */ - if ( - perf && - perf.mark && - perf.measure && - perf.clearMarks && - perf.clearMeasures - ) { - mark = function (tag) { return perf.mark(tag); }; - measure = function (name, startTag, endTag) { - perf.measure(name, startTag, endTag); - perf.clearMarks(startTag); - perf.clearMarks(endTag); - perf.clearMeasures(name); - }; - } -} - -/* not type checking this file because flow doesn't play well with Proxy */ - -var initProxy; - -{ - var allowedGlobals = makeMap( - 'Infinity,undefined,NaN,isFinite,isNaN,' + - 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + - 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + - 'require' // for Webpack/Browserify - ); - - var warnNonPresent = function (target, key) { - warn( - "Property or method \"" + key + "\" is not defined on the instance but " + - 'referenced during render. Make sure that this property is reactive, ' + - 'either in the data option, or for class-based components, by ' + - 'initializing the property. ' + - 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', - target - ); - }; - - var hasProxy = - typeof Proxy !== 'undefined' && - Proxy.toString().match(/native code/); - - if (hasProxy) { - var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact'); - config.keyCodes = new Proxy(config.keyCodes, { - set: function set (target, key, value) { - if (isBuiltInModifier(key)) { - warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); - return false - } else { - target[key] = value; - return true - } - } - }); - } - - var hasHandler = { - has: function has (target, key) { - var has = key in target; - var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; - if (!has && !isAllowed) { - warnNonPresent(target, key); - } - return has || !isAllowed - } - }; - - var getHandler = { - get: function get (target, key) { - if (typeof key === 'string' && !(key in target)) { - warnNonPresent(target, key); - } - return target[key] - } - }; - - initProxy = function initProxy (vm) { - if (hasProxy) { - // determine which proxy handler to use - var options = vm.$options; - var handlers = options.render && options.render._withStripped - ? getHandler - : hasHandler; - vm._renderProxy = new Proxy(vm, handlers); - } else { - vm._renderProxy = vm; - } - }; -} - -/* */ - -var normalizeEvent = cached(function (name) { - var passive = name.charAt(0) === '&'; - name = passive ? name.slice(1) : name; - var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first - name = once$$1 ? name.slice(1) : name; - var capture = name.charAt(0) === '!'; - name = capture ? name.slice(1) : name; - return { - name: name, - once: once$$1, - capture: capture, - passive: passive - } -}); - -function createFnInvoker (fns) { - function invoker () { - var arguments$1 = arguments; - - var fns = invoker.fns; - if (Array.isArray(fns)) { - var cloned = fns.slice(); - for (var i = 0; i < cloned.length; i++) { - cloned[i].apply(null, arguments$1); - } - } else { - // return handler return value for single handlers - return fns.apply(null, arguments) - } - } - invoker.fns = fns; - return invoker -} - -function updateListeners ( - on, - oldOn, - add, - remove$$1, - vm -) { - var name, cur, old, event; - for (name in on) { - cur = on[name]; - old = oldOn[name]; - event = normalizeEvent(name); - if (isUndef(cur)) { - "development" !== 'production' && warn( - "Invalid handler for event \"" + (event.name) + "\": got " + String(cur), - vm - ); - } else if (isUndef(old)) { - if (isUndef(cur.fns)) { - cur = on[name] = createFnInvoker(cur); - } - add(event.name, cur, event.once, event.capture, event.passive); - } else if (cur !== old) { - old.fns = cur; - on[name] = old; - } - } - for (name in oldOn) { - if (isUndef(on[name])) { - event = normalizeEvent(name); - remove$$1(event.name, oldOn[name], event.capture); - } - } -} - -/* */ - -function mergeVNodeHook (def, hookKey, hook) { - var invoker; - var oldHook = def[hookKey]; - - function wrappedHook () { - hook.apply(this, arguments); - // important: remove merged hook to ensure it's called only once - // and prevent memory leak - remove(invoker.fns, wrappedHook); - } - - if (isUndef(oldHook)) { - // no existing hook - invoker = createFnInvoker([wrappedHook]); - } else { - /* istanbul ignore if */ - if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { - // already a merged invoker - invoker = oldHook; - invoker.fns.push(wrappedHook); - } else { - // existing plain hook - invoker = createFnInvoker([oldHook, wrappedHook]); - } - } - - invoker.merged = true; - def[hookKey] = invoker; -} - -/* */ - -function extractPropsFromVNodeData ( - data, - Ctor, - tag -) { - // we are only extracting raw values here. - // validation and default values are handled in the child - // component itself. - var propOptions = Ctor.options.props; - if (isUndef(propOptions)) { - return - } - var res = {}; - var attrs = data.attrs; - var props = data.props; - if (isDef(attrs) || isDef(props)) { - for (var key in propOptions) { - var altKey = hyphenate(key); - { - var keyInLowerCase = key.toLowerCase(); + { + var perf = inBrowser && window.performance; + /* istanbul ignore if */ if ( - key !== keyInLowerCase && - attrs && hasOwn(attrs, keyInLowerCase) + perf && + perf.mark && + perf.measure && + perf.clearMarks && + perf.clearMeasures ) { - tip( - "Prop \"" + keyInLowerCase + "\" is passed to component " + - (formatComponentName(tag || Ctor)) + ", but the declared prop name is" + - " \"" + key + "\". " + - "Note that HTML attributes are case-insensitive and camelCased " + - "props need to use their kebab-case equivalents when using in-DOM " + - "templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"." - ); - } - } - checkProp(res, props, key, altKey, true) || - checkProp(res, attrs, key, altKey, false); - } - } - return res -} - -function checkProp ( - res, - hash, - key, - altKey, - preserve -) { - if (isDef(hash)) { - if (hasOwn(hash, key)) { - res[key] = hash[key]; - if (!preserve) { - delete hash[key]; - } - return true - } else if (hasOwn(hash, altKey)) { - res[key] = hash[altKey]; - if (!preserve) { - delete hash[altKey]; - } - return true - } - } - return false -} - -/* */ - -// The template compiler attempts to minimize the need for normalization by -// statically analyzing the template at compile time. -// -// For plain HTML markup, normalization can be completely skipped because the -// generated render function is guaranteed to return Array. There are -// two cases where extra normalization is needed: - -// 1. When the children contains components - because a functional component -// may return an Array instead of a single root. In this case, just a simple -// normalization is needed - if any child is an Array, we flatten the whole -// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep -// because functional components already normalize their own children. -function simpleNormalizeChildren (children) { - for (var i = 0; i < children.length; i++) { - if (Array.isArray(children[i])) { - return Array.prototype.concat.apply([], children) - } - } - return children -} - -// 2. When the children contains constructs that always generated nested Arrays, -// e.g.