Compare commits

...

5 Commits

Author SHA1 Message Date
663b6b03ea Build docker containers
Some checks failed
Build and Push Docker Image / build (push) Failing after 1m50s
2026-03-17 21:36:23 +01:00
c489503403 New: tooling_container 2026-03-17 21:36:14 +01:00
9ed7eb8e60 Fix: RollbackService.cs 2026-03-17 21:35:38 +01:00
27a90d2847 Einheit 4: SmartRent ASPNETCORE Blazor Web App 2026-03-17 21:13:33 +01:00
e897ffe9d9 Bulk: Einheit 1-3 2026-03-17 20:25:47 +01:00
92 changed files with 63188 additions and 50 deletions

View File

@@ -0,0 +1,38 @@
name: Build and Push Docker Image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
container:
image: quay.io/buildah/stable
options: --security-opt seccomp=unconfined --security-opt apparmor=unconfined --device /dev/fuse:rw --privileged
env:
BUILDAH_ISOLATION: chroot
STORAGE_DRIVER: vfs
steps:
- name: Install Node.js
run: dnf install -y nodejs git
- uses: actions/checkout@v4
- name: Login to Registry
run: buildah login -u ${{ secrets.REGISTRY_USER }} -p ${{ secrets.REGISTRY_PASSWORD }} git.kocoder.xyz
- name: Buildah Build
run: |
buildah build -t ${{ github.sha }} ./Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/Dockerfile
buildah build -t ${{ github.sha }}-tooling ./Einheit_4/tooling_container/Dockerfile
buildah tag ${{ github.sha }} latest
- name: Push Docker Images
run: |
buildah push ${{ github.sha }} docker://git.kocoder.xyz/kocoded/2025_5BHITN_Hintermayer_Konstantin_smarterrent_db:${{ github.sha }}
buildah push ${{ github.sha }}-tooling docker://git.kocoder.xyz/kocoded/2025_5BHITN_Hintermayer_Konstantin_smarterrent_db_init_db:${{ github.sha }}
buildah push latest docker://git.kocoder.xyz/kocoded/2025_5BHITN_Hintermayer_Konstantin_smarterrent_db:latest

View File

@@ -3,71 +3,67 @@ GO
USE "2025_5bhitn_konstantin_hintermayer_smarter_rentDB";
GO
DROP TABLE IF EXISTS Rental;
CREATE TABLE Customer
(
id BIGINT NOT NULL IDENTITY(1,1),
name VARCHAR(50) NOT NULL,
Adress VARCHAR(100) NOT NULL,
driverlicenseid VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
DROP TABLE IF EXISTS Customer;
DROP TABLE IF EXISTS [Location];
DROP TABLE IF EXISTS Vehicle;
DROP TABLE IF EXISTS VehicleCategory;
CREATE TABLE Customer (
id BIGINT NOT NULL IDENTITY (1, 1),
[name] VARCHAR(50) NOT NULL,
Adress VARCHAR(100) NOT NULL,
driverlicenseid VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE Location
(
id BIGINT NOT NULL IDENTITY(1,1),
name VARCHAR NOT NULL,
address VARCHAR NOT NULL,
PRIMARY KEY (id)
CREATE TABLE Location (
id BIGINT NOT NULL IDENTITY (1, 1),
[name] VARCHAR(250) NOT NULL,
[address] VARCHAR(250) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE Rental
(
id BIGINT NOT NULL IDENTITY(1,1),
rentalStart DATETIME NOT NULL,
rentalEnd DATETIME NOT NULL,
actualEnd DATETIME NOT NULL,
customerID BIGINT NOT NULL,
vehicleID BIGINT NOT NULL,
PRIMARY KEY (id)
CREATE TABLE Rental (
id BIGINT NOT NULL IDENTITY (1, 1),
rentalStart DATETIME NOT NULL,
rentalEnd DATETIME NOT NULL,
actualEnd DATETIME NULL,
customerID BIGINT NOT NULL,
vehicleID BIGINT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE Vehicle
(
id BIGINT NOT NULL IDENTITY(1,1),
brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
licensePlate VARCHAR(8) NOT NULL,
buyDate DATE NOT NULL,
locationID BIGINT NOT NULL,
vehicleCategoryID BIGINT NOT NULL,
PRIMARY KEY (id)
CREATE TABLE Vehicle (
id BIGINT NOT NULL IDENTITY (1, 1),
brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
licensePlate VARCHAR(8) NOT NULL,
buyDate DATE NOT NULL,
locationID BIGINT NOT NULL,
vehicleCategoryID BIGINT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE VehicleCategory
(
id BIGINT NOT NULL IDENTITY(1,1),
description Varchar NOT NULL,
pricePerDay DECIMAL NOT NULL,
PRIMARY KEY (id)
CREATE TABLE VehicleCategory (
id BIGINT NOT NULL IDENTITY (1, 1),
[description] VARCHAR(250) NOT NULL,
pricePerDay DECIMAL NOT NULL,
PRIMARY KEY (id)
);
ALTER TABLE Rental
ADD CONSTRAINT FK_Customer_TO_Rental
FOREIGN KEY (customerID)
REFERENCES Customer (id);
ADD CONSTRAINT FK_Customer_TO_Rental FOREIGN KEY (customerID) REFERENCES Customer (id);
ALTER TABLE Rental
ADD CONSTRAINT FK_Vehicle_TO_Rental
FOREIGN KEY (vehicleID)
REFERENCES Vehicle (id);
ADD CONSTRAINT FK_Vehicle_TO_Rental FOREIGN KEY (vehicleID) REFERENCES Vehicle (id);
ALTER TABLE Vehicle
ADD CONSTRAINT FK_Location_TO_Vehicle
FOREIGN KEY (locationID)
REFERENCES Location (id);
ADD CONSTRAINT FK_Location_TO_Vehicle FOREIGN KEY (locationID) REFERENCES Location (id);
ALTER TABLE Vehicle
ADD CONSTRAINT FK_VehicleCategory_TO_Vehicle
FOREIGN KEY (vehicleCategoryID)
REFERENCES VehicleCategory (id);
ADD CONSTRAINT FK_VehicleCategory_TO_Vehicle FOREIGN KEY (vehicleCategoryID) REFERENCES VehicleCategory (id);

View File

@@ -0,0 +1,137 @@
-- Insert test data into the Location table
INSERT INTO [dbo].[Location] ([name], [address])
VALUES
('Downtown Office', '123 Main St, Cityville'),
('Airport Terminal', '456 Airport Rd, Cityville'),
('City Center', '789 Central Ave, Cityville'),
('Suburban Outlet', '321 Suburb St, Cityville'),
('Train Station', '654 Rail Rd, Cityville');
-- Insert test data into the VehicleCategory table
INSERT INTO VehicleCategory ([description], [pricePerDay])
VALUES
('Compact Car', 29.99),
('SUV', 49.99),
('Luxury Sedan', 89.99),
('Minivan', 59.99),
('Pickup Truck', 69.99);
-- Insert test data into the Vehicle table
INSERT INTO Vehicle (brand, model, licensePlate, buyDate, locationID, vehicleCategoryID)
VALUES
('Toyota', 'Corolla', 'ABC1234', '2020-06-15', 1, 1),
('Honda', 'CR-V', 'XYZ5678', '2019-03-22', 2, 2),
('BMW', '5 Series', 'LMN9012', '2021-01-10', 3, 3),
('Ford', 'Transit', 'GHI3456', '2020-11-05', 4, 4),
('Chevrolet', 'Silverado', 'JKL7890', '2018-07-19', 5, 5);
-- Insert test data into the Customer table
INSERT INTO Customer (name, Adress, driverlicenseid)
VALUES
('John Doe', '1 Elm St, Cityville', 'D123456789'),
('Jane Smith', '2 Oak St, Cityville', 'D987654321'),
('Bob Johnson', '3 Pine St, Cityville', 'D456123789'),
('Alice Williams', '4 Maple St, Cityville', 'D654789123'),
('Charlie Brown', '5 Cedar St, Cityville', 'D321654987');
GO
-- ########################################################
-- # Views #
-- ########################################################
-- View: v_VerfuegbareFahrzeuge
-- Zeigt Fahrzeuge an, die nicht vermietet sind oder deren Rückgabedatum in der Vergangenheit liegt
CREATE OR ALTER VIEW v_VerfuegbareFahrzeuge AS
SELECT
v.id,
v.brand,
v.model,
v.licensePlate,
vc.description AS category,
vc.pricePerDay,
l.name AS location,
l.address AS locationAddress,
CASE
WHEN r.id IS NULL THEN 'Available'
WHEN r.rentalEnd < CAST(GETDATE() AS DATE) THEN 'Available (Overdue Return)'
ELSE 'Not Available'
END AS status
FROM Vehicle v
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
JOIN Location l ON v.locationID = l.id
LEFT JOIN Rental r ON v.id = r.vehicleID AND r.actualEnd IS NULL
WHERE r.id IS NULL OR r.actualEnd < CAST(GETDATE() AS DATE);
GO
-- View: v_UmsatzProKategorie
-- Zeigt den kumulierten Umsatz pro Fahrzeugkategorie an
CREATE OR ALTER VIEW v_UmsatzProKategorie AS
SELECT
vc.id,
vc.description AS category,
vc.pricePerDay,
COUNT(r.id) AS totalRentals,
SUM(
DATEDIFF(DAY, r.rentalStart, COALESCE(r.rentalEnd, CAST(GETDATE() AS DATE)))
* vc.pricePerDay
) AS totalRevenue
FROM VehicleCategory vc
LEFT JOIN Vehicle v ON vc.id = v.vehicleCategoryID
LEFT JOIN Rental r ON v.id = r.vehicleID
GROUP BY
vc.id,
vc.description,
vc.pricePerDay;
GO
-- ########################################################
-- # User Defined Functions #
-- ########################################################
-- Scalar Function: fn_BerechneMietkosten
CREATE OR ALTER FUNCTION fn_BerechneMietkosten (
@StartDatum DATE,
@EndDatum DATE,
@Tagespreis DECIMAL(10, 2)
)
RETURNS DECIMAL(10, 2)
AS
BEGIN
DECLARE @AnzahlTage INT;
DECLARE @Mietkosten DECIMAL(10, 2);
-- Berechne die Anzahl der Tage (mindestens 1 Tag)
SET @AnzahlTage = DATEDIFF(DAY, @StartDatum, @EndDatum);
-- Falls das Enddatum vor oder gleich dem Startdatum ist, sind es mindestens 1 Tag
IF @AnzahlTage < 1
SET @AnzahlTage = 1;
-- Berechne die Gesamtkosten
SET @Mietkosten = @AnzahlTage * @Tagespreis;
RETURN @Mietkosten;
END;
GO
-- Table-Valued Function: fn_FahrzeugeAnStandort
CREATE OR ALTER FUNCTION fn_FahrzeugeAnStandort (
@StandortID INT
)
RETURNS TABLE
AS
RETURN (
SELECT
v.id,
v.brand,
v.model,
v.licensePlate,
v.buyDate,
vc.description AS category,
vc.pricePerDay,
l.name AS locationName,
l.address AS locationAddress
FROM Vehicle v
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
JOIN Location l ON v.locationID = l.id
WHERE v.locationID = @StandortID
);

View File

@@ -0,0 +1,205 @@
-- ####################################################
-- # STORED PROCEDURES #
-- ####################################################
-- Stored Procedure: sp_MieteFahrzeug
CREATE OR ALTER PROCEDURE sp_MieteFahrzeug
@KundeID BIGINT,
@FahrzeugID BIGINT,
@Start DATE,
@Ende DATE
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @VerfuegbareFahrzeuge INT;
BEGIN TRY
BEGIN TRANSACTION;
-- Prüfe, ob Kunde existiert
IF NOT EXISTS (SELECT 1 FROM Customer WHERE id = @KundeID)
BEGIN
RAISERROR('Kunde mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Prüfe, ob Fahrzeug existiert
IF NOT EXISTS (SELECT 1 FROM Vehicle WHERE id = @FahrzeugID)
BEGIN
RAISERROR('Fahrzeug mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Prüfe, ob Enddatum nach Startdatum liegt
IF @Ende <= @Start
BEGIN
RAISERROR('Das Enddatum muss nach dem Startdatum liegen.', 16, 1);
END;
-- Prüfe Verfügbarkeit des Fahrzeugs
SELECT @VerfuegbareFahrzeuge = COUNT(*)
FROM Rental
WHERE vehicleID = @FahrzeugID
-- Ein Fahrzeug ist besetzt, wenn der neue Zeitraum sich mit einem bestehenden überschneidet
-- und noch nicht zurückgegeben wurde (actualEnd IS NULL)
AND actualEnd IS NULL
AND (
(@Start < rentalEnd)
AND (@Ende > rentalStart)
);
IF @VerfuegbareFahrzeuge > 0
BEGIN
RAISERROR('Das Fahrzeug ist im angegebenen Zeitraum nicht verfügbar.', 16, 1);
END;
-- Erstelle den Mietdatensatz
-- Hinweis: actualEnd ist initial NULL
INSERT INTO Rental (customerID, vehicleID, rentalStart, rentalEnd, actualEnd)
VALUES (@KundeID, @FahrzeugID, @Start, @Ende, NULL);
DECLARE @MietID BIGINT = SCOPE_IDENTITY();
COMMIT TRANSACTION;
-- Rückgabewert
SELECT
@MietID AS id,
'Mietvertrag erfolgreich erstellt.' AS message,
@Start AS rentalStart,
@Ende AS rentalEnd;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMssp_MieteFahrzeug NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMssp_MieteFahrzeug, 16, 1);
END CATCH;
END;
GO
-- Stored Procedure: sp_RueckgabeFahrzeug
-- Aktualisiert actualEnd und berechnet Endpreis via UDF
-- Stored Procedure: sp_RueckgabeFahrzeug
-- Aktualisiert actualEnd und berechnet Endpreis via UDF
CREATE OR ALTER PROCEDURE sp_RueckgabeFahrzeug
@MietID BIGINT,
@RueckgabeDatum DATETIME
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @Tagespreis DECIMAL(10, 2);
DECLARE @StartDatum DATE;
DECLARE @Endpreis DECIMAL(10, 2);
BEGIN TRY
BEGIN TRANSACTION;
-- Prüfe, ob Miet-ID existiert
IF NOT EXISTS (SELECT 1 FROM Rental WHERE id = @MietID)
BEGIN
RAISERROR('Mietvertrag mit der angegebenen ID existiert nicht.', 16, 1);
END;
-- Hole Start-Datum und Tagespreis (aus VehicleCategory via Vehicle)
SELECT
@StartDatum = r.rentalStart,
@Tagespreis = vc.pricePerDay
FROM Rental r
JOIN Vehicle v ON r.vehicleID = v.id
JOIN VehicleCategory vc ON v.vehicleCategoryID = vc.id
WHERE r.id = @MietID;
-- Berechne den Endpreis mit Hilfe der UDF aus Einheit 2
SET @Endpreis = dbo.fn_BerechneMietkosten(@StartDatum, @RueckgabeDatum, @Tagespreis);
-- Prüfe, ob Rückgabedatum nach Startdatum liegt
IF @RueckgabeDatum < @StartDatum
BEGIN
RAISERROR('Das Rückgabedatum kann nicht vor dem Mietstart liegen.', 16, 1);
END;
-- Aktualisiere den Rental-Datensatz (actualEnd)
UPDATE Rental
SET
actualEnd = @RueckgabeDatum
WHERE id = @MietID;
COMMIT TRANSACTION;
-- Rückgabewert
SELECT
@MietID AS id,
'Fahrzeug erfolgreich zurückgegeben.' AS message,
@RueckgabeDatum AS actualEnd,
@Endpreis AS calculatedTotalPrice;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMssp_RueckgabeFahrzeug NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMssp_RueckgabeFahrzeug, 16, 1);
END CATCH;
END;
GO
-- =====================================================
-- TRIGGER
-- =====================================================
-- Hinweis: Die Status-Update Trigger wurden entfernt, da die Tabelle 'Vehicle'
-- laut Schema keine 'status' Spalte besitzt. Die Verfügbarkeit wird
-- dynamisch über Views (v_VerfuegbareFahrzeuge) ermittelt.
-- Archive table for Customer (if not exists)
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='CustomerArchiv' AND xtype='U')
BEGIN
CREATE TABLE CustomerArchiv (
id BIGINT NOT NULL,
name VARCHAR(50) NOT NULL,
Adress VARCHAR(100) NOT NULL,
driverlicenseid VARCHAR(100) NOT NULL,
deletedDate DATETIME NOT NULL,
PRIMARY KEY (id, deletedDate)
);
END;
GO
-- Trigger: trg_Archivierung
-- Kopiert gelöschte Kunden in KundenArchiv-Tabelle statt physisch zu löschen
CREATE OR ALTER TRIGGER trg_Archivierung
ON Customer
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- Kopiere gelöschte Kunden in die Archiv-Tabelle
INSERT INTO CustomerArchiv (id, name, Adress, driverlicenseid, deletedDate)
SELECT
id,
name,
Adress,
driverlicenseid,
GETDATE()
FROM deleted;
-- Lösche den Datensatz nur, wenn die Archivierung erfolgreich war
DELETE FROM Customer
WHERE id IN (SELECT id FROM deleted);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
DECLARE @ErrMsstrg_Archivierung NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(@ErrMsstrg_Archivierung, 16, 1);
END CATCH;
END;
GO

View File

@@ -0,0 +1,3 @@
<Solution>
<Project Path="2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj" />
</Solution>

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.4" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<ResourcePreloader />
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["2025_5BHITN_Konstantin_Hintermayer_smarterrent.styles.css"]" />
<ImportMap />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<ReconnectModal />
<script src="@Assets["_framework/blazor.web.js"]"></script>
</body>
</html>

View File

@@ -0,0 +1,19 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui" data-nosnippet>
An unhandled error has occurred.
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>

View File

@@ -0,0 +1,106 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a,
.top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover,
.top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a,
.top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row,
article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
color-scheme: light only;
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
table {
background-color: #3a0647;
}

View File

@@ -0,0 +1,30 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">SmartRent</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="nav flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Available Vehicles
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="rent">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Rent
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="rollback">
Rollback
</NavLink>
</div>
</nav>
</div>

View File

@@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
min-height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@@ -0,0 +1,31 @@
<script type="module" src="@Assets["Components/Layout/ReconnectModal.razor.js"]"></script>
<dialog id="components-reconnect-modal" data-nosnippet>
<div class="components-reconnect-container">
<div class="components-rejoining-animation" aria-hidden="true">
<div></div>
<div></div>
</div>
<p class="components-reconnect-first-attempt-visible">
Rejoining the server...
</p>
<p class="components-reconnect-repeated-attempt-visible">
Rejoin failed... trying again in <span id="components-seconds-to-next-attempt"></span> seconds.
</p>
<p class="components-reconnect-failed-visible">
Failed to rejoin.<br />Please retry or reload the page.
</p>
<button id="components-reconnect-button" class="components-reconnect-failed-visible">
Retry
</button>
<p class="components-pause-visible">
The session has been paused by the server.
</p>
<p class="components-resume-failed-visible">
Failed to resume the session.<br />Please retry or reload the page.
</p>
<button id="components-resume-button" class="components-pause-visible components-resume-failed-visible">
Resume
</button>
</div>
</dialog>

View File

@@ -0,0 +1,157 @@
.components-reconnect-first-attempt-visible,
.components-reconnect-repeated-attempt-visible,
.components-reconnect-failed-visible,
.components-pause-visible,
.components-resume-failed-visible,
.components-rejoining-animation {
display: none;
}
#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible,
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-paused .components-pause-visible,
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible,
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible {
display: block;
}
#components-reconnect-modal {
background-color: white;
width: 20rem;
margin: 20vh auto;
padding: 2rem;
border: 0;
border-radius: 0.5rem;
box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
animation: components-reconnect-modal-fadeOutOpacity 0.5s both;
&[open]
{
animation: components-reconnect-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity 0.5s ease-in-out 0.3s;
animation-fill-mode: both;
}
}
#components-reconnect-modal::backdrop {
background-color: rgba(0, 0, 0, 0.4);
animation: components-reconnect-modal-fadeInOpacity 0.5s ease-in-out;
opacity: 1;
}
@keyframes components-reconnect-modal-slideUp {
0% {
transform: translateY(30px) scale(0.95);
}
100% {
transform: translateY(0);
}
}
@keyframes components-reconnect-modal-fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes components-reconnect-modal-fadeOutOpacity {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.components-reconnect-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
#components-reconnect-modal p {
margin: 0;
text-align: center;
}
#components-reconnect-modal button {
border: 0;
background-color: #6b9ed2;
color: white;
padding: 4px 24px;
border-radius: 4px;
}
#components-reconnect-modal button:hover {
background-color: #3b6ea2;
}
#components-reconnect-modal button:active {
background-color: #6b9ed2;
}
.components-rejoining-animation {
position: relative;
width: 80px;
height: 80px;
}
.components-rejoining-animation div {
position: absolute;
border: 3px solid #0087ff;
opacity: 1;
border-radius: 50%;
animation: components-rejoining-animation 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
.components-rejoining-animation div:nth-child(2) {
animation-delay: -0.5s;
}
@keyframes components-rejoining-animation {
0% {
top: 40px;
left: 40px;
width: 0;
height: 0;
opacity: 0;
}
4.9% {
top: 40px;
left: 40px;
width: 0;
height: 0;
opacity: 0;
}
5% {
top: 40px;
left: 40px;
width: 0;
height: 0;
opacity: 1;
}
100% {
top: 0px;
left: 0px;
width: 80px;
height: 80px;
opacity: 0;
}
}

View File

@@ -0,0 +1,63 @@
// Set up event handlers
const reconnectModal = document.getElementById("components-reconnect-modal");
reconnectModal.addEventListener("components-reconnect-state-changed", handleReconnectStateChanged);
const retryButton = document.getElementById("components-reconnect-button");
retryButton.addEventListener("click", retry);
const resumeButton = document.getElementById("components-resume-button");
resumeButton.addEventListener("click", resume);
function handleReconnectStateChanged(event) {
if (event.detail.state === "show") {
reconnectModal.showModal();
} else if (event.detail.state === "hide") {
reconnectModal.close();
} else if (event.detail.state === "failed") {
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
} else if (event.detail.state === "rejected") {
location.reload();
}
}
async function retry() {
document.removeEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
try {
// Reconnect will asynchronously return:
// - true to mean success
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
// - exception to mean we didn't reach the server (this can be sync or async)
const successful = await Blazor.reconnect();
if (!successful) {
// We have been able to reach the server, but the circuit is no longer available.
// We'll reload the page so the user can continue using the app as quickly as possible.
const resumeSuccessful = await Blazor.resumeCircuit();
if (!resumeSuccessful) {
location.reload();
} else {
reconnectModal.close();
}
}
} catch (err) {
// We got an exception, server is currently unavailable
document.addEventListener("visibilitychange", retryWhenDocumentBecomesVisible);
}
}
async function resume() {
try {
const successful = await Blazor.resumeCircuit();
if (BlazorApp3!successful) {
location.reload();
}
} catch {
reconnectModal.classList.replace("components-reconnect-paused", "components-reconnect-resume-failed");
}
}
async function retryWhenDocumentBecomesVisible() {
if (document.visibilityState === "visible") {
await retry();
}
}

View File

@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@@ -0,0 +1,53 @@
@page "/"
@using Models
@using Services
@inject IRentService RentService
<PageTitle>Home</PageTitle>
<h1>Available Vehicles</h1>
<table class="table table-striped">
<thead>
<tr>
<td>ID</td>
<td>Brand</td>
<td>Model</td>
<td>LicencePlate</td>
<td>Category</td>
<td>PricePerDay</td>
<td>Location</td>
<td>LocationAddress</td>
<td>Status</td>
</tr>
</thead>
<tbody>
@foreach (Vehicle v in _vehicles)
{
<tr>
<td>@v.Id</td>
<td>@v.Brand</td>
<td>@v.Model</td>
<td>@v.LicencePlate</td>
<td>@v.Category</td>
<td>@v.PricePerDay</td>
<td>@v.Location</td>
<td>@v.LocationAddress</td>
<td>@v.Status</td>
</tr>
}
</tbody>
</table>
@code {
private List<Vehicle> _vehicles = new List<Vehicle>();
protected override void OnInitialized()
{
_vehicles = RentService.GetAvailableCars();
Console.WriteLine("VC" + _vehicles.Count);
@* return Task.CompletedTask; *@
}
}

View File

@@ -0,0 +1,5 @@
@page "/not-found"
@layout MainLayout
<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>

View File

@@ -0,0 +1,55 @@
@page "/rent"
@using Models
@using Services
@inject IRentService RentService
@inject NavigationManager NavigationManager
<PageTitle>Rent</PageTitle>
<h1>Rent</h1>
<form @onsubmit="RentCar">
<InputSelect @bind-Value="_vehicleId">
@foreach (Vehicle v in _vehicles)
{
<option value=@v.Id>@v.Id - @v.Brand - @v.Model</option>
}
</InputSelect>
<InputSelect @bind-Value="_customerId">
@foreach (Customer c in _customers)
{
<option value=@c.Id>@c.Name</option>
}
</InputSelect>
<InputDate @bind-Value="_from"/>
<InputDate @bind-Value="_thru"/>
<button type="submit">Submit</button>
</form>
@code {
private List<Vehicle> _vehicles = new List<Vehicle>();
private List<Customer> _customers = new List<Customer>();
private long _vehicleId;
private long _customerId;
private DateTime _from = DateTime.Now;
private DateTime _thru = DateTime.Now;
protected override void OnInitialized()
{
_vehicles = RentService.GetAvailableCars();
_customers = RentService.GetCustomers();
}
private Task RentCar()
{
RentService.RentCar(_customerId, _vehicleId, _from, _thru);
Console.WriteLine("Rented Car");
NavigationManager.NavigateTo("/");
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,18 @@
@page "/rollback"
@using Models
@using Services
@inject IRollbackService RollbackService
<PageTitle>Rollback</PageTitle>
<h1>Reset to defaults</h1>
<button @onclick="PerformRollback" class="btn btn-danger">Rolback Database</button>
@code {
private Task PerformRollback() {
RollbackService.ResetToDefaults();
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

View File

@@ -0,0 +1,11 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using _2025_5BHITN_Konstantin_Hintermayer_smarterrent
@using _2025_5BHITN_Konstantin_Hintermayer_smarterrent.Components
@using _2025_5BHITN_Konstantin_Hintermayer_smarterrent.Components.Layout

View File

@@ -0,0 +1,22 @@
using Configuration;
using Microsoft.Extensions.Options;
using Services;
public static class ServiceCollectionExtension
{
public static WebApplicationBuilder AddCustomComponents(this WebApplicationBuilder services)
{
services.Services.AddOptions<SqlConnectionOptions>().BindConfiguration("SqlConnectionFactory");
services.Services.AddSingleton<SqlConnectionFactory>(sp =>
{
var options = sp.GetService<IOptions<SqlConnectionOptions>>()!.Value;
return new SqlConnectionFactory(options.ConnectionUrl);
});
services.Services.AddScoped<IRentService, RentService>();
services.Services.AddScoped<IRollbackService, RollbackService>();
return services;
}
}

View File

@@ -0,0 +1,26 @@
using Microsoft.Data.SqlClient;
namespace Configuration
{
public class SqlConnectionOptions
{
public required string ConnectionUrl { get; set; }
}
public class SqlConnectionFactory
{
private readonly string _connectionUrl;
public SqlConnectionFactory(string connectionUrl)
{
_connectionUrl = connectionUrl;
}
public SqlConnection CreateSqlConnection()
{
SqlConnection conn = new SqlConnection(_connectionUrl);
conn.Open();
return conn;
}
}
}

View File

@@ -0,0 +1,15 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:10.0
WORKDIR /App
COPY --from=build /App/out .
ENTRYPOINT ["dotnet", "2025_5BHITN_Konstantin_Hintermayer_smarterrent.dll"]

View File

@@ -0,0 +1,23 @@
using Microsoft.Data.SqlClient;
namespace Models;
public class Customer
{
public required long Id { get; set; }
public required string Name { get; set; }
public required string Adress { get; set; }
public required string DriverlicenseId { get; set; }
public static Customer FromReader(SqlDataReader reader)
{
return new Customer
{
Id = (long)reader["id"],
Name = (string)reader["name"],
Adress = (string)reader["Adress"],
DriverlicenseId = (string)reader["driverlicenseid"],
};
}
}

View File

@@ -0,0 +1,33 @@
using Microsoft.Data.SqlClient;
namespace Models;
public class Vehicle
{
public required long Id { get; set; }
public required string Brand { get; set; }
public required string Model { get; set; }
public required string LicencePlate { get; set; }
public required string Category { get; set; }
public required decimal PricePerDay { get; set; }
public required string Location { get; set; }
public required string LocationAddress { get; set; }
public required string Status { get; set; }
public static Vehicle FromReader(SqlDataReader reader)
{
return new Vehicle
{
Id = (long)reader["id"],
Brand = (string)reader["brand"],
Model = (string)reader["model"],
LicencePlate = (string)reader["licensePlate"],
Category = (string)reader["category"],
PricePerDay = (decimal)reader["pricePerDay"],
Location = (string)reader["location"],
LocationAddress = (string)reader["locationAddress"],
Status = (string)reader["status"]
};
}
}

View File

@@ -0,0 +1,29 @@
using _2025_5BHITN_Konstantin_Hintermayer_smarterrent.Components;
var builder = WebApplication.CreateBuilder(args);
builder.AddCustomComponents();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection();
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5170",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7000;http://localhost:5170",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,19 @@
SELECT * FROM Vehicle;
SELECT * FROM Rental;
SELECT * FROM v_VerfuegbareFahrzeuge;
-- Create Snapshot;
CREATE DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB_snapshot]
ON
(
NAME = [2025_5bhitn_konstantin_hintermayer_smarter_rentDB],
FILENAME = N'/var/opt/mssql/data/smarter_rentDB.ss'
) AS SNAPSHOT OF [2025_5bhitn_konstantin_hintermayer_smarter_rentDB];
GO
-- Restore Snapshot
USE [master];
ALTER DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB] FROM DATABASE_SNAPSHOT = '2025_5bhitn_konstantin_hintermayer_smarter_rentDB_snapshot';
GO

View File

@@ -0,0 +1,85 @@
using System.Data;
using Configuration;
using Microsoft.Data.SqlClient;
using Models;
namespace Services
{
public interface IRentService
{
void RentCar(long customerId,long vehicleId, DateTime start, DateTime end);
List<Vehicle> GetAvailableCars();
List<Customer> GetCustomers();
}
public class RentService(SqlConnectionFactory sqlConnectionFactory) : IRentService
{
public List<Vehicle> GetAvailableCars()
{
List<Vehicle> vehicles = new List<Vehicle>();
try
{
using SqlConnection conn = sqlConnectionFactory.CreateSqlConnection();
string sql = "SELECT * FROM v_VerfuegbareFahrzeuge;";
SqlCommand cmd = new SqlCommand(sql, conn);
using SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
vehicles.Add(Vehicle.FromReader(reader));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return vehicles;
}
public List<Customer> GetCustomers()
{
List<Customer> customers = new List<Customer>();
try
{
using SqlConnection conn = sqlConnectionFactory.CreateSqlConnection();
string sql = "SELECT * FROM Customer;";
SqlCommand cmd = new SqlCommand(sql, conn);
using SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
customers.Add(Customer.FromReader(reader));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return customers;
}
public void RentCar(long customerId, long vehicleId, DateTime start, DateTime end)
{
try
{
using SqlConnection conn = sqlConnectionFactory.CreateSqlConnection();
using SqlCommand cmd = new SqlCommand("sp_MieteFahrzeug", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@KundeID", customerId);
cmd.Parameters.AddWithValue("@FahrzeugID", vehicleId);
cmd.Parameters.AddWithValue("@Start", start);
cmd.Parameters.AddWithValue("@Ende", end);
cmd.ExecuteNonQuery();
}catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System.Data;
using Configuration;
using Microsoft.Data.SqlClient;
using Models;
namespace Services
{
public interface IRollbackService
{
void ResetToDefaults();
}
public class RollbackService(SqlConnectionFactory sqlConnectionFactory) : IRollbackService
{
public void ResetToDefaults()
{
try
{
using SqlConnection conn = sqlConnectionFactory.CreateSqlConnection();
string sql = @"
USE [master];
ALTER DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB] FROM DATABASE_SNAPSHOT = '2025_5bhitn_konstantin_hintermayer_smarter_rentDB_snapshot';
ALTER DATABASE [2025_5bhitn_konstantin_hintermayer_smarter_rentDB] SET MULTI_USER;";
using SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,497 @@
{
"format": 1,
"restore": {
"/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj": {}
},
"projects": {
"/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj",
"projectName": "2025_5BHITN_Konstantin_Hintermayer_smarterrent",
"projectPath": "/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj",
"packagesPath": "/home/kocoder/.nuget/packages/",
"outputPath": "/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/obj/",
"projectStyle": "PackageReference",
"configFilePaths": [
"/home/kocoder/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"net10.0"
],
"sources": {
"https://api.nuget.org/v3/index.json": {},
"https://git.kocoder.xyz/api/packages/Diplomarbeit-Absolventenverein/nuget/index.json": {}
},
"frameworks": {
"net10.0": {
"targetAlias": "net10.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "all"
},
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"net10.0": {
"targetAlias": "net10.0",
"dependencies": {
"Microsoft.AspNetCore.App.Internal.Assets": {
"suppressParent": "All",
"target": "Package",
"version": "[10.0.3, )",
"autoReferenced": true
},
"Microsoft.Data.SqlClient": {
"target": "Package",
"version": "[6.1.4, )"
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.AspNetCore.App": {
"privateAssets": "none"
},
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/10.0.103/PortableRuntimeIdentifierGraph.json",
"packagesToPrune": {
"Microsoft.AspNetCore": "(,10.0.32767]",
"Microsoft.AspNetCore.Antiforgery": "(,10.0.32767]",
"Microsoft.AspNetCore.App": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication.BearerToken": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication.Cookies": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication.Core": "(,10.0.32767]",
"Microsoft.AspNetCore.Authentication.OAuth": "(,10.0.32767]",
"Microsoft.AspNetCore.Authorization": "(,10.0.32767]",
"Microsoft.AspNetCore.Authorization.Policy": "(,10.0.32767]",
"Microsoft.AspNetCore.Components": "(,10.0.32767]",
"Microsoft.AspNetCore.Components.Authorization": "(,10.0.32767]",
"Microsoft.AspNetCore.Components.Endpoints": "(,10.0.32767]",
"Microsoft.AspNetCore.Components.Forms": "(,10.0.32767]",
"Microsoft.AspNetCore.Components.Server": "(,10.0.32767]",
"Microsoft.AspNetCore.Components.Web": "(,10.0.32767]",
"Microsoft.AspNetCore.Connections.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.CookiePolicy": "(,10.0.32767]",
"Microsoft.AspNetCore.Cors": "(,10.0.32767]",
"Microsoft.AspNetCore.Cryptography.Internal": "(,10.0.32767]",
"Microsoft.AspNetCore.Cryptography.KeyDerivation": "(,10.0.32767]",
"Microsoft.AspNetCore.DataProtection": "(,10.0.32767]",
"Microsoft.AspNetCore.DataProtection.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.DataProtection.Extensions": "(,10.0.32767]",
"Microsoft.AspNetCore.Diagnostics": "(,10.0.32767]",
"Microsoft.AspNetCore.Diagnostics.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Diagnostics.HealthChecks": "(,10.0.32767]",
"Microsoft.AspNetCore.HostFiltering": "(,10.0.32767]",
"Microsoft.AspNetCore.Hosting": "(,10.0.32767]",
"Microsoft.AspNetCore.Hosting.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Hosting.Server.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Html.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Http": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Connections": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Connections.Common": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Extensions": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Features": "(,10.0.32767]",
"Microsoft.AspNetCore.Http.Results": "(,10.0.32767]",
"Microsoft.AspNetCore.HttpLogging": "(,10.0.32767]",
"Microsoft.AspNetCore.HttpOverrides": "(,10.0.32767]",
"Microsoft.AspNetCore.HttpsPolicy": "(,10.0.32767]",
"Microsoft.AspNetCore.Identity": "(,10.0.32767]",
"Microsoft.AspNetCore.Localization": "(,10.0.32767]",
"Microsoft.AspNetCore.Localization.Routing": "(,10.0.32767]",
"Microsoft.AspNetCore.Metadata": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.ApiExplorer": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Core": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Cors": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.DataAnnotations": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Formatters.Json": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Formatters.Xml": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Localization": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.Razor": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.RazorPages": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.TagHelpers": "(,10.0.32767]",
"Microsoft.AspNetCore.Mvc.ViewFeatures": "(,10.0.32767]",
"Microsoft.AspNetCore.OutputCaching": "(,10.0.32767]",
"Microsoft.AspNetCore.RateLimiting": "(,10.0.32767]",
"Microsoft.AspNetCore.Razor": "(,10.0.32767]",
"Microsoft.AspNetCore.Razor.Runtime": "(,10.0.32767]",
"Microsoft.AspNetCore.RequestDecompression": "(,10.0.32767]",
"Microsoft.AspNetCore.ResponseCaching": "(,10.0.32767]",
"Microsoft.AspNetCore.ResponseCaching.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.ResponseCompression": "(,10.0.32767]",
"Microsoft.AspNetCore.Rewrite": "(,10.0.32767]",
"Microsoft.AspNetCore.Routing": "(,10.0.32767]",
"Microsoft.AspNetCore.Routing.Abstractions": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.HttpSys": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.IIS": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.IISIntegration": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.Kestrel": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.Kestrel.Core": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Quic": "(,10.0.32767]",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets": "(,10.0.32767]",
"Microsoft.AspNetCore.Session": "(,10.0.32767]",
"Microsoft.AspNetCore.SignalR": "(,10.0.32767]",
"Microsoft.AspNetCore.SignalR.Common": "(,10.0.32767]",
"Microsoft.AspNetCore.SignalR.Core": "(,10.0.32767]",
"Microsoft.AspNetCore.SignalR.Protocols.Json": "(,10.0.32767]",
"Microsoft.AspNetCore.StaticAssets": "(,10.0.32767]",
"Microsoft.AspNetCore.StaticFiles": "(,10.0.32767]",
"Microsoft.AspNetCore.WebSockets": "(,10.0.32767]",
"Microsoft.AspNetCore.WebUtilities": "(,10.0.32767]",
"Microsoft.CSharp": "(,4.7.32767]",
"Microsoft.Extensions.Caching.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Caching.Memory": "(,10.0.32767]",
"Microsoft.Extensions.Configuration": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.Binder": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.CommandLine": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.FileExtensions": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.Ini": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.Json": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.KeyPerFile": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.UserSecrets": "(,10.0.32767]",
"Microsoft.Extensions.Configuration.Xml": "(,10.0.32767]",
"Microsoft.Extensions.DependencyInjection": "(,10.0.32767]",
"Microsoft.Extensions.DependencyInjection.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Diagnostics": "(,10.0.32767]",
"Microsoft.Extensions.Diagnostics.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Diagnostics.HealthChecks": "(,10.0.32767]",
"Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Features": "(,10.0.32767]",
"Microsoft.Extensions.FileProviders.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.FileProviders.Composite": "(,10.0.32767]",
"Microsoft.Extensions.FileProviders.Physical": "(,10.0.32767]",
"Microsoft.Extensions.FileSystemGlobbing": "(,10.0.32767]",
"Microsoft.Extensions.Hosting": "(,10.0.32767]",
"Microsoft.Extensions.Hosting.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Http": "(,10.0.32767]",
"Microsoft.Extensions.Identity.Core": "(,10.0.32767]",
"Microsoft.Extensions.Identity.Stores": "(,10.0.32767]",
"Microsoft.Extensions.Localization": "(,10.0.32767]",
"Microsoft.Extensions.Localization.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Logging": "(,10.0.32767]",
"Microsoft.Extensions.Logging.Abstractions": "(,10.0.32767]",
"Microsoft.Extensions.Logging.Configuration": "(,10.0.32767]",
"Microsoft.Extensions.Logging.Console": "(,10.0.32767]",
"Microsoft.Extensions.Logging.Debug": "(,10.0.32767]",
"Microsoft.Extensions.Logging.EventLog": "(,10.0.32767]",
"Microsoft.Extensions.Logging.EventSource": "(,10.0.32767]",
"Microsoft.Extensions.Logging.TraceSource": "(,10.0.32767]",
"Microsoft.Extensions.ObjectPool": "(,10.0.32767]",
"Microsoft.Extensions.Options": "(,10.0.32767]",
"Microsoft.Extensions.Options.ConfigurationExtensions": "(,10.0.32767]",
"Microsoft.Extensions.Options.DataAnnotations": "(,10.0.32767]",
"Microsoft.Extensions.Primitives": "(,10.0.32767]",
"Microsoft.Extensions.Validation": "(,10.0.32767]",
"Microsoft.Extensions.WebEncoders": "(,10.0.32767]",
"Microsoft.JSInterop": "(,10.0.32767]",
"Microsoft.Net.Http.Headers": "(,10.0.32767]",
"Microsoft.VisualBasic": "(,10.4.32767]",
"Microsoft.Win32.Primitives": "(,4.3.32767]",
"Microsoft.Win32.Registry": "(,5.0.32767]",
"runtime.any.System.Collections": "(,4.3.32767]",
"runtime.any.System.Diagnostics.Tools": "(,4.3.32767]",
"runtime.any.System.Diagnostics.Tracing": "(,4.3.32767]",
"runtime.any.System.Globalization": "(,4.3.32767]",
"runtime.any.System.Globalization.Calendars": "(,4.3.32767]",
"runtime.any.System.IO": "(,4.3.32767]",
"runtime.any.System.Reflection": "(,4.3.32767]",
"runtime.any.System.Reflection.Extensions": "(,4.3.32767]",
"runtime.any.System.Reflection.Primitives": "(,4.3.32767]",
"runtime.any.System.Resources.ResourceManager": "(,4.3.32767]",
"runtime.any.System.Runtime": "(,4.3.32767]",
"runtime.any.System.Runtime.Handles": "(,4.3.32767]",
"runtime.any.System.Runtime.InteropServices": "(,4.3.32767]",
"runtime.any.System.Text.Encoding": "(,4.3.32767]",
"runtime.any.System.Text.Encoding.Extensions": "(,4.3.32767]",
"runtime.any.System.Threading.Tasks": "(,4.3.32767]",
"runtime.any.System.Threading.Timer": "(,4.3.32767]",
"runtime.aot.System.Collections": "(,4.3.32767]",
"runtime.aot.System.Diagnostics.Tools": "(,4.3.32767]",
"runtime.aot.System.Diagnostics.Tracing": "(,4.3.32767]",
"runtime.aot.System.Globalization": "(,4.3.32767]",
"runtime.aot.System.Globalization.Calendars": "(,4.3.32767]",
"runtime.aot.System.IO": "(,4.3.32767]",
"runtime.aot.System.Reflection": "(,4.3.32767]",
"runtime.aot.System.Reflection.Extensions": "(,4.3.32767]",
"runtime.aot.System.Reflection.Primitives": "(,4.3.32767]",
"runtime.aot.System.Resources.ResourceManager": "(,4.3.32767]",
"runtime.aot.System.Runtime": "(,4.3.32767]",
"runtime.aot.System.Runtime.Handles": "(,4.3.32767]",
"runtime.aot.System.Runtime.InteropServices": "(,4.3.32767]",
"runtime.aot.System.Text.Encoding": "(,4.3.32767]",
"runtime.aot.System.Text.Encoding.Extensions": "(,4.3.32767]",
"runtime.aot.System.Threading.Tasks": "(,4.3.32767]",
"runtime.aot.System.Threading.Timer": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.debian.9-x64.runtime.native.System": "(,4.3.32767]",
"runtime.debian.9-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.debian.9-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.debian.9-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.fedora.27-x64.runtime.native.System": "(,4.3.32767]",
"runtime.fedora.27-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.fedora.27-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.fedora.27-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.fedora.28-x64.runtime.native.System": "(,4.3.32767]",
"runtime.fedora.28-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.fedora.28-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.fedora.28-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.opensuse.42.3-x64.runtime.native.System": "(,4.3.32767]",
"runtime.opensuse.42.3-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.opensuse.42.3-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.opensuse.42.3-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "(,4.3.32767]",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography": "(,4.3.32767]",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "(,4.3.32767]",
"runtime.ubuntu.18.04-x64.runtime.native.System": "(,4.3.32767]",
"runtime.ubuntu.18.04-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.ubuntu.18.04-x64.runtime.native.System.Net.Http": "(,4.3.32767]",
"runtime.ubuntu.18.04-x64.runtime.native.System.Net.Security": "(,4.3.32767]",
"runtime.unix.Microsoft.Win32.Primitives": "(,4.3.32767]",
"runtime.unix.System.Console": "(,4.3.32767]",
"runtime.unix.System.Diagnostics.Debug": "(,4.3.32767]",
"runtime.unix.System.IO.FileSystem": "(,4.3.32767]",
"runtime.unix.System.Net.Primitives": "(,4.3.32767]",
"runtime.unix.System.Net.Sockets": "(,4.3.32767]",
"runtime.unix.System.Private.Uri": "(,4.3.32767]",
"runtime.unix.System.Runtime.Extensions": "(,4.3.32767]",
"runtime.win.Microsoft.Win32.Primitives": "(,4.3.32767]",
"runtime.win.System.Console": "(,4.3.32767]",
"runtime.win.System.Diagnostics.Debug": "(,4.3.32767]",
"runtime.win.System.IO.FileSystem": "(,4.3.32767]",
"runtime.win.System.Net.Primitives": "(,4.3.32767]",
"runtime.win.System.Net.Sockets": "(,4.3.32767]",
"runtime.win.System.Runtime.Extensions": "(,4.3.32767]",
"runtime.win10-arm-aot.runtime.native.System.IO.Compression": "(,4.0.32767]",
"runtime.win10-arm64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.win10-x64-aot.runtime.native.System.IO.Compression": "(,4.0.32767]",
"runtime.win10-x86-aot.runtime.native.System.IO.Compression": "(,4.0.32767]",
"runtime.win7-x64.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.win7-x86.runtime.native.System.IO.Compression": "(,4.3.32767]",
"runtime.win7.System.Private.Uri": "(,4.3.32767]",
"runtime.win8-arm.runtime.native.System.IO.Compression": "(,4.3.32767]",
"System.AppContext": "(,4.3.32767]",
"System.Buffers": "(,5.0.32767]",
"System.Collections": "(,4.3.32767]",
"System.Collections.Concurrent": "(,4.3.32767]",
"System.Collections.Immutable": "(,10.0.32767]",
"System.Collections.NonGeneric": "(,4.3.32767]",
"System.Collections.Specialized": "(,4.3.32767]",
"System.ComponentModel": "(,4.3.32767]",
"System.ComponentModel.Annotations": "(,4.3.32767]",
"System.ComponentModel.EventBasedAsync": "(,4.3.32767]",
"System.ComponentModel.Primitives": "(,4.3.32767]",
"System.ComponentModel.TypeConverter": "(,4.3.32767]",
"System.Console": "(,4.3.32767]",
"System.Data.Common": "(,4.3.32767]",
"System.Data.DataSetExtensions": "(,4.4.32767]",
"System.Diagnostics.Contracts": "(,4.3.32767]",
"System.Diagnostics.Debug": "(,4.3.32767]",
"System.Diagnostics.DiagnosticSource": "(,10.0.32767]",
"System.Diagnostics.EventLog": "(,10.0.32767]",
"System.Diagnostics.FileVersionInfo": "(,4.3.32767]",
"System.Diagnostics.Process": "(,4.3.32767]",
"System.Diagnostics.StackTrace": "(,4.3.32767]",
"System.Diagnostics.TextWriterTraceListener": "(,4.3.32767]",
"System.Diagnostics.Tools": "(,4.3.32767]",
"System.Diagnostics.TraceSource": "(,4.3.32767]",
"System.Diagnostics.Tracing": "(,4.3.32767]",
"System.Drawing.Primitives": "(,4.3.32767]",
"System.Dynamic.Runtime": "(,4.3.32767]",
"System.Formats.Asn1": "(,10.0.32767]",
"System.Formats.Cbor": "(,10.0.32767]",
"System.Formats.Tar": "(,10.0.32767]",
"System.Globalization": "(,4.3.32767]",
"System.Globalization.Calendars": "(,4.3.32767]",
"System.Globalization.Extensions": "(,4.3.32767]",
"System.IO": "(,4.3.32767]",
"System.IO.Compression": "(,4.3.32767]",
"System.IO.Compression.ZipFile": "(,4.3.32767]",
"System.IO.FileSystem": "(,4.3.32767]",
"System.IO.FileSystem.AccessControl": "(,4.4.32767]",
"System.IO.FileSystem.DriveInfo": "(,4.3.32767]",
"System.IO.FileSystem.Primitives": "(,4.3.32767]",
"System.IO.FileSystem.Watcher": "(,4.3.32767]",
"System.IO.IsolatedStorage": "(,4.3.32767]",
"System.IO.MemoryMappedFiles": "(,4.3.32767]",
"System.IO.Pipelines": "(,10.0.32767]",
"System.IO.Pipes": "(,4.3.32767]",
"System.IO.Pipes.AccessControl": "(,5.0.32767]",
"System.IO.UnmanagedMemoryStream": "(,4.3.32767]",
"System.Linq": "(,4.3.32767]",
"System.Linq.AsyncEnumerable": "(,10.0.32767]",
"System.Linq.Expressions": "(,4.3.32767]",
"System.Linq.Parallel": "(,4.3.32767]",
"System.Linq.Queryable": "(,4.3.32767]",
"System.Memory": "(,5.0.32767]",
"System.Net.Http": "(,4.3.32767]",
"System.Net.Http.Json": "(,10.0.32767]",
"System.Net.NameResolution": "(,4.3.32767]",
"System.Net.NetworkInformation": "(,4.3.32767]",
"System.Net.Ping": "(,4.3.32767]",
"System.Net.Primitives": "(,4.3.32767]",
"System.Net.Requests": "(,4.3.32767]",
"System.Net.Security": "(,4.3.32767]",
"System.Net.ServerSentEvents": "(,10.0.32767]",
"System.Net.Sockets": "(,4.3.32767]",
"System.Net.WebHeaderCollection": "(,4.3.32767]",
"System.Net.WebSockets": "(,4.3.32767]",
"System.Net.WebSockets.Client": "(,4.3.32767]",
"System.Numerics.Vectors": "(,5.0.32767]",
"System.ObjectModel": "(,4.3.32767]",
"System.Private.DataContractSerialization": "(,4.3.32767]",
"System.Private.Uri": "(,4.3.32767]",
"System.Reflection": "(,4.3.32767]",
"System.Reflection.DispatchProxy": "(,6.0.32767]",
"System.Reflection.Emit": "(,4.7.32767]",
"System.Reflection.Emit.ILGeneration": "(,4.7.32767]",
"System.Reflection.Emit.Lightweight": "(,4.7.32767]",
"System.Reflection.Extensions": "(,4.3.32767]",
"System.Reflection.Metadata": "(,10.0.32767]",
"System.Reflection.Primitives": "(,4.3.32767]",
"System.Reflection.TypeExtensions": "(,4.3.32767]",
"System.Resources.Reader": "(,4.3.32767]",
"System.Resources.ResourceManager": "(,4.3.32767]",
"System.Resources.Writer": "(,4.3.32767]",
"System.Runtime": "(,4.3.32767]",
"System.Runtime.CompilerServices.Unsafe": "(,7.0.32767]",
"System.Runtime.CompilerServices.VisualC": "(,4.3.32767]",
"System.Runtime.Extensions": "(,4.3.32767]",
"System.Runtime.Handles": "(,4.3.32767]",
"System.Runtime.InteropServices": "(,4.3.32767]",
"System.Runtime.InteropServices.RuntimeInformation": "(,4.3.32767]",
"System.Runtime.Loader": "(,4.3.32767]",
"System.Runtime.Numerics": "(,4.3.32767]",
"System.Runtime.Serialization.Formatters": "(,4.3.32767]",
"System.Runtime.Serialization.Json": "(,4.3.32767]",
"System.Runtime.Serialization.Primitives": "(,4.3.32767]",
"System.Runtime.Serialization.Xml": "(,4.3.32767]",
"System.Security.AccessControl": "(,6.0.32767]",
"System.Security.Claims": "(,4.3.32767]",
"System.Security.Cryptography.Algorithms": "(,4.3.32767]",
"System.Security.Cryptography.Cng": "(,5.0.32767]",
"System.Security.Cryptography.Csp": "(,4.3.32767]",
"System.Security.Cryptography.Encoding": "(,4.3.32767]",
"System.Security.Cryptography.OpenSsl": "(,5.0.32767]",
"System.Security.Cryptography.Primitives": "(,4.3.32767]",
"System.Security.Cryptography.X509Certificates": "(,4.3.32767]",
"System.Security.Cryptography.Xml": "(,10.0.32767]",
"System.Security.Principal": "(,4.3.32767]",
"System.Security.Principal.Windows": "(,5.0.32767]",
"System.Security.SecureString": "(,4.3.32767]",
"System.Text.Encoding": "(,4.3.32767]",
"System.Text.Encoding.CodePages": "(,10.0.32767]",
"System.Text.Encoding.Extensions": "(,4.3.32767]",
"System.Text.Encodings.Web": "(,10.0.32767]",
"System.Text.Json": "(,10.0.32767]",
"System.Text.RegularExpressions": "(,4.3.32767]",
"System.Threading": "(,4.3.32767]",
"System.Threading.AccessControl": "(,10.0.32767]",
"System.Threading.Channels": "(,10.0.32767]",
"System.Threading.Overlapped": "(,4.3.32767]",
"System.Threading.RateLimiting": "(,10.0.32767]",
"System.Threading.Tasks": "(,4.3.32767]",
"System.Threading.Tasks.Dataflow": "(,10.0.32767]",
"System.Threading.Tasks.Extensions": "(,5.0.32767]",
"System.Threading.Tasks.Parallel": "(,4.3.32767]",
"System.Threading.Thread": "(,4.3.32767]",
"System.Threading.ThreadPool": "(,4.3.32767]",
"System.Threading.Timer": "(,4.3.32767]",
"System.ValueTuple": "(,4.5.32767]",
"System.Xml.ReaderWriter": "(,4.3.32767]",
"System.Xml.XDocument": "(,4.3.32767]",
"System.Xml.XmlDocument": "(,4.3.32767]",
"System.Xml.XmlSerializer": "(,4.3.32767]",
"System.Xml.XPath": "(,4.3.32767]",
"System.Xml.XPath.XDocument": "(,5.0.32767]"
}
}
}
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/kocoder/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/kocoder/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/home/kocoder/.nuget/packages/" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.app.internal.assets/10.0.3/build/Microsoft.AspNetCore.App.Internal.Assets.props" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.app.internal.assets/10.0.3/build/Microsoft.AspNetCore.App.Internal.Assets.props')" />
</ImportGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.app.internal.assets/10.0.3/buildTransitive/Microsoft.AspNetCore.App.Internal.Assets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.app.internal.assets/10.0.3/buildTransitive/Microsoft.AspNetCore.App.Internal.Assets.targets')" />
</ImportGroup>
</Project>

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]

View File

@@ -0,0 +1,18 @@
// <auto-generated/>
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Routing;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Validation.Embedded;
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Net.Http.Json;
global using System.Threading;
global using System.Threading.Tasks;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
{
"version": 2,
"dgSpecHash": "ZhKgKzSz21U=",
"success": true,
"projectFilePath": "/home/kocoder/src/szu/2025_5BHITN_Hintermayer_Konstantin_smartrent/Einheit_4/2025_5BHITN_Konstantin_Hintermayer_smarterrent/2025_5BHITN_Konstantin_Hintermayer_smarterrent.csproj",
"expectedPackageFiles": [
"/home/kocoder/.nuget/packages/azure.core/1.50.0/azure.core.1.50.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/azure.identity/1.17.1/azure.identity.1.17.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.aspnetcore.app.internal.assets/10.0.3/microsoft.aspnetcore.app.internal.assets.10.0.3.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.bcl.asyncinterfaces/8.0.0/microsoft.bcl.asyncinterfaces.8.0.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.data.sqlclient/6.1.4/microsoft.data.sqlclient.6.1.4.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.data.sqlclient.sni.runtime/6.0.2/microsoft.data.sqlclient.sni.runtime.6.0.2.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identity.client/4.80.0/microsoft.identity.client.4.80.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identity.client.extensions.msal/4.78.0/microsoft.identity.client.extensions.msal.4.78.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.abstractions/8.14.0/microsoft.identitymodel.abstractions.8.14.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.jsonwebtokens/7.7.1/microsoft.identitymodel.jsonwebtokens.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.logging/7.7.1/microsoft.identitymodel.logging.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.protocols/7.7.1/microsoft.identitymodel.protocols.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.protocols.openidconnect/7.7.1/microsoft.identitymodel.protocols.openidconnect.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.identitymodel.tokens/7.7.1/microsoft.identitymodel.tokens.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/microsoft.sqlserver.server/1.0.0/microsoft.sqlserver.server.1.0.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.clientmodel/1.8.0/system.clientmodel.1.8.0.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.configuration.configurationmanager/9.0.11/system.configuration.configurationmanager.9.0.11.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.identitymodel.tokens.jwt/7.7.1/system.identitymodel.tokens.jwt.7.7.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.memory.data/8.0.1/system.memory.data.8.0.1.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.security.cryptography.pkcs/9.0.11/system.security.cryptography.pkcs.9.0.11.nupkg.sha512",
"/home/kocoder/.nuget/packages/system.security.cryptography.protecteddata/9.0.11/system.security.cryptography.protecteddata.9.0.11.nupkg.sha512"
],
"logs": []
}

View File

@@ -0,0 +1,60 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #006bb7;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
color: var(--bs-secondary-color);
text-align: end;
}
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
text-align: start;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,597 @@
/*!
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root,
[data-bs-theme=light] {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-primary-text-emphasis: #052c65;
--bs-secondary-text-emphasis: #2b2f32;
--bs-success-text-emphasis: #0a3622;
--bs-info-text-emphasis: #055160;
--bs-warning-text-emphasis: #664d03;
--bs-danger-text-emphasis: #58151c;
--bs-light-text-emphasis: #495057;
--bs-dark-text-emphasis: #495057;
--bs-primary-bg-subtle: #cfe2ff;
--bs-secondary-bg-subtle: #e2e3e5;
--bs-success-bg-subtle: #d1e7dd;
--bs-info-bg-subtle: #cff4fc;
--bs-warning-bg-subtle: #fff3cd;
--bs-danger-bg-subtle: #f8d7da;
--bs-light-bg-subtle: #fcfcfd;
--bs-dark-bg-subtle: #ced4da;
--bs-primary-border-subtle: #9ec5fe;
--bs-secondary-border-subtle: #c4c8cb;
--bs-success-border-subtle: #a3cfbb;
--bs-info-border-subtle: #9eeaf9;
--bs-warning-border-subtle: #ffe69c;
--bs-danger-border-subtle: #f1aeb5;
--bs-light-border-subtle: #e9ecef;
--bs-dark-border-subtle: #adb5bd;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-emphasis-color: #000;
--bs-emphasis-color-rgb: 0, 0, 0;
--bs-secondary-color: rgba(33, 37, 41, 0.75);
--bs-secondary-color-rgb: 33, 37, 41;
--bs-secondary-bg: #e9ecef;
--bs-secondary-bg-rgb: 233, 236, 239;
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
--bs-tertiary-color-rgb: 33, 37, 41;
--bs-tertiary-bg: #f8f9fa;
--bs-tertiary-bg-rgb: 248, 249, 250;
--bs-heading-color: inherit;
--bs-link-color: #0d6efd;
--bs-link-color-rgb: 13, 110, 253;
--bs-link-decoration: underline;
--bs-link-hover-color: #0a58ca;
--bs-link-hover-color-rgb: 10, 88, 202;
--bs-code-color: #d63384;
--bs-highlight-color: #212529;
--bs-highlight-bg: #fff3cd;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-xxl: 2rem;
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
--bs-border-radius-pill: 50rem;
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
--bs-focus-ring-width: 0.25rem;
--bs-focus-ring-opacity: 0.25;
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
--bs-form-valid-color: #198754;
--bs-form-valid-border-color: #198754;
--bs-form-invalid-color: #dc3545;
--bs-form-invalid-border-color: #dc3545;
}
[data-bs-theme=dark] {
color-scheme: dark;
--bs-body-color: #dee2e6;
--bs-body-color-rgb: 222, 226, 230;
--bs-body-bg: #212529;
--bs-body-bg-rgb: 33, 37, 41;
--bs-emphasis-color: #fff;
--bs-emphasis-color-rgb: 255, 255, 255;
--bs-secondary-color: rgba(222, 226, 230, 0.75);
--bs-secondary-color-rgb: 222, 226, 230;
--bs-secondary-bg: #343a40;
--bs-secondary-bg-rgb: 52, 58, 64;
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
--bs-tertiary-color-rgb: 222, 226, 230;
--bs-tertiary-bg: #2b3035;
--bs-tertiary-bg-rgb: 43, 48, 53;
--bs-primary-text-emphasis: #6ea8fe;
--bs-secondary-text-emphasis: #a7acb1;
--bs-success-text-emphasis: #75b798;
--bs-info-text-emphasis: #6edff6;
--bs-warning-text-emphasis: #ffda6a;
--bs-danger-text-emphasis: #ea868f;
--bs-light-text-emphasis: #f8f9fa;
--bs-dark-text-emphasis: #dee2e6;
--bs-primary-bg-subtle: #031633;
--bs-secondary-bg-subtle: #161719;
--bs-success-bg-subtle: #051b11;
--bs-info-bg-subtle: #032830;
--bs-warning-bg-subtle: #332701;
--bs-danger-bg-subtle: #2c0b0e;
--bs-light-bg-subtle: #343a40;
--bs-dark-bg-subtle: #1a1d20;
--bs-primary-border-subtle: #084298;
--bs-secondary-border-subtle: #41464b;
--bs-success-border-subtle: #0f5132;
--bs-info-border-subtle: #087990;
--bs-warning-border-subtle: #997404;
--bs-danger-border-subtle: #842029;
--bs-light-border-subtle: #495057;
--bs-dark-border-subtle: #343a40;
--bs-heading-color: inherit;
--bs-link-color: #6ea8fe;
--bs-link-hover-color: #8bb9fe;
--bs-link-color-rgb: 110, 168, 254;
--bs-link-hover-color-rgb: 139, 185, 254;
--bs-code-color: #e685b5;
--bs-highlight-color: #dee2e6;
--bs-highlight-bg: #664d03;
--bs-border-color: #495057;
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
--bs-form-valid-color: #75b798;
--bs-form-valid-border-color: #75b798;
--bs-form-invalid-color: #ea868f;
--bs-form-invalid-border-color: #ea868f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: var(--bs-border-width) solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
color: var(--bs-heading-color);
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
color: var(--bs-highlight-color);
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
text-decoration: underline;
}
a:hover {
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: var(--bs-secondary-color);
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,594 @@
/*!
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root,
[data-bs-theme=light] {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-primary-text-emphasis: #052c65;
--bs-secondary-text-emphasis: #2b2f32;
--bs-success-text-emphasis: #0a3622;
--bs-info-text-emphasis: #055160;
--bs-warning-text-emphasis: #664d03;
--bs-danger-text-emphasis: #58151c;
--bs-light-text-emphasis: #495057;
--bs-dark-text-emphasis: #495057;
--bs-primary-bg-subtle: #cfe2ff;
--bs-secondary-bg-subtle: #e2e3e5;
--bs-success-bg-subtle: #d1e7dd;
--bs-info-bg-subtle: #cff4fc;
--bs-warning-bg-subtle: #fff3cd;
--bs-danger-bg-subtle: #f8d7da;
--bs-light-bg-subtle: #fcfcfd;
--bs-dark-bg-subtle: #ced4da;
--bs-primary-border-subtle: #9ec5fe;
--bs-secondary-border-subtle: #c4c8cb;
--bs-success-border-subtle: #a3cfbb;
--bs-info-border-subtle: #9eeaf9;
--bs-warning-border-subtle: #ffe69c;
--bs-danger-border-subtle: #f1aeb5;
--bs-light-border-subtle: #e9ecef;
--bs-dark-border-subtle: #adb5bd;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-emphasis-color: #000;
--bs-emphasis-color-rgb: 0, 0, 0;
--bs-secondary-color: rgba(33, 37, 41, 0.75);
--bs-secondary-color-rgb: 33, 37, 41;
--bs-secondary-bg: #e9ecef;
--bs-secondary-bg-rgb: 233, 236, 239;
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
--bs-tertiary-color-rgb: 33, 37, 41;
--bs-tertiary-bg: #f8f9fa;
--bs-tertiary-bg-rgb: 248, 249, 250;
--bs-heading-color: inherit;
--bs-link-color: #0d6efd;
--bs-link-color-rgb: 13, 110, 253;
--bs-link-decoration: underline;
--bs-link-hover-color: #0a58ca;
--bs-link-hover-color-rgb: 10, 88, 202;
--bs-code-color: #d63384;
--bs-highlight-color: #212529;
--bs-highlight-bg: #fff3cd;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-xxl: 2rem;
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
--bs-border-radius-pill: 50rem;
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
--bs-focus-ring-width: 0.25rem;
--bs-focus-ring-opacity: 0.25;
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
--bs-form-valid-color: #198754;
--bs-form-valid-border-color: #198754;
--bs-form-invalid-color: #dc3545;
--bs-form-invalid-border-color: #dc3545;
}
[data-bs-theme=dark] {
color-scheme: dark;
--bs-body-color: #dee2e6;
--bs-body-color-rgb: 222, 226, 230;
--bs-body-bg: #212529;
--bs-body-bg-rgb: 33, 37, 41;
--bs-emphasis-color: #fff;
--bs-emphasis-color-rgb: 255, 255, 255;
--bs-secondary-color: rgba(222, 226, 230, 0.75);
--bs-secondary-color-rgb: 222, 226, 230;
--bs-secondary-bg: #343a40;
--bs-secondary-bg-rgb: 52, 58, 64;
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
--bs-tertiary-color-rgb: 222, 226, 230;
--bs-tertiary-bg: #2b3035;
--bs-tertiary-bg-rgb: 43, 48, 53;
--bs-primary-text-emphasis: #6ea8fe;
--bs-secondary-text-emphasis: #a7acb1;
--bs-success-text-emphasis: #75b798;
--bs-info-text-emphasis: #6edff6;
--bs-warning-text-emphasis: #ffda6a;
--bs-danger-text-emphasis: #ea868f;
--bs-light-text-emphasis: #f8f9fa;
--bs-dark-text-emphasis: #dee2e6;
--bs-primary-bg-subtle: #031633;
--bs-secondary-bg-subtle: #161719;
--bs-success-bg-subtle: #051b11;
--bs-info-bg-subtle: #032830;
--bs-warning-bg-subtle: #332701;
--bs-danger-bg-subtle: #2c0b0e;
--bs-light-bg-subtle: #343a40;
--bs-dark-bg-subtle: #1a1d20;
--bs-primary-border-subtle: #084298;
--bs-secondary-border-subtle: #41464b;
--bs-success-border-subtle: #0f5132;
--bs-info-border-subtle: #087990;
--bs-warning-border-subtle: #997404;
--bs-danger-border-subtle: #842029;
--bs-light-border-subtle: #495057;
--bs-dark-border-subtle: #343a40;
--bs-heading-color: inherit;
--bs-link-color: #6ea8fe;
--bs-link-hover-color: #8bb9fe;
--bs-link-color-rgb: 110, 168, 254;
--bs-link-hover-color-rgb: 139, 185, 254;
--bs-code-color: #e685b5;
--bs-highlight-color: #dee2e6;
--bs-highlight-bg: #664d03;
--bs-border-color: #495057;
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
--bs-form-valid-color: #75b798;
--bs-form-valid-border-color: #75b798;
--bs-form-invalid-color: #ea868f;
--bs-form-invalid-border-color: #ea868f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
border: 0;
border-top: var(--bs-border-width) solid;
opacity: 0.25;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
color: var(--bs-heading-color);
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.1875em;
color: var(--bs-highlight-color);
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
text-decoration: underline;
}
a:hover {
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: var(--bs-secondary-color);
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
FROM mcr.microsoft.com/mssql-tools
WORKDIR /App
# Copy everything
COPY ../../Einheit_1/2025_5BHITN_Konstantin_Hintermayer_create_schema.sql ./01.sql
COPY ../../Einheit_2/2025_5BHITN_Konstantin_Hintermayer_seed_database.sql ./02.sql
COPY ../../Einheit_3/2025_5BHITN_Konstantin_Hintermayer_procedures_and_triggers.sql ./03.sql
ENTRYPOINT ["sqlcmd", "-D", ""]

View File

@@ -0,0 +1,19 @@
#!/bin/bash
# Wait for SQL Server to boot up (adjust sleep if needed)
echo "Waiting for SQL Server to start..."
sleep 20s
# Run the three SQL files using sqlcmd
# -S: Server, -U: User, -P: Password (passed via ENV)
echo "Applying SQL files..."
for migration in $(ls . | grep -E '\.sql$')
do
echo "Applying $migration."
/opt/mssql-tools/bin/sqlcmd -D $DSN_PASSWORD -i $migration.sql
done
echo "Database initialization complete."
# Keep the container alive by bringing the background process to the foreground
wait