Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
883cd41232 | |||
3f48a478af | |||
8d3b45bdec | |||
bbd19a96ec | |||
ce17e3212a | |||
c3ea63c6ce | |||
1ee4bd9c92 | |||
e6bb6619e5 | |||
cc29d863d7 | |||
8cb2c93abd | |||
2187e05a10 | |||
4c07483383 | |||
65916755b6 | |||
3cefbc89e4 | |||
c40b47b1dd | |||
a2d17bfa7e | |||
cdf0c6d27d | |||
8154986102 | |||
203494e809 | |||
d49bbc95af | |||
c44132fd35 | |||
c75512303d | |||
97d50df13e | |||
0e1ef78af1 | |||
464ab30fea | |||
3ee1c05646 | |||
c54c39926b | |||
33d18a3278 | |||
97e564901e | |||
832069dd44 | |||
1ac17e96c3 | |||
d907031ec7 | |||
4b5af9cb5c |
@ -120,7 +120,7 @@ namespace BTCPayServer.Tests
|
||||
.Build();
|
||||
_Host.Start();
|
||||
InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository));
|
||||
|
||||
StoreRepository = (StoreRepository)_Host.Services.GetService(typeof(StoreRepository));
|
||||
var rateProvider = (BTCPayRateProviderFactory)_Host.Services.GetService(typeof(BTCPayRateProviderFactory));
|
||||
rateProvider.DirectProviders.Clear();
|
||||
|
||||
@ -152,6 +152,7 @@ namespace BTCPayServer.Tests
|
||||
internal set;
|
||||
}
|
||||
public InvoiceRepository InvoiceRepository { get; private set; }
|
||||
public StoreRepository StoreRepository { get; private set; }
|
||||
public Uri IntegratedLightning { get; internal set; }
|
||||
public bool InContainer { get; internal set; }
|
||||
|
||||
|
@ -12,6 +12,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using NBitpayClient;
|
||||
using System.Globalization;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace BTCPayServer.Tests.Lnd
|
||||
{
|
||||
@ -100,7 +101,7 @@ namespace BTCPayServer.Tests.Lnd
|
||||
var waitTask3 = listener.WaitInvoice(waitToken);
|
||||
await Task.Delay(100);
|
||||
listener.Dispose();
|
||||
Assert.Throws<TaskCanceledException>(()=> waitTask3.GetAwaiter().GetResult());
|
||||
Assert.Throws<TaskCanceledException>(() => waitTask3.GetAwaiter().GetResult());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -114,11 +115,29 @@ namespace BTCPayServer.Tests.Lnd
|
||||
Payment_request = merchantInvoice.BOLT11
|
||||
});
|
||||
|
||||
var invoice = await InvoiceClient.GetInvoice(merchantInvoice.Id);
|
||||
|
||||
Assert.True(invoice.PaidAt.HasValue);
|
||||
await EventuallyAsync(async () =>
|
||||
{
|
||||
var invoice = await InvoiceClient.GetInvoice(merchantInvoice.Id);
|
||||
Assert.True(invoice.PaidAt.HasValue);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task EventuallyAsync(Func<Task> act)
|
||||
{
|
||||
CancellationTokenSource cts = new CancellationTokenSource(20000);
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await act();
|
||||
break;
|
||||
}
|
||||
catch (XunitException) when (!cts.Token.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LnrpcChannel> EnsureLightningChannelAsync()
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ namespace BTCPayServer.Tests
|
||||
CustomerLightningD = (CLightningRPCClient)LightningClientFactory.CreateClient(GetEnvironment("TEST_CUSTOMERLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30992/"), btc);
|
||||
MerchantLightningD = (CLightningRPCClient)LightningClientFactory.CreateClient(GetEnvironment("TEST_MERCHANTLIGHTNINGD", "type=clightning;server=tcp://127.0.0.1:30993/"), btc);
|
||||
|
||||
MerchantCharge = new ChargeTester(this, "TEST_MERCHANTCHARGE", "type=charge;server=https://127.0.0.1:54938/;api-token=foiewnccewuify", "merchant_lightningd", btc);
|
||||
MerchantCharge = new ChargeTester(this, "TEST_MERCHANTCHARGE", "type=charge;server=http://127.0.0.1:54938/;api-token=foiewnccewuify", "merchant_lightningd", btc);
|
||||
|
||||
MerchantLnd = new LndMockTester(this, "TEST_MERCHANTLND", "https://lnd:lnd@127.0.0.1:53280/", "merchant_lnd", btc);
|
||||
|
||||
@ -214,9 +214,14 @@ namespace BTCPayServer.Tests
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public List<string> Stores { get; internal set; } = new List<string>();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach(var store in Stores)
|
||||
{
|
||||
Xunit.Assert.True(PayTester.StoreRepository.DeleteStore(store).GetAwaiter().GetResult());
|
||||
}
|
||||
if (PayTester != null)
|
||||
PayTester.Dispose();
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ namespace BTCPayServer.Tests
|
||||
var store = this.GetController<UserStoresController>();
|
||||
await store.CreateStore(new CreateStoreViewModel() { Name = "Test Store" });
|
||||
StoreId = store.CreatedStoreId;
|
||||
parent.Stores.Add(StoreId);
|
||||
}
|
||||
|
||||
public BTCPayNetwork SupportedNetwork { get; set; }
|
||||
|
@ -410,7 +410,8 @@ namespace BTCPayServer.Tests
|
||||
|
||||
var testResult = storeController.AddLightningNode(user.StoreId, new LightningNodeViewModel()
|
||||
{
|
||||
ConnectionString = "type=charge;server=" + tester.MerchantCharge.Client.Uri.AbsoluteUri
|
||||
ConnectionString = "type=charge;server=" + tester.MerchantCharge.Client.Uri.AbsoluteUri,
|
||||
SkipPortTest = true // We can't test this as the IP can't be resolved by the test host :(
|
||||
}, "test", "BTC").GetAwaiter().GetResult();
|
||||
Assert.DoesNotContain("Error", ((LightningNodeViewModel)Assert.IsType<ViewResult>(testResult).Model).StatusMessage, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.True(storeController.ModelState.IsValid);
|
||||
|
@ -45,6 +45,7 @@ namespace BTCPayServer
|
||||
public string BlockExplorerLink { get; internal set; }
|
||||
public string UriScheme { get; internal set; }
|
||||
public Money MinFee { get; internal set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
[Obsolete("Should not be needed")]
|
||||
public bool IsBTC
|
||||
|
@ -17,12 +17,13 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Bitcoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://www.smartbit.com.au/tx/{0}" : "https://testnet.smartbit.com.au/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
UriScheme = "bitcoin",
|
||||
CryptoImagePath = "imlegacy/bitcoin-symbol.svg",
|
||||
LightningImagePath = "imlegacy/btc-lightning.svg",
|
||||
CryptoImagePath = "imlegacy/bitcoin.svg",
|
||||
LightningImagePath = "imlegacy/bitcoin-lightning.svg",
|
||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
|
||||
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("0'") : new KeyPath("1'")
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "BGold",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://explorer.bitcoingold.org/insight/tx/{0}/" : "https://test-explorer.bitcoingold.org/insight/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
@ -19,8 +20,8 @@ namespace BTCPayServer
|
||||
"BTG_X = BTG_BTC * BTC_X",
|
||||
"BTG_BTC = bitfinex(BTG_BTC)",
|
||||
},
|
||||
CryptoImagePath = "imlegacy/btg-symbol.svg",
|
||||
LightningImagePath = "imlegacy/btg-symbol.svg",
|
||||
CryptoImagePath = "imlegacy/btg.svg",
|
||||
LightningImagePath = "imlegacy/btg-lightning.svg",
|
||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
|
||||
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("156'") : new KeyPath("1'")
|
||||
});
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Dogecoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://dogechain.info/tx/{0}" : "https://dogechain.info/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Feathercoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://explorer.feathercoin.com/tx/{0}" : "https://explorer.feathercoin.com/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -15,6 +15,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Groestlcoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://chainz.cryptoid.info/grs/tx.dws?{0}.htm" : "https://chainz.cryptoid.info/grs-test/tx.dws?{0}.htm",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -16,12 +16,13 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Litecoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://live.blockcypher.com/ltc/tx/{0}/" : "http://explorer.litecointools.com/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
UriScheme = "litecoin",
|
||||
CryptoImagePath = "imlegacy/litecoin-symbol.svg",
|
||||
LightningImagePath = "imlegacy/ltc-lightning.svg",
|
||||
CryptoImagePath = "imlegacy/litecoin.svg",
|
||||
LightningImagePath = "imlegacy/litecoin-lightning.svg",
|
||||
DefaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType),
|
||||
CoinType = NetworkType == NetworkType.Mainnet ? new KeyPath("2'") : new KeyPath("1'")
|
||||
});
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Monacoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://mona.insight.monaco-ex.org/insight/tx/{0}" : "https://testnet-mona.insight.monaco-ex.org/insight/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Polis",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://insight.polispay.org/tx/{0}" : "https://insight.polispay.org/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Ufo",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://chainz.cryptoid.info/ufo/tx.dws?{0}" : "https://chainz.cryptoid.info/ufo/tx.dws?{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -16,6 +16,7 @@ namespace BTCPayServer
|
||||
Add(new BTCPayNetwork()
|
||||
{
|
||||
CryptoCode = nbxplorerNetwork.CryptoCode,
|
||||
DisplayName = "Viacoin",
|
||||
BlockExplorerLink = NetworkType == NetworkType.Mainnet ? "https://explorer.viacoin.org/tx/{0}" : "https://explorer.viacoin.org/tx/{0}",
|
||||
NBitcoinNetwork = nbxplorerNetwork.NBitcoinNetwork,
|
||||
NBXplorerNetwork = nbxplorerNetwork,
|
||||
|
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<Version>1.0.2.46</Version>
|
||||
<Version>1.0.2.52</Version>
|
||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
@ -27,19 +27,19 @@ namespace BTCPayServer.Configuration
|
||||
};
|
||||
app.HelpOption("-? | -h | --help");
|
||||
app.Option("-n | --network", $"Set the network among (mainnet,testnet,regtest) (default: mainnet)", CommandOptionType.SingleValue);
|
||||
app.Option("--testnet | -testnet", $"Use testnet (Deprecated, use --network instead)", CommandOptionType.BoolValue);
|
||||
app.Option("--regtest | -regtest", $"Use regtest (Deprecated, use --network instead)", CommandOptionType.BoolValue);
|
||||
app.Option("--chains | -c", $"Chains to support comma separated (default: btc, available: {chains})", CommandOptionType.SingleValue);
|
||||
app.Option("--postgres", $"Connection string to postgres database (default: sqlite is used)", CommandOptionType.SingleValue);
|
||||
app.Option("--externalurl", $"The expected external url of this service, to use if BTCPay is behind a reverse proxy (default: empty, use the incoming HTTP request to figure out)", CommandOptionType.SingleValue);
|
||||
app.Option("--bundlejscss", $"Bundle javascript and css files for better performance (default: true)", CommandOptionType.SingleValue);
|
||||
app.Option("--testnet | -testnet", $"Use testnet (deprecated, use --network instead)", CommandOptionType.BoolValue);
|
||||
app.Option("--regtest | -regtest", $"Use regtest (deprecated, use --network instead)", CommandOptionType.BoolValue);
|
||||
app.Option("--chains | -c", $"Chains to support as a comma separated (default: btc; available: {chains})", CommandOptionType.SingleValue);
|
||||
app.Option("--postgres", $"Connection string to a PostgreSQL database (default: SQLite)", CommandOptionType.SingleValue);
|
||||
app.Option("--externalurl", $"The expected external URL of this service, to use if BTCPay is behind a reverse proxy (default: empty, use the incoming HTTP request to figure out)", CommandOptionType.SingleValue);
|
||||
app.Option("--bundlejscss", $"Bundle JavaScript and CSS files for better performance (default: true)", CommandOptionType.SingleValue);
|
||||
app.Option("--rootpath", "The root path in the URL to access BTCPay (default: /)", CommandOptionType.SingleValue);
|
||||
foreach (var network in provider.GetAll())
|
||||
{
|
||||
var crypto = network.CryptoCode.ToLowerInvariant();
|
||||
app.Option($"--{crypto}explorerurl", $"Url of the NBxplorer for {network.CryptoCode} (default: {network.NBXplorerNetwork.DefaultSettings.DefaultUrl})", CommandOptionType.SingleValue);
|
||||
app.Option($"--{crypto}explorerurl", $"URL of the NBXplorer for {network.CryptoCode} (default: {network.NBXplorerNetwork.DefaultSettings.DefaultUrl})", CommandOptionType.SingleValue);
|
||||
app.Option($"--{crypto}explorercookiefile", $"Path to the cookie file (default: {network.NBXplorerNetwork.DefaultSettings.DefaultCookieFile})", CommandOptionType.SingleValue);
|
||||
app.Option($"--{crypto}lightning", $"Easy configuration of lightning for the server adnistrator: Must be a unix socket of CLightning (lightning-rpc) or URL to a charge server (default: empty)", CommandOptionType.SingleValue);
|
||||
app.Option($"--{crypto}lightning", $"Easy configuration of lightning for the server administrator: Must be a UNIX socket of c-lightning (lightning-rpc) or URL to a charge server (default: empty)", CommandOptionType.SingleValue);
|
||||
}
|
||||
return app;
|
||||
}
|
||||
|
@ -162,7 +162,8 @@ namespace BTCPayServer.Controllers
|
||||
using (var ctx = _ContextFactory.CreateContext())
|
||||
{
|
||||
return await ctx.Apps
|
||||
.Where(us => us.Id == appId && us.AppType == appType.ToString())
|
||||
.Where(us => us.Id == appId &&
|
||||
us.AppType == appType.ToString())
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
|
||||
_CSP.Add(new ConsentSecurityPolicy("script-src", "'unsafe-eval'")); // Needed by Vue
|
||||
if(!string.IsNullOrEmpty(model.CustomCSSLink) &&
|
||||
if (!string.IsNullOrEmpty(model.CustomCSSLink) &&
|
||||
Uri.TryCreate(model.CustomCSSLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
_CSP.Clear();
|
||||
@ -248,6 +248,8 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
CryptoCode = network.CryptoCode,
|
||||
PaymentMethodId = paymentMethodId.ToString(),
|
||||
PaymentMethodName = GetDisplayName(paymentMethodId, network),
|
||||
CryptoImage = GetImage(paymentMethodId, network),
|
||||
IsLightning = paymentMethodId.PaymentType == PaymentTypes.LightningLike,
|
||||
ServerUrl = HttpContext.Request.GetAbsoluteRoot(),
|
||||
OrderId = invoice.OrderId,
|
||||
@ -279,7 +281,6 @@ namespace BTCPayServer.Controllers
|
||||
TxCount = accounting.TxRequired,
|
||||
BtcPaid = accounting.Paid.ToString(),
|
||||
Status = invoice.Status,
|
||||
CryptoImage = "/" + GetImage(paymentMethodId, network),
|
||||
NetworkFee = paymentMethodDetails.GetTxFee(),
|
||||
IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1,
|
||||
AllowCoinConversion = storeBlob.AllowCoinConversion,
|
||||
@ -288,10 +289,14 @@ namespace BTCPayServer.Controllers
|
||||
.Select(kv => new PaymentModel.AvailableCrypto()
|
||||
{
|
||||
PaymentMethodId = kv.GetId().ToString(),
|
||||
CryptoImage = "/" + GetImage(kv.GetId(), kv.Network),
|
||||
CryptoCode = kv.GetId().CryptoCode,
|
||||
PaymentMethodName = GetDisplayName(kv.GetId(), kv.Network),
|
||||
IsLightning = kv.GetId().PaymentType == PaymentTypes.LightningLike,
|
||||
CryptoImage = GetImage(kv.GetId(), kv.Network),
|
||||
Link = Url.Action(nameof(Checkout), new { invoiceId = invoiceId, paymentMethodId = kv.GetId().ToString() })
|
||||
}).Where(c => c.CryptoImage != "/")
|
||||
.ToList()
|
||||
.OrderByDescending(a => a.CryptoCode == "BTC").ThenBy(a => a.PaymentMethodName).ThenBy(a => a.IsLightning ? 1 : 0)
|
||||
.ToList()
|
||||
};
|
||||
|
||||
var expiration = TimeSpan.FromSeconds(model.ExpirationSeconds);
|
||||
@ -299,9 +304,17 @@ namespace BTCPayServer.Controllers
|
||||
return model;
|
||||
}
|
||||
|
||||
private string GetDisplayName(PaymentMethodId paymentMethodId, BTCPayNetwork network)
|
||||
{
|
||||
return paymentMethodId.PaymentType == PaymentTypes.BTCLike ?
|
||||
network.DisplayName : network.DisplayName + " - Lightning";
|
||||
}
|
||||
|
||||
private string GetImage(PaymentMethodId paymentMethodId, BTCPayNetwork network)
|
||||
{
|
||||
return (paymentMethodId.PaymentType == PaymentTypes.BTCLike ? Url.Content(network.CryptoImagePath) : Url.Content(network.LightningImagePath));
|
||||
var res = paymentMethodId.PaymentType == PaymentTypes.BTCLike ?
|
||||
Url.Content(network.CryptoImagePath) : Url.Content(network.LightningImagePath);
|
||||
return "/" + res;
|
||||
}
|
||||
|
||||
private string OrderAmountFromInvoice(string cryptoCode, ProductInformation productInformation)
|
||||
@ -338,7 +351,7 @@ namespace BTCPayServer.Controllers
|
||||
provider = (NumberFormatInfo)provider.Clone();
|
||||
provider.CurrencyDecimalDigits = divisibility;
|
||||
}
|
||||
|
||||
|
||||
if (currencyData.Crypto)
|
||||
return price.ToString("C", provider);
|
||||
else
|
||||
|
@ -122,8 +122,6 @@ namespace BTCPayServer.Controllers
|
||||
HashSet<CurrencyPair> currencyPairsToFetch = new HashSet<CurrencyPair>();
|
||||
var rules = storeBlob.GetRateRules(_NetworkProvider);
|
||||
|
||||
await UpdateCLightningConnectionStringIfNeeded(store);
|
||||
|
||||
foreach (var network in store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Select(c => _NetworkProvider.GetNetwork(c.PaymentId.CryptoCode))
|
||||
.Where(c => c != null))
|
||||
@ -213,22 +211,6 @@ namespace BTCPayServer.Controllers
|
||||
return new DataWrapper<InvoiceResponse>(resp) { Facade = "pos/invoice" };
|
||||
}
|
||||
|
||||
private async Task UpdateCLightningConnectionStringIfNeeded(StoreData store)
|
||||
{
|
||||
bool needUpdate = false;
|
||||
foreach (var method in store.GetSupportedPaymentMethods(_NetworkProvider).OfType<Payments.Lightning.LightningSupportedPaymentMethod>())
|
||||
{
|
||||
var lightning = method.GetLightningUrl();
|
||||
if (lightning.IsLegacy)
|
||||
{
|
||||
method.SetLightningUrl(lightning);
|
||||
needUpdate = true;
|
||||
}
|
||||
}
|
||||
if(needUpdate)
|
||||
await _StoreRepository.UpdateStore(store);
|
||||
}
|
||||
|
||||
private async Task<PaymentMethod> CreatePaymentMethodAsync(Dictionary<CurrencyPair, Task<RateResult>> fetchingByCurrencyPair, IPaymentMethodHandler handler, ISupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network, InvoiceEntity entity, StoreData store)
|
||||
{
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
|
@ -283,7 +283,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
CurrencyPair = fetch.Key.ToString(),
|
||||
Error = testResult.Errors.Count != 0,
|
||||
Rule = testResult.Errors.Count == 0 ? testResult.Rule + " = " + testResult.Value.Value.ToString(CultureInfo.InvariantCulture)
|
||||
Rule = testResult.Errors.Count == 0 ? testResult.Rule + " = " + testResult.Value.Value.ToString(CultureInfo.InvariantCulture)
|
||||
: testResult.EvaluatedRule
|
||||
});
|
||||
}
|
||||
@ -424,6 +424,7 @@ namespace BTCPayServer.Controllers
|
||||
vm.StoreWebsite = store.StoreWebsite;
|
||||
vm.NetworkFee = !storeBlob.NetworkFeeDisabled;
|
||||
vm.SpeedPolicy = store.SpeedPolicy;
|
||||
vm.CanDelete = _Repo.CanDeleteStores();
|
||||
AddPaymentMethods(store, vm);
|
||||
vm.MonitoringExpiration = storeBlob.MonitoringExpiration;
|
||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||
@ -468,10 +469,8 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}")]
|
||||
public async Task<IActionResult> UpdateStore(StoreViewModel model)
|
||||
public async Task<IActionResult> UpdateStore(StoreViewModel model, string command = null)
|
||||
{
|
||||
AddPaymentMethods(StoreData, model);
|
||||
|
||||
bool needUpdate = false;
|
||||
if (StoreData.SpeedPolicy != model.SpeedPolicy)
|
||||
{
|
||||
@ -511,6 +510,29 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
storeId = StoreData.Id
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{storeId}/delete")]
|
||||
public IActionResult DeleteStore(string storeId)
|
||||
{
|
||||
return View("Confirm", new ConfirmModel()
|
||||
{
|
||||
Action = "Delete this store",
|
||||
Title = "Delete this store",
|
||||
Description = "This action is irreversible and will remove all information related to this store. (Invoices, Apps etc...)",
|
||||
ButtonClass = "btn-danger"
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}/delete")]
|
||||
public async Task<IActionResult> DeleteStorePost(string storeId)
|
||||
{
|
||||
await _Repo.DeleteStore(StoreData.Id);
|
||||
StatusMessage = "Success: Store successfully deleted";
|
||||
return RedirectToAction(nameof(UserStoresController.ListStores), "UserStores");
|
||||
}
|
||||
|
||||
private CoinAverageExchange[] GetSupportedExchanges()
|
||||
|
@ -35,21 +35,7 @@ namespace BTCPayServer.Controllers
|
||||
_NetworkProvider = networkProvider;
|
||||
_UserManager = userManager;
|
||||
_WalletProvider = walletProvider;
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("{storeId}/delete")]
|
||||
public IActionResult DeleteStore(string storeId)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
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("create")]
|
||||
@ -63,8 +49,23 @@ namespace BTCPayServer.Controllers
|
||||
get; set;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{storeId}/me/delete")]
|
||||
public IActionResult DeleteStore(string storeId)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
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")]
|
||||
[Route("{storeId}/me/delete")]
|
||||
public async Task<IActionResult> DeleteStorePost(string storeId)
|
||||
{
|
||||
var userId = GetUserId();
|
||||
|
@ -19,5 +19,7 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public StoreData StoreData { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -102,14 +102,27 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
builder.Entity<InvoiceData>()
|
||||
.HasIndex(o => o.StoreDataId);
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(a => a.Invoices).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<InvoiceData>().HasIndex(o => o.StoreDataId);
|
||||
|
||||
|
||||
builder.Entity<PaymentData>()
|
||||
.HasIndex(o => o.InvoiceDataId);
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.Payments).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<PaymentData>()
|
||||
.HasIndex(o => o.InvoiceDataId);
|
||||
|
||||
|
||||
builder.Entity<RefundAddressesData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.RefundAddresses).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<RefundAddressesData>()
|
||||
.HasIndex(o => o.InvoiceDataId);
|
||||
|
||||
builder.Entity<UserStore>()
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(i => i.UserStores).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<UserStore>()
|
||||
.HasKey(t => new
|
||||
{
|
||||
@ -117,9 +130,16 @@ namespace BTCPayServer.Data
|
||||
t.StoreDataId
|
||||
});
|
||||
|
||||
builder.Entity<APIKeyData>()
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(i => i.APIKeys)
|
||||
.HasForeignKey(i => i.StoreId).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<APIKeyData>()
|
||||
.HasIndex(o => o.StoreId);
|
||||
|
||||
builder.Entity<AppData>()
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(i => i.Apps).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<AppData>()
|
||||
.HasOne(a => a.StoreData);
|
||||
|
||||
@ -133,6 +153,10 @@ namespace BTCPayServer.Data
|
||||
.WithMany(t => t.UserStores)
|
||||
.HasForeignKey(pt => pt.StoreDataId);
|
||||
|
||||
|
||||
builder.Entity<AddressInvoiceData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.AddressInvoices).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<AddressInvoiceData>()
|
||||
#pragma warning disable CS0618
|
||||
.HasKey(o => o.Address);
|
||||
@ -141,12 +165,24 @@ namespace BTCPayServer.Data
|
||||
builder.Entity<PairingCodeData>()
|
||||
.HasKey(o => o.Id);
|
||||
|
||||
builder.Entity<PendingInvoiceData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(o => o.PendingInvoices)
|
||||
.HasForeignKey(o => o.Id).OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
builder.Entity<PairedSINData>()
|
||||
.HasOne(o => o.StoreData)
|
||||
.WithMany(i => i.PairedSINs).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<PairedSINData>(b =>
|
||||
{
|
||||
b.HasIndex(o => o.SIN);
|
||||
b.HasIndex(o => o.StoreDataId);
|
||||
});
|
||||
|
||||
builder.Entity<HistoricalAddressInvoiceData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.HistoricalAddressInvoices).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<HistoricalAddressInvoiceData>()
|
||||
.HasKey(o => new
|
||||
{
|
||||
@ -156,6 +192,10 @@ namespace BTCPayServer.Data
|
||||
#pragma warning restore CS0618
|
||||
});
|
||||
|
||||
|
||||
builder.Entity<InvoiceEventData>()
|
||||
.HasOne(o => o.InvoiceData)
|
||||
.WithMany(i => i.Events).OnDelete(DeleteBehavior.Cascade);
|
||||
builder.Entity<InvoiceEventData>()
|
||||
.HasKey(o => new
|
||||
{
|
||||
|
@ -29,6 +29,15 @@ namespace BTCPayServer.Data
|
||||
_Type = type;
|
||||
}
|
||||
|
||||
|
||||
public DatabaseType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Type;
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationDbContext CreateContext()
|
||||
{
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
|
@ -12,6 +12,11 @@ namespace BTCPayServer.Data
|
||||
get; set;
|
||||
}
|
||||
|
||||
public InvoiceData InvoiceData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some crypto currencies share same address prefix
|
||||
/// For not having exceptions thrown by two address on different network, we suffix by "#CRYPTOCODE"
|
||||
|
@ -80,5 +80,6 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public List<PendingInvoiceData> PendingInvoices { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public InvoiceData InvoiceData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string UniqueId { get; internal set; }
|
||||
public DateTimeOffset Timestamp
|
||||
{
|
||||
|
@ -21,6 +21,9 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public StoreData StoreData { get; set; }
|
||||
|
||||
public string Label
|
||||
{
|
||||
get;
|
||||
|
@ -11,5 +11,6 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public InvoiceData InvoiceData { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -34,12 +34,13 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public List<AppData> Apps
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public List<InvoiceData> Invoices { get; set; }
|
||||
|
||||
[Obsolete("Use GetDerivationStrategies instead")]
|
||||
public string DerivationStrategy
|
||||
{
|
||||
@ -192,6 +193,8 @@ namespace BTCPayServer.Data
|
||||
}
|
||||
[Obsolete("Use GetDefaultCrypto instead")]
|
||||
public string DefaultCrypto { get; set; }
|
||||
public List<PairedSINData> PairedSINs { get; set; }
|
||||
public IEnumerable<APIKeyData> APIKeys { get; set; }
|
||||
|
||||
#pragma warning disable CS0618
|
||||
public string GetDefaultCrypto()
|
||||
|
@ -31,6 +31,7 @@ using System.Security.Claims;
|
||||
using System.Globalization;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
@ -82,6 +83,15 @@ namespace BTCPayServer
|
||||
return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite";
|
||||
}
|
||||
|
||||
public static bool SupportDropForeignKey(this Microsoft.EntityFrameworkCore.Migrations.Migration migration, string activeProvider)
|
||||
{
|
||||
return activeProvider != "Microsoft.EntityFrameworkCore.Sqlite";
|
||||
}
|
||||
public static bool SupportDropForeignKey(this DatabaseFacade facade)
|
||||
{
|
||||
return facade.ProviderName != "Microsoft.EntityFrameworkCore.Sqlite";
|
||||
}
|
||||
|
||||
public static async Task<Dictionary<uint256, TransactionResult>> GetTransactions(this BTCPayWallet client, uint256[] hashes, CancellationToken cts = default(CancellationToken))
|
||||
{
|
||||
hashes = hashes.Distinct().ToArray();
|
||||
@ -179,19 +189,26 @@ namespace BTCPayServer
|
||||
|
||||
public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
|
||||
{
|
||||
var waiting = Task.Delay(-1, cancellationToken);
|
||||
var doing = task;
|
||||
await Task.WhenAny(waiting, doing);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return await doing;
|
||||
using (var delayCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
|
||||
{
|
||||
var waiting = Task.Delay(-1, delayCTS.Token);
|
||||
var doing = task;
|
||||
await Task.WhenAny(waiting, doing);
|
||||
delayCTS.Cancel();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return await doing;
|
||||
}
|
||||
}
|
||||
public static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
|
||||
{
|
||||
var waiting = Task.Delay(-1, cancellationToken);
|
||||
var doing = task;
|
||||
await Task.WhenAny(waiting, doing);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await doing;
|
||||
using (var delayCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
|
||||
{
|
||||
var waiting = Task.Delay(-1, delayCTS.Token);
|
||||
var doing = task;
|
||||
await Task.WhenAny(waiting, doing);
|
||||
delayCTS.Cancel();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
|
||||
public static (string Signature, String Id, String Authorization) GetBitpayAuth(this HttpContext ctx)
|
||||
|
98
BTCPayServer/HostedServices/MigratorHostedService.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Logging;
|
||||
|
||||
namespace BTCPayServer.HostedServices
|
||||
{
|
||||
public class MigratorHostedService : BaseAsyncService
|
||||
{
|
||||
private ApplicationDbContextFactory _DBContextFactory;
|
||||
private StoreRepository _StoreRepository;
|
||||
private BTCPayNetworkProvider _NetworkProvider;
|
||||
private SettingsRepository _Settings;
|
||||
public MigratorHostedService(
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
StoreRepository storeRepository,
|
||||
ApplicationDbContextFactory dbContextFactory,
|
||||
SettingsRepository settingsRepository)
|
||||
{
|
||||
_DBContextFactory = dbContextFactory;
|
||||
_StoreRepository = storeRepository;
|
||||
_NetworkProvider = networkProvider;
|
||||
_Settings = settingsRepository;
|
||||
}
|
||||
internal override Task[] InitializeTasks()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
Update()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task Update()
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = (await _Settings.GetSettingAsync<MigrationSettings>()) ?? new MigrationSettings();
|
||||
if (!settings.DeprecatedLightningConnectionStringCheck)
|
||||
{
|
||||
await DeprecatedLightningConnectionStringCheck();
|
||||
settings.DeprecatedLightningConnectionStringCheck = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
if (!settings.UnreachableStoreCheck)
|
||||
{
|
||||
await UnreachableStoreCheck();
|
||||
settings.UnreachableStoreCheck = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logs.PayServer.LogError(ex, "Error on the MigratorHostedService");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UnreachableStoreCheck()
|
||||
{
|
||||
using (var ctx = _DBContextFactory.CreateContext())
|
||||
{
|
||||
if (!ctx.Database.SupportDropForeignKey())
|
||||
return;
|
||||
foreach (var store in await ctx.Stores.Where(s => s.UserStores.Where(u => u.Role == StoreRoles.Owner).Count() == 0).ToArrayAsync())
|
||||
{
|
||||
ctx.Stores.Remove(store);
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeprecatedLightningConnectionStringCheck()
|
||||
{
|
||||
using (var ctx = _DBContextFactory.CreateContext())
|
||||
{
|
||||
foreach (var store in await ctx.Stores.ToArrayAsync())
|
||||
{
|
||||
foreach (var method in store.GetSupportedPaymentMethods(_NetworkProvider).OfType<Payments.Lightning.LightningSupportedPaymentMethod>())
|
||||
{
|
||||
var lightning = method.GetLightningUrl();
|
||||
if (lightning.IsLegacy)
|
||||
{
|
||||
method.SetLightningUrl(lightning);
|
||||
store.SetSupportedPaymentMethod(method.PaymentId, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -106,6 +106,7 @@ namespace BTCPayServer.Hosting
|
||||
services.AddSingleton<CssThemeManager>();
|
||||
services.Configure<MvcOptions>((o) => { o.Filters.Add(new ContentSecurityPolicyCssThemeManager()); });
|
||||
services.AddSingleton<IHostedService, CssThemeManagerHostedService>();
|
||||
services.AddSingleton<IHostedService, MigratorHostedService>();
|
||||
|
||||
services.AddSingleton<Payments.IPaymentMethodHandler<DerivationStrategy>, Payments.Bitcoin.BitcoinLikePaymentHandler>();
|
||||
services.AddSingleton<IHostedService, Payments.Bitcoin.NBXplorerListener>();
|
||||
|
578
BTCPayServer/Migrations/20180719095626_CanDeleteStores.Designer.cs
generated
Normal file
@ -0,0 +1,578 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20180719095626_CanDeleteStores")]
|
||||
partial class CanDeleteStores
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.0-rtm-30799");
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||
{
|
||||
b.Property<string>("Address")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTimeOffset?>("CreatedTime");
|
||||
|
||||
b.Property<string>("InvoiceDataId");
|
||||
|
||||
b.HasKey("Address");
|
||||
|
||||
b.HasIndex("InvoiceDataId");
|
||||
|
||||
b.ToTable("AddressInvoices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50);
|
||||
|
||||
b.Property<string>("StoreId")
|
||||
.HasMaxLength(50);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StoreId");
|
||||
|
||||
b.ToTable("ApiKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AppData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("AppType");
|
||||
|
||||
b.Property<DateTimeOffset>("Created");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Settings");
|
||||
|
||||
b.Property<string>("StoreDataId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StoreDataId");
|
||||
|
||||
b.ToTable("Apps");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
|
||||
{
|
||||
b.Property<string>("InvoiceDataId");
|
||||
|
||||
b.Property<string>("Address");
|
||||
|
||||
b.Property<DateTimeOffset>("Assigned");
|
||||
|
||||
b.Property<string>("CryptoCode");
|
||||
|
||||
b.Property<DateTimeOffset?>("UnAssigned");
|
||||
|
||||
b.HasKey("InvoiceDataId", "Address");
|
||||
|
||||
b.ToTable("HistoricalAddressInvoices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<byte[]>("Blob");
|
||||
|
||||
b.Property<DateTimeOffset>("Created");
|
||||
|
||||
b.Property<string>("CustomerEmail");
|
||||
|
||||
b.Property<string>("ExceptionStatus");
|
||||
|
||||
b.Property<string>("ItemCode");
|
||||
|
||||
b.Property<string>("OrderId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.Property<string>("StoreDataId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StoreDataId");
|
||||
|
||||
b.ToTable("Invoices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceEventData", b =>
|
||||
{
|
||||
b.Property<string>("InvoiceDataId");
|
||||
|
||||
b.Property<string>("UniqueId");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp");
|
||||
|
||||
b.HasKey("InvoiceDataId", "UniqueId");
|
||||
|
||||
b.ToTable("InvoiceEvents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Facade");
|
||||
|
||||
b.Property<string>("Label");
|
||||
|
||||
b.Property<DateTimeOffset>("PairingTime");
|
||||
|
||||
b.Property<string>("SIN");
|
||||
|
||||
b.Property<string>("StoreDataId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SIN");
|
||||
|
||||
b.HasIndex("StoreDataId");
|
||||
|
||||
b.ToTable("PairedSINData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PairingCodeData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("DateCreated");
|
||||
|
||||
b.Property<DateTimeOffset>("Expiration");
|
||||
|
||||
b.Property<string>("Facade");
|
||||
|
||||
b.Property<string>("Label");
|
||||
|
||||
b.Property<string>("SIN");
|
||||
|
||||
b.Property<string>("StoreDataId");
|
||||
|
||||
b.Property<string>("TokenValue");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PairingCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Accounted");
|
||||
|
||||
b.Property<byte[]>("Blob");
|
||||
|
||||
b.Property<string>("InvoiceDataId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InvoiceDataId");
|
||||
|
||||
b.ToTable("Payments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
|
||||
{
|
||||
b.Property<string>("Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PendingInvoices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<byte[]>("Blob");
|
||||
|
||||
b.Property<string>("InvoiceDataId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InvoiceDataId");
|
||||
|
||||
b.ToTable("RefundAddresses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.SettingData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.StoreData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("DefaultCrypto");
|
||||
|
||||
b.Property<string>("DerivationStrategies");
|
||||
|
||||
b.Property<string>("DerivationStrategy");
|
||||
|
||||
b.Property<int>("SpeedPolicy");
|
||||
|
||||
b.Property<byte[]>("StoreBlob");
|
||||
|
||||
b.Property<byte[]>("StoreCertificate");
|
||||
|
||||
b.Property<string>("StoreName");
|
||||
|
||||
b.Property<string>("StoreWebsite");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Stores");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||
{
|
||||
b.Property<string>("ApplicationUserId");
|
||||
|
||||
b.Property<string>("StoreDataId");
|
||||
|
||||
b.Property<string>("Role");
|
||||
|
||||
b.HasKey("ApplicationUserId", "StoreDataId");
|
||||
|
||||
b.HasIndex("StoreDataId");
|
||||
|
||||
b.ToTable("UserStore");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AccessFailedCount");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed");
|
||||
|
||||
b.Property<bool>("LockoutEnabled");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("PhoneNumber");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed");
|
||||
|
||||
b.Property<bool>("RequiresEmailConfirmation");
|
||||
|
||||
b.Property<string>("SecurityStamp");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("ProviderKey");
|
||||
|
||||
b.Property<string>("ProviderDisplayName");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("RoleId");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("AddressInvoices")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("APIKeys")
|
||||
.HasForeignKey("StoreId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AppData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("Apps")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("HistoricalAddressInvoices")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("Invoices")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceEventData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("Events")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("PairedSINs")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("Payments")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("PendingInvoices")
|
||||
.HasForeignKey("Id")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("RefundAddresses")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Models.ApplicationUser", "ApplicationUser")
|
||||
.WithMany("UserStores")
|
||||
.HasForeignKey("ApplicationUserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("UserStores")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
172
BTCPayServer/Migrations/20180719095626_CanDeleteStores.cs
Normal file
@ -0,0 +1,172 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
public partial class CanDeleteStores : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (this.SupportDropForeignKey(migrationBuilder.ActiveProvider))
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AddressInvoices_Invoices_InvoiceDataId",
|
||||
table: "AddressInvoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Apps_Stores_StoreDataId",
|
||||
table: "Apps");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Invoices_Stores_StoreDataId",
|
||||
table: "Invoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Payments_Invoices_InvoiceDataId",
|
||||
table: "Payments");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_RefundAddresses_Invoices_InvoiceDataId",
|
||||
table: "RefundAddresses");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AddressInvoices_Invoices_InvoiceDataId",
|
||||
table: "AddressInvoices",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ApiKeys_Stores_StoreId",
|
||||
table: "ApiKeys",
|
||||
column: "StoreId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Apps_Stores_StoreDataId",
|
||||
table: "Apps",
|
||||
column: "StoreDataId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Invoices_Stores_StoreDataId",
|
||||
table: "Invoices",
|
||||
column: "StoreDataId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PairedSINData_Stores_StoreDataId",
|
||||
table: "PairedSINData",
|
||||
column: "StoreDataId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Payments_Invoices_InvoiceDataId",
|
||||
table: "Payments",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_PendingInvoices_Invoices_Id",
|
||||
table: "PendingInvoices",
|
||||
column: "Id",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_RefundAddresses_Invoices_InvoiceDataId",
|
||||
table: "RefundAddresses",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AddressInvoices_Invoices_InvoiceDataId",
|
||||
table: "AddressInvoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ApiKeys_Stores_StoreId",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Apps_Stores_StoreDataId",
|
||||
table: "Apps");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Invoices_Stores_StoreDataId",
|
||||
table: "Invoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PairedSINData_Stores_StoreDataId",
|
||||
table: "PairedSINData");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Payments_Invoices_InvoiceDataId",
|
||||
table: "Payments");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_PendingInvoices_Invoices_Id",
|
||||
table: "PendingInvoices");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_RefundAddresses_Invoices_InvoiceDataId",
|
||||
table: "RefundAddresses");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AddressInvoices_Invoices_InvoiceDataId",
|
||||
table: "AddressInvoices",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Apps_Stores_StoreDataId",
|
||||
table: "Apps",
|
||||
column: "StoreDataId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Invoices_Stores_StoreDataId",
|
||||
table: "Invoices",
|
||||
column: "StoreDataId",
|
||||
principalTable: "Stores",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Payments_Invoices_InvoiceDataId",
|
||||
table: "Payments",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_RefundAddresses_Invoices_InvoiceDataId",
|
||||
table: "RefundAddresses",
|
||||
column: "InvoiceDataId",
|
||||
principalTable: "Invoices",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BTCPayServer.Migrations
|
||||
{
|
||||
@ -18,7 +14,7 @@ namespace BTCPayServer.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
||||
.HasAnnotation("ProductVersion", "2.1.0-rtm-30799");
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AddressInvoiceData", b =>
|
||||
{
|
||||
@ -202,8 +198,7 @@ namespace BTCPayServer.Migrations
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
b.Property<string>("Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@ -442,19 +437,29 @@ namespace BTCPayServer.Migrations
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("AddressInvoices")
|
||||
.HasForeignKey("InvoiceDataId");
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.APIKeyData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("APIKeys")
|
||||
.HasForeignKey("StoreId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.AppData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("Apps")
|
||||
.HasForeignKey("StoreDataId");
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.HistoricalAddressInvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData")
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("HistoricalAddressInvoices")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
@ -463,30 +468,49 @@ namespace BTCPayServer.Migrations
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany()
|
||||
.HasForeignKey("StoreDataId");
|
||||
.WithMany("Invoices")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.InvoiceEventData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData")
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("Events")
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PairedSINData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.StoreData", "StoreData")
|
||||
.WithMany("PairedSINs")
|
||||
.HasForeignKey("StoreDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PaymentData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("Payments")
|
||||
.HasForeignKey("InvoiceDataId");
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.PendingInvoiceData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("PendingInvoices")
|
||||
.HasForeignKey("Id")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.RefundAddressesData", b =>
|
||||
{
|
||||
b.HasOne("BTCPayServer.Data.InvoiceData", "InvoiceData")
|
||||
.WithMany("RefundAddresses")
|
||||
.HasForeignKey("InvoiceDataId");
|
||||
.HasForeignKey("InvoiceDataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BTCPayServer.Data.UserStore", b =>
|
||||
|
@ -12,6 +12,9 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
public string PaymentMethodId { get; set; }
|
||||
public string CryptoImage { get; set; }
|
||||
public string Link { get; set; }
|
||||
public string PaymentMethodName { get; set; }
|
||||
public bool IsLightning { get; set; }
|
||||
public string CryptoCode { get; set; }
|
||||
}
|
||||
public string HtmlTitle { get; set; }
|
||||
public string CustomCSSLink { get; set; }
|
||||
@ -30,8 +33,7 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
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; }
|
||||
@ -45,12 +47,13 @@ namespace BTCPayServer.Models.InvoicingModels
|
||||
public string StoreEmail { get; set; }
|
||||
|
||||
public string OrderId { get; set; }
|
||||
public string CryptoImage { get; set; }
|
||||
public decimal NetworkFee { get; set; }
|
||||
public bool IsMultiCurrency { get; set; }
|
||||
public int MaxTimeMinutes { get; internal set; }
|
||||
public string PaymentType { get; internal set; }
|
||||
public string PaymentMethodId { get; internal set; }
|
||||
public int MaxTimeMinutes { get; set; }
|
||||
public string PaymentType { get; set; }
|
||||
public string PaymentMethodId { get; set; }
|
||||
public string PaymentMethodName { get; set; }
|
||||
public string CryptoImage { get; set; }
|
||||
|
||||
public bool AllowCoinConversion { get; set; }
|
||||
public string PeerInfo { get; set; }
|
||||
|
@ -25,6 +25,7 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
|
||||
}
|
||||
|
||||
public bool CanDelete { get; set; }
|
||||
public string Id { get; set; }
|
||||
[Display(Name = "Store Name")]
|
||||
[Required]
|
||||
|
@ -207,6 +207,8 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
async Task<InvoiceEntity> UpdatePaymentStates(BTCPayWallet wallet, string invoiceId)
|
||||
{
|
||||
var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId, false);
|
||||
if (invoice == null)
|
||||
return null;
|
||||
List<PaymentEntity> updatedPaymentEntities = new List<PaymentEntity>();
|
||||
var transactions = await wallet.GetTransactions(GetAllBitcoinPaymentData(invoice)
|
||||
.Select(p => p.Outpoint.Hash)
|
||||
@ -315,6 +317,8 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
foreach (var invoiceId in invoices)
|
||||
{
|
||||
var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId, true);
|
||||
if (invoice == null)
|
||||
continue;
|
||||
var alreadyAccounted = GetAllBitcoinPaymentData(invoice).Select(p => p.Outpoint).ToHashSet();
|
||||
var strategy = GetDerivationStrategy(invoice, network);
|
||||
if (strategy == null)
|
||||
@ -332,8 +336,12 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
var payment = await _InvoiceRepository.AddPayment(invoice.Id, coin.Timestamp, paymentData, network.CryptoCode).ConfigureAwait(false);
|
||||
alreadyAccounted.Add(coin.Coin.Outpoint);
|
||||
if (payment != null)
|
||||
{
|
||||
invoice = await ReceivedPayment(wallet, invoice, payment, strategy);
|
||||
totalPayment++;
|
||||
if(invoice == null)
|
||||
continue;
|
||||
totalPayment++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalPayment;
|
||||
@ -350,6 +358,8 @@ namespace BTCPayServer.Payments.Bitcoin
|
||||
{
|
||||
var paymentData = (BitcoinLikePaymentData)payment.GetCryptoPaymentData();
|
||||
invoice = (await UpdatePaymentStates(wallet, invoice.Id));
|
||||
if (invoice == null)
|
||||
return null;
|
||||
var paymentMethod = invoice.GetPaymentMethod(wallet.Network, PaymentTypes.BTCLike, _ExplorerClients.NetworkProviders);
|
||||
if (paymentMethod != null &&
|
||||
paymentMethod.GetPaymentMethodDetails() is BitcoinLikeOnChainPaymentMethod btc &&
|
||||
|
@ -39,36 +39,51 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
_Parent = parent;
|
||||
}
|
||||
|
||||
public async Task StartListening()
|
||||
public Task StartListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
_Client = _Parent.CreateHttpClient();
|
||||
_Client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, _Parent.BaseUrl.WithTrailingSlash() + "v1/invoices/subscribe");
|
||||
_Response = await _Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _Cts.Token);
|
||||
_Body = await _Response.Content.ReadAsStreamAsync();
|
||||
_Reader = new StreamReader(_Body);
|
||||
_ListenLoop = ListenLoop();
|
||||
_Parent._Authentication.AddAuthentication(request);
|
||||
_ListenLoop = ListenLoop(request);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task ListenLoop()
|
||||
private async Task ListenLoop(HttpRequestMessage request)
|
||||
{
|
||||
try
|
||||
{
|
||||
_Response = await _Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _Cts.Token);
|
||||
_Body = await _Response.Content.ReadAsStreamAsync();
|
||||
_Reader = new StreamReader(_Body);
|
||||
while (!_Cts.IsCancellationRequested)
|
||||
{
|
||||
string line = await _Reader.ReadLineAsync().WithCancellation(_Cts.Token);
|
||||
if (line != null && line.StartsWith("{\"result\":", StringComparison.OrdinalIgnoreCase))
|
||||
if (line != null)
|
||||
{
|
||||
var invoiceString = JObject.Parse(line)["result"].ToString();
|
||||
LnrpcInvoice parsedInvoice = _Parent.Deserialize<LnrpcInvoice>(invoiceString);
|
||||
await _Invoices.Writer.WriteAsync(ConvertLndInvoice(parsedInvoice), _Cts.Token);
|
||||
if (line.StartsWith("{\"result\":", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var invoiceString = JObject.Parse(line)["result"].ToString();
|
||||
LnrpcInvoice parsedInvoice = _Parent.Deserialize<LnrpcInvoice>(invoiceString);
|
||||
await _Invoices.Writer.WriteAsync(ConvertLndInvoice(parsedInvoice), _Cts.Token);
|
||||
}
|
||||
else if (line.StartsWith("{\"error\":", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var errorString = JObject.Parse(line)["error"].ToString();
|
||||
var error = _Parent.Deserialize<LndError>(errorString);
|
||||
throw new LndException(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LndException("Unknown result from LND: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,7 +91,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
_Invoices.Writer.TryComplete(ex);
|
||||
}
|
||||
@ -95,7 +110,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
throw new TaskCanceledException();
|
||||
}
|
||||
catch(ChannelClosedException ex)
|
||||
catch (ChannelClosedException ex)
|
||||
{
|
||||
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
|
||||
throw;
|
||||
@ -119,7 +134,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
_Response = null;
|
||||
_Client?.Dispose();
|
||||
_Client = null;
|
||||
if(waitLoop)
|
||||
if (waitLoop)
|
||||
_ListenLoop?.Wait();
|
||||
_Invoices.Writer.TryComplete();
|
||||
}
|
||||
|
@ -16,6 +16,41 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public class LndException : Exception
|
||||
{
|
||||
public LndException(string message) : base(message)
|
||||
{
|
||||
|
||||
}
|
||||
public LndException(LndError error) : base(error.Message)
|
||||
{
|
||||
if (error == null)
|
||||
throw new ArgumentNullException(nameof(error));
|
||||
_Error = error;
|
||||
}
|
||||
|
||||
|
||||
private readonly LndError _Error;
|
||||
public LndError Error
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
// {"grpc_code":2,"http_code":500,"message":"rpc error: code = Unknown desc = expected 1 macaroon, got 0","http_status":"Internal Server Error"}
|
||||
public class LndError
|
||||
{
|
||||
[JsonProperty("grpc_code")]
|
||||
public int GRPCCode { get; set; }
|
||||
[JsonProperty("http_code")]
|
||||
public int HttpCode { get; set; }
|
||||
[JsonProperty("message")]
|
||||
public string Message { get; set; }
|
||||
[JsonProperty("http_status")]
|
||||
public string HttpStatus { get; set; }
|
||||
}
|
||||
public partial class LndSwaggerClient
|
||||
{
|
||||
public LndSwaggerClient(LndRestSettings settings)
|
||||
@ -34,7 +69,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
});
|
||||
}
|
||||
LndRestSettings _LndSettings;
|
||||
LndAuthentication _Authentication;
|
||||
internal LndAuthentication _Authentication;
|
||||
|
||||
partial void PrepareRequest(HttpClient client, HttpRequestMessage request, string url)
|
||||
{
|
||||
|
13
BTCPayServer/Services/MigrationSettings.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Services
|
||||
{
|
||||
public class MigrationSettings
|
||||
{
|
||||
public bool UnreachableStoreCheck { get; set; }
|
||||
public bool DeprecatedLightningConnectionStringCheck { get; set; }
|
||||
}
|
||||
}
|
@ -120,6 +120,27 @@ namespace BTCPayServer.Services.Stores
|
||||
ctx.UserStore.Add(userStore);
|
||||
ctx.Entry<UserStore>(userStore).State = EntityState.Deleted;
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
}
|
||||
await DeleteStoreIfOrphan(storeId);
|
||||
}
|
||||
|
||||
private async Task DeleteStoreIfOrphan(string storeId)
|
||||
{
|
||||
using (var ctx = _ContextFactory.CreateContext())
|
||||
{
|
||||
if (ctx.Database.SupportDropForeignKey())
|
||||
{
|
||||
if (await ctx.UserStore.Where(u => u.StoreDataId == storeId && u.Role == StoreRoles.Owner).CountAsync() == 0)
|
||||
{
|
||||
var store = await ctx.Stores.FindAsync(storeId);
|
||||
if (store != null)
|
||||
{
|
||||
ctx.Stores.Remove(store);
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +179,7 @@ namespace BTCPayServer.Services.Stores
|
||||
ctx.UserStore.Remove(storeUser);
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
await DeleteStoreIfOrphan(storeId);
|
||||
}
|
||||
|
||||
public async Task UpdateStore(StoreData store)
|
||||
@ -169,5 +191,28 @@ namespace BTCPayServer.Services.Stores
|
||||
await ctx.SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteStore(string storeId)
|
||||
{
|
||||
using (var ctx = _ContextFactory.CreateContext())
|
||||
{
|
||||
if (!ctx.Database.SupportDropForeignKey())
|
||||
return false;
|
||||
var store = await ctx.Stores.FindAsync(storeId);
|
||||
if (store == null)
|
||||
return false;
|
||||
ctx.Stores.Remove(store);
|
||||
await ctx.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanDeleteStores()
|
||||
{
|
||||
using (var ctx = _ContextFactory.CreateContext())
|
||||
{
|
||||
return ctx.Database.SupportDropForeignKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,14 +42,30 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-item-order__right">
|
||||
<div class="payment__currencies">
|
||||
@foreach (var crypto in Model.AvailableCryptos)
|
||||
{
|
||||
<a href="@crypto.Link" onclick="return changeCurrency('@crypto.PaymentMethodId');">
|
||||
<img style="height:32px; margin-left:5px;" alt="@crypto.PaymentMethodId" src="@crypto.CryptoImage" />
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
@if (Model.AvailableCryptos.Count > 1)
|
||||
{
|
||||
<div class="payment__currencies" onclick="openPaymentMethodDialog()">
|
||||
<img v-bind:src="srvModel.cryptoImage" />
|
||||
<span class="clickable_underline">{{srvModel.paymentMethodName}} ({{srvModel.cryptoCode}})</span>
|
||||
<span v-show="srvModel.isLightning">⚡</span>
|
||||
<span class="clickable_indicator fa fa-angle-right"></span>
|
||||
</div>
|
||||
<div id="vexPopupDialog">
|
||||
<ul class="vexmenu">
|
||||
@foreach (var crypto in Model.AvailableCryptos)
|
||||
{
|
||||
<li class="vexmenuitem">
|
||||
<a href="@crypto.Link" onclick="return closePaymentMethodDialog('@crypto.PaymentMethodId');">
|
||||
<img alt="@crypto.PaymentMethodName" src="@crypto.CryptoImage" />
|
||||
@crypto.PaymentMethodName
|
||||
@(crypto.IsLightning ? Html.Raw("⚡") : null)
|
||||
<span>@crypto.CryptoCode</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
<div class="payment__spinner">
|
||||
<partial name="Checkout-Spinner" />
|
||||
</div>
|
||||
|
@ -20,12 +20,15 @@
|
||||
</script>
|
||||
|
||||
<bundle name="wwwroot/bundles/checkout-bundle.min.js" />
|
||||
<script>vex.defaultOptions.className = 'vex-theme-btcpay'</script>
|
||||
|
||||
|
||||
@if(Model.CustomCSSLink != null)
|
||||
@if (Model.CustomCSSLink != null)
|
||||
{
|
||||
<link href="@Model.CustomCSSLink" rel="stylesheet" />
|
||||
}
|
||||
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
<body style="background: #E4E4E4">
|
||||
<noscript>
|
||||
@ -82,7 +85,7 @@
|
||||
|
||||
$('select').prettyDropdown({
|
||||
classic: false,
|
||||
height: 30,
|
||||
height: 32,
|
||||
reverse: true,
|
||||
hoverIntent: 5000
|
||||
});
|
||||
|
@ -130,6 +130,16 @@
|
||||
Available placeholders are: {StoreName}, {ItemDescription} and {OrderId}
|
||||
</p>
|
||||
</div>
|
||||
@if(Model.CanDelete)
|
||||
{
|
||||
<div class="form-group">
|
||||
<h5>Other actions...</h5>
|
||||
<p><a href="#danger-zone" data-toggle="collapse"><b>Click here to see more actions</b></a></p>
|
||||
<div id="danger-zone" class="collapse">
|
||||
<a class="btn btn-outline-danger form-control" asp-action="DeleteStore" asp-route-storeId="@Model.Id">Delete this store</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<button name="command" type="submit" class="btn btn-primary" value="Save">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -33,6 +33,7 @@
|
||||
"outputFileName": "wwwroot/bundles/checkout-bundle.min.css",
|
||||
"inputFiles": [
|
||||
"wwwroot/vendor/font-awesome/css/font-awesome.css",
|
||||
"wwwroot/vendor/vex/css/vex.css",
|
||||
"wwwroot/checkout/**/*.css",
|
||||
"wwwroot/vendor/jquery-prettydropdowns/prettydropdowns.css"
|
||||
]
|
||||
@ -47,6 +48,7 @@
|
||||
"wwwroot/vendor/i18next/i18next.js",
|
||||
"wwwroot/vendor/i18next/vue-i18next.js",
|
||||
"wwwroot/vendor/jquery-prettydropdowns/jquery.prettydropdowns.js",
|
||||
"wwwroot/vendor/vex/js/vex.combined.min.js",
|
||||
"wwwroot/checkout/**/*.js"
|
||||
]
|
||||
}
|
||||
|
@ -8289,7 +8289,7 @@ strong {
|
||||
.modal.page {
|
||||
overflow-y: hidden;
|
||||
position: relative;
|
||||
z-index: 105111;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.content {
|
||||
@ -8420,6 +8420,7 @@ strong {
|
||||
color: #565D6E;
|
||||
letter-spacing: .45px;
|
||||
background: #fff;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.single-item-order {
|
||||
@ -10156,6 +10157,8 @@ All mobile class names should be prefixed by m- */
|
||||
.manual-flow {
|
||||
opacity: 0;
|
||||
margin-top: -15px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
transition: all .3s ease-out;
|
||||
}
|
||||
|
||||
@ -11286,7 +11289,7 @@ low-fee-timeline {
|
||||
}
|
||||
|
||||
.copySectionBox {
|
||||
padding: 12px;
|
||||
padding: 12px 10px;
|
||||
}
|
||||
|
||||
.copySectionBox label {
|
||||
@ -11323,17 +11326,18 @@ low-fee-timeline {
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
padding: 8px 10px;
|
||||
padding: 8px 4px 8px;
|
||||
background: #f6f6f6;
|
||||
box-sizing: border-box;
|
||||
transition: .3s;
|
||||
font-size: 11px;
|
||||
color: #4a4a4a;
|
||||
cursor: copy;
|
||||
text-overflow: ellipsis
|
||||
}
|
||||
|
||||
.inputWithIcon .checkoutTextbox {
|
||||
padding-left: 40px;
|
||||
padding-left: 31px;
|
||||
}
|
||||
|
||||
.inputWithIcon {
|
||||
@ -11343,10 +11347,10 @@ low-fee-timeline {
|
||||
.inputWithIcon img {
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 8px;
|
||||
top: 9px;
|
||||
color: #aaa;
|
||||
height: 16px;
|
||||
padding: 0px 6px;
|
||||
padding: 0px 4px;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
}
|
||||
|
||||
|
67
BTCPayServer/wwwroot/checkout/css/vex-extrastyles.css
Normal file
@ -0,0 +1,67 @@
|
||||
.vexmenu {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.vexmenuitem {
|
||||
display: block;
|
||||
float: none;
|
||||
line-height: inherit;
|
||||
position: relative;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.vexmenuitem a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.vexmenuitem a span {
|
||||
float: right;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.vexmenuitem a img {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.vexmenuitem:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.vexmenuitem:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#vexPopupDialog {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.payment__currencies {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.payment__currencies img {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.clickable_underline {
|
||||
border-bottom: 1px dotted #ccc;
|
||||
}
|
||||
|
||||
.payment__currencies:hover .clickable_underline {
|
||||
border-bottom: 1px dotted black;
|
||||
}
|
||||
|
||||
.clickable_indicator {
|
||||
margin-right: -10px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.payment__currencies:hover .clickable_indicator {
|
||||
opacity: 1;
|
||||
}
|
204
BTCPayServer/wwwroot/checkout/css/vex-theme-btcpay.css
Normal file
@ -0,0 +1,204 @@
|
||||
@-webkit-keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent;
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent;
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay {
|
||||
padding-top: 160px;
|
||||
padding-bottom: 160px;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay.vex-closing .vex-content {
|
||||
-webkit-animation: vex-flyout .5s forwards;
|
||||
animation: vex-flyout .5s forwards;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-content {
|
||||
-webkit-animation: vex-flyin .5s;
|
||||
animation: vex-flyin .5s;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-content {
|
||||
border-radius: 5px;
|
||||
background: #ffffff;
|
||||
color: #444;
|
||||
padding: 5px;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 300px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-content h1, .vex.vex-theme-btcpay .vex-content h2, .vex.vex-theme-btcpay .vex-content h3, .vex.vex-theme-btcpay .vex-content h4, .vex.vex-theme-btcpay .vex-content h5, .vex.vex-theme-btcpay .vex-content h6, .vex.vex-theme-btcpay .vex-content p, .vex.vex-theme-btcpay .vex-content ul, .vex.vex-theme-btcpay .vex-content li {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #8dbdf1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-button {
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-button.vex-last {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-btcpay .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.vex.vex-theme-btcpay .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.vex-loading-spinner.vex-theme-btcpay {
|
||||
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
background: #f0f0f0;
|
||||
border: .2em solid transparent;
|
||||
border-top-color: #bbb;
|
||||
top: -1.1em;
|
||||
bottom: auto;
|
||||
}
|
@ -16,6 +16,8 @@ function resetTabsSlider() {
|
||||
|
||||
$("#altcoins").hide();
|
||||
$("#altcoins").removeClass("active");
|
||||
|
||||
closePaymentMethodDialog(null);
|
||||
}
|
||||
|
||||
function onDataCallback(jsonData) {
|
||||
@ -69,7 +71,7 @@ function onDataCallback(jsonData) {
|
||||
}
|
||||
|
||||
function changeCurrency(currency) {
|
||||
if (srvModel.paymentMethodId !== currency) {
|
||||
if (currency !== null && srvModel.paymentMethodId !== currency) {
|
||||
$(".payment__currencies").hide();
|
||||
$(".payment__spinner").show();
|
||||
srvModel.paymentMethodId = currency;
|
||||
|
11
BTCPayServer/wwwroot/checkout/js/vexdialog.js
Normal file
@ -0,0 +1,11 @@
|
||||
function openPaymentMethodDialog() {
|
||||
var content = $("#vexPopupDialog").html();
|
||||
vex.open({
|
||||
unsafeContent: content
|
||||
});
|
||||
}
|
||||
|
||||
function closePaymentMethodDialog(currencyId) {
|
||||
vex.closeAll();
|
||||
return changeCurrency(currencyId);
|
||||
}
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
11
BTCPayServer/wwwroot/imlegacy/bitcoin.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="64" width="64" version="1.1"
|
||||
x="0px" y="0px"
|
||||
viewBox="0 0 64 64"
|
||||
xml:space="preserve"
|
||||
xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<g transform="translate(0.00630876,-0.00301984)">
|
||||
<path fill="#f7931a" d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"/>
|
||||
<path fill="#FFF" d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
50
BTCPayServer/wwwroot/imlegacy/btg-lightning.svg
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 600 600" style="enable-background:new 0 0 600 600;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M300,45C159.2,45,45,159.2,45,300s114.2,255,255,255s255-114.2,255-255S440.8,45,300,45z M300,496.3
|
||||
c-108.4,0-196.3-87.9-196.3-196.3S191.6,103.7,300,103.7S496.3,191.6,496.3,300S408.4,496.3,300,496.3z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path id="XMLID_145_" d="M215,387.2l9.8-19.6h117.7c16.2,0,29.4-13.2,29.4-29.4v0c0-16.2-13.2-29.4-29.4-29.4h-98.1v-19.6h98.1
|
||||
c27.1,0,49,22,49,49v0c0,27.1-22,49-49,49H215z"/>
|
||||
<path d="M342.5,392.6H206.2l15.3-30.5h121.1c13.2,0,24-10.8,24-24c0-13.2-10.8-24-24-24H239v-30.5h103.5
|
||||
c30,0,54.5,24.4,54.5,54.5C397,368.2,372.5,392.6,342.5,392.6z M223.8,381.7h118.7c24,0,43.6-19.6,43.6-43.6
|
||||
c0-24-19.6-43.6-43.6-43.6h-92.6v8.7h92.6c19.2,0,34.9,15.6,34.9,34.9c0,19.2-15.6,34.9-34.9,34.9H228.2L223.8,381.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path id="XMLID_144_" d="M215,209.6l9.8,19.6h104.6c16.2,0,29.4,13.2,29.4,29.4v0c0,16.2-13.2,29.4-29.4,29.4h-75.2v19.6h75.2
|
||||
c27.1,0,49-22,49-49v0c0-27.1-22-49-49-49H215z"/>
|
||||
<path d="M329.4,313.1h-80.6v-30.5h80.6c13.2,0,24-10.8,24-24c0-13.2-10.8-24-24-24h-108l-15.3-30.5h123.2
|
||||
c30,0,54.5,24.4,54.5,54.5C383.9,288.6,359.5,313.1,329.4,313.1z M259.7,302.2h69.7c24,0,43.6-19.6,43.6-43.6
|
||||
S353.5,215,329.4,215H223.8l4.4,8.7h101.2c19.2,0,34.9,15.6,34.9,34.9s-15.6,34.9-34.9,34.9h-69.7V302.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect id="XMLID_143_" x="244.4" y="210.6" width="19.6" height="176.5"/>
|
||||
<path d="M269.5,392.6H239V205.2h30.5V392.6z M249.9,381.7h8.7V216.1h-8.7V381.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect id="XMLID_142_" x="268.4" y="180.1" width="19.6" height="39.2"/>
|
||||
<path d="M290.7,222.1h-25.1v-44.7h25.1V222.1z M271.1,216.6h14.2v-33.8h-14.2V216.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect id="XMLID_141_" x="310.9" y="180.1" width="19.6" height="39.2"/>
|
||||
<path d="M333.2,222.1h-25.1v-44.7h25.1V222.1z M313.6,216.6h14.2v-33.8h-14.2V216.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect id="XMLID_140_" x="268.4" y="376.3" width="19.6" height="39.2"/>
|
||||
<path d="M290.7,418.2h-25.1v-44.7h25.1V418.2z M271.1,412.8h14.2V379h-14.2V412.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect id="XMLID_139_" x="310.9" y="376.3" width="19.6" height="39.2"/>
|
||||
<path d="M333.2,418.2h-25.1v-44.7h25.1V418.2z M313.6,412.8h14.2V379h-14.2V412.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M300,473.8c-95.8,0-173.8-77.9-173.8-173.8c0-95.8,77.9-173.8,173.8-173.8c95.8,0,173.8,77.9,173.8,173.8
|
||||
C473.8,395.8,395.8,473.8,300,473.8z M300,143.6c-86.2,0-156.4,70.2-156.4,156.4S213.8,456.4,300,456.4S456.4,386.2,456.4,300
|
||||
S386.2,143.6,300,143.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 747 B After Width: | Height: | Size: 747 B |
1
BTCPayServer/wwwroot/imlegacy/litecoin.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0.847 0.876 329.254 329.256"><title>Litecoin</title><path d="M330.102 165.503c0 90.922-73.705 164.629-164.626 164.629C74.554 330.132.848 256.425.848 165.503.848 74.582 74.554.876 165.476.876c90.92 0 164.626 73.706 164.626 164.627" fill="#bebebe"/><path d="M295.15 165.505c0 71.613-58.057 129.675-129.674 129.675-71.616 0-129.677-58.062-129.677-129.675 0-71.619 58.061-129.677 129.677-129.677 71.618 0 129.674 58.057 129.674 129.677" fill="#bebebe"/><path d="M155.854 209.482l10.693-40.264 25.316-9.249 6.297-23.663-.215-.587-24.92 9.104 17.955-67.608h-50.921l-23.481 88.23-19.605 7.162-6.478 24.395 19.59-7.156-13.839 51.998h135.521l8.688-32.362h-84.601" fill="#fff"/></svg>
|
After Width: | Height: | Size: 747 B |
183
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-bottom-right-corner.css
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
@-webkit-keyframes vex-slideup {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 0; }
|
||||
1% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px);
|
||||
opacity: 0; }
|
||||
2% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px);
|
||||
opacity: 1; }
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes vex-slideup {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 0; }
|
||||
1% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px);
|
||||
opacity: 0; }
|
||||
2% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px);
|
||||
opacity: 1; }
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@-webkit-keyframes vex-slidedown {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px); } }
|
||||
|
||||
@keyframes vex-slidedown {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
-webkit-transform: translateY(800px);
|
||||
transform: translateY(800px); } }
|
||||
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-bottom-right-corner {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
overflow: visible; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-overlay {
|
||||
display: none; }
|
||||
.vex.vex-theme-bottom-right-corner.vex-closing .vex-content {
|
||||
-webkit-animation: vex-slidedown .5s forwards;
|
||||
animation: vex-slidedown .5s forwards; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-content {
|
||||
-webkit-animation: vex-slideup .5s;
|
||||
animation: vex-slideup .5s; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-content {
|
||||
border-radius: 5px 0 0 0;
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
background: #f0f0f0;
|
||||
color: #444;
|
||||
padding: 1em;
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: auto; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-content h1, .vex.vex-theme-bottom-right-corner .vex-content h2, .vex.vex-theme-bottom-right-corner .vex-content h3, .vex.vex-theme-bottom-right-corner .vex-content h4, .vex.vex-theme-bottom-right-corner .vex-content h5, .vex.vex-theme-bottom-right-corner .vex-content h6, .vex.vex-theme-bottom-right-corner .vex-content p, .vex.vex-theme-bottom-right-corner .vex-content ul, .vex.vex-theme-bottom-right-corner .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-close {
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-close:before {
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 26px;
|
||||
font-weight: normal;
|
||||
line-height: 31px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #bbb;
|
||||
background: transparent; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-close:hover:before, .vex.vex-theme-bottom-right-corner .vex-close:active:before {
|
||||
color: #777;
|
||||
background: #e0e0e0; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #8dbdf1;
|
||||
outline: none; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button {
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-bottom-right-corner {
|
||||
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
background: #f0f0f0;
|
||||
border: .2em solid transparent;
|
||||
border-top-color: #bbb;
|
||||
top: -1.1em;
|
||||
bottom: auto; }
|
||||
|
||||
body.vex-open {
|
||||
overflow: initial; }
|
162
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-default.css
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
@-webkit-keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); } }
|
||||
|
||||
@keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); } }
|
||||
|
||||
@-webkit-keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
|
||||
@keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-default {
|
||||
padding-top: 160px;
|
||||
padding-bottom: 160px; }
|
||||
.vex.vex-theme-default.vex-closing .vex-content {
|
||||
-webkit-animation: vex-flyout .5s forwards;
|
||||
animation: vex-flyout .5s forwards; }
|
||||
.vex.vex-theme-default .vex-content {
|
||||
-webkit-animation: vex-flyin .5s;
|
||||
animation: vex-flyin .5s; }
|
||||
.vex.vex-theme-default .vex-content {
|
||||
border-radius: 5px;
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
background: #f0f0f0;
|
||||
color: #444;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em; }
|
||||
.vex.vex-theme-default .vex-content h1, .vex.vex-theme-default .vex-content h2, .vex.vex-theme-default .vex-content h3, .vex.vex-theme-default .vex-content h4, .vex.vex-theme-default .vex-content h5, .vex.vex-theme-default .vex-content h6, .vex.vex-theme-default .vex-content p, .vex.vex-theme-default .vex-content ul, .vex.vex-theme-default .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-default .vex-close {
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-default .vex-close:before {
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 26px;
|
||||
font-weight: normal;
|
||||
line-height: 31px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #bbb;
|
||||
background: transparent; }
|
||||
.vex.vex-theme-default .vex-close:hover:before, .vex.vex-theme-default .vex-close:active:before {
|
||||
color: #777;
|
||||
background: #e0e0e0; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #8dbdf1;
|
||||
outline: none; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-default .vex-dialog-button {
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-default .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-default .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-default .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-default .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-default .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-default {
|
||||
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
background: #f0f0f0;
|
||||
border: .2em solid transparent;
|
||||
border-top-color: #bbb;
|
||||
top: -1.1em;
|
||||
bottom: auto; }
|
176
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-flat-attack.css
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
@-webkit-keyframes vex-flipin-horizontal {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: rotateY(-90deg);
|
||||
transform: rotateY(-90deg); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: rotateY(0deg);
|
||||
transform: rotateY(0deg); } }
|
||||
|
||||
@keyframes vex-flipin-horizontal {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: rotateY(-90deg);
|
||||
transform: rotateY(-90deg); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: rotateY(0deg);
|
||||
transform: rotateY(0deg); } }
|
||||
|
||||
@-webkit-keyframes vex-flipout-horizontal {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: rotateY(0deg);
|
||||
transform: rotateY(0deg); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: rotateY(90deg);
|
||||
transform: rotateY(90deg); } }
|
||||
|
||||
@keyframes vex-flipout-horizontal {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: rotateY(0deg);
|
||||
transform: rotateY(0deg); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: rotateY(90deg);
|
||||
transform: rotateY(90deg); } }
|
||||
|
||||
.vex.vex-theme-flat-attack {
|
||||
-webkit-perspective: 1300px;
|
||||
perspective: 1300px;
|
||||
-webkit-perspective-origin: 50% 150px;
|
||||
perspective-origin: 50% 150px;
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
font-size: 1.5em; }
|
||||
.vex.vex-theme-flat-attack.vex-closing .vex-content {
|
||||
-webkit-animation: vex-flipout-horizontal .5s forwards;
|
||||
animation: vex-flipout-horizontal .5s forwards; }
|
||||
.vex.vex-theme-flat-attack .vex-content {
|
||||
-webkit-transform-style: preserve-3d;
|
||||
transform-style: preserve-3d;
|
||||
-webkit-animation: vex-flipin-horizontal .5s;
|
||||
animation: vex-flipin-horizontal .5s; }
|
||||
.vex.vex-theme-flat-attack .vex-content {
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
font-weight: 200;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
padding: 2em 2em 3em 2em;
|
||||
line-height: 1.5em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 600px; }
|
||||
.vex.vex-theme-flat-attack .vex-content h1, .vex.vex-theme-flat-attack .vex-content h2, .vex.vex-theme-flat-attack .vex-content h3, .vex.vex-theme-flat-attack .vex-content h4, .vex.vex-theme-flat-attack .vex-content h5, .vex.vex-theme-flat-attack .vex-content h6, .vex.vex-theme-flat-attack .vex-content p, .vex.vex-theme-flat-attack .vex-content ul, .vex.vex-theme-flat-attack .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-flat-attack .vex-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-flat-attack .vex-close:before {
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
font-weight: 100;
|
||||
line-height: 1px;
|
||||
padding-top: .5em;
|
||||
display: block;
|
||||
font-size: 2em;
|
||||
text-indent: 1px;
|
||||
overflow: hidden;
|
||||
height: 1.25em;
|
||||
width: 1.25em;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #fff;
|
||||
background: #666; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #f0f0f0;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #666;
|
||||
outline: none; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1;
|
||||
padding-top: 1em;
|
||||
margin-bottom: -3em;
|
||||
margin-left: -2em;
|
||||
margin-right: -2em; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
float: right;
|
||||
padding: .5em 1em;
|
||||
font-size: 1.13em;
|
||||
text-transform: uppercase;
|
||||
font-weight: 200;
|
||||
letter-spacing: .1em;
|
||||
line-height: 1em;
|
||||
font-family: inherit; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button:focus {
|
||||
outline: none; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #666;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-primary:focus {
|
||||
box-shadow: inset 0 3px rgba(0, 0, 0, 0.2); }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #fff;
|
||||
color: #ccc; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:focus {
|
||||
box-shadow: inset 0 3px #aaa;
|
||||
background: #eee;
|
||||
color: #777; }
|
||||
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:hover, .vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:active {
|
||||
color: #777; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-close:before {
|
||||
background: #ff7ea7; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #ff7ea7; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #ff7ea7; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-close:before {
|
||||
background: #ce4a55; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #ce4a55; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #ce4a55; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-close:before {
|
||||
background: #34b989; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #34b989; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #34b989; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-close:before {
|
||||
background: #477FA5; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #477FA5; }
|
||||
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #477FA5; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-flat-attack {
|
||||
height: 4em;
|
||||
width: 4em; }
|
165
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-os.css
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
@-webkit-keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); } }
|
||||
|
||||
@keyframes vex-flyin {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); }
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); } }
|
||||
|
||||
@-webkit-keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
|
||||
@keyframes vex-flyout {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-40px);
|
||||
transform: translateY(-40px); } }
|
||||
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-os {
|
||||
padding-top: 160px;
|
||||
padding-bottom: 160px; }
|
||||
.vex.vex-theme-os.vex-closing .vex-content {
|
||||
-webkit-animation: vex-flyout .5s forwards;
|
||||
animation: vex-flyout .5s forwards; }
|
||||
.vex.vex-theme-os .vex-content {
|
||||
-webkit-animation: vex-flyin .5s;
|
||||
animation: vex-flyin .5s; }
|
||||
.vex.vex-theme-os .vex-content {
|
||||
border-radius: 5px;
|
||||
box-shadow: inset 0 1px #a6a6a6, 0 0 0 1px rgba(0, 0, 0, 0.08);
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
border-top: 20px solid #bbb;
|
||||
background: #f0f0f0;
|
||||
color: #444;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em; }
|
||||
.vex.vex-theme-os .vex-content h1, .vex.vex-theme-os .vex-content h2, .vex.vex-theme-os .vex-content h3, .vex.vex-theme-os .vex-content h4, .vex.vex-theme-os .vex-content h5, .vex.vex-theme-os .vex-content h6, .vex.vex-theme-os .vex-content p, .vex.vex-theme-os .vex-content ul, .vex.vex-theme-os .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-os .vex-close {
|
||||
border-radius: 0 5px 0 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-os .vex-close:before {
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 26px;
|
||||
font-weight: normal;
|
||||
line-height: 31px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #bbb;
|
||||
background: transparent; }
|
||||
.vex.vex-theme-os .vex-close:hover:before, .vex.vex-theme-os .vex-close:active:before {
|
||||
color: #777;
|
||||
background: #e0e0e0; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 1px #3288e6;
|
||||
outline: none; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-os .vex-dialog-button {
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-os .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-os .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-os .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-os {
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0.5em rgba(0, 0, 0, 0.2);
|
||||
border-radius: 100%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 1.2em solid #bbb;
|
||||
border-top-color: #f0f0f0;
|
||||
border-bottom-color: #f0f0f0; }
|
107
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-plain.css
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-plain {
|
||||
padding-top: 160px;
|
||||
padding-bottom: 160px; }
|
||||
.vex.vex-theme-plain .vex-content {
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em; }
|
||||
.vex.vex-theme-plain .vex-content h1, .vex.vex-theme-plain .vex-content h2, .vex.vex-theme-plain .vex-content h3, .vex.vex-theme-plain .vex-content h4, .vex.vex-theme-plain .vex-content h5, .vex.vex-theme-plain .vex-content h6, .vex.vex-theme-plain .vex-content p, .vex.vex-theme-plain .vex-content ul, .vex.vex-theme-plain .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-plain .vex-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-plain .vex-close:before {
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 26px;
|
||||
font-weight: normal;
|
||||
line-height: 31px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #bbb;
|
||||
background: transparent; }
|
||||
.vex.vex-theme-plain .vex-close:hover:before, .vex.vex-theme-plain .vex-close:active:before {
|
||||
color: #777;
|
||||
background: #e0e0e0; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
background: #f0f0f0;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
|
||||
outline: none; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-plain .vex-dialog-button {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-plain .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-plain .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-plain .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-plain {
|
||||
height: 2.5em;
|
||||
width: 2.5em; }
|
178
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-top.css
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
@-webkit-keyframes vex-dropin {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 0; }
|
||||
1% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px);
|
||||
opacity: 0; }
|
||||
2% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px);
|
||||
opacity: 1; }
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes vex-dropin {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 0; }
|
||||
1% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px);
|
||||
opacity: 0; }
|
||||
2% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px);
|
||||
opacity: 1; }
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@-webkit-keyframes vex-dropout {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px); } }
|
||||
|
||||
@keyframes vex-dropout {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
-webkit-transform: translateY(-800px);
|
||||
transform: translateY(-800px); } }
|
||||
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-top.vex-closing .vex-content {
|
||||
-webkit-animation: vex-dropout .5s forwards;
|
||||
animation: vex-dropout .5s forwards; }
|
||||
|
||||
.vex.vex-theme-top .vex-content {
|
||||
-webkit-animation: vex-dropin .5s;
|
||||
animation: vex-dropin .5s; }
|
||||
|
||||
.vex.vex-theme-top .vex-content {
|
||||
border-radius: 0 0 5px 5px;
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
background: #f0f0f0;
|
||||
color: #444;
|
||||
padding: 1em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em; }
|
||||
.vex.vex-theme-top .vex-content h1, .vex.vex-theme-top .vex-content h2, .vex.vex-theme-top .vex-content h3, .vex.vex-theme-top .vex-content h4, .vex.vex-theme-top .vex-content h5, .vex.vex-theme-top .vex-content h6, .vex.vex-theme-top .vex-content p, .vex.vex-theme-top .vex-content ul, .vex.vex-theme-top .vex-content li {
|
||||
color: inherit; }
|
||||
|
||||
.vex.vex-theme-top .vex-close {
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-top .vex-close:before {
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 26px;
|
||||
font-weight: normal;
|
||||
line-height: 31px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #bbb;
|
||||
background: transparent; }
|
||||
.vex.vex-theme-top .vex-close:hover:before, .vex.vex-theme-top .vex-close:active:before {
|
||||
color: #777;
|
||||
background: #e0e0e0; }
|
||||
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
border: 0;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em; }
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
box-shadow: inset 0 0 0 2px #8dbdf1;
|
||||
outline: none; }
|
||||
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
|
||||
.vex.vex-theme-top .vex-dialog-button {
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-top .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-top .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-top .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-top .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #3288e6;
|
||||
color: #fff; }
|
||||
.vex.vex-theme-top .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #e0e0e0;
|
||||
color: #777; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-top {
|
||||
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
background: #f0f0f0;
|
||||
border: .2em solid transparent;
|
||||
border-top-color: #bbb;
|
||||
top: -1.1em;
|
||||
bottom: auto; }
|
110
BTCPayServer/wwwroot/vendor/vex/css/vex-theme-wireframe.css
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
@-webkit-keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
@keyframes vex-pulse {
|
||||
0% {
|
||||
box-shadow: inset 0 0 0 300px transparent; }
|
||||
70% {
|
||||
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
|
||||
100% {
|
||||
box-shadow: inset 0 0 0 300px transparent; } }
|
||||
|
||||
.vex.vex-theme-wireframe {
|
||||
padding-top: 160px;
|
||||
padding-bottom: 160px; }
|
||||
.vex.vex-theme-wireframe .vex-overlay {
|
||||
background: rgba(255, 255, 255, 0.4); }
|
||||
.vex.vex-theme-wireframe .vex-content {
|
||||
font-family: "Helvetica Neue", sans-serif;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 2px solid #000;
|
||||
padding: 2em;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
width: 400px;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em; }
|
||||
.vex.vex-theme-wireframe .vex-content h1, .vex.vex-theme-wireframe .vex-content h2, .vex.vex-theme-wireframe .vex-content h3, .vex.vex-theme-wireframe .vex-content h4, .vex.vex-theme-wireframe .vex-content h5, .vex.vex-theme-wireframe .vex-content h6, .vex.vex-theme-wireframe .vex-content p, .vex.vex-theme-wireframe .vex-content ul, .vex.vex-theme-wireframe .vex-content li {
|
||||
color: inherit; }
|
||||
.vex.vex-theme-wireframe .vex-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer; }
|
||||
.vex.vex-theme-wireframe .vex-close:before {
|
||||
position: absolute;
|
||||
content: "\00D7";
|
||||
font-size: 40px;
|
||||
font-weight: normal;
|
||||
line-height: 80px;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
color: #000; }
|
||||
.vex.vex-theme-wireframe .vex-close:hover:before, .vex.vex-theme-wireframe .vex-close:active:before {
|
||||
color: #000; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-message {
|
||||
margin-bottom: .5em; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input {
|
||||
margin-bottom: 1em; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"] {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
padding: .25em .67em;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
min-height: 2.5em;
|
||||
margin: 0 0 .25em;
|
||||
border: 2px solid #000; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
|
||||
border-style: dashed;
|
||||
outline: none; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons {
|
||||
*zoom: 1; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-button {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
float: right;
|
||||
margin: 0 0 0 .5em;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
font-size: .8em;
|
||||
line-height: 1em;
|
||||
padding: .75em 2em; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-button.vex-last {
|
||||
margin-left: 0; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-button:focus {
|
||||
-webkit-animation: vex-pulse 1.1s infinite;
|
||||
animation: vex-pulse 1.1s infinite;
|
||||
outline: none; }
|
||||
@media (max-width: 568px) {
|
||||
.vex.vex-theme-wireframe .vex-dialog-button:focus {
|
||||
-webkit-animation: none;
|
||||
animation: none; } }
|
||||
.vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-primary {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
border: 2px solid transparent; }
|
||||
.vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-secondary {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 2px solid #000; }
|
||||
|
||||
.vex-loading-spinner.vex-theme-wireframe {
|
||||
height: 2.5em;
|
||||
width: 2.5em; }
|
117
BTCPayServer/wwwroot/vendor/vex/css/vex.css
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
@-webkit-keyframes vex-fadein {
|
||||
0% {
|
||||
opacity: 0; }
|
||||
100% {
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes vex-fadein {
|
||||
0% {
|
||||
opacity: 0; }
|
||||
100% {
|
||||
opacity: 1; } }
|
||||
|
||||
@-webkit-keyframes vex-fadeout {
|
||||
0% {
|
||||
opacity: 1; }
|
||||
100% {
|
||||
opacity: 0; } }
|
||||
|
||||
@keyframes vex-fadeout {
|
||||
0% {
|
||||
opacity: 1; }
|
||||
100% {
|
||||
opacity: 0; } }
|
||||
|
||||
@-webkit-keyframes vex-rotation {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg); }
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg); } }
|
||||
|
||||
@keyframes vex-rotation {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg); }
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg); } }
|
||||
|
||||
.vex, .vex *, .vex *:before, .vex *:after {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.vex {
|
||||
position: fixed;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
z-index: 1111;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0; }
|
||||
|
||||
.vex-scrollbar-measure {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
overflow: scroll; }
|
||||
|
||||
.vex-overlay {
|
||||
-webkit-animation: vex-fadein .5s;
|
||||
animation: vex-fadein .5s;
|
||||
position: fixed;
|
||||
z-index: 1111;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0; }
|
||||
|
||||
.vex-overlay.vex-closing {
|
||||
-webkit-animation: vex-fadeout .5s forwards;
|
||||
animation: vex-fadeout .5s forwards; }
|
||||
|
||||
.vex-content {
|
||||
-webkit-animation: vex-fadein .5s;
|
||||
animation: vex-fadein .5s;
|
||||
background: #fff; }
|
||||
|
||||
.vex.vex-closing .vex-content {
|
||||
-webkit-animation: vex-fadeout .5s forwards;
|
||||
animation: vex-fadeout .5s forwards; }
|
||||
|
||||
.vex-close:before {
|
||||
font-family: Arial, sans-serif;
|
||||
content: "\00D7"; }
|
||||
|
||||
.vex-dialog-form {
|
||||
margin: 0; }
|
||||
|
||||
.vex-dialog-button {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent; }
|
||||
|
||||
.vex-loading-spinner {
|
||||
-webkit-animation: vex-rotation .7s linear infinite;
|
||||
animation: vex-rotation .7s linear infinite;
|
||||
box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
z-index: 1112;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
background: #fff; }
|
||||
|
||||
body.vex-open {
|
||||
overflow: hidden; }
|
1629
BTCPayServer/wwwroot/vendor/vex/js/vex.combined.js
vendored
Normal file
2
BTCPayServer/wwwroot/vendor/vex/js/vex.combined.min.js
vendored
Normal file
754
BTCPayServer/wwwroot/vendor/vex/js/vex.js
vendored
Normal file
@ -0,0 +1,754 @@
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vex = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/*
|
||||
* classList.js: Cross-browser full element.classList implementation.
|
||||
* 2014-07-23
|
||||
*
|
||||
* By Eli Grey, http://eligrey.com
|
||||
* Public Domain.
|
||||
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
*/
|
||||
|
||||
/*global self, document, DOMException */
|
||||
|
||||
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
|
||||
|
||||
/* Copied from MDN:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
|
||||
*/
|
||||
|
||||
if ("document" in window.self) {
|
||||
|
||||
// Full polyfill for browsers with no classList support
|
||||
// Including IE < Edge missing SVGElement.classList
|
||||
if (!("classList" in document.createElement("_"))
|
||||
|| document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {
|
||||
|
||||
(function (view) {
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!('Element' in view)) return;
|
||||
|
||||
var
|
||||
classListProp = "classList"
|
||||
, protoProp = "prototype"
|
||||
, elemCtrProto = view.Element[protoProp]
|
||||
, objCtr = Object
|
||||
, strTrim = String[protoProp].trim || function () {
|
||||
return this.replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
, arrIndexOf = Array[protoProp].indexOf || function (item) {
|
||||
var
|
||||
i = 0
|
||||
, len = this.length
|
||||
;
|
||||
for (; i < len; i++) {
|
||||
if (i in this && this[i] === item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
// Vendors: please allow content code to instantiate DOMExceptions
|
||||
, DOMEx = function (type, message) {
|
||||
this.name = type;
|
||||
this.code = DOMException[type];
|
||||
this.message = message;
|
||||
}
|
||||
, checkTokenAndGetIndex = function (classList, token) {
|
||||
if (token === "") {
|
||||
throw new DOMEx(
|
||||
"SYNTAX_ERR"
|
||||
, "An invalid or illegal string was specified"
|
||||
);
|
||||
}
|
||||
if (/\s/.test(token)) {
|
||||
throw new DOMEx(
|
||||
"INVALID_CHARACTER_ERR"
|
||||
, "String contains an invalid character"
|
||||
);
|
||||
}
|
||||
return arrIndexOf.call(classList, token);
|
||||
}
|
||||
, ClassList = function (elem) {
|
||||
var
|
||||
trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
|
||||
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
|
||||
, i = 0
|
||||
, len = classes.length
|
||||
;
|
||||
for (; i < len; i++) {
|
||||
this.push(classes[i]);
|
||||
}
|
||||
this._updateClassName = function () {
|
||||
elem.setAttribute("class", this.toString());
|
||||
};
|
||||
}
|
||||
, classListProto = ClassList[protoProp] = []
|
||||
, classListGetter = function () {
|
||||
return new ClassList(this);
|
||||
}
|
||||
;
|
||||
// Most DOMException implementations don't allow calling DOMException's toString()
|
||||
// on non-DOMExceptions. Error's toString() is sufficient here.
|
||||
DOMEx[protoProp] = Error[protoProp];
|
||||
classListProto.item = function (i) {
|
||||
return this[i] || null;
|
||||
};
|
||||
classListProto.contains = function (token) {
|
||||
token += "";
|
||||
return checkTokenAndGetIndex(this, token) !== -1;
|
||||
};
|
||||
classListProto.add = function () {
|
||||
var
|
||||
tokens = arguments
|
||||
, i = 0
|
||||
, l = tokens.length
|
||||
, token
|
||||
, updated = false
|
||||
;
|
||||
do {
|
||||
token = tokens[i] + "";
|
||||
if (checkTokenAndGetIndex(this, token) === -1) {
|
||||
this.push(token);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
while (++i < l);
|
||||
|
||||
if (updated) {
|
||||
this._updateClassName();
|
||||
}
|
||||
};
|
||||
classListProto.remove = function () {
|
||||
var
|
||||
tokens = arguments
|
||||
, i = 0
|
||||
, l = tokens.length
|
||||
, token
|
||||
, updated = false
|
||||
, index
|
||||
;
|
||||
do {
|
||||
token = tokens[i] + "";
|
||||
index = checkTokenAndGetIndex(this, token);
|
||||
while (index !== -1) {
|
||||
this.splice(index, 1);
|
||||
updated = true;
|
||||
index = checkTokenAndGetIndex(this, token);
|
||||
}
|
||||
}
|
||||
while (++i < l);
|
||||
|
||||
if (updated) {
|
||||
this._updateClassName();
|
||||
}
|
||||
};
|
||||
classListProto.toggle = function (token, force) {
|
||||
token += "";
|
||||
|
||||
var
|
||||
result = this.contains(token)
|
||||
, method = result ?
|
||||
force !== true && "remove"
|
||||
:
|
||||
force !== false && "add"
|
||||
;
|
||||
|
||||
if (method) {
|
||||
this[method](token);
|
||||
}
|
||||
|
||||
if (force === true || force === false) {
|
||||
return force;
|
||||
} else {
|
||||
return !result;
|
||||
}
|
||||
};
|
||||
classListProto.toString = function () {
|
||||
return this.join(" ");
|
||||
};
|
||||
|
||||
if (objCtr.defineProperty) {
|
||||
var classListPropDesc = {
|
||||
get: classListGetter
|
||||
, enumerable: true
|
||||
, configurable: true
|
||||
};
|
||||
try {
|
||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
||||
} catch (ex) { // IE 8 doesn't support enumerable:true
|
||||
if (ex.number === -0x7FF5EC54) {
|
||||
classListPropDesc.enumerable = false;
|
||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
||||
}
|
||||
}
|
||||
} else if (objCtr[protoProp].__defineGetter__) {
|
||||
elemCtrProto.__defineGetter__(classListProp, classListGetter);
|
||||
}
|
||||
|
||||
}(window.self));
|
||||
|
||||
} else {
|
||||
// There is full or partial native classList support, so just check if we need
|
||||
// to normalize the add/remove and toggle APIs.
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var testElement = document.createElement("_");
|
||||
|
||||
testElement.classList.add("c1", "c2");
|
||||
|
||||
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
|
||||
// classList.remove exist but support only one argument at a time.
|
||||
if (!testElement.classList.contains("c2")) {
|
||||
var createMethod = function(method) {
|
||||
var original = DOMTokenList.prototype[method];
|
||||
|
||||
DOMTokenList.prototype[method] = function(token) {
|
||||
var i, len = arguments.length;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
token = arguments[i];
|
||||
original.call(this, token);
|
||||
}
|
||||
};
|
||||
};
|
||||
createMethod('add');
|
||||
createMethod('remove');
|
||||
}
|
||||
|
||||
testElement.classList.toggle("c3", false);
|
||||
|
||||
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
|
||||
// support the second argument.
|
||||
if (testElement.classList.contains("c3")) {
|
||||
var _toggle = DOMTokenList.prototype.toggle;
|
||||
|
||||
DOMTokenList.prototype.toggle = function(token, force) {
|
||||
if (1 in arguments && !this.contains(token) === !force) {
|
||||
return force;
|
||||
} else {
|
||||
return _toggle.call(this, token);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
testElement = null;
|
||||
}());
|
||||
}
|
||||
}
|
||||
|
||||
},{}],2:[function(require,module,exports){
|
||||
|
||||
/**
|
||||
* Expose `parse`.
|
||||
*/
|
||||
|
||||
module.exports = parse;
|
||||
|
||||
/**
|
||||
* Tests for browser support.
|
||||
*/
|
||||
|
||||
var innerHTMLBug = false;
|
||||
var bugTestDiv;
|
||||
if (typeof document !== 'undefined') {
|
||||
bugTestDiv = document.createElement('div');
|
||||
// Setup
|
||||
bugTestDiv.innerHTML = ' <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
|
||||
// Make sure that link elements get serialized correctly by innerHTML
|
||||
// This requires a wrapper element in IE
|
||||
innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
|
||||
bugTestDiv = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap map from jquery.
|
||||
*/
|
||||
|
||||
var map = {
|
||||
legend: [1, '<fieldset>', '</fieldset>'],
|
||||
tr: [2, '<table><tbody>', '</tbody></table>'],
|
||||
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
|
||||
// for script/link/style tags to work in IE6-8, you have to wrap
|
||||
// in a div with a non-whitespace character in front, ha!
|
||||
_default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
|
||||
};
|
||||
|
||||
map.td =
|
||||
map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
|
||||
|
||||
map.option =
|
||||
map.optgroup = [1, '<select multiple="multiple">', '</select>'];
|
||||
|
||||
map.thead =
|
||||
map.tbody =
|
||||
map.colgroup =
|
||||
map.caption =
|
||||
map.tfoot = [1, '<table>', '</table>'];
|
||||
|
||||
map.polyline =
|
||||
map.ellipse =
|
||||
map.polygon =
|
||||
map.circle =
|
||||
map.text =
|
||||
map.line =
|
||||
map.path =
|
||||
map.rect =
|
||||
map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'];
|
||||
|
||||
/**
|
||||
* Parse `html` and return a DOM Node instance, which could be a TextNode,
|
||||
* HTML DOM Node of some kind (<div> for example), or a DocumentFragment
|
||||
* instance, depending on the contents of the `html` string.
|
||||
*
|
||||
* @param {String} html - HTML string to "domify"
|
||||
* @param {Document} doc - The `document` instance to create the Node for
|
||||
* @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(html, doc) {
|
||||
if ('string' != typeof html) throw new TypeError('String expected');
|
||||
|
||||
// default to the global `document` object
|
||||
if (!doc) doc = document;
|
||||
|
||||
// tag name
|
||||
var m = /<([\w:]+)/.exec(html);
|
||||
if (!m) return doc.createTextNode(html);
|
||||
|
||||
html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace
|
||||
|
||||
var tag = m[1];
|
||||
|
||||
// body support
|
||||
if (tag == 'body') {
|
||||
var el = doc.createElement('html');
|
||||
el.innerHTML = html;
|
||||
return el.removeChild(el.lastChild);
|
||||
}
|
||||
|
||||
// wrap map
|
||||
var wrap = map[tag] || map._default;
|
||||
var depth = wrap[0];
|
||||
var prefix = wrap[1];
|
||||
var suffix = wrap[2];
|
||||
var el = doc.createElement('div');
|
||||
el.innerHTML = prefix + html + suffix;
|
||||
while (depth--) el = el.lastChild;
|
||||
|
||||
// one element
|
||||
if (el.firstChild == el.lastChild) {
|
||||
return el.removeChild(el.firstChild);
|
||||
}
|
||||
|
||||
// several elements
|
||||
var fragment = doc.createDocumentFragment();
|
||||
while (el.firstChild) {
|
||||
fragment.appendChild(el.removeChild(el.firstChild));
|
||||
}
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
},{}],3:[function(require,module,exports){
|
||||
/**
|
||||
* Code refactored from Mozilla Developer Network:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function assign(target, firstSource) {
|
||||
if (target === undefined || target === null) {
|
||||
throw new TypeError('Cannot convert first argument to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var nextSource = arguments[i];
|
||||
if (nextSource === undefined || nextSource === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var keysArray = Object.keys(Object(nextSource));
|
||||
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
|
||||
var nextKey = keysArray[nextIndex];
|
||||
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
|
||||
if (desc !== undefined && desc.enumerable) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
function polyfill() {
|
||||
if (!Object.assign) {
|
||||
Object.defineProperty(Object, 'assign', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: assign
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
assign: assign,
|
||||
polyfill: polyfill
|
||||
};
|
||||
|
||||
},{}],4:[function(require,module,exports){
|
||||
// classList polyfill for old browsers
|
||||
require('classlist-polyfill')
|
||||
// Object.assign polyfill
|
||||
require('es6-object-assign').polyfill()
|
||||
|
||||
// String to DOM function
|
||||
var domify = require('domify')
|
||||
|
||||
// Use the DOM's HTML parsing to escape any dangerous strings
|
||||
var escapeHtml = function escapeHtml (str) {
|
||||
if (typeof str !== 'undefined') {
|
||||
var div = document.createElement('div')
|
||||
div.appendChild(document.createTextNode(str))
|
||||
return div.innerHTML
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function to add space-delimited class strings to a DOM element's classList
|
||||
var addClasses = function addClasses (el, classStr) {
|
||||
if (typeof classStr !== 'string' || classStr.length === 0) {
|
||||
return
|
||||
}
|
||||
var classes = classStr.split(' ')
|
||||
for (var i = 0; i < classes.length; i++) {
|
||||
var className = classes[i]
|
||||
if (className.length) {
|
||||
el.classList.add(className)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect CSS Animation End Support
|
||||
// https://github.com/limonte/sweetalert2/blob/99bd539f85e15ac170f69d35001d12e092ef0054/src/utils/dom.js#L194
|
||||
var animationEndEvent = (function detectAnimationEndEvent () {
|
||||
var el = document.createElement('div')
|
||||
var eventNames = {
|
||||
'WebkitAnimation': 'webkitAnimationEnd',
|
||||
'MozAnimation': 'animationend',
|
||||
'OAnimation': 'oanimationend',
|
||||
'msAnimation': 'MSAnimationEnd',
|
||||
'animation': 'animationend'
|
||||
}
|
||||
for (var i in eventNames) {
|
||||
if (el.style[i] !== undefined) {
|
||||
return eventNames[i]
|
||||
}
|
||||
}
|
||||
return false
|
||||
})()
|
||||
|
||||
// vex base CSS classes
|
||||
var baseClassNames = {
|
||||
vex: 'vex',
|
||||
content: 'vex-content',
|
||||
overlay: 'vex-overlay',
|
||||
close: 'vex-close',
|
||||
closing: 'vex-closing',
|
||||
open: 'vex-open'
|
||||
}
|
||||
|
||||
// Private lookup table of all open vex objects, keyed by id
|
||||
var vexes = {}
|
||||
var globalId = 1
|
||||
|
||||
// Private boolean to assist the escapeButtonCloses option
|
||||
var isEscapeActive = false
|
||||
|
||||
// vex itself is an object that exposes a simple API to open and close vex objects in various ways
|
||||
var vex = {
|
||||
open: function open (opts) {
|
||||
// Check for usage of deprecated options, and log a warning
|
||||
var warnDeprecated = function warnDeprecated (prop) {
|
||||
console.warn('The "' + prop + '" property is deprecated in vex 3. Use CSS classes and the appropriate "ClassName" options, instead.')
|
||||
console.warn('See http://github.hubspot.com/vex/api/advanced/#options')
|
||||
}
|
||||
if (opts.css) {
|
||||
warnDeprecated('css')
|
||||
}
|
||||
if (opts.overlayCSS) {
|
||||
warnDeprecated('overlayCSS')
|
||||
}
|
||||
if (opts.contentCSS) {
|
||||
warnDeprecated('contentCSS')
|
||||
}
|
||||
if (opts.closeCSS) {
|
||||
warnDeprecated('closeCSS')
|
||||
}
|
||||
|
||||
// The dialog instance
|
||||
var vexInstance = {}
|
||||
|
||||
// Set id
|
||||
vexInstance.id = globalId++
|
||||
|
||||
// Store internally
|
||||
vexes[vexInstance.id] = vexInstance
|
||||
|
||||
// Set state
|
||||
vexInstance.isOpen = true
|
||||
|
||||
// Close function on the vex instance
|
||||
// This is how all API functions should close individual vexes
|
||||
vexInstance.close = function instanceClose () {
|
||||
// Check state
|
||||
if (!this.isOpen) {
|
||||
return true
|
||||
}
|
||||
|
||||
var options = this.options
|
||||
|
||||
// escapeButtonCloses is checked first
|
||||
if (isEscapeActive && !options.escapeButtonCloses) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Allow the user to validate any info or abort the close with the beforeClose callback
|
||||
var shouldClose = (function shouldClose () {
|
||||
// Call before close callback
|
||||
if (options.beforeClose) {
|
||||
return options.beforeClose.call(this)
|
||||
}
|
||||
// Otherwise indicate that it's ok to continue with close
|
||||
return true
|
||||
}.bind(this)())
|
||||
|
||||
// If beforeClose() fails, abort the close
|
||||
if (shouldClose === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Update state
|
||||
this.isOpen = false
|
||||
|
||||
// Detect if the content el has any CSS animations defined
|
||||
var style = window.getComputedStyle(this.contentEl)
|
||||
function hasAnimationPre (prefix) {
|
||||
return style.getPropertyValue(prefix + 'animation-name') !== 'none' && style.getPropertyValue(prefix + 'animation-duration') !== '0s'
|
||||
}
|
||||
var hasAnimation = hasAnimationPre('') || hasAnimationPre('-webkit-') || hasAnimationPre('-moz-') || hasAnimationPre('-o-')
|
||||
|
||||
// Define the function that will actually close the instance
|
||||
var close = function close () {
|
||||
if (!this.rootEl.parentNode) {
|
||||
return
|
||||
}
|
||||
// Run once
|
||||
this.rootEl.removeEventListener(animationEndEvent, close)
|
||||
this.overlayEl.removeEventListener(animationEndEvent, close)
|
||||
// Remove from lookup table (prevent memory leaks)
|
||||
delete vexes[this.id]
|
||||
// Remove the dialog from the DOM
|
||||
this.rootEl.parentNode.removeChild(this.rootEl)
|
||||
// Remove the overlay from the DOM
|
||||
this.bodyEl.removeChild(this.overlayEl);
|
||||
// Call after close callback
|
||||
if (options.afterClose) {
|
||||
options.afterClose.call(this)
|
||||
}
|
||||
// Remove styling from the body, if no more vexes are open
|
||||
if (Object.keys(vexes).length === 0) {
|
||||
document.body.classList.remove(baseClassNames.open)
|
||||
}
|
||||
}.bind(this)
|
||||
|
||||
// Close the vex
|
||||
if (animationEndEvent && hasAnimation) {
|
||||
// Setup the end event listener, to remove the el from the DOM
|
||||
this.rootEl.addEventListener(animationEndEvent, close)
|
||||
this.overlayEl.addEventListener(animationEndEvent, close)
|
||||
// Add the closing class to the dialog, showing the close animation
|
||||
this.rootEl.classList.add(baseClassNames.closing)
|
||||
this.overlayEl.classList.add(baseClassNames.closing)
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Allow strings as content
|
||||
if (typeof opts === 'string') {
|
||||
opts = {
|
||||
content: opts
|
||||
}
|
||||
}
|
||||
|
||||
// `content` is unsafe internally, so translate
|
||||
// safe default: HTML-escape the content before passing it through
|
||||
if (opts.unsafeContent && !opts.content) {
|
||||
opts.content = opts.unsafeContent
|
||||
} else if (opts.content) {
|
||||
opts.content = escapeHtml(opts.content)
|
||||
}
|
||||
|
||||
// Store options on instance for future reference
|
||||
var options = vexInstance.options = Object.assign({}, vex.defaultOptions, opts)
|
||||
|
||||
// Get Body Element
|
||||
var bodyEl = vexInstance.bodyEl = document.getElementsByTagName('body')[0];
|
||||
|
||||
// vex root
|
||||
var rootEl = vexInstance.rootEl = document.createElement('div')
|
||||
rootEl.classList.add(baseClassNames.vex)
|
||||
addClasses(rootEl, options.className)
|
||||
|
||||
// Overlay
|
||||
var overlayEl = vexInstance.overlayEl = document.createElement('div')
|
||||
overlayEl.classList.add(baseClassNames.overlay)
|
||||
addClasses(overlayEl, options.overlayClassName)
|
||||
if (options.overlayClosesOnClick) {
|
||||
rootEl.addEventListener('click', function overlayClickListener (e) {
|
||||
if (e.target === rootEl) {
|
||||
vexInstance.close()
|
||||
}
|
||||
})
|
||||
}
|
||||
bodyEl.appendChild(overlayEl)
|
||||
|
||||
// Content
|
||||
var contentEl = vexInstance.contentEl = document.createElement('div')
|
||||
contentEl.classList.add(baseClassNames.content)
|
||||
addClasses(contentEl, options.contentClassName)
|
||||
contentEl.appendChild(options.content instanceof window.Node ? options.content : domify(options.content))
|
||||
rootEl.appendChild(contentEl)
|
||||
|
||||
// Close button
|
||||
if (options.showCloseButton) {
|
||||
var closeEl = vexInstance.closeEl = document.createElement('div')
|
||||
closeEl.classList.add(baseClassNames.close)
|
||||
addClasses(closeEl, options.closeClassName)
|
||||
closeEl.addEventListener('click', vexInstance.close.bind(vexInstance))
|
||||
contentEl.appendChild(closeEl)
|
||||
}
|
||||
|
||||
// Add to DOM
|
||||
document.querySelector(options.appendLocation).appendChild(rootEl)
|
||||
|
||||
// Call after open callback
|
||||
if (options.afterOpen) {
|
||||
options.afterOpen.call(vexInstance)
|
||||
}
|
||||
|
||||
// Apply styling to the body
|
||||
document.body.classList.add(baseClassNames.open)
|
||||
|
||||
// Return the created vex instance
|
||||
return vexInstance
|
||||
},
|
||||
|
||||
// A top-level vex.close function to close dialogs by reference or id
|
||||
close: function close (vexOrId) {
|
||||
var id
|
||||
if (vexOrId.id) {
|
||||
id = vexOrId.id
|
||||
} else if (typeof vexOrId === 'string') {
|
||||
id = vexOrId
|
||||
} else {
|
||||
throw new TypeError('close requires a vex object or id string')
|
||||
}
|
||||
if (!vexes[id]) {
|
||||
return false
|
||||
}
|
||||
return vexes[id].close()
|
||||
},
|
||||
|
||||
// Close the most recently created/opened vex
|
||||
closeTop: function closeTop () {
|
||||
var ids = Object.keys(vexes)
|
||||
if (!ids.length) {
|
||||
return false
|
||||
}
|
||||
return vexes[ids[ids.length - 1]].close()
|
||||
},
|
||||
|
||||
// Close every vex!
|
||||
closeAll: function closeAll () {
|
||||
for (var id in vexes) {
|
||||
this.close(id)
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
// A getter for the internal lookup table
|
||||
getAll: function getAll () {
|
||||
return vexes
|
||||
},
|
||||
|
||||
// A getter for the internal lookup table
|
||||
getById: function getById (id) {
|
||||
return vexes[id]
|
||||
}
|
||||
}
|
||||
|
||||
// Close top vex on escape
|
||||
window.addEventListener('keyup', function vexKeyupListener (e) {
|
||||
if (e.keyCode === 27) {
|
||||
isEscapeActive = true
|
||||
vex.closeTop()
|
||||
isEscapeActive = false
|
||||
}
|
||||
})
|
||||
|
||||
// Close all vexes on history pop state (useful in single page apps)
|
||||
window.addEventListener('popstate', function () {
|
||||
if (vex.defaultOptions.closeAllOnPopState) {
|
||||
vex.closeAll()
|
||||
}
|
||||
})
|
||||
|
||||
vex.defaultOptions = {
|
||||
content: '',
|
||||
showCloseButton: true,
|
||||
escapeButtonCloses: true,
|
||||
overlayClosesOnClick: true,
|
||||
appendLocation: 'body',
|
||||
className: '',
|
||||
overlayClassName: '',
|
||||
contentClassName: '',
|
||||
closeClassName: '',
|
||||
closeAllOnPopState: true
|
||||
}
|
||||
|
||||
// TODO Loading symbols?
|
||||
|
||||
// Include escapeHtml function on the library object
|
||||
Object.defineProperty(vex, '_escapeHtml', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: escapeHtml
|
||||
})
|
||||
|
||||
// Plugin system!
|
||||
vex.registerPlugin = function registerPlugin (pluginFn, name) {
|
||||
var plugin = pluginFn(vex)
|
||||
var pluginName = name || plugin.name
|
||||
if (vex[pluginName]) {
|
||||
throw new Error('Plugin ' + name + ' is already registered.')
|
||||
}
|
||||
vex[pluginName] = plugin
|
||||
}
|
||||
|
||||
module.exports = vex
|
||||
|
||||
},{"classlist-polyfill":1,"domify":2,"es6-object-assign":3}]},{},[4])(4)
|
||||
});
|