Muuuuuch faster, local vector search, local embedding service and api
This commit is contained in:
parent
4effccf3a7
commit
492fa9209b
|
|
@ -1,6 +1,6 @@
|
||||||
@page "/"
|
@page "/"
|
||||||
@page "/menu/{topic?}"
|
@page "/menu/{topic?}"
|
||||||
@inherits SharedDisplayLogic
|
@inherits MainPageBase
|
||||||
@using BLAIzor.Models
|
@using BLAIzor.Models
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using BLAIzor.Components.Partials
|
@using BLAIzor.Components.Partials
|
||||||
|
|
@ -10,21 +10,15 @@
|
||||||
@using System.Net
|
@using System.Net
|
||||||
@using System.Text.Json
|
@using System.Text.Json
|
||||||
@using Sidio.Sitemap.Blazor
|
@using Sidio.Sitemap.Blazor
|
||||||
@* @inject AIService ChatGptService *@
|
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
@* @inject IJSRuntime jsRuntime; *@
|
|
||||||
@* @inject IConfiguration configuration *@
|
|
||||||
@inject ContentService _contentService
|
@inject ContentService _contentService
|
||||||
@* @inject ContentEditorService _contentEditorService *@
|
|
||||||
@* @inject ScopedContentService _scopedContentService *@
|
|
||||||
@* @inject IEmailSender _emailService *@
|
|
||||||
@inject NavigationManager _navigationManager
|
@inject NavigationManager _navigationManager
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
@inject IHttpContextAccessor HttpContextAccessor
|
||||||
@inject DesignTemplateService DesignTemplateService
|
@inject DesignTemplateService DesignTemplateService
|
||||||
@inject CssTemplateService CssTemplateService
|
@inject CssTemplateService CssTemplateService
|
||||||
@inject CssInjectorService CssService
|
@inject CssInjectorService CssService
|
||||||
@* @inject HttpClient Http *@
|
|
||||||
@attribute [Sitemap]
|
@attribute [Sitemap]
|
||||||
|
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
<div class="page" style="z-index: 1">
|
<div class="page" style="z-index: 1">
|
||||||
|
|
@ -264,7 +258,7 @@
|
||||||
// Load the CSS template for the selected brand from the database
|
// Load the CSS template for the selected brand from the database
|
||||||
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
||||||
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
||||||
CollectionName = designTemplate.QDrandCollectionName;
|
TemplateCollectionName = designTemplate.QDrandCollectionName;
|
||||||
|
|
||||||
if (cssTemplate != null)
|
if (cssTemplate != null)
|
||||||
{
|
{
|
||||||
|
|
@ -284,11 +278,11 @@
|
||||||
if(!string.IsNullOrWhiteSpace(topic))
|
if(!string.IsNullOrWhiteSpace(topic))
|
||||||
{
|
{
|
||||||
UserInput = topic;
|
UserInput = topic;
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, Menu, true);
|
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, Menu);
|
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu);
|
||||||
}
|
}
|
||||||
// HtmlContent = await ChatGptService.GetChatGptWelcomeMessage();
|
// HtmlContent = await ChatGptService.GetChatGptWelcomeMessage();
|
||||||
// UserInput = "Sumerize for me, what is this website about, and what can I do on this website?";
|
// UserInput = "Sumerize for me, what is this website about, and what can I do on this website?";
|
||||||
|
|
@ -413,7 +407,7 @@
|
||||||
var menu = await GetMenuList(SiteId);
|
var menu = await GetMenuList(SiteId);
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
string input = "Please tell me more about: " + UserInput;
|
string input = "Please tell me more about: " + UserInput;
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
await ChatGptService.ProcessUserIntent(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ using UglyToad.PdfPig.DocumentLayoutAnalysis;
|
||||||
|
|
||||||
namespace BLAIzor.Components.Pages
|
namespace BLAIzor.Components.Pages
|
||||||
{
|
{
|
||||||
public class SharedDisplayLogic : ComponentBase
|
public class MainPageBase : ComponentBase
|
||||||
{
|
{
|
||||||
public string SelectedBrandName = "default";
|
public string SelectedBrandName = "default";
|
||||||
[Inject] protected ScopedContentService _scopedContentService { get; set; }
|
[Inject] protected ScopedContentService _scopedContentService { get; set; }
|
||||||
|
|
@ -22,10 +22,10 @@ namespace BLAIzor.Components.Pages
|
||||||
[Inject] protected IJSRuntime jsRuntime { get; set; }
|
[Inject] protected IJSRuntime jsRuntime { get; set; }
|
||||||
[Inject] protected AIService ChatGptService { get; set; }
|
[Inject] protected AIService ChatGptService { get; set; }
|
||||||
|
|
||||||
public static readonly Dictionary<string, SharedDisplayLogic> _instances = new();
|
public static readonly Dictionary<string, MainPageBase> _instances = new();
|
||||||
|
|
||||||
public string SessionId;
|
public string SessionId;
|
||||||
public static SharedDisplayLogic myHome;
|
public static MainPageBase myHome;
|
||||||
|
|
||||||
public int SiteId;
|
public int SiteId;
|
||||||
public SiteInfo SiteInfo;
|
public SiteInfo SiteInfo;
|
||||||
|
|
@ -33,7 +33,7 @@ namespace BLAIzor.Components.Pages
|
||||||
public string TextContent = "";
|
public string TextContent = "";
|
||||||
public string StatusContent = "";
|
public string StatusContent = "";
|
||||||
public string UserInput = string.Empty;
|
public string UserInput = string.Empty;
|
||||||
public string CollectionName = "html_snippets";
|
public string TemplateCollectionName = "html_snippets";
|
||||||
|
|
||||||
public bool VoiceEnabled;
|
public bool VoiceEnabled;
|
||||||
public bool TTSEnabled;
|
public bool TTSEnabled;
|
||||||
|
|
@ -123,9 +123,9 @@ namespace BLAIzor.Components.Pages
|
||||||
|
|
||||||
var requestJson = JsonSerializer.Serialize(requestContent);
|
var requestJson = JsonSerializer.Serialize(requestContent);
|
||||||
string voiceId;
|
string voiceId;
|
||||||
if (SiteInfo.voiceId != null)
|
if (SiteInfo.VoiceId != null)
|
||||||
{
|
{
|
||||||
voiceId = SiteInfo.voiceId;
|
voiceId = SiteInfo.VoiceId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -199,7 +199,7 @@ namespace BLAIzor.Components.Pages
|
||||||
{
|
{
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
var menu = await GetMenuList(SiteId);
|
var menu = await GetMenuList(SiteId);
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,11 +214,11 @@ namespace BLAIzor.Components.Pages
|
||||||
var menuItem = (await GetMenuItems(SiteId)).Where(m => m.Name == input).FirstOrDefault();
|
var menuItem = (await GetMenuItems(SiteId)).Where(m => m.Name == input).FirstOrDefault();
|
||||||
if (menuItem == null)
|
if (menuItem == null)
|
||||||
{
|
{
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu, forceUnmodified);
|
await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu, forceUnmodified);
|
await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu, forceUnmodified);
|
||||||
}
|
}
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +302,7 @@ namespace BLAIzor.Components.Pages
|
||||||
Console.WriteLine("Button clicked!");
|
Console.WriteLine("Button clicked!");
|
||||||
var menu = await GetMenuList(SiteId);
|
var menu = await GetMenuList(SiteId);
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@page "/preview/{siteid:int}"
|
@page "/preview/{siteid:int}"
|
||||||
@page "/preview/{siteid:int}/{topic?}"
|
@page "/preview/{siteid:int}/{topic?}"
|
||||||
@inherits SharedDisplayLogic
|
@inherits MainPageBase
|
||||||
@using BLAIzor.Models
|
@using BLAIzor.Models
|
||||||
@using BLAIzor.Services
|
@using BLAIzor.Services
|
||||||
@using Google.Cloud.Speech.V1
|
@using Google.Cloud.Speech.V1
|
||||||
|
|
@ -10,21 +10,14 @@
|
||||||
@using System.Text.Json
|
@using System.Text.Json
|
||||||
@using System.Net
|
@using System.Net
|
||||||
|
|
||||||
@* @inject AIService ChatGptService *@
|
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
@* @inject IJSRuntime jsRuntime; *@
|
|
||||||
@* @inject IConfiguration configuration *@
|
|
||||||
@inject ContentService _contentService
|
@inject ContentService _contentService
|
||||||
@* @inject ContentEditorService _contentEditorService *@
|
|
||||||
@* @inject ScopedContentService _scopedContentService *@
|
|
||||||
@inject IEmailSender _emailService
|
@inject IEmailSender _emailService
|
||||||
@inject NavigationManager _navigationManager
|
@inject NavigationManager _navigationManager
|
||||||
@inject IHttpContextAccessor HttpContextAccessor
|
@inject IHttpContextAccessor HttpContextAccessor
|
||||||
@inject DesignTemplateService DesignTemplateService
|
@inject DesignTemplateService DesignTemplateService
|
||||||
@inject CssTemplateService CssTemplateService
|
@inject CssTemplateService CssTemplateService
|
||||||
@inject CssInjectorService CssService
|
@inject CssInjectorService CssService
|
||||||
@* @inject HttpClient Http *@
|
|
||||||
|
|
||||||
|
|
||||||
<div class="page" style="z-index: 1">
|
<div class="page" style="z-index: 1">
|
||||||
<NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu>
|
<NavMenu MenuString="@Menu" OnMenuClicked=@MenuClick></NavMenu>
|
||||||
|
|
@ -99,9 +92,7 @@
|
||||||
@{
|
@{
|
||||||
if (!string.IsNullOrEmpty(HtmlContent.ToString()))
|
if (!string.IsNullOrEmpty(HtmlContent.ToString()))
|
||||||
{
|
{
|
||||||
// <div class="pt-5 @FirstColumnClass">
|
|
||||||
// @((MarkupString)HtmlContent.ToString())
|
|
||||||
// </div>
|
|
||||||
if (isEmailFormVisible)
|
if (isEmailFormVisible)
|
||||||
{
|
{
|
||||||
<div class="conteiner-fluid">
|
<div class="conteiner-fluid">
|
||||||
|
|
@ -330,7 +321,7 @@
|
||||||
// Load the CSS template for the selected brand from the database
|
// Load the CSS template for the selected brand from the database
|
||||||
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
var designTemplate = await DesignTemplateService.GetByIdAsync((int)SiteInfo.TemplateId!);
|
||||||
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
var cssTemplate = await CssTemplateService.GetByDesignTemplateIdAsync((int)SiteInfo.TemplateId);
|
||||||
CollectionName = designTemplate.QDrandCollectionName;
|
TemplateCollectionName = designTemplate.QDrandCollectionName;
|
||||||
|
|
||||||
if (cssTemplate != null)
|
if (cssTemplate != null)
|
||||||
{
|
{
|
||||||
|
|
@ -354,11 +345,11 @@
|
||||||
if (!string.IsNullOrWhiteSpace(topic))
|
if (!string.IsNullOrWhiteSpace(topic))
|
||||||
{
|
{
|
||||||
UserInput = topic;
|
UserInput = topic;
|
||||||
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, Menu, true);
|
await ChatGptService.ProcessContentRequest(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, Menu, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, Menu);
|
await ChatGptService.GetChatGptWelcomeMessage(SessionId, SiteId, TemplateCollectionName, Menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -429,7 +420,7 @@
|
||||||
{
|
{
|
||||||
HtmlContent.Clear();
|
HtmlContent.Clear();
|
||||||
var menu = await GetMenuList(SiteId);
|
var menu = await GetMenuList(SiteId);
|
||||||
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, CollectionName, menu);
|
await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu);
|
||||||
UserInput = string.Empty;
|
UserInput = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ else if (ExtractedMenuItems.Any())
|
||||||
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
<MenuItemContentEditor Subject=@subject MenuItem="item" WordFile=@document SessionId="SessionId" OnContentUpdated="UpdateMenuItem" />
|
||||||
}
|
}
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
|
||||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ else if (ExtractedMenuItems.Any())
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||||
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(ErrorMessage))
|
else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
|
|
@ -163,6 +163,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
if (selectedPoint != null)
|
if (selectedPoint != null)
|
||||||
{
|
{
|
||||||
model.Content = selectedPoint.result.payload.content;
|
model.Content = selectedPoint.result.payload.content;
|
||||||
|
model.ContentDescription = selectedPoint.result.payload.description;
|
||||||
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,6 +247,7 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
//item.MenuItem.
|
//item.MenuItem.
|
||||||
|
item.MenuItem.Name = updatedItem.MenuItem.Name;
|
||||||
item.Content = updatedItem.Content;
|
item.Content = updatedItem.Content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -287,10 +289,12 @@ else if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
foreach (var menuItemToReorder in menuItems)
|
foreach (var menuItemToReorder in menuItems)
|
||||||
{
|
{
|
||||||
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
|
menuItemToReorder.SortOrder = menuItems.IndexOf(menuItemToReorder);
|
||||||
|
Console.WriteLine($"{menuItemToReorder.Name}, {menuItemToReorder.SortOrder}");
|
||||||
}
|
}
|
||||||
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
foreach (var extractedMenuItemToReorder in ExtractedMenuItems)
|
||||||
{
|
{
|
||||||
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
|
extractedMenuItemToReorder.MenuItem.SortOrder = ExtractedMenuItems.IndexOf(extractedMenuItemToReorder);
|
||||||
|
Console.WriteLine($"{extractedMenuItemToReorder.MenuItem.Name}, {extractedMenuItemToReorder.MenuItem.SortOrder}");
|
||||||
}
|
}
|
||||||
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
|
JSRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ else if (extractedMenuItems.Any())
|
||||||
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
|
<MenuItemContentEditor Subject=@subject MenuItem="item" OnContentUpdated="UpdateMenuItem" SessionId="SessionId" />
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
<button class="btn btn-danger btn-sm mt-2" @onclick="() => RemoveMenuItem(item)">Remove</button>
|
||||||
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ else if (extractedMenuItems.Any())
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<button class="btn btn-default btn-sm mt-2" @onclick="() => AddMenuItem()">Add a new menu item after this one</button>
|
||||||
|
|
||||||
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
<button class="btn btn-success mt-3" @onclick="() => SaveMenuItems(true)">Save All</button>
|
||||||
}
|
}
|
||||||
|
|
@ -133,6 +133,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
if (selectedPoint != null)
|
if (selectedPoint != null)
|
||||||
{
|
{
|
||||||
model.Content = selectedPoint.result.payload.content;
|
model.Content = selectedPoint.result.payload.content;
|
||||||
|
model.ContentDescription = selectedPoint.result.payload.description;
|
||||||
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
Console.Write($"Found point: {selectedPoint.result.payload.content}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,6 +183,7 @@ else if (!string.IsNullOrEmpty(errorMessage))
|
||||||
var newItem = new MenuItemModel("New menu item", "");
|
var newItem = new MenuItemModel("New menu item", "");
|
||||||
//TODO Fix
|
//TODO Fix
|
||||||
extractedMenuItems.Add(newItem);
|
extractedMenuItems.Add(newItem);
|
||||||
|
isLoading = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -17,14 +17,20 @@
|
||||||
}
|
}
|
||||||
<button class="btn btn-primary mb-2" @onclick="GenerateContent" disabled="@IsLoading">Generate by AI</button>
|
<button class="btn btn-primary mb-2" @onclick="GenerateContent" disabled="@IsLoading">Generate by AI</button>
|
||||||
@* <textarea class="form-control border-0 text-white" @bind="GeneratedContent" rows="5"></textarea> *@
|
@* <textarea class="form-control border-0 text-white" @bind="GeneratedContent" rows="5"></textarea> *@
|
||||||
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
<div class="row">
|
||||||
<RadzenHtmlEditorUndo />
|
|
||||||
<RadzenHtmlEditorRedo />
|
|
||||||
<RadzenHtmlEditorSource />
|
|
||||||
</RadzenHtmlEditor>
|
|
||||||
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
|
||||||
|
|
||||||
<EventConsole @ref=@console />
|
<RadzenTextArea @bind-Value=@MenuItem.ContentDescription></RadzenTextArea>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<RadzenHtmlEditor @bind-Value=@GeneratedContent style="height: 450px; color:#000; background-color: rgba(255,255,255,0.4)" Input=@OnInput Change=@OnChange Paste=@OnPaste UploadComplete=@OnUploadComplete Execute=@OnExecute UploadUrl="upload/image">
|
||||||
|
<RadzenHtmlEditorUndo />
|
||||||
|
<RadzenHtmlEditorRedo />
|
||||||
|
<RadzenHtmlEditorSource />
|
||||||
|
</RadzenHtmlEditor>
|
||||||
|
</div>
|
||||||
|
<InputFile class="btn btn-default" type="file" multiple OnChange=HandleFileUpload accept=".mp3,.mp4,.jpg,.png" />
|
||||||
|
|
||||||
|
@* <EventConsole @ref=@console /> *@
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
<p>Loading content...</p>
|
<p>Loading content...</p>
|
||||||
|
|
@ -40,15 +46,17 @@
|
||||||
|
|
||||||
private bool IsLoading = false;
|
private bool IsLoading = false;
|
||||||
private string GeneratedContent = string.Empty;
|
private string GeneratedContent = string.Empty;
|
||||||
|
// private string Description = string.Empty;
|
||||||
private string? userId;
|
private string? userId;
|
||||||
private string? userName;
|
private string? userName;
|
||||||
private AuthenticationState? authState;
|
private AuthenticationState? authState;
|
||||||
|
|
||||||
EventConsole console;
|
//EventConsole console;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
GeneratedContent = MenuItem.Content;
|
GeneratedContent = MenuItem.Content;
|
||||||
|
// Description = MenuItem.ContentDescription;
|
||||||
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
if (authState.User.Identity?.IsAuthenticated == true)
|
if (authState.User.Identity?.IsAuthenticated == true)
|
||||||
{
|
{
|
||||||
|
|
@ -103,33 +111,33 @@
|
||||||
|
|
||||||
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
async Task OnPaste(HtmlEditorPasteEventArgs args)
|
||||||
{
|
{
|
||||||
console.Log($"Paste: {args.Html}");
|
// console.Log($"Paste: {args.Html}");
|
||||||
MenuItem.Content = args.Html;
|
MenuItem.Content = args.Html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnChange(string html)
|
async Task OnChange(string html)
|
||||||
{
|
{
|
||||||
console.Log($"Change: {html}");
|
// console.Log($"Change: {html}");
|
||||||
MenuItem.Content = html;
|
MenuItem.Content = html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnInput(string html)
|
async Task OnInput(string html)
|
||||||
{
|
{
|
||||||
console.Log($"Input: {html}");
|
// console.Log($"Input: {html}");
|
||||||
MenuItem.Content = html;
|
MenuItem.Content = html;
|
||||||
await OnContentUpdated.InvokeAsync(MenuItem);
|
await OnContentUpdated.InvokeAsync(MenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||||
{
|
{
|
||||||
console.Log($"Execute: {args.CommandName}");
|
//console.Log($"Execute: {args.CommandName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUploadComplete(UploadCompleteEventArgs args)
|
void OnUploadComplete(UploadCompleteEventArgs args)
|
||||||
{
|
{
|
||||||
console.Log($"Upload complete: {args.RawResponse}");
|
//console.Log($"Upload complete: {args.RawResponse}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
private async Task HandleFileUpload(InputFileChangeEventArgs e)
|
||||||
|
|
@ -167,7 +175,7 @@
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
console.Log($"Error uploading files: {ex.Message}");
|
// console.Log($"Error uploading files: {ex.Message}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,645 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using BLAIzor.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace BLAIzor.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20250615203806_EmbeddingServiceAndDefaultLanguage")]
|
||||||
|
partial class EmbeddingServiceAndDefaultLanguage
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.3")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("CssContent")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("DesignTemplateId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastUpdated")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DesignTemplateId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("CssTemplates");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeprecated")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPrivate")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPublished")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("QDrandCollectionName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Tags")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("TemplateName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("TemplatePhotoUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("UpdatedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<int>("Version")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("DesignTemplates");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
|
Description = "The default template",
|
||||||
|
IsDeprecated = false,
|
||||||
|
IsPrivate = false,
|
||||||
|
IsPublished = false,
|
||||||
|
QDrandCollectionName = "html_snippets",
|
||||||
|
Status = "Draft",
|
||||||
|
Tags = "system",
|
||||||
|
TemplateName = "Default Site",
|
||||||
|
TemplatePhotoUrl = "/images/default-logo.png",
|
||||||
|
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
||||||
|
Version = 1
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("JsonDefinition")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("SiteInfoId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<int>("Version")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SiteInfoId", "Slug")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("FormDefinitions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("PointId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<Guid?>("QdrantPointId")
|
||||||
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
|
b.Property<bool>("ShowInMainMenu")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<int>("SiteInfoId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("SortOrder")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("StoredHtml")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SiteInfoId");
|
||||||
|
|
||||||
|
b.ToTable("MenuItems");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundVideo")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("BrandLogoUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultColor")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultLanguage")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultUrl")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("DomainUrl")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("EmbeddingService")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Entity")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPublished")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("Persona")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("STTActive")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("SiteDescription")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("SiteName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("TTSActive")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<int?>("TemplateId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("VoiceId")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TemplateId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("SiteInfos");
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
BrandLogoUrl = "/images/default-logo.png",
|
||||||
|
DefaultColor = "#FFFFFF",
|
||||||
|
DefaultUrl = "https://ai.poppixel.cloud",
|
||||||
|
DomainUrl = "poppixel.cloud",
|
||||||
|
IsPublished = false,
|
||||||
|
STTActive = false,
|
||||||
|
SiteName = "Default Site",
|
||||||
|
TTSActive = false,
|
||||||
|
TemplateId = 1,
|
||||||
|
UserId = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex")
|
||||||
|
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("datetimeoffset");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex")
|
||||||
|
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = "0988758e-e16c-4c2c-8c1e-efa3ac5f0274",
|
||||||
|
AccessFailedCount = 0,
|
||||||
|
ConcurrencyStamp = "a2836246-0303-4370-b283-e53a9a3f2813",
|
||||||
|
Email = "adam.g@aycode.com",
|
||||||
|
EmailConfirmed = true,
|
||||||
|
LockoutEnabled = false,
|
||||||
|
NormalizedEmail = "ADAM.G@AYCODE.COM",
|
||||||
|
NormalizedUserName = "ADAM.G@AYCODE.COM",
|
||||||
|
PasswordHash = "AQAAAAIAAYagAAAAEChxKCu+ReGvcZFR/6kPASbpnQdMp1MJuepeRyR4bfHTkUk8SfNAqmckGXvuw+GaGA==",
|
||||||
|
PhoneNumberConfirmed = false,
|
||||||
|
SecurityStamp = "7ecf121a-b0e7-4e30-a1f1-299eeaf0a9cc",
|
||||||
|
TwoFactorEnabled = false,
|
||||||
|
UserName = "adam.g@aycode.com"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.CssTemplate", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BLAIzor.Models.DesignTemplate", "DesignTemplate")
|
||||||
|
.WithOne("CssTemplate")
|
||||||
|
.HasForeignKey("BLAIzor.Models.CssTemplate", "DesignTemplateId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("DesignTemplate");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.FormDefinition", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
||||||
|
.WithMany("FormDefinitions")
|
||||||
|
.HasForeignKey("SiteInfoId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SiteInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.MenuItem", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BLAIzor.Models.SiteInfo", "SiteInfo")
|
||||||
|
.WithMany("MenuItems")
|
||||||
|
.HasForeignKey("SiteInfoId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SiteInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("BLAIzor.Models.DesignTemplate", "Template")
|
||||||
|
.WithMany("Sites")
|
||||||
|
.HasForeignKey("TemplateId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Template");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.DesignTemplate", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("CssTemplate")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Sites");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("BLAIzor.Models.SiteInfo", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("FormDefinitions");
|
||||||
|
|
||||||
|
b.Navigation("MenuItems");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace BLAIzor.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class EmbeddingServiceAndDefaultLanguage : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "voiceId",
|
||||||
|
table: "SiteInfos",
|
||||||
|
newName: "VoiceId");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "BackgroundVideo",
|
||||||
|
table: "SiteInfos",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "DefaultLanguage",
|
||||||
|
table: "SiteInfos",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "EmbeddingService",
|
||||||
|
table: "SiteInfos",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "StoredHtml",
|
||||||
|
table: "MenuItems",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "nvarchar(max)");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "SiteInfos",
|
||||||
|
keyColumn: "Id",
|
||||||
|
keyValue: 1,
|
||||||
|
columns: new[] { "BackgroundVideo", "DefaultLanguage", "EmbeddingService" },
|
||||||
|
values: new object[] { null, null, null });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "BackgroundVideo",
|
||||||
|
table: "SiteInfos");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "DefaultLanguage",
|
||||||
|
table: "SiteInfos");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "EmbeddingService",
|
||||||
|
table: "SiteInfos");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "VoiceId",
|
||||||
|
table: "SiteInfos",
|
||||||
|
newName: "voiceId");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "StoredHtml",
|
||||||
|
table: "MenuItems",
|
||||||
|
type: "nvarchar(max)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "",
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "nvarchar(max)",
|
||||||
|
oldNullable: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -193,7 +193,6 @@ namespace BLAIzor.Migrations
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("StoredHtml")
|
b.Property<string>("StoredHtml")
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
@ -211,12 +210,18 @@ namespace BLAIzor.Migrations
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundVideo")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("BrandLogoUrl")
|
b.Property<string>("BrandLogoUrl")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("DefaultColor")
|
b.Property<string>("DefaultColor")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("DefaultLanguage")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("DefaultUrl")
|
b.Property<string>("DefaultUrl")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
@ -225,6 +230,9 @@ namespace BLAIzor.Migrations
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("EmbeddingService")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<string>("Entity")
|
b.Property<string>("Entity")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
|
@ -253,7 +261,7 @@ namespace BLAIzor.Migrations
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
b.Property<string>("voiceId")
|
b.Property<string>("VoiceId")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
public string? Variant { get; set; } // 👈 NEW: e.g. "image-left", "image-right", "no-image"
|
||||||
public string SampleHtml { get; set; } //for design purposes
|
public string SampleHtml { get; set; } //for design purposes
|
||||||
public List<string> Slots { get; set; } // e.g. ["title", "subtitle", "image", "cta"]
|
public List<string> Slots { get; set; } // e.g. ["title", "subtitle", "image", "cta"]
|
||||||
|
public float[] Vectors { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace BLAIzor.Models
|
||||||
|
|
||||||
public bool ShowInMainMenu { get; set; } = false;
|
public bool ShowInMainMenu { get; set; } = false;
|
||||||
|
|
||||||
public string StoredHtml { get; set; }
|
public string? StoredHtml { get; set; }
|
||||||
|
|
||||||
public Guid? QdrantPointId { get; set; }
|
public Guid? QdrantPointId { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ namespace BLAIzor.Models
|
||||||
{
|
{
|
||||||
public MenuItem MenuItem { get; set; }
|
public MenuItem MenuItem { get; set; }
|
||||||
public string Content { get; set; } = string.Empty;
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public string ContentDescription { get; set; } = string.Empty;
|
||||||
|
|
||||||
public MenuItemModel(string name)
|
public MenuItemModel(string name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,13 @@ namespace BLAIzor.Models
|
||||||
public int? TemplateId { get; set; }
|
public int? TemplateId { get; set; }
|
||||||
public bool TTSActive { get; set; } = false;
|
public bool TTSActive { get; set; } = false;
|
||||||
public bool STTActive { get; set; } = false;
|
public bool STTActive { get; set; } = false;
|
||||||
public string? voiceId { get; set; }
|
public string? VoiceId { get; set; }
|
||||||
public string? Persona { get; set; }
|
public string? Persona { get; set; }
|
||||||
public string? Entity { get; set; }
|
public string? Entity { get; set; }
|
||||||
|
public string? DefaultLanguage { get; set; }
|
||||||
|
public string? BackgroundVideo { get; set; }
|
||||||
|
|
||||||
|
public string? EmbeddingService { get; set; }
|
||||||
|
|
||||||
// Navigation property for IdentityUser
|
// Navigation property for IdentityUser
|
||||||
public IdentityUser User { get; set; }
|
public IdentityUser User { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ namespace BLAIzor.Models
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public string Content { get; set; }
|
public string Content { get; set; }
|
||||||
|
public float[] Vectors { get; set; }
|
||||||
public DateTime LastUpdated { get; set; }
|
public DateTime LastUpdated { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ builder.Services.AddSingleton<ContentService>();
|
||||||
builder.Services.AddScoped<ScopedContentService>();
|
builder.Services.AddScoped<ScopedContentService>();
|
||||||
builder.Services.AddScoped<QDrantService>();
|
builder.Services.AddScoped<QDrantService>();
|
||||||
builder.Services.AddScoped<OpenAIEmbeddingService>();
|
builder.Services.AddScoped<OpenAIEmbeddingService>();
|
||||||
|
builder.Services.AddScoped<LocalEmbeddingService>();
|
||||||
builder.Services.AddScoped<HtmlSnippetProcessor>();
|
builder.Services.AddScoped<HtmlSnippetProcessor>();
|
||||||
builder.Services
|
builder.Services
|
||||||
.AddHttpContextAccessor()
|
.AddHttpContextAccessor()
|
||||||
|
|
@ -64,6 +65,7 @@ builder.Services.AddScoped<DeepSeekApiService>();
|
||||||
builder.Services.AddScoped<OpenAiRealtimeService>();
|
builder.Services.AddScoped<OpenAiRealtimeService>();
|
||||||
builder.Services.AddScoped<CerebrasAPIService>();
|
builder.Services.AddScoped<CerebrasAPIService>();
|
||||||
builder.Services.AddScoped<CssInjectorService>();
|
builder.Services.AddScoped<CssInjectorService>();
|
||||||
|
builder.Services.AddScoped<LocalVectorSearchService>();
|
||||||
builder.Services.AddHostedService<TempFileCleanupService>();
|
builder.Services.AddHostedService<TempFileCleanupService>();
|
||||||
builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true).AddHubOptions(options =>
|
builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true).AddHubOptions(options =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -13,8 +13,11 @@ namespace BLAIzor.Services
|
||||||
private readonly QDrantService _qDrantService;
|
private readonly QDrantService _qDrantService;
|
||||||
private readonly HtmlSnippetProcessor _htmlSnippetProcessor;
|
private readonly HtmlSnippetProcessor _htmlSnippetProcessor;
|
||||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||||
|
private readonly ScopedContentService _scopedContentService;
|
||||||
|
|
||||||
public ContentEditorService(/*AIService aiService,*/ OpenAIApiService openAIApiService, /*ApplicationDbContext context,*/ QDrantService qDrantService, HtmlSnippetProcessor htmlSnippetProcessor, IServiceScopeFactory serviceScopeFactory)
|
public static IConfiguration? _configuration;
|
||||||
|
|
||||||
|
public ContentEditorService(/*AIService aiService,*/ OpenAIApiService openAIApiService, /*ApplicationDbContext context,*/ QDrantService qDrantService, HtmlSnippetProcessor htmlSnippetProcessor, IServiceScopeFactory serviceScopeFactory, ScopedContentService scopedContentService, IConfiguration? configuration)
|
||||||
{
|
{
|
||||||
//_aiService = aiService;
|
//_aiService = aiService;
|
||||||
_openAIApiService = openAIApiService;
|
_openAIApiService = openAIApiService;
|
||||||
|
|
@ -22,8 +25,14 @@ namespace BLAIzor.Services
|
||||||
_qDrantService = qDrantService;
|
_qDrantService = qDrantService;
|
||||||
_htmlSnippetProcessor = htmlSnippetProcessor;
|
_htmlSnippetProcessor = htmlSnippetProcessor;
|
||||||
_serviceScopeFactory = serviceScopeFactory;
|
_serviceScopeFactory = serviceScopeFactory;
|
||||||
|
_scopedContentService = scopedContentService;
|
||||||
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetAiEmbeddingSettings() =>
|
||||||
|
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||||
|
|
||||||
|
|
||||||
// Existing methods
|
// Existing methods
|
||||||
public async Task<List<string>> GetMenuSuggestionsAsync(string sessionId, string prompt)
|
public async Task<List<string>> GetMenuSuggestionsAsync(string sessionId, string prompt)
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +161,7 @@ namespace BLAIzor.Services
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//check if Collection is created already
|
|
||||||
|
|
||||||
if (!hasCollection)
|
if (!hasCollection)
|
||||||
{
|
{
|
||||||
|
|
@ -160,7 +169,29 @@ namespace BLAIzor.Services
|
||||||
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
||||||
hasCollection = true;
|
hasCollection = true;
|
||||||
}
|
}
|
||||||
var updateQdrantList = ExtractedMenuItems.OrderBy(mi => mi.MenuItem.PointId).ToList();
|
else
|
||||||
|
{
|
||||||
|
//check if Collection is really created already
|
||||||
|
var collection = await _qDrantService.GetCollectionCount("Site" + SiteId.ToString());
|
||||||
|
if(collection != null)
|
||||||
|
{
|
||||||
|
var siteInfo = await _scopedContentService.GetSiteInfoByIdAsync(SiteId);
|
||||||
|
if(siteInfo.EmbeddingService != null)
|
||||||
|
{
|
||||||
|
var currentEmbeddingServiceName = GetAiEmbeddingSettings();
|
||||||
|
if (siteInfo.EmbeddingService == currentEmbeddingServiceName)
|
||||||
|
{
|
||||||
|
//drop existing collection
|
||||||
|
await _qDrantService.DeleteCollectionAsync("Site" + SiteId.ToString());
|
||||||
|
//create will automatically handle the new vector size
|
||||||
|
await _qDrantService.CreateQdrantCollectionAsync("Site" + SiteId.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var updateQdrantList = ExtractedMenuItems.OrderBy(mi => mi.MenuItem.PointId).ToList();
|
||||||
|
|
||||||
for (int i = 0; i < updateQdrantList.Count(); i++)
|
for (int i = 0; i < updateQdrantList.Count(); i++)
|
||||||
{
|
{
|
||||||
|
|
@ -180,16 +211,23 @@ namespace BLAIzor.Services
|
||||||
content.Type = "page";
|
content.Type = "page";
|
||||||
content.SiteId = SiteId;
|
content.SiteId = SiteId;
|
||||||
content.Name = ExtractedMenuItems[i].MenuItem.Name;
|
content.Name = ExtractedMenuItems[i].MenuItem.Name;
|
||||||
content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
|
if (ExtractedMenuItems[i].ContentDescription == null)
|
||||||
|
{
|
||||||
|
content.Description = $"A section called {ExtractedMenuItems[i].MenuItem.Name} of a website of {subject}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content.Description = ExtractedMenuItems[i].ContentDescription;
|
||||||
|
}
|
||||||
content.Content = ExtractedMenuItems[i].Content;
|
content.Content = ExtractedMenuItems[i].Content;
|
||||||
content.LastUpdated = DateTime.UtcNow;
|
content.LastUpdated = DateTime.UtcNow;
|
||||||
|
|
||||||
menuItem.QdrantPointId = guid;
|
menuItem.QdrantPointId = guid;
|
||||||
menuItem.PointId = i;
|
menuItem.PointId = i;
|
||||||
await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(i, content, SiteId);
|
await _htmlSnippetProcessor.ProcessAndStoreWebContentAsync(i, content, SiteId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
menuItem.PointId = i;
|
||||||
menuItem.QdrantPointId = ExtractedMenuItems[i].MenuItem.QdrantPointId;
|
menuItem.QdrantPointId = ExtractedMenuItems[i].MenuItem.QdrantPointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,6 +252,7 @@ namespace BLAIzor.Services
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
thisItem.PointId = menuItem.PointId;
|
||||||
thisItem.QdrantPointId = menuItem.QdrantPointId;
|
thisItem.QdrantPointId = menuItem.QdrantPointId;
|
||||||
thisItem.SortOrder = ExtractedMenuItems[i].MenuItem.SortOrder;
|
thisItem.SortOrder = ExtractedMenuItems[i].MenuItem.SortOrder;
|
||||||
thisItem.ShowInMainMenu = ExtractedMenuItems[i].MenuItem.ShowInMainMenu;
|
thisItem.ShowInMainMenu = ExtractedMenuItems[i].MenuItem.ShowInMainMenu;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BLAIzor.Models;
|
using BLAIzor.Models;
|
||||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
|
|
@ -16,16 +17,18 @@ namespace BLAIzor.Services
|
||||||
|
|
||||||
public class HtmlSnippetProcessor
|
public class HtmlSnippetProcessor
|
||||||
{
|
{
|
||||||
private readonly OpenAIEmbeddingService _embeddingService;
|
private readonly OpenAIEmbeddingService _openAIEmbeddingService;
|
||||||
|
private readonly LocalEmbeddingService _localEmbeddingService;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly QDrantService _drantService;
|
private readonly QDrantService _drantService;
|
||||||
public static IConfiguration? _configuration;
|
public static IConfiguration? _configuration;
|
||||||
private string _qdrantApiKey;
|
private string _qdrantApiKey;
|
||||||
|
|
||||||
public HtmlSnippetProcessor(QDrantService drantService, IConfiguration? configuration)
|
public HtmlSnippetProcessor(QDrantService drantService, OpenAIEmbeddingService openAIEmbeddingService, LocalEmbeddingService localEmbeddingService, IConfiguration? configuration)
|
||||||
{
|
{
|
||||||
_drantService = drantService;
|
_drantService = drantService;
|
||||||
_embeddingService = new OpenAIEmbeddingService();
|
_openAIEmbeddingService = openAIEmbeddingService;
|
||||||
|
_localEmbeddingService = localEmbeddingService;
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +38,9 @@ namespace BLAIzor.Services
|
||||||
return _configuration?.GetSection("QDrant")?.GetValue<string>("ApiKey") ?? string.Empty;
|
return _configuration?.GetSection("QDrant")?.GetValue<string>("ApiKey") ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetAiEmbeddingSettings() =>
|
||||||
|
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||||
|
|
||||||
//public async Task ProcessAndStoreSnippetsAsync()
|
//public async Task ProcessAndStoreSnippetsAsync()
|
||||||
//{
|
//{
|
||||||
// _qdrantApiKey = GetApiKey();
|
// _qdrantApiKey = GetApiKey();
|
||||||
|
|
@ -101,7 +107,20 @@ namespace BLAIzor.Services
|
||||||
$"Variant: {snippet.Variant ?? "default"}. " +
|
$"Variant: {snippet.Variant ?? "default"}. " +
|
||||||
$"Tags: {snippet.Tags}. " +
|
$"Tags: {snippet.Tags}. " +
|
||||||
$"HTML: {snippet.Html}";
|
$"HTML: {snippet.Html}";
|
||||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
|
float[] embedding = [];
|
||||||
|
|
||||||
|
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||||
|
//if (embeddingServiceProvider == "local")
|
||||||
|
//{
|
||||||
|
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
//}
|
||||||
|
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
|
||||||
|
|
||||||
// Add data for batch insertion
|
// Add data for batch insertion
|
||||||
ids.Add(snippet.Id);
|
ids.Add(snippet.Id);
|
||||||
|
|
@ -110,7 +129,7 @@ namespace BLAIzor.Services
|
||||||
{
|
{
|
||||||
["type"] = snippet.Type,
|
["type"] = snippet.Type,
|
||||||
["name"] = snippet.Name,
|
["name"] = snippet.Name,
|
||||||
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant)? "" : snippet.Variant,
|
["variant"] = string.IsNullOrWhiteSpace(snippet.Variant) ? "" : snippet.Variant,
|
||||||
["tags"] = snippet.Tags,
|
["tags"] = snippet.Tags,
|
||||||
["description"] = snippet.Description,
|
["description"] = snippet.Description,
|
||||||
["html"] = snippet.Html,
|
["html"] = snippet.Html,
|
||||||
|
|
@ -133,94 +152,113 @@ namespace BLAIzor.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
//public async Task ProcessAndStoreWebContentsAsync(List<WebPageContent> pageContentList, int siteId)
|
||||||
{
|
//{
|
||||||
_qdrantApiKey = GetApiKey();
|
// _qdrantApiKey = GetApiKey();
|
||||||
|
|
||||||
var ids = new List<int>();
|
// var ids = new List<int>();
|
||||||
var vectors = new List<float[]>();
|
// var vectors = new List<float[]>();
|
||||||
var payloads = new List<MapField<string, Value>>();
|
// var payloads = new List<MapField<string, Value>>();
|
||||||
|
|
||||||
foreach (var content in pageContentList)
|
// foreach (var content in pageContentList)
|
||||||
{
|
// {
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
// Combine details to generate the embedding
|
// // Combine details to generate the embedding
|
||||||
var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
// var combinedText = $"{content.Name}: Description: {content.Description}, complete text: {content.Content}";
|
||||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
|
|
||||||
// Add data for batch insertion
|
// float[] embedding = [];
|
||||||
ids.Add(content.Id);
|
|
||||||
vectors.Add(embedding);
|
// var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||||
|
// if (embeddingServiceProvider == "local")
|
||||||
|
// {
|
||||||
|
// embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Add data for batch insertion
|
||||||
|
// ids.Add(content.Id);
|
||||||
|
// vectors.Add(embedding);
|
||||||
|
|
||||||
|
|
||||||
payloads.Add(new MapField<string, Value>
|
// payloads.Add(new MapField<string, Value>
|
||||||
{
|
// {
|
||||||
["uid"] = content.UId,
|
// ["uid"] = content.UId,
|
||||||
["type"] = content.Type,
|
// ["type"] = content.Type,
|
||||||
["siteId"] = content.SiteId,
|
// ["siteId"] = content.SiteId,
|
||||||
//["menuItemId"] = content.MenuItemId,
|
// //["menuItemId"] = content.MenuItemId,
|
||||||
["name"] = content.Name,
|
// ["name"] = content.Name,
|
||||||
["description"] = content.Description,
|
// ["description"] = content.Description,
|
||||||
["content"] = content.Content,
|
// ["content"] = content.Content,
|
||||||
["lastUpdated"] = content.LastUpdated.ToString()
|
// ["lastUpdated"] = content.LastUpdated.ToString()
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
// Console.WriteLine($"Error processing content {content.Name}: {ex.Message}");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (ids.Count > 0)
|
// if (ids.Count > 0)
|
||||||
{
|
// {
|
||||||
await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site"+siteId);
|
// await _drantService.QDrantInsertManyAsync(ids, vectors, payloads, "Site" + siteId);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
Console.WriteLine("No points were processed successfully.");
|
// Console.WriteLine("No points were processed successfully.");
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
public async Task ProcessAndStoreWebContentAsync(int id, WebPageContent pageContent, int siteId)
|
public async Task ProcessAndStoreWebContentAsync(int id, WebPageContent pageContent, int siteId)
|
||||||
{
|
{
|
||||||
_qdrantApiKey = GetApiKey();
|
_qdrantApiKey = GetApiKey();
|
||||||
|
|
||||||
|
|
||||||
float[] vectors = [];
|
float[] vectors = [];
|
||||||
var payload = new MapField<string, Value>();
|
var payload = new MapField<string, Value>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Combine details to generate the embedding
|
||||||
|
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
||||||
|
float[] embedding = [];
|
||||||
|
|
||||||
try
|
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||||
|
if (embeddingServiceProvider == "local")
|
||||||
{
|
{
|
||||||
// Combine details to generate the embedding
|
embedding = await _localEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
var combinedText = $"{pageContent.Name}: {pageContent.Description} - {pageContent.Content}";
|
|
||||||
var embedding = await _embeddingService.GenerateEmbeddingAsync(combinedText);
|
|
||||||
|
|
||||||
// Add data for batch insertion
|
|
||||||
|
|
||||||
vectors = embedding;
|
|
||||||
|
|
||||||
|
|
||||||
payload = new MapField<string, Value>
|
|
||||||
{
|
|
||||||
["uid"] = pageContent.UId,
|
|
||||||
["type"] = pageContent.Type,
|
|
||||||
["siteId"] = pageContent.SiteId,
|
|
||||||
//["menuItemId"] = pageContent.MenuItemId,
|
|
||||||
["name"] = pageContent.Name,
|
|
||||||
["description"] = pageContent.Description,
|
|
||||||
["content"] = pageContent.Content,
|
|
||||||
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
embedding = await _openAIEmbeddingService.GenerateEmbeddingAsync(combinedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add data for batch insertion
|
||||||
|
|
||||||
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site"+siteId);
|
vectors = embedding;
|
||||||
|
|
||||||
|
|
||||||
|
payload = new MapField<string, Value>
|
||||||
|
{
|
||||||
|
["uid"] = pageContent.UId,
|
||||||
|
["type"] = pageContent.Type,
|
||||||
|
["siteId"] = pageContent.SiteId,
|
||||||
|
//["menuItemId"] = pageContent.MenuItemId,
|
||||||
|
["name"] = pageContent.Name,
|
||||||
|
["description"] = pageContent.Description,
|
||||||
|
["content"] = pageContent.Content,
|
||||||
|
["lastUpdated"] = pageContent.LastUpdated.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error processing content {pageContent.Name}: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await _drantService.QDrantInsertPointAsync(id, vectors, payload, "Site" + siteId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public class LocalEmbeddingService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly string _localOllamaUrl = "http://localhost:11434/api/embeddings";
|
||||||
|
|
||||||
|
public LocalEmbeddingService()
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<float[]> GenerateEmbeddingAsync(string text)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
model = "bge-m3",
|
||||||
|
prompt = text
|
||||||
|
};
|
||||||
|
|
||||||
|
var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = await _httpClient.PostAsync(_localOllamaUrl, content);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
var result = JsonConvert.DeserializeObject<OllamaEmbeddingResponse>(responseContent);
|
||||||
|
return result.Embedding;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorText = await response.Content.ReadAsStringAsync();
|
||||||
|
throw new Exception($"Failed to generate embedding: {response.StatusCode} - {errorText}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OllamaEmbeddingResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("embedding")]
|
||||||
|
public float[] Embedding { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
using BLAIzor.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
|
namespace BLAIzor.Services
|
||||||
|
{
|
||||||
|
public class LocalVectorSearchService
|
||||||
|
{
|
||||||
|
//private List<WebPageContent> _cachedContents = new();
|
||||||
|
//private List<HtmlSnippet> _cachedSnippets = new();
|
||||||
|
private int _cachedContentVersion = -1;
|
||||||
|
private int _cachedSnippetVersion = -1;
|
||||||
|
|
||||||
|
// Inject any needed services (e.g. DbContext, versioning service)
|
||||||
|
public LocalVectorSearchService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//public void SetContentCache(List<WebPageContent> contents, int contentVersion)
|
||||||
|
//{
|
||||||
|
// _cachedContents = contents;
|
||||||
|
// _cachedContentVersion = contentVersion;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public void SetSnippetCache(List<HtmlSnippet> snippets, int snippetVersion)
|
||||||
|
//{
|
||||||
|
// _cachedSnippets = snippets;
|
||||||
|
// _cachedSnippetVersion = snippetVersion;
|
||||||
|
//}
|
||||||
|
|
||||||
|
public bool IsContentVersionOutdated(int currentVersion)
|
||||||
|
=> currentVersion != _cachedContentVersion;
|
||||||
|
|
||||||
|
public bool IsSnippetVersionOutdated(int currentVersion)
|
||||||
|
=> currentVersion != _cachedSnippetVersion;
|
||||||
|
|
||||||
|
public List<WebPageContent> SearchContent(float[] queryVector, List<WebPageContent> cachedContents, int maxResults = 5)
|
||||||
|
{
|
||||||
|
return cachedContents
|
||||||
|
.Select(c => new
|
||||||
|
{
|
||||||
|
Content = c,
|
||||||
|
Similarity = CosineSimilarity(queryVector, c.Vectors)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.Similarity)
|
||||||
|
.Take(maxResults)
|
||||||
|
.Select(x => x.Content)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HtmlSnippet> SearchSnippets(float[] queryVector, List<HtmlSnippet> cachedSnippets, int maxResults = 5)
|
||||||
|
{
|
||||||
|
return cachedSnippets
|
||||||
|
.Select(s => new
|
||||||
|
{
|
||||||
|
Snippet = s,
|
||||||
|
Similarity = CosineSimilarity(queryVector, s.Vectors)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.Similarity)
|
||||||
|
.Take(maxResults)
|
||||||
|
.Select(x => x.Snippet)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CosineSimilarity(float[] vectorA, float[] vectorB)
|
||||||
|
{
|
||||||
|
if (vectorA == null || vectorB == null || vectorA.Length != vectorB.Length)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
float dot = 0f, magA = 0f, magB = 0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < vectorA.Length; i++)
|
||||||
|
{
|
||||||
|
dot += vectorA[i] * vectorB[i];
|
||||||
|
magA += vectorA[i] * vectorA[i];
|
||||||
|
magB += vectorB[i] * vectorB[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magA == 0 || magB == 0)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
return dot / ((float)Math.Sqrt(magA) * (float)Math.Sqrt(magB));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Google.Protobuf.Collections;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Qdrant.Client;
|
using Qdrant.Client;
|
||||||
using Qdrant.Client.Grpc;
|
using Qdrant.Client.Grpc;
|
||||||
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace BLAIzor.Services
|
namespace BLAIzor.Services
|
||||||
|
|
@ -20,6 +21,9 @@ namespace BLAIzor.Services
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetAiEmbeddingSettings() =>
|
||||||
|
_configuration?.GetSection("AiSettings")?.GetValue<string>("EmbeddingService") ?? string.Empty;
|
||||||
|
|
||||||
public string GetApiKey()
|
public string GetApiKey()
|
||||||
{
|
{
|
||||||
if (_configuration == null)
|
if (_configuration == null)
|
||||||
|
|
@ -47,32 +51,51 @@ namespace BLAIzor.Services
|
||||||
return Convert.ToInt32(result);
|
return Convert.ToInt32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateQdrantCollectionAsync()
|
//public async Task CreateQdrantCollectionAsync()
|
||||||
{
|
//{
|
||||||
_apiKey = GetApiKey();
|
// _apiKey = GetApiKey();
|
||||||
var httpClient = new HttpClient();
|
// var httpClient = new HttpClient();
|
||||||
|
|
||||||
httpClient.DefaultRequestHeaders.Clear();
|
// httpClient.DefaultRequestHeaders.Clear();
|
||||||
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
// httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
||||||
|
|
||||||
var collectionName = "web_content";
|
// var collectionName = "web_content";
|
||||||
var createCollectionPayload = new
|
|
||||||
{
|
|
||||||
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
|
||||||
};
|
|
||||||
|
|
||||||
var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
// var createCollectionPayload = new
|
||||||
var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
// {
|
||||||
|
// vectors = new { size = 0, distance = "" } // Adjust size based on embedding model
|
||||||
|
// };
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
// var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||||
{
|
// if (embeddingServiceProvider == "local")
|
||||||
Console.WriteLine("Collection created successfully!" + response.Content.ReadAsStringAsync());
|
// {
|
||||||
}
|
// createCollectionPayload = new
|
||||||
else
|
// {
|
||||||
{
|
// vectors = new { size = 1024, distance = "Cosine" } // Adjust size based on embedding model
|
||||||
Console.WriteLine($"Failed to create collection: {response.StatusCode}");
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// else
|
||||||
|
// {
|
||||||
|
// createCollectionPayload = new
|
||||||
|
// {
|
||||||
|
// vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
||||||
|
// var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
||||||
|
|
||||||
|
// if (response.IsSuccessStatusCode)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine("Collection created successfully!" + response.Content.ReadAsStringAsync());
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"Failed to create collection: {response.StatusCode}");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
public async Task<string> GetCollectionBySiteIdAsync(int siteId)
|
public async Task<string> GetCollectionBySiteIdAsync(int siteId)
|
||||||
{
|
{
|
||||||
|
|
@ -127,9 +150,25 @@ namespace BLAIzor.Services
|
||||||
|
|
||||||
var createCollectionPayload = new
|
var createCollectionPayload = new
|
||||||
{
|
{
|
||||||
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
vectors = new { size = 0, distance = "" } // Adjust size based on embedding model
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var embeddingServiceProvider = GetAiEmbeddingSettings();
|
||||||
|
if (embeddingServiceProvider == "local")
|
||||||
|
{
|
||||||
|
createCollectionPayload = new
|
||||||
|
{
|
||||||
|
vectors = new { size = 1024, distance = "Cosine" } // Adjust size based on embedding model
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createCollectionPayload = new
|
||||||
|
{
|
||||||
|
vectors = new { size = 1536, distance = "Cosine" } // Adjust size based on embedding model
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
var content = new StringContent(JsonConvert.SerializeObject(createCollectionPayload), Encoding.UTF8, "application/json");
|
||||||
var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
var response = await httpClient.PutAsync($"{qdrantUrl}/collections/{collectionName}", content);
|
||||||
|
|
||||||
|
|
@ -256,15 +295,6 @@ namespace BLAIzor.Services
|
||||||
_apiKey = GetApiKey();
|
_apiKey = GetApiKey();
|
||||||
var httpClient = new HttpClient();
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
//httpClient.DefaultRequestHeaders.Clear();
|
|
||||||
//httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
|
||||||
|
|
||||||
//var queryPayload = new
|
|
||||||
//{
|
|
||||||
// vector = queryVector,
|
|
||||||
// limit = limit
|
|
||||||
//};
|
|
||||||
|
|
||||||
var client = new QdrantClient(
|
var client = new QdrantClient(
|
||||||
host: _qdrantHost,
|
host: _qdrantHost,
|
||||||
https: true,
|
https: true,
|
||||||
|
|
@ -408,6 +438,15 @@ namespace BLAIzor.Services
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DeleteCollectionAsync(string collectionName)
|
||||||
|
{
|
||||||
|
|
||||||
|
_apiKey = GetApiKey();
|
||||||
|
|
||||||
|
var client = new QdrantClient(_qdrantHost, 6334, true, _apiKey);
|
||||||
|
await client.DeleteCollectionAsync(collectionName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PointResult
|
public class PointResult
|
||||||
|
|
@ -438,6 +477,11 @@ namespace BLAIzor.Services
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
public HtmlSnippet payload { get; set; }
|
public HtmlSnippet payload { get; set; }
|
||||||
public List<double> vector { get; set; }
|
public List<double> vector { get; set; }
|
||||||
|
|
||||||
|
public float[] GetFloatVector()
|
||||||
|
{
|
||||||
|
return vector?.Select(d => (float)d).ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -460,6 +504,10 @@ namespace BLAIzor.Services
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
public ContentPayload payload { get; set; }
|
public ContentPayload payload { get; set; }
|
||||||
public List<double> vector { get; set; }
|
public List<double> vector { get; set; }
|
||||||
|
public float[] GetFloatVector()
|
||||||
|
{
|
||||||
|
return vector?.Select(d => (float)d).ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContentPayload
|
public class ContentPayload
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ namespace BLAIzor.Services
|
||||||
public string CurrentDOM { get; set; }
|
public string CurrentDOM { get; set; }
|
||||||
public string currentLocale { get; set; }
|
public string currentLocale { get; set; }
|
||||||
public string SelectedDocument { get; set; } = "Poppixel.docx";
|
public string SelectedDocument { get; set; } = "Poppixel.docx";
|
||||||
|
|
||||||
private string _selectedBrandName;
|
private string _selectedBrandName;
|
||||||
public string SelectedBrandName
|
public string SelectedBrandName
|
||||||
{
|
{
|
||||||
|
|
@ -33,6 +32,8 @@ namespace BLAIzor.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<HtmlSnippet> AvailableTemplateSnippets { get; set; }
|
||||||
|
public List<WebPageContent> AvailableSiteContent { get; set; }
|
||||||
public event Action OnBrandNameChanged;
|
public event Action OnBrandNameChanged;
|
||||||
public int SelectedSiteId { get; set; } = 1;
|
public int SelectedSiteId { get; set; } = 1;
|
||||||
//public string SelectedDocument { get; set; } = "Poppixel.docx";
|
//public string SelectedDocument { get; set; } = "Poppixel.docx";
|
||||||
|
|
@ -64,8 +65,6 @@ namespace BLAIzor.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SiteInfo?> GetSiteInfoWithFormsByIdAsync(int siteId)
|
public async Task<SiteInfo?> GetSiteInfoWithFormsByIdAsync(int siteId)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@
|
||||||
"AiSettings": {
|
"AiSettings": {
|
||||||
"Provider": "cerebras",
|
"Provider": "cerebras",
|
||||||
//"Provider": "chatgpt",
|
//"Provider": "chatgpt",
|
||||||
"VoiceActivated": true
|
"VoiceActivated": true,
|
||||||
|
"EmbeddingService": "openai"
|
||||||
|
//"EmbeddingService": "local"
|
||||||
},
|
},
|
||||||
"DeepSeek": {
|
"DeepSeek": {
|
||||||
"ApiKey": "sk-b97350ccb28c4129b5df08835bf2ea5f"
|
"ApiKey": "sk-b97350ccb28c4129b5df08835bf2ea5f"
|
||||||
|
|
@ -33,6 +35,7 @@
|
||||||
"Model": "llama-3.3-70b"
|
"Model": "llama-3.3-70b"
|
||||||
//"Model": "llama-4-scout-17b-16e-instruct"
|
//"Model": "llama-4-scout-17b-16e-instruct"
|
||||||
//"Model": "qwen-3-32b"
|
//"Model": "qwen-3-32b"
|
||||||
|
//"Model": "deepseek-r1-distill-llama-70b"
|
||||||
//"Model": "llama3.1-8b"
|
//"Model": "llama3.1-8b"
|
||||||
},
|
},
|
||||||
"OpenAI": {
|
"OpenAI": {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,471 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
|
||||||
|
|
||||||
|
|
||||||
|
/*search*/
|
||||||
|
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
border: 0;
|
||||||
|
color: #000000;
|
||||||
|
/* width: 98%; */
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
/*min-height: 50px;*/
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menubtn {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
border: 0;
|
||||||
|
color: #000000;
|
||||||
|
/* width: 98%; */
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 40px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:active {
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.search_bar{
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
width: 75px;
|
||||||
|
border-radius: 55px;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1.3em;
|
||||||
|
color: #0d2840;
|
||||||
|
padding: 15px 30px 15px 45px;
|
||||||
|
transition: all .3s cubic-bezier(0,0,.5,1.5);
|
||||||
|
box-shadow: 0 3px 10px -2px rgba(0,0,0,.1);
|
||||||
|
background: rgba(255, 255, 255, 0.3) url(https://i.imgur.com/seveWIw.png) no-repeat center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.search_bar:focus{
|
||||||
|
width: 100%;
|
||||||
|
background-position: calc(100% - 35px) center
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Removes default x in search fields (webkit only i guess)*/
|
||||||
|
input[type=search]::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
/*Changes the color of the placeholder*/
|
||||||
|
::-webkit-input-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-moz-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-ms-input-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*search*/
|
||||||
|
|
||||||
|
/*Search2*/
|
||||||
|
.searchBox {
|
||||||
|
width: 60px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 40px;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput:active > .searchBox{
|
||||||
|
width:100%
|
||||||
|
}
|
||||||
|
.searchInput:focus > .searchBox {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
.searchInput::placeholder {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover > .searchInput {
|
||||||
|
width: calc(100% - 60px);
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover > .searchButton {
|
||||||
|
background: white;
|
||||||
|
color: #2f3640;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchButton {
|
||||||
|
color: white;
|
||||||
|
float: right;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e9bb86;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 1.3em !important;
|
||||||
|
color: #e9bb86 !important;
|
||||||
|
float: left;
|
||||||
|
padding: 0;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: 0.4s;
|
||||||
|
line-height: 40px;
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Search2*/
|
||||||
|
|
||||||
|
|
||||||
|
.event {
|
||||||
|
border-radius: 20px !important;
|
||||||
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*card design*/
|
||||||
|
.card {
|
||||||
|
border-radius: 10px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1), 0 10px 8px rgba(0, 0, 0, 0.015);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body .card-title {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 15px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .container {
|
||||||
|
width: 88%;
|
||||||
|
/*background: #F0EEF8;*/
|
||||||
|
border-radius: 30px;
|
||||||
|
/*height: 140px;*/
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container:hover > img {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container img {
|
||||||
|
/*padding: 75px;*/
|
||||||
|
/*margin-top: -40px;
|
||||||
|
margin-bottom: -40px;*/
|
||||||
|
transition: 0.4s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: #9b7d5a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus {
|
||||||
|
background: #9b7d5a;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
/*card design*/
|
||||||
|
|
||||||
|
/*bg*/
|
||||||
|
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
color: #f2d8bb;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #000;
|
||||||
|
/*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
|
||||||
|
/*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
|
||||||
|
/*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/*animation: 10s movement linear infinite;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.myspan {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 5rem;
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: 0px 0px 1px rgba(255, 255, 255, .6), 0px 4px 4px rgba(0, 0, 0, .05);
|
||||||
|
letter-spacing: .2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@keyframes movement {
|
||||||
|
0%, 100% {
|
||||||
|
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
|
||||||
|
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax;
|
||||||
|
background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax;
|
||||||
|
background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax;
|
||||||
|
background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*bg*/
|
||||||
|
|
||||||
|
.mytextarea {
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0px;
|
||||||
|
height: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mytextarea:active {
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mytextarea:focus-visible {
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
border-width: 0px !important;
|
||||||
|
outline: -webkit-focus-ring-color auto 0px;
|
||||||
|
outline-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-toggler {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
color: #e9bb86;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 15px;
|
||||||
|
display: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select > option {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-overlay {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 100;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
padding: 100px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
/* padding-top: 10vh; */
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
/* background-color: rgba(1, 1, 1, .4); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
background-color: rgba(255,255,255,0.4);
|
||||||
|
border-radius: 15px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form-control::placeholder{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-close-overlay {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-popup-content {
|
||||||
|
height: 80vh;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-popup-close {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-overlay {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
top: 0px;
|
||||||
|
/* padding-top: 10vh; */
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
/* background-color: rgba(1, 1, 1, .4); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-close-overlay {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-popup-content {
|
||||||
|
height: 80vh;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-popup-close {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
#myVideo {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
color: #f2d8bb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse {
|
||||||
|
height: 100vh;
|
||||||
|
/*display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;*/
|
||||||
|
text-align: center !important;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse .nav-link {
|
||||||
|
font-size: 1.4em;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse .nav-item:not(:last-child) {
|
||||||
|
border-bottom: 0px solid white;
|
||||||
|
padding: 0.2em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background-color: #1c120c;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
color: #f2d8bb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-dark {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-fluid {
|
||||||
|
max-height: 50vh !important;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,471 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Quicksand&display=swap');
|
||||||
|
|
||||||
|
|
||||||
|
/*search*/
|
||||||
|
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
border: 0;
|
||||||
|
color: #000000;
|
||||||
|
/* width: 98%; */
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
/*min-height: 50px;*/
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menubtn {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
border: 0;
|
||||||
|
color: #000000;
|
||||||
|
/* width: 98%; */
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 40px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:active {
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.search_bar{
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
width: 75px;
|
||||||
|
border-radius: 55px;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1.3em;
|
||||||
|
color: #0d2840;
|
||||||
|
padding: 15px 30px 15px 45px;
|
||||||
|
transition: all .3s cubic-bezier(0,0,.5,1.5);
|
||||||
|
box-shadow: 0 3px 10px -2px rgba(0,0,0,.1);
|
||||||
|
background: rgba(255, 255, 255, 0.3) url(https://i.imgur.com/seveWIw.png) no-repeat center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.search_bar:focus{
|
||||||
|
width: 100%;
|
||||||
|
background-position: calc(100% - 35px) center
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Removes default x in search fields (webkit only i guess)*/
|
||||||
|
input[type=search]::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
/*Changes the color of the placeholder*/
|
||||||
|
::-webkit-input-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-moz-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-ms-input-placeholder {
|
||||||
|
color: #0d2840;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*search*/
|
||||||
|
|
||||||
|
/*Search2*/
|
||||||
|
.searchBox {
|
||||||
|
width: 60px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 40px;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput:active > .searchBox{
|
||||||
|
width:100%
|
||||||
|
}
|
||||||
|
.searchInput:focus > .searchBox {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
.searchInput::placeholder {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover > .searchInput {
|
||||||
|
width: calc(100% - 60px);
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchBox:hover > .searchButton {
|
||||||
|
background: white;
|
||||||
|
color: #2f3640;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchButton {
|
||||||
|
color: white;
|
||||||
|
float: right;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e9bb86;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 1.3em !important;
|
||||||
|
color: #e9bb86 !important;
|
||||||
|
float: left;
|
||||||
|
padding: 0;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: 0.4s;
|
||||||
|
line-height: 40px;
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Search2*/
|
||||||
|
|
||||||
|
|
||||||
|
.event {
|
||||||
|
border-radius: 20px !important;
|
||||||
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*card design*/
|
||||||
|
.card {
|
||||||
|
border-radius: 10px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06), 0 2px 4px rgba(0, 0, 0, 0.07);
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.1), 0 10px 8px rgba(0, 0, 0, 0.015);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body .card-title {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 15px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .container {
|
||||||
|
width: 88%;
|
||||||
|
/*background: #F0EEF8;*/
|
||||||
|
border-radius: 30px;
|
||||||
|
/*height: 140px;*/
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container:hover > img {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container img {
|
||||||
|
/*padding: 75px;*/
|
||||||
|
/*margin-top: -40px;
|
||||||
|
margin-bottom: -40px;*/
|
||||||
|
transition: 0.4s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background: #9b7d5a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus {
|
||||||
|
background: #9b7d5a;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
/*card design*/
|
||||||
|
|
||||||
|
/*bg*/
|
||||||
|
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
color: #f2d8bb;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #000;
|
||||||
|
/*background-image: radial-gradient(closest-side, rgba(235, 105, 78, 1), rgba(235, 105, 78, 0)), radial-gradient(closest-side, rgba(243, 11, 164, 1), rgba(243, 11, 164, 0)), radial-gradient(closest-side, rgba(254, 234, 131, 1), rgba(254, 234, 131, 0)), radial-gradient(closest-side, rgba(170, 142, 245, 1), rgba(170, 142, 245, 0)), radial-gradient(closest-side, rgba(248, 192, 147, 1), rgba(248, 192, 147, 0));*/
|
||||||
|
/*background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;*/
|
||||||
|
/*background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;*/
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/*animation: 10s movement linear infinite;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.myspan {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 5rem;
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: 0px 0px 1px rgba(255, 255, 255, .6), 0px 4px 4px rgba(0, 0, 0, .05);
|
||||||
|
letter-spacing: .2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@keyframes movement {
|
||||||
|
0%, 100% {
|
||||||
|
background-size: 130vmax 130vmax, 80vmax 80vmax, 90vmax 90vmax, 110vmax 110vmax, 90vmax 90vmax;
|
||||||
|
background-position: -80vmax -80vmax, 60vmax -30vmax, 10vmax 10vmax, -30vmax -10vmax, 50vmax 50vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
25% {
|
||||||
|
background-size: 100vmax 100vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 60vmax 60vmax;
|
||||||
|
background-position: -60vmax -90vmax, 50vmax -40vmax, 0vmax -20vmax, -40vmax -20vmax, 40vmax 60vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-size: 80vmax 80vmax, 110vmax 110vmax, 80vmax 80vmax, 60vmax 60vmax, 80vmax 80vmax;
|
||||||
|
background-position: -50vmax -70vmax, 40vmax -30vmax, 10vmax 0vmax, 20vmax 10vmax, 30vmax 70vmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
background-size: 90vmax 90vmax, 90vmax 90vmax, 100vmax 100vmax, 90vmax 90vmax, 70vmax 70vmax;
|
||||||
|
background-position: -50vmax -40vmax, 50vmax -30vmax, 20vmax 0vmax, -10vmax 10vmax, 40vmax 60vmax;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*bg*/
|
||||||
|
|
||||||
|
.mytextarea {
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0px;
|
||||||
|
height: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mytextarea:active {
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mytextarea:focus-visible {
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
border-width: 0px !important;
|
||||||
|
outline: -webkit-focus-ring-color auto 0px;
|
||||||
|
outline-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-toggler {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
color: #e9bb86;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 15px;
|
||||||
|
display: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select > option {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-overlay {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 100;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
padding: 100px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
/* padding-top: 10vh; */
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
/* background-color: rgba(1, 1, 1, .4); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
background-color: rgba(255,255,255,0.4);
|
||||||
|
border-radius: 15px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form-control::placeholder{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-close-overlay {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-popup-content {
|
||||||
|
height: 80vh;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactform-popup-close {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-overlay {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
top: 0px;
|
||||||
|
/* padding-top: 10vh; */
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
/* background-color: rgba(1, 1, 1, .4); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-close-overlay {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-popup-content {
|
||||||
|
height: 80vh;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendly-popup-close {
|
||||||
|
position: relative;
|
||||||
|
height: 10vh;
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
#myVideo {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
color: #f2d8bb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse {
|
||||||
|
height: 100vh;
|
||||||
|
/*display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;*/
|
||||||
|
text-align: center !important;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse .nav-link {
|
||||||
|
font-size: 1.4em;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-collapse .nav-item:not(:last-child) {
|
||||||
|
border-bottom: 0px solid white;
|
||||||
|
padding: 0.2em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background-color: #1c120c;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
color: #f2d8bb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-dark {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-fluid {
|
||||||
|
max-height: 50vh !important;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
color: #f2d8bb !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center !important;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-link {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-collapse .nav-item:not(:last-child) {
|
|
||||||
padding: 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
background-color: #022c28;
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: #d0eae9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #022c28;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
color: aqua;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 1rem; /* Base size */
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2rem;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #d0eae9;
|
|
||||||
background-color: #014d4e;
|
|
||||||
border: 0px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #086262;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding-bottom: 30px;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchInput::placeholder {
|
|
||||||
color: #d0eae9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myVideo {
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: -100px;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
transform: translateX(calc((100% - 100vw) / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-fluid {
|
|
||||||
max-height: 50vh;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sp-img {
|
|
||||||
box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-webkit-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
-moz-box-shadow: 10px 10px 30px 0px rgba(0,0,0,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 5px;
|
|
||||||
display: unset !important;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item,
|
|
||||||
.bg-light {
|
|
||||||
background-color: rgb(11 24 23 / 76%) !important;
|
|
||||||
backdrop-filter: blur(8px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-primary {
|
|
||||||
--bs-text-opacity: 1;
|
|
||||||
color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 🔽 Mobile Responsiveness */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
h1 { font-size: 2rem; }
|
|
||||||
h2 { font-size: 1.6rem; }
|
|
||||||
h3 { font-size: 1.4rem; }
|
|
||||||
p, li { font-size: 1rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1.1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
h1 { font-size: 1.6rem; }
|
|
||||||
h2 { font-size: 1.3rem; }
|
|
||||||
h3 { font-size: 1.1rem; }
|
|
||||||
p, li { font-size: 0.95rem; }
|
|
||||||
.navbar-collapse .nav-link { font-size: 1rem; }
|
|
||||||
p {text-align: justify;}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 864 KiB |
Loading…
Reference in New Issue