Initial commit
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
|
||||
namespace RobotNet10.Components.Clients;
|
||||
|
||||
public abstract class HubClient
|
||||
{
|
||||
public event Func<HubConnectionState, Task>? ConnectionStateChanged;
|
||||
public bool IsConnected => Connection.State == HubConnectionState.Connected;
|
||||
protected HubConnection Connection { get; }
|
||||
private readonly ManualResetEvent connectedWaitHandler = new(false);
|
||||
|
||||
protected HubClient(Uri url)
|
||||
{
|
||||
Connection = new HubConnectionBuilder()
|
||||
.WithUrl(url)
|
||||
.WithAutomaticReconnect(new HubClientRepeatRetryPolicy(TimeSpan.FromSeconds(3)))
|
||||
.Build();
|
||||
|
||||
Connection.Closed += Connection_Closed;
|
||||
Connection.Reconnected += Connection_Reconnected;
|
||||
}
|
||||
|
||||
private Task Connection_Closed(Exception? arg)
|
||||
{
|
||||
return ConnectionStateChanged?.Invoke(Connection.State) ?? Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task Connection_Reconnected(string? arg)
|
||||
{
|
||||
return ConnectionStateChanged?.Invoke(Connection.State) ?? Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task StartAsync()
|
||||
{
|
||||
if (Connection.State == HubConnectionState.Disconnected)
|
||||
{
|
||||
await Connection.StartAsync();
|
||||
ConnectionStateChanged?.Invoke(Connection.State);
|
||||
connectedWaitHandler.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForConnected() => connectedWaitHandler.WaitOne();
|
||||
|
||||
public virtual async Task StopAsync()
|
||||
{
|
||||
if (Connection.State != HubConnectionState.Disconnected)
|
||||
{
|
||||
await Connection.StopAsync();
|
||||
ConnectionStateChanged?.Invoke(Connection.State);
|
||||
}
|
||||
}
|
||||
|
||||
public class HubClientRepeatRetryPolicy(TimeSpan repeatSpan) : IRetryPolicy
|
||||
{
|
||||
private readonly TimeSpan RepeatTimeSpan = repeatSpan;
|
||||
|
||||
public TimeSpan? NextRetryDelay(RetryContext retryContext) => RepeatTimeSpan;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<div class="@WidthClass @HeightClass position-relative overflow-hidden">
|
||||
<div class="w-100 h-100 position-absolute top-0 start-0 @OverflowX @OverflowY @Class">
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@code{
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string WidthClass { get; set; } = "w-100";
|
||||
|
||||
[Parameter]
|
||||
public string HeightClass { get; set; } = "h-100";
|
||||
|
||||
[Parameter]
|
||||
public string OverflowX { get; set; } = "overflow-x-hidden";
|
||||
|
||||
[Parameter]
|
||||
public string OverflowY { get; set; } = "overflow-y-hidden";
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
|
||||
<button class="icon-button @DisabledClass" @onclick="HandleClick" title="@Title" disabled="@Disabled">
|
||||
<span class="mdi @IconClass"></span>
|
||||
</button>
|
||||
|
||||
@code {
|
||||
[Parameter] public string Icon { get; set; } = string.Empty;
|
||||
[Parameter] public string? Title { get; set; }
|
||||
[Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }
|
||||
[Parameter] public bool Disabled { get; set; }
|
||||
|
||||
private string IconClass => $"mdi-{Icon} mdi-18px"; /* Giảm icon size để phù hợp với button nhỏ hơn */
|
||||
private string DisabledClass => Disabled ? "disabled" : string.Empty;
|
||||
|
||||
private async Task HandleClick(MouseEventArgs e)
|
||||
{
|
||||
if (Disabled || !OnClick.HasDelegate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await OnClick.InvokeAsync(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
.icon-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px; /* Giảm từ 24px xuống 20px */
|
||||
height: 20px; /* Giảm từ 24px xuống 20px */
|
||||
padding: 0;
|
||||
margin: 0 1px; /* Giảm margin từ 2px xuống 1px */
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: #858585;
|
||||
cursor: pointer;
|
||||
transition: color 0.15s ease, background-color 0.15s ease;
|
||||
border-radius: 2px;
|
||||
flex-shrink: 0; /* Không cho phép shrink */
|
||||
}
|
||||
|
||||
.icon-button:hover {
|
||||
background-color: #2a2d2e;
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
.icon-button:active {
|
||||
background-color: #3e3e42;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.icon-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.icon-button.disabled,
|
||||
.icon-button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.icon-button span {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject IJSRuntime JS
|
||||
@inject OptionLayout Options
|
||||
|
||||
<div class="w-100 h-100 d-flex flex-column overflow-hidden">
|
||||
<div class="d-flex flex-row justify-content-between position-relative" style="height: 50px; background-color: #233871">
|
||||
<div class="h-100 d-flex align-items-center" onclick="robotnet.components.toggleSidebar()">
|
||||
<img class="ms-1" src="_content/RobotNet10.Components/images/logoLight.svg" alt="PhenikaaX" style="height: 35px;" />
|
||||
</div>
|
||||
<div class="w-100 h-100 position-absolute pe-none">
|
||||
<div class="h-100 mx-auto pe-none" style="width: fit-content;">
|
||||
<div class="h-100 d-flex align-items-center">
|
||||
<span class="text-white" style="font-size: 36px;">
|
||||
@Options.AppName
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<div class="d-flex flex-row align-items-center">
|
||||
<div>
|
||||
<span class="mdi mdi-account mdi-36px text-white "></span>
|
||||
</div>
|
||||
<MudText Class="text-white name" Typo="Typo.subtitle1">@context.User.Identity?.Name</MudText>
|
||||
<MudSpacer />
|
||||
<form action="Account/Logout" method="post">
|
||||
<AntiforgeryToken />
|
||||
<input type="hidden" name="returnUrl" value="" />
|
||||
<MudIconButton Class="text-white" ButtonType="@ButtonType.Submit" Icon="@Icons.Material.Filled.Logout" />
|
||||
</form>
|
||||
</div>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
</div>
|
||||
<div class="w-100 flex-grow-1 d-flex flex-row">
|
||||
<NavMenu />
|
||||
<main>
|
||||
<div>
|
||||
@Body
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui" data-nosnippet>
|
||||
An unhandled error has occurred.
|
||||
<a href="." class="reload">Reload</a>
|
||||
<span class="dismiss">🗙</span>
|
||||
</div>
|
||||
@@ -0,0 +1,34 @@
|
||||
main {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
main > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.Extensions.Options
|
||||
@using Microsoft.JSInterop
|
||||
@using RobotNet10.Components
|
||||
|
||||
@inject IJSRuntime JS
|
||||
@inject OptionLayout Options
|
||||
|
||||
<div class="sidebar">
|
||||
<DivContainer HeightClass="flex-grow-1" OverflowY="overflow-y-auto" Class="d-flex flex-column">
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
@foreach (var nav in Options.NavModels)
|
||||
{
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="@nav.Path" Match="@nav.Match">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="nav-icon">
|
||||
<span class="mdi @nav.Icon mdi-36px" aria-hidden="true"></span>
|
||||
</div>
|
||||
<span class="nav-label">@nav.Label</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
}
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
</DivContainer>
|
||||
<div class="copyright d-flex align-items-center justify-content-end">
|
||||
<span class="text-white" style="font-size: 10px; text-align: end; margin-right: 5px;">
|
||||
© Copyright 2025 Phenikaa X <br />v@(Options.Version) | All Rights Reserved
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JS.InvokeVoidAsync("robotnet.components.loadToggleSidebarState");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, #e06e2e 0%, #3a0647 70%);
|
||||
height: 100%;
|
||||
width: 250px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.collapsed {
|
||||
width: 74px;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .copyright {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*.sidebar .user {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .user > div {
|
||||
display: none !important;
|
||||
}*/
|
||||
|
||||
.sidebar.collapsed .nav-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav-item .nav-label {
|
||||
font-size: 18px;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.nav-item .nav-icon {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
|
||||
namespace RobotNet10.Components;
|
||||
|
||||
public record NavModel(string Icon, string Path, string Label, NavLinkMatch Match);
|
||||
|
||||
public class OptionLayout()
|
||||
{
|
||||
public string AppName { get; set; } = "RobotNet";
|
||||
public string Version { get; set; } = "";
|
||||
public NavModel[] NavModels { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace RobotNet10.Components;
|
||||
|
||||
public static class RenderMode
|
||||
{
|
||||
public readonly static InteractiveWebAssemblyRenderMode InteractiveWebAssemblyNoPrerender = new(prerender: false);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.3" />
|
||||
<PackageReference Include="MudBlazor" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\RobotNet10.ScriptEngine.Shared\RobotNet10.ScriptEngine.Shared.csproj" />
|
||||
<ProjectReference Include="..\..\Shared\RobotNet10.Shared\RobotNet10.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,5 @@
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
@using Microsoft.JSInterop
|
||||
@using MudBlazor
|
||||
@using RobotNet10.Components
|
||||
15
srcs/RobotNet10/Components/RobotNet10.Components/libman.json
Normal file
15
srcs/RobotNet10/Components/RobotNet10.Components/libman.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "3.0",
|
||||
"defaultProvider": "cdnjs",
|
||||
"libraries": [
|
||||
{
|
||||
"library": "bootstrap@5.3.8",
|
||||
"destination": "wwwroot/lib/bootstrap/"
|
||||
},
|
||||
{
|
||||
"provider": "jsdelivr",
|
||||
"library": "@mdi/font@7.4.47",
|
||||
"destination": "wwwroot/lib/mdi/font/"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmZiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmQiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmYiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmXiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
/* math */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVnoiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
|
||||
}
|
||||
/* symbols */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVn6iArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmbiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmaiArmlw.woff2) format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-stretch: 100%;
|
||||
src: url(KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAo.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 809 B |
@@ -0,0 +1,5 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<path d="M31.81,1.79,21.29,14.32l-2.48-3a2.6,2.6,0,0,1,0-3.34l4.45-5.31a2.64,2.64,0,0,1,2-.93Z" fill="#e06e2e"/>
|
||||
<path d="M.19,1.8,10.71,14.34l2.48-2.95a2.6,2.6,0,0,0,0-3.34L8.75,2.74a2.66,2.66,0,0,0-2-.94Z" fill="#e06e2e"/>
|
||||
<path d="M32,30.21H25.36a2.61,2.61,0,0,1-2-.92L16.5,21.1a.65.65,0,0,0-1,0L8.63,29.29a2.58,2.58,0,0,1-2,.92H0L12.07,15.83,14,13.57a2.67,2.67,0,0,1,4.08,0l1.89,2.26Z" fill="#233871"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 514 B |
@@ -0,0 +1,10 @@
|
||||
<svg
|
||||
id="Layer_1"
|
||||
data-name="Layer 1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 32 32"
|
||||
>
|
||||
<path d="M31.81,1.79,21.29,14.32l-2.48-3a2.6,2.6,0,0,1,0-3.34l4.45-5.31a2.64,2.64,0,0,1,2-.93Z" fill="#e06e2e"/>
|
||||
<path d="M.19,1.8,10.71,14.34l2.48-2.95a2.6,2.6,0,0,0,0-3.34L8.75,2.74a2.66,2.66,0,0,0-2-.94Z" fill="#e06e2e"/>
|
||||
<path d="M32,30.21H25.36a2.61,2.61,0,0,1-2-.92L16.5,21.1a.65.65,0,0,0-1,0L8.63,29.29a2.58,2.58,0,0,1-2,.92H0L12.07,15.83,14,13.57a2.67,2.67,0,0,1,4.08,0l1.89,2.26Z" fill="#233871"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 532 B |
@@ -0,0 +1,48 @@
|
||||
<svg
|
||||
id="Layer_1"
|
||||
data-name="Layer 1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 370.84 59.64"
|
||||
>
|
||||
<path
|
||||
d="M66.68,0,44.62,26.28,39.43,20.1a5.45,5.45,0,0,1,0-7L48.75,2A5.53,5.53,0,0,1,53,0Z"
|
||||
fill="#e06e2e"
|
||||
/>
|
||||
<path
|
||||
d="M.4,0,22.46,26.31l5.19-6.18a5.45,5.45,0,0,0,0-7L18.33,2a5.53,5.53,0,0,0-4.22-2Z"
|
||||
fill="#e06e2e"
|
||||
/>
|
||||
<path
|
||||
d="M67.08,59.59H53.15A5.44,5.44,0,0,1,49,57.65L34.58,40.49a1.36,1.36,0,0,0-2.09,0L18.09,57.65a5.46,5.46,0,0,1-4.17,1.94H0L25.31,29.43l4-4.72a5.57,5.57,0,0,1,8.54,0l4,4.72Z"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M98.34,24.3A12.87,12.87,0,0,1,104,42.84a12.29,12.29,0,0,1-5.61,4.56A21.47,21.47,0,0,1,89.74,49H81.17v7.93a2.72,2.72,0,0,1-2.72,2.73H74.13V22.72H89.74a21.64,21.64,0,0,1,8.6,1.58m-1.93,17a6.52,6.52,0,0,0,2.39-5.43,6.54,6.54,0,0,0-2.39-5.43q-2.39-1.91-7-1.9H81.17V43.18h8.25q4.6,0,7-1.9"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M145.86,25.44V56.91a2.72,2.72,0,0,1-2.72,2.73h-4.33V43.81H119.18V59.64h-4.32a2.73,2.73,0,0,1-2.73-2.73V25.44a2.72,2.72,0,0,1,2.73-2.72h4.32V38h19.63V22.72h4.33a2.72,2.72,0,0,1,2.72,2.72"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M183,56.58v3h-24.8a3.6,3.6,0,0,1-3.6-3.6V26.36a3.6,3.6,0,0,1,3.6-3.6h24.05v3a2.73,2.73,0,0,1-2.73,2.73H161.62v9.57h18.29V43.7H161.62V53.86h18.65A2.72,2.72,0,0,1,183,56.58"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M222.73,22.76V59.59h-4.52a2.71,2.71,0,0,1-2.09-1l-20.06-24V59.59h-7V22.76h4.51a2.72,2.72,0,0,1,2.09,1l20.07,24V22.76Z"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<rect x="231.85" y="22.76" width="7.03" height="36.83" fill="#ffffff" />
|
||||
<path
|
||||
d="M261,44.18l-6,6v9.42h-7V22.76h7V41.65L273,23.57a2.71,2.71,0,0,1,1.93-.81h6.77L265.75,39.23l16.88,20.36h-7a2.72,2.72,0,0,1-2.06-.94Z"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M315.59,51.07H296.65l-3,6.89a2.74,2.74,0,0,1-2.5,1.63h-5.47l16.08-34.74A3.6,3.6,0,0,1,305,22.76h2.32a3.61,3.61,0,0,1,3.27,2.08l16.13,34.75h-5.59A2.72,2.72,0,0,1,318.66,58Zm-2.33-5.37-7.14-16.1L299,45.7Z"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
<path
|
||||
d="M359.69,51.07H340.76l-3,6.89a2.71,2.71,0,0,1-2.49,1.63h-5.47l16.07-34.74a3.62,3.62,0,0,1,3.27-2.09h2.33a3.59,3.59,0,0,1,3.26,2.08l16.13,34.75h-5.59A2.7,2.7,0,0,1,362.77,58Zm-2.32-5.37-7.14-16.1-7.09,16.1Z"
|
||||
fill="#ffffff"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,36 @@
|
||||
window.robotnet = {
|
||||
localStorageHelper: {
|
||||
getItem: function (key) {
|
||||
return localStorage.getItem(key);
|
||||
},
|
||||
setItem: function (key, value) {
|
||||
localStorage.setItem(key, value);
|
||||
},
|
||||
removeItem: function (key) {
|
||||
localStorage.removeItem(key);
|
||||
},
|
||||
clear: function () {
|
||||
localStorage.clear();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
loadToggleSidebarState: function () {
|
||||
let toggle = localStorage.getItem("navMenuCollapsed");
|
||||
if (toggle === "collapsed") {
|
||||
let sidebar = document.querySelector(".sidebar");
|
||||
sidebar.classList.add("collapsed");
|
||||
}
|
||||
},
|
||||
toggleSidebar: function () {
|
||||
let sidebar = document.querySelector(".sidebar");
|
||||
sidebar.classList.toggle("collapsed");
|
||||
let toggle = localStorage.getItem("navMenuCollapsed");
|
||||
if (toggle === "collapsed") {
|
||||
localStorage.setItem("navMenuCollapsed", "");
|
||||
}
|
||||
else {
|
||||
localStorage.setItem("navMenuCollapsed", "collapsed");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
@import url("lib/bootstrap/css/bootstrap.min.css");
|
||||
@import url("lib/mdi/font/css/materialdesignicons.min.css");
|
||||
@import url("fonts/fonts.googleapis.com.css");
|
||||
@import url("/_content/MudBlazor/MudBlazor.min.css");
|
||||
@import url("/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css");
|
||||
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.mud-popover-provider > div {
|
||||
position: fixed;
|
||||
}
|
||||
Reference in New Issue
Block a user