Fixed few layout issues with spinners.

Add a new Test Folder button in settings to test.
Add Docker images.
This commit is contained in:
Roger Far 2020-12-12 14:10:05 -07:00
parent b990a910be
commit 02c154f094
22 changed files with 648 additions and 288 deletions

40
.dockerignore Normal file
View file

@ -0,0 +1,40 @@
### Angular ###
# compiled output
client/dist/
client/tmp/
client/app/**/*.js
client/app/**/*.js.map
# dependencies
client/node_modules/
client/bower_components/
# IDEs and editors
client/.idea/
# misc
client/.sass-cache/
client/connect.lock/
client/coverage/
client/libpeerconnection.log/
client/npm-debug.log
client/testem.log
client/typings/
# e2e
client/e2e/*.js
client/e2e/*.map
#System Files
**/.DS_Store/
### DotnetCore ###
# .NET Core build folders
server/**/bin
server/**/obj
server/**/*.user
server/**/.vs
server/RdtClient.Web/wwwroot/
build/
publish/

28
Dockerfile Normal file
View file

@ -0,0 +1,28 @@
# Stage 1 - Build the frontend
FROM node:12.15-buster AS node-build-env
RUN mkdir /appclient
WORKDIR /appclient
COPY client/. .
RUN npm ci
RUN npx ng build --prod --output-path=out
# Stage 2 - Build the backend
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS dotnet-build-env
RUN mkdir /appserver
WORKDIR /appserver
COPY server/. .
RUN dotnet restore RdtClient.sln
RUN dotnet build -c Release
RUN dotnet publish -c Release -o out
# Stage 3 - Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:5.0.1-buster-slim AS base
RUN mkdir /app
WORKDIR /app
COPY --from=dotnet-build-env /appserver/out .
COPY --from=node-build-env /appclient/out ./wwwroot
ENTRYPOINT ["dotnet", "RdtClient.Web.dll"]

View file

@ -10,21 +10,34 @@ This is a web interface to manage your torrents on Real-Debrid. It supports the
**You will need a Premium service at Real-Debrid!** **You will need a Premium service at Real-Debrid!**
## Installation ## Docker Run
### Docker Installation ```console
docker run --cap-add=NET_ADMIN -d \
-v /your/storage/path/:/data/downloads \
--log-driver json-file \
--log-opt max-size=10m \
-p 6500:6500 \
rogerfar/rdtclient
```
### Windows Service Installation Replace `/your/storage/path/` with your local path to download files to. For Windows i.e. `C:/Downloads`.
## Windows Service Installation
1. Make sure you have the .NET 5.0.1+ runtime installed from [here](https://dotnet.microsoft.com/download). 1. Make sure you have the .NET 5.0.1+ runtime installed from [here](https://dotnet.microsoft.com/download).
1. Unpack the latest release from the releases folder and run `startup.bat`. This will start the application on port 6500. 1. Unpack the latest release from the releases folder and run `startup.bat`. This will start the application on port 6500.
1. Browse to http://127.0.0.1:6500
1. The very first credentials you enter in will be remembered for future logins.
1. Click on Settings on the top and enter your Real-Debrid API key.
1. Change your download path if needed.
1. To install as service on Windows, exit the console and run `serviceinstall.bat` as administrator. 1. To install as service on Windows, exit the console and run `serviceinstall.bat` as administrator.
1. To change the default port edit the `appsettings.json` file. 1. To change the default port edit the `appsettings.json` file.
## Setup
1. Browse to [http://127.0.0.1:6500](http://127.0.0.1:6500) (or the path of your server).
1. The very first credentials you enter in will be remembered for future logins.
1. Click on `Settings` on the top and enter your Real-Debrid API key (found here: [https://real-debrid.com/apitoken](https://real-debrid.com/apitoken).
1. Change your download path if needed. When using Docker, this path will be the path on your local machine.
1. Save your settings.
## Removing ## Removing
1. Run `serviceremove.bat` to remove the service and firewall rules. 1. Run `serviceremove.bat` to remove the service and firewall rules.
@ -35,21 +48,40 @@ This is a web interface to manage your torrents on Real-Debrid. It supports the
## Connecting Sonarr/Radarr ## Connecting Sonarr/Radarr
1. Login to Sonarr or Radarr and click Settings RdtClient emulates the qBittorrent web protocol and allow applications to use those APIs. This way you can use Sonarr and Radarr to download directly from RealDebrid.
1. Go to the Download Client tab and click the plus to add
1. Click "qBittorrent" in the list 1. Login to Sonarr or Radarr and click `Settings`.
1. Enter the IP or hostname of the RealDebridClient in the Host field 1. Go to the `Download Client` tab and click the plus to add.
1. Enter the port 6500 in the Port field 1. Click `qBittorrent` in the list.
1. Enter the IP or hostname of the RealDebridClient in the `Host` field.
1. Enter the 6500 in the `Port` field.
1. Enter your Username/Password you setup in step 3 above in the Username/Password field. 1. Enter your Username/Password you setup in step 3 above in the Username/Password field.
1. Leave the other settings as is. 1. Leave the other settings as is.
1. Hit Test and then Save if all is well. 1. Hit `Test` and then `Save` if all is well.
1. Sonarr will now think you have a regular Torrent client hooked up. 1. Sonarr will now think you have a regular Torrent client hooked up.
Notice: the progress and ETA reported in Sonarr's Activity tab will not be accurate, but it will report the torrent as completed so it can be processed after it is done downloading. Notice: the progress and ETA reported in Sonarr's Activity tab will not be accurate, but it will report the torrent as completed so it can be processed after it is done downloading.
## Build instructions ## Build instructions
1. Open the client folder project in VS Code and run `npm install` ### Prerequisites
2. To debug run `ng serve`, to build run `ng build --prod`
3. Open the Visual Studio 2019 project `RdtClient.sln` and `Publish` - NodeJS
4. The result is found in `\rdt-client\Publish` - NPM
- (optional) Angular CLI
- .NET 5
- Visual Studio 2019
- (optional) Resharper
1. Open the client folder project in VS Code and run `npm install`.
1. To debug run `ng serve`, to build run `ng build --prod`.
1. Open the Visual Studio 2019 project `RdtClient.sln` and `Publish` the `RdtClient.Web` to the given `PublishFolder` target.
1. When debugging, make sure to run `RdtClient.Web.dll` and not `IISExpress`.
1. The result is found in `Publish`.
## Build docker container
1. In the root of the project run `docker build --tag rdtclient .`
1. To create the docker container run `docker run --publish 6500:6500 --detach --name rdtclientdev rdtclient:latest`
1. To stop: `docker stop rdtclient`
1. To remove: `docker rm rdtclient`

View file

@ -40,17 +40,7 @@
<button <button
class="button is-success" class="button is-success"
(click)="login()" (click)="login()"
*ngIf="loggingIn" [ngClass]="{ 'is-loading': loggingIn }"
>
<span class="icon">
<i class="fas fa-spinner fa-pulse"></i>
</span>
Login
</button>
<button
class="button is-success"
(click)="login()"
*ngIf="!loggingIn"
> >
Login Login
</button> </button>

View file

@ -33,9 +33,7 @@
<span class="file-icon"> <span class="file-icon">
<i class="fas fa-upload"></i> <i class="fas fa-upload"></i>
</span> </span>
<span class="file-label"> <span class="file-label"> Pick a torrent file... </span>
Pick a torrent file...
</span>
</span> </span>
<span class="file-name"> <span class="file-name">
{{ fileName }} {{ fileName }}
@ -59,16 +57,13 @@
</div> </div>
</section> </section>
<footer class="modal-card-foot"> <footer class="modal-card-foot">
<button class="button is-success" *ngIf="saving"> <button
<span class="icon"> class="button is-success"
<i class="fas fa-spinner fa-pulse"></i> [disabled]="saving"
</span> [ngClass]="{ 'is-loading': saving }"
>
<span>Add Torrent</span> <span>Add Torrent</span>
</button> </button>
<button class="button is-success" (click)="ok()" *ngIf="!saving">
Add Torrent
</button>
<button class="button" (click)="cancel()" [disabled]="saving"> <button class="button" (click)="cancel()" [disabled]="saving">
Cancel Cancel
</button> </button>

View file

@ -36,9 +36,7 @@
[(ngModel)]="settingDownloadFolder" [(ngModel)]="settingDownloadFolder"
/> />
</div> </div>
<p class="help"> <p class="help">Path on the host where Real Debrid Client is hosted.</p>
Path on the host where Real Debrid Client is hosted.
</p>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Maximum parallel downloads</label> <label class="label">Maximum parallel downloads</label>
@ -59,18 +57,42 @@
<div class="notification is-danger is-light" *ngIf="error?.length > 0"> <div class="notification is-danger is-light" *ngIf="error?.length > 0">
Error saving settings: {{ error }} Error saving settings: {{ error }}
</div> </div>
<div
class="notification is-danger is-light"
*ngIf="testFolderError?.length > 0"
>
Could not test your download folder<br />
{{ testFolderError }}
</div>
<div class="notification is-success is-light" *ngIf="testFolderSuccess">
Successfully tested your download folder
</div>
</section> </section>
<footer class="modal-card-foot"> <footer class="modal-card-foot">
<button class="button is-success" *ngIf="saving"> <button
<span class="icon"> class="button is-success"
<i class="fas fa-spinner fa-pulse"></i> (click)="ok()"
</span> [disabled]="saving"
<span>Save Settings</span> [ngClass]="{ 'is-loading': saving }"
</button> >
<button class="button is-success" (click)="ok()" *ngIf="!saving">
Save Settings Save Settings
</button> </button>
<button class="button" (click)="cancel()" [disabled]="saving"> <button
class="button is-warning"
(click)="test()"
[disabled]="saving"
[ngClass]="{ 'is-loading': saving }"
>
Test permissions
</button>
<button
class="button"
(click)="cancel()"
[disabled]="saving"
[ngClass]="{ 'is-loading': saving }"
>
Cancel Cancel
</button> </button>
</footer> </footer>

View file

@ -1,6 +1,6 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { SettingsService } from 'src/app/settings.service';
import { Setting } from 'src/app/models/setting.model'; import { Setting } from 'src/app/models/setting.model';
import { SettingsService } from 'src/app/settings.service';
@Component({ @Component({
selector: 'app-settings', selector: 'app-settings',
@ -25,6 +25,8 @@ export class SettingsComponent implements OnInit {
public saving = false; public saving = false;
public error: string; public error: string;
public testFolderError: string;
public testFolderSuccess: boolean;
public settingRealDebridApiKey: string; public settingRealDebridApiKey: string;
public settingDownloadFolder: string; public settingDownloadFolder: string;
@ -86,6 +88,24 @@ export class SettingsComponent implements OnInit {
); );
} }
public test(): void {
this.saving = true;
this.testFolderError = null;
this.testFolderSuccess = false;
this.settingsService.testFolder(this.settingDownloadFolder).subscribe(
() => {
this.saving = false;
this.testFolderSuccess = true;
},
(err) => {
console.log(err);
this.testFolderError = err.error;
this.saving = false;
}
);
}
public cancel(): void { public cancel(): void {
this.isActive = false; this.isActive = false;
this.openChange.emit(this.open); this.openChange.emit(this.open);

View file

@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { Setting } from './models/setting.model';
import { Profile } from './models/profile.model'; import { Profile } from './models/profile.model';
import { Setting } from './models/setting.model';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@ -21,4 +21,8 @@ export class SettingsService {
public getProfile(): Observable<Profile> { public getProfile(): Observable<Profile> {
return this.http.get<Profile>(`/Api/Settings/Profile`); return this.http.get<Profile>(`/Api/Settings/Profile`);
} }
public testFolder(folder: string): Observable<void> {
return this.http.post<void>(`/Api/Settings/TestFolder`, { folder });
}
} }

4
docker-build.bat Normal file
View file

@ -0,0 +1,4 @@
docker stop rdtclient
docker rm rdtclient
docker build --tag rdtclient .
docker-compose up -d

14
docker-compose.yml Normal file
View file

@ -0,0 +1,14 @@
version: '3.3'
services:
rdtclient:
container_name: rogerfar/rdtclient
volumes:
- 'C:/Downloads/:/data/downloads'
image: rdtclient
restart: always
logging:
driver: json-file
options:
max-size: 10m
ports:
- '6500:6500'

2
docker-connect.bat Normal file
View file

@ -0,0 +1,2 @@
@echo off
docker exec -it rdtclient /bin/bash

View file

@ -12,46 +12,21 @@ namespace RdtClient.Data.Data
{ {
} }
public DataContext()
{
}
public static String ConnectionString => $"Data Source={AppContext.BaseDirectory}database.db"; public static String ConnectionString => $"Data Source={AppContext.BaseDirectory}database.db";
public DbSet<Download> Downloads { get; set; } public DbSet<Download> Downloads { get; set; }
public DbSet<Setting> Settings { get; set; } public DbSet<Setting> Settings { get; set; }
public DbSet<Torrent> Torrents { get; set; } public DbSet<Torrent> Torrents { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite(ConnectionString); protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite(ConnectionString);
}
protected override void OnModelCreating(ModelBuilder builder) protected override void OnModelCreating(ModelBuilder builder)
{ {
base.OnModelCreating(builder); base.OnModelCreating(builder);
builder.Entity<Setting>()
.HasData(new Setting
{
SettingId = "RealDebridApiKey",
Type = "String",
Value = ""
});
builder.Entity<Setting>()
.HasData(new Setting
{
SettingId = "DownloadFolder",
Type = "String",
Value = @"C:\Downloads"
});
builder.Entity<Setting>()
.HasData(new Setting
{
SettingId = "DownloadLimit",
Type = "Int32",
Value = "10"
});
var cascadeFKs = builder.Model.GetEntityTypes() var cascadeFKs = builder.Model.GetEntityTypes()
.SelectMany(t => t.GetForeignKeys()) .SelectMany(t => t.GetForeignKeys())
.Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade); .Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade);
@ -61,10 +36,5 @@ namespace RdtClient.Data.Data
fk.DeleteBehavior = DeleteBehavior.Restrict; fk.DeleteBehavior = DeleteBehavior.Restrict;
} }
} }
public void Migrate()
{
Database.Migrate();
}
} }
} }

View file

@ -0,0 +1,63 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RdtClient.Data.Models.Data;
namespace RdtClient.Data.Data
{
public static class DataMigration
{
private static Boolean InDocker => Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";
public static void Setup(IServiceScope serviceScope)
{
using var scope = serviceScope.ServiceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
var dataContext = scope.ServiceProvider.GetRequiredService<DataContext>();
dataContext.Database.Migrate();
Seed(dataContext);
}
private static void Seed(DataContext dataContext)
{
var defaultDownloadPath = "/data/downloads";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !InDocker)
{
defaultDownloadPath = @"C:\Downloads";
}
var configuration = dataContext.Settings.FirstOrDefault();
if (configuration == null)
{
dataContext.Settings.Add(new Setting
{
SettingId = "RealDebridApiKey",
Type = "String",
Value = ""
});
dataContext.Settings.Add(new Setting
{
SettingId = "DownloadFolder",
Type = "String",
Value = defaultDownloadPath
});
dataContext.Settings.Add(new Setting
{
SettingId = "DownloadLimit",
Type = "Int32",
Value = "10"
});
dataContext.SaveChanges();
}
}
}
}

View file

@ -9,14 +9,14 @@ using RdtClient.Data.Data;
namespace RdtClient.Data.Migrations namespace RdtClient.Data.Migrations
{ {
[DbContext(typeof(DataContext))] [DbContext(typeof(DataContext))]
[Migration("20200408224831_Initial")] [Migration("20201212204128_Initial")]
partial class Initial partial class Initial
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.3"); .HasAnnotation("ProductVersion", "5.0.1");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
@ -28,18 +28,18 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Name") b.Property<string>("Name")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("NormalizedName") b.Property<string>("NormalizedName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("NormalizedName") b.HasIndex("NormalizedName")
.IsUnique() .IsUnique()
.HasName("RoleNameIndex"); .HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles"); b.ToTable("AspNetRoles");
}); });
@ -80,8 +80,8 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Email") b.Property<string>("Email")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed") b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -93,12 +93,12 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("NormalizedEmail") b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("NormalizedUserName") b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("PasswordHash") b.Property<string>("PasswordHash")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -116,17 +116,17 @@ namespace RdtClient.Data.Migrations
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("UserName") b.Property<string>("UserName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("NormalizedEmail") b.HasIndex("NormalizedEmail")
.HasName("EmailIndex"); .HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName") b.HasIndex("NormalizedUserName")
.IsUnique() .IsUnique()
.HasName("UserNameIndex"); .HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers"); b.ToTable("AspNetUsers");
}); });
@ -249,26 +249,6 @@ namespace RdtClient.Data.Migrations
b.HasKey("SettingId"); b.HasKey("SettingId");
b.ToTable("Settings"); b.ToTable("Settings");
b.HasData(
new
{
SettingId = "RealDebridApiKey",
Type = "String",
Value = ""
},
new
{
SettingId = "DownloadFolder",
Type = "String",
Value = "C:\\Downloads"
},
new
{
SettingId = "DownloadLimit",
Type = "Int32",
Value = "10"
});
}); });
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b => modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
@ -391,6 +371,13 @@ namespace RdtClient.Data.Migrations
.HasForeignKey("TorrentId") .HasForeignKey("TorrentId")
.OnDelete(DeleteBehavior.Restrict) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.Navigation("Torrent");
});
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
{
b.Navigation("Downloads");
}); });
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }

View file

@ -11,10 +11,10 @@ namespace RdtClient.Data.Migrations
name: "AspNetRoles", name: "AspNetRoles",
columns: table => new columns: table => new
{ {
Id = table.Column<string>(nullable: false), Id = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true), Name = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true), NormalizedName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true) ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -25,21 +25,21 @@ namespace RdtClient.Data.Migrations
name: "AspNetUsers", name: "AspNetUsers",
columns: table => new columns: table => new
{ {
Id = table.Column<string>(nullable: false), Id = table.Column<string>(type: "TEXT", nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true), UserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true), NormalizedUserName = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true), Email = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true), NormalizedEmail = table.Column<string>(type: "TEXT", maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false), EmailConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
PasswordHash = table.Column<string>(nullable: true), PasswordHash = table.Column<string>(type: "TEXT", nullable: true),
SecurityStamp = table.Column<string>(nullable: true), SecurityStamp = table.Column<string>(type: "TEXT", nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true), ConcurrencyStamp = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumber = table.Column<string>(nullable: true), PhoneNumber = table.Column<string>(type: "TEXT", nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false), PhoneNumberConfirmed = table.Column<bool>(type: "INTEGER", nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false), TwoFactorEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true), LockoutEnd = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false), LockoutEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
AccessFailedCount = table.Column<int>(nullable: false) AccessFailedCount = table.Column<int>(type: "INTEGER", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -50,9 +50,9 @@ namespace RdtClient.Data.Migrations
name: "Settings", name: "Settings",
columns: table => new columns: table => new
{ {
SettingId = table.Column<string>(nullable: false), SettingId = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(nullable: true), Value = table.Column<string>(type: "TEXT", nullable: true),
Type = table.Column<string>(nullable: true) Type = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -63,24 +63,24 @@ namespace RdtClient.Data.Migrations
name: "Torrents", name: "Torrents",
columns: table => new columns: table => new
{ {
TorrentId = table.Column<Guid>(nullable: false), TorrentId = table.Column<Guid>(type: "TEXT", nullable: false),
Hash = table.Column<string>(nullable: true), Hash = table.Column<string>(type: "TEXT", nullable: true),
Category = table.Column<string>(nullable: true), Category = table.Column<string>(type: "TEXT", nullable: true),
AutoDownload = table.Column<bool>(nullable: false), AutoDownload = table.Column<bool>(type: "INTEGER", nullable: false),
AutoDelete = table.Column<bool>(nullable: false), AutoDelete = table.Column<bool>(type: "INTEGER", nullable: false),
Status = table.Column<int>(nullable: false), Status = table.Column<int>(type: "INTEGER", nullable: false),
RdId = table.Column<string>(nullable: true), RdId = table.Column<string>(type: "TEXT", nullable: true),
RdName = table.Column<string>(nullable: true), RdName = table.Column<string>(type: "TEXT", nullable: true),
RdSize = table.Column<long>(nullable: false), RdSize = table.Column<long>(type: "INTEGER", nullable: false),
RdHost = table.Column<string>(nullable: true), RdHost = table.Column<string>(type: "TEXT", nullable: true),
RdSplit = table.Column<long>(nullable: false), RdSplit = table.Column<long>(type: "INTEGER", nullable: false),
RdProgress = table.Column<long>(nullable: false), RdProgress = table.Column<long>(type: "INTEGER", nullable: false),
RdStatus = table.Column<string>(nullable: true), RdStatus = table.Column<string>(type: "TEXT", nullable: true),
RdAdded = table.Column<DateTimeOffset>(nullable: false), RdAdded = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
RdEnded = table.Column<DateTimeOffset>(nullable: true), RdEnded = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
RdSpeed = table.Column<long>(nullable: true), RdSpeed = table.Column<long>(type: "INTEGER", nullable: true),
RdSeeders = table.Column<long>(nullable: true), RdSeeders = table.Column<long>(type: "INTEGER", nullable: true),
RdFiles = table.Column<string>(nullable: true) RdFiles = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -91,11 +91,11 @@ namespace RdtClient.Data.Migrations
name: "AspNetRoleClaims", name: "AspNetRoleClaims",
columns: table => new columns: table => new
{ {
Id = table.Column<int>(nullable: false) Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true), .Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<string>(nullable: false), RoleId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(nullable: true), ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(nullable: true) ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -112,11 +112,11 @@ namespace RdtClient.Data.Migrations
name: "AspNetUserClaims", name: "AspNetUserClaims",
columns: table => new columns: table => new
{ {
Id = table.Column<int>(nullable: false) Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true), .Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(nullable: false), UserId = table.Column<string>(type: "TEXT", nullable: false),
ClaimType = table.Column<string>(nullable: true), ClaimType = table.Column<string>(type: "TEXT", nullable: true),
ClaimValue = table.Column<string>(nullable: true) ClaimValue = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -133,10 +133,10 @@ namespace RdtClient.Data.Migrations
name: "AspNetUserLogins", name: "AspNetUserLogins",
columns: table => new columns: table => new
{ {
LoginProvider = table.Column<string>(nullable: false), LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
ProviderKey = table.Column<string>(nullable: false), ProviderKey = table.Column<string>(type: "TEXT", nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true), ProviderDisplayName = table.Column<string>(type: "TEXT", nullable: true),
UserId = table.Column<string>(nullable: false) UserId = table.Column<string>(type: "TEXT", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -153,8 +153,8 @@ namespace RdtClient.Data.Migrations
name: "AspNetUserRoles", name: "AspNetUserRoles",
columns: table => new columns: table => new
{ {
UserId = table.Column<string>(nullable: false), UserId = table.Column<string>(type: "TEXT", nullable: false),
RoleId = table.Column<string>(nullable: false) RoleId = table.Column<string>(type: "TEXT", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -177,10 +177,10 @@ namespace RdtClient.Data.Migrations
name: "AspNetUserTokens", name: "AspNetUserTokens",
columns: table => new columns: table => new
{ {
UserId = table.Column<string>(nullable: false), UserId = table.Column<string>(type: "TEXT", nullable: false),
LoginProvider = table.Column<string>(nullable: false), LoginProvider = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(nullable: false), Name = table.Column<string>(type: "TEXT", nullable: false),
Value = table.Column<string>(nullable: true) Value = table.Column<string>(type: "TEXT", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -197,11 +197,11 @@ namespace RdtClient.Data.Migrations
name: "Downloads", name: "Downloads",
columns: table => new columns: table => new
{ {
DownloadId = table.Column<Guid>(nullable: false), DownloadId = table.Column<Guid>(type: "TEXT", nullable: false),
TorrentId = table.Column<Guid>(nullable: false), TorrentId = table.Column<Guid>(type: "TEXT", nullable: false),
Link = table.Column<string>(nullable: true), Link = table.Column<string>(type: "TEXT", nullable: true),
Added = table.Column<DateTimeOffset>(nullable: false), Added = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
Status = table.Column<int>(nullable: false) Status = table.Column<int>(type: "INTEGER", nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -214,21 +214,6 @@ namespace RdtClient.Data.Migrations
onDelete: ReferentialAction.Restrict); onDelete: ReferentialAction.Restrict);
}); });
migrationBuilder.InsertData(
table: "Settings",
columns: new[] { "SettingId", "Type", "Value" },
values: new object[] { "RealDebridApiKey", "String", "" });
migrationBuilder.InsertData(
table: "Settings",
columns: new[] { "SettingId", "Type", "Value" },
values: new object[] { "DownloadFolder", "String", "C:\\Downloads" });
migrationBuilder.InsertData(
table: "Settings",
columns: new[] { "SettingId", "Type", "Value" },
values: new object[] { "DownloadLimit", "Int32", "10" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId", name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims", table: "AspNetRoleClaims",

View file

@ -2,6 +2,7 @@
using System; using System;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using RdtClient.Data.Data; using RdtClient.Data.Data;
namespace RdtClient.Data.Migrations namespace RdtClient.Data.Migrations
@ -13,7 +14,7 @@ namespace RdtClient.Data.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.3"); .HasAnnotation("ProductVersion", "5.0.1");
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{ {
@ -25,18 +26,18 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Name") b.Property<string>("Name")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("NormalizedName") b.Property<string>("NormalizedName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("NormalizedName") b.HasIndex("NormalizedName")
.IsUnique() .IsUnique()
.HasName("RoleNameIndex"); .HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles"); b.ToTable("AspNetRoles");
}); });
@ -77,8 +78,8 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Email") b.Property<string>("Email")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed") b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -90,12 +91,12 @@ namespace RdtClient.Data.Migrations
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("NormalizedEmail") b.Property<string>("NormalizedEmail")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("NormalizedUserName") b.Property<string>("NormalizedUserName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.Property<string>("PasswordHash") b.Property<string>("PasswordHash")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -113,17 +114,17 @@ namespace RdtClient.Data.Migrations
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("UserName") b.Property<string>("UserName")
.HasColumnType("TEXT") .HasMaxLength(256)
.HasMaxLength(256); .HasColumnType("TEXT");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("NormalizedEmail") b.HasIndex("NormalizedEmail")
.HasName("EmailIndex"); .HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName") b.HasIndex("NormalizedUserName")
.IsUnique() .IsUnique()
.HasName("UserNameIndex"); .HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers"); b.ToTable("AspNetUsers");
}); });
@ -246,26 +247,6 @@ namespace RdtClient.Data.Migrations
b.HasKey("SettingId"); b.HasKey("SettingId");
b.ToTable("Settings"); b.ToTable("Settings");
b.HasData(
new
{
SettingId = "RealDebridApiKey",
Type = "String",
Value = ""
},
new
{
SettingId = "DownloadFolder",
Type = "String",
Value = "C:\\Downloads"
},
new
{
SettingId = "DownloadLimit",
Type = "Int32",
Value = "10"
});
}); });
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b => modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
@ -388,6 +369,13 @@ namespace RdtClient.Data.Migrations
.HasForeignKey("TorrentId") .HasForeignKey("TorrentId")
.OnDelete(DeleteBehavior.Restrict) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.Navigation("Torrent");
});
modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
{
b.Navigation("Downloads");
}); });
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }

View file

@ -7,7 +7,7 @@ namespace RdtClient.Service.Middleware
{ {
public class AuthorizeMiddleware public class AuthorizeMiddleware
{ {
readonly RequestDelegate _next; private readonly RequestDelegate _next;
public AuthorizeMiddleware(RequestDelegate next) public AuthorizeMiddleware(RequestDelegate next)
{ {

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using RdtClient.Data.Data; using RdtClient.Data.Data;
using RdtClient.Data.Models.Data; using RdtClient.Data.Models.Data;
@ -12,6 +13,7 @@ namespace RdtClient.Service.Services
Task Update(IList<Setting> settings); Task Update(IList<Setting> settings);
Task<String> GetString(String key); Task<String> GetString(String key);
Task<Int32> GetNumber(String key); Task<Int32> GetNumber(String key);
Task TestFolder(String folder);
} }
public class Settings : ISettings public class Settings : ISettings
@ -56,5 +58,25 @@ namespace RdtClient.Service.Services
return Int32.Parse(setting.Value); return Int32.Parse(setting.Value);
} }
public async Task TestFolder(String folder)
{
if (String.IsNullOrWhiteSpace(folder))
{
throw new Exception("Folder path is not set");
}
folder = folder.TrimEnd('/').TrimEnd('\\');
if (!Directory.Exists(folder))
{
throw new Exception($"Folder {folder} does not exist");
}
var testFile = $"{folder}/test.txt";
await File.WriteAllTextAsync(testFile, "RealDebridClient Test File, you can remove this file.");
File.Delete(testFile);
}
} }
} }

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -46,10 +47,24 @@ namespace RdtClient.Web.Controllers
var profile = await _torrents.GetProfile(); var profile = await _torrents.GetProfile();
return Ok(profile); return Ok(profile);
} }
[HttpPost]
[Route("TestFolder")]
public async Task<ActionResult<Profile>> TestFolder([FromBody] SettingsControllerTestFolderRequest request)
{
await _settings.TestFolder(request.Folder);
return Ok();
}
} }
public class SettingsControllerUpdateRequest public class SettingsControllerUpdateRequest
{ {
public IList<Setting> Settings { get; set; } public IList<Setting> Settings { get; set; }
} }
public class SettingsControllerTestFolderRequest
{
public String Folder { get; set; }
}
} }

View file

@ -2,9 +2,10 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection; using RdtClient.Data.Data;
using RdtClient.Service.Services; using RdtClient.Service.Services;
namespace RdtClient.Web namespace RdtClient.Web
@ -12,6 +13,15 @@ namespace RdtClient.Web
public class Program public class Program
{ {
public static async Task Main(String[] args) public static async Task Main(String[] args)
{
var host = CreateHostBuilder(args).Build();
DataMigration.Setup(host.Services.CreateScope());
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(String[] args)
{ {
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, false) .AddJsonFile("appsettings.json", true, false)
@ -24,47 +34,24 @@ namespace RdtClient.Web
hostUrl = "http://0.0.0.0:6500"; hostUrl = "http://0.0.0.0:6500";
} }
await Host.CreateDefaultBuilder(args) return Host.CreateDefaultBuilder(args)
.UseWindowsService() .UseWindowsService()
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddHostedService<TaskRunner>(); services.AddHostedService<TaskRunner>();
}) })
.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
{ {
webBuilder.ConfigureLogging(logging => webBuilder.ConfigureLogging(logging =>
{ {
logging.ClearProviders(); logging.ClearProviders();
logging.AddConsole(); logging.AddConsole();
logging.AddFile($"{AppContext.BaseDirectory}app.log"); logging.AddFile($"{AppContext.BaseDirectory}app.log");
}) })
.UseUrls(hostUrl) .UseUrls(hostUrl)
.UseKestrel() .UseKestrel()
.UseStartup<Startup>(); .UseStartup<Startup>();
}) });
.Build()
.RunAsync();
} }
} }
/*public class Program
{
public static void Main(String[] args)
{
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.CaptureStartupErrors(false)
.UseStartup<Startup>()
.UseKestrel();
});
}
}*/
} }

View file

@ -123,8 +123,6 @@ namespace RdtClient.Web
spa.Options.DefaultPage = "/index.html"; spa.Options.DefaultPage = "/index.html";
}); });
}); });
dataContext.Migrate();
} }
} }
} }

View file

@ -0,0 +1,194 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/Browsers/Enable/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Eappxmanifest/@EntryIndexedValue">*.appxmanifest</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Ed_002Ets/@EntryIndexedValue">*.d.ts</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Edebug_002Ejs/@EntryIndexedValue">*.debug.js</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002EDesigner_002Ecs/@EntryIndexedValue">*.Designer.cs</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002EDesigner_002Evb/@EntryIndexedValue">*.Designer.vb</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002EGenerated_002Ecs/@EntryIndexedValue">*.Generated.cs</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002EGenerated_002Evb/@EntryIndexedValue">*.Generated.vb</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Eintellisense_002Ejs/@EntryIndexedValue">*.intellisense.js</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Emin_002Ecss/@EntryIndexedValue">*.min.css</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002Emin_002Ejs/@EntryIndexedValue">*.min.js</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002A_002EStoreAssociation_002Exml/@EntryIndexedValue">*.StoreAssociation.xml</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=_002Avsdoc_002Ejs/@EntryIndexedValue">*vsdoc.js</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Component_0020Designer_0020generated_0020code/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Component_0020Designer_0020generated_0020code/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Designer_0020generated_0020code/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Designer_0020generated_0020code/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=lib_002Ed_002Ets/@EntryIndexedValue">lib.d.ts</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Reference_002Evb/@EntryIndexedValue">Reference.vb</s:String>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Web_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Web_0020Form_0020Designer_0020generated_0020code/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Windows_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue"></s:String>
<s:Boolean x:Key="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Windows_0020Form_0020Designer_0020generated_0020code/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/GeneratedCode/GeneratedFileMasks/=_002A_002Ed_002Ets/@EntryIndexedValue">*.d.ts</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeLocalFunctionBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMethodOrOperatorBody/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeModifiersOrder/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeRedundantParentheses/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeThisQualifier/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeMemberModifiers/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeTypeModifiers/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=BuiltInTypeReferenceStyle/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=BuiltInTypeReferenceStyleForMemberAccess/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002EGlobal/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverUpdated_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstantConditionalAccessQualifier/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToConditionalTernaryExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToNullCoalescingExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToUsingDeclaration/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EmptyStatement/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Html_002ECssClassNotUsed/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Html_002EObsolete/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Html_002EPathError/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImplicitAnyTypeWarning/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InlineOutVariableDeclaration/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvalidValue/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvertIf/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LocalizableElement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NotAccessedField_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=OptionalParameterHierarchyMismatch/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterTypeCanBeEnumerable_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PossibleInvalidOperationException/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=PossibleNullReferenceException/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAnonymousTypePropertyName/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantArgumentDefaultValue/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantCast/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantExplicitArrayCreation/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantNameQualifier/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantStringInterpolation/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantTypeArgumentsOfMethod/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantUsingDirective/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantVariableTypeSpecification/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RemoveRedundantBraces/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyVariableTypeExplicitly/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StatementIsNotTerminated/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringConcatenationToTemplateString/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralWrongQuotes/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestBaseTypeForParameter/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FElsewhere/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TailRecursiveCall/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnknownCssClass/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedParameter_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedVariable/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseStringInterpolation/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=VariableCanBeMadeConst/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=WrongPublicModifierSpecification/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Xaml_002EBindingWithContextNotResolved/@EntryIndexedValue">ERROR</s:String>
<s:Boolean x:Key="/Default/CodeInspection/Highlighting/SuppressVsSquiggles/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CommonFormatter/END_OF_LINE/@EntryValue">CRLF</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CommonFormatter/ENFORCE_LINE_ENDING_STYLE/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BUILTIN_TYPE_REFERENCE_FOR_MEMBER_ACCESS_STYLE/@EntryValue">UseClrName</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BUILTIN_TYPE_REFERENCE_STYLE/@EntryValue">UseClrName</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_NON_OBVIOUS_OPERATIONS/@EntryValue">Arithmetic, Shift, Bitwise</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_FIRST_ARG_BY_PAREN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_CONTROL_TRANSFER_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_MULTILINE_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_START_COMMENT/@EntryValue">0</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_BLOCK_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_CONTROL_TRANSFER_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_MULTILINE_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_SINGLE_LINE_COMMENT/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_INSIDE_REGION/@EntryValue">0</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FIXED_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOR_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOREACH_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_IFELSE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_USING_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FIXED_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_USINGS_STMT/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_REGION/@EntryValue">NO_INDENT</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_SWITCH_EXPRESSION_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_INITIALIZER_ELEMENTS_ON_LINE/@EntryValue">1</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_INITIALIZER_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_WHILE_ON_NEW_LINE/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/USE_INDENT_FROM_VS/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARRAY_INITIALIZER_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_FIRST_TYPE_PARAMETER_CONSTRAINT/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">180</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINQ_EXPRESSIONS/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_DECLARATION_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_TYPE_PARAMEER_CONSTRAINTS_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_OBJECT_AND_COLLECTION_INITIALIZER_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/SyncToVisualStudio/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=DisposePattern/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=DisposePattern/Options/=ChangeFinalize/@EntryIndexedValue">Replace</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">True</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=PropertyBody/@EntryIndexedValue">Default body (from options)</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=PropertyBody/@EntryIndexedValue">Default body (from options)</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AWS/@EntryIndexedValue">AWS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FQL/@EntryIndexedValue">FQL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HCP/@EntryIndexedValue">HCP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QA/@EntryIndexedValue">QA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QB/@EntryIndexedValue">QB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XML/@EntryIndexedValue">XML</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FHTML_005FCONTROL/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FNAME/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FPREFIX/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=NAMESPACE_005FALIAS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>