From 6bf1e4f13c53bf3afd33db07d087c93230d10290 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Wed, 20 May 2026 06:28:43 +0800 Subject: [PATCH 01/14] Add ERPNext engineer onboarding flows --- apps/admin_dashboard/src/main.tsx | 740 +++++++++++++----- apps/api/src/five08/backend/api.py | 178 ++++- .../static/dashboard/.vite/manifest.json | 4 +- .../static/dashboard/assets/index-617IyoY5.js | 9 - ...{index-Cjc8hvil.css => index-Bu9GOZtL.css} | 2 +- .../static/dashboard/assets/index-CyCn29M4.js | 9 + .../backend/static/dashboard/index.html | 4 +- .../discord_bot/cogs/engineer_onboarding.py | 335 ++++++++ packages/shared/src/five08/clients/erpnext.py | 86 ++ .../shared/src/five08/engineer_onboarding.py | 550 +++++++++++++ tests/unit/test_backend_api.py | 50 +- tests/unit/test_engineer_onboarding.py | 284 +++++++ 12 files changed, 2022 insertions(+), 229 deletions(-) delete mode 100644 apps/api/src/five08/backend/static/dashboard/assets/index-617IyoY5.js rename apps/api/src/five08/backend/static/dashboard/assets/{index-Cjc8hvil.css => index-Bu9GOZtL.css} (78%) create mode 100644 apps/api/src/five08/backend/static/dashboard/assets/index-CyCn29M4.js create mode 100644 apps/discord_bot/src/five08/discord_bot/cogs/engineer_onboarding.py create mode 100644 packages/shared/src/five08/engineer_onboarding.py create mode 100644 tests/unit/test_engineer_onboarding.py diff --git a/apps/admin_dashboard/src/main.tsx b/apps/admin_dashboard/src/main.tsx index 0b998bc8..ddc6646e 100644 --- a/apps/admin_dashboard/src/main.tsx +++ b/apps/admin_dashboard/src/main.tsx @@ -10,6 +10,7 @@ import { RefreshCw, Search, ShieldCheck, + UserPlus, Users, X, } from "lucide-react" @@ -273,6 +274,27 @@ type AgentReport = { }> } +type EngineerSetupRequest = { + email: string + first_name: string + last_name?: string + country?: string + department?: string + gender?: string + date_of_birth?: string + create_user_permission?: boolean +} + +type EngineerSetupResult = { + user?: string + employee?: string + employee_name?: string + supplier?: string + role?: string + created?: Record + updated?: Record +} + const routes: Record = { people: "/dashboard/people", gigs: "/dashboard/gigs", @@ -845,23 +867,27 @@ function App() { } } - async function addProjectUser(projectId: string, userName: string) { + async function addProjectUser( + projectId: string, + userName: string, + rates?: { activity_type?: string; billing_rate?: number; costing_rate?: number }, + ) { const normalizedUser = userName.trim() if (!normalizedUser) return false setBusy(`project:${projectId}:user`, true) try { - const payload = await requestJson<{ project: Project }>( + const payload = await requestJson<{ project: Project; activity_cost?: object | null }>( `/dashboard/api/projects/${encodeURIComponent(projectId)}/users`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ user: normalizedUser }), + body: JSON.stringify({ user: normalizedUser, ...(rates || {}) }), }, ) setProjects((current) => current.map((project) => (project.id === projectId ? payload.project : project)), ) - showToast("Added project user", "ok") + showToast(payload.activity_cost ? "Added project user and rate" : "Added project user", "ok") return true } catch (error) { showToast(error instanceof Error ? error.message : "Unable to add project user", "error") @@ -1197,6 +1223,54 @@ function App() { } } + async function setupEngineer(payload: EngineerSetupRequest) { + const normalizedEmail = payload.email.trim().toLowerCase() + const normalizedFirstName = payload.first_name.trim() + if (!normalizedEmail?.endsWith("@508.dev")) { + showToast("Enter the engineer's @508.dev email", "error") + return null + } + if (!normalizedFirstName) { + showToast("Enter the engineer name", "error") + return null + } + setBusy("engineerSetup", true) + try { + const result = await requestJson("/dashboard/api/onboarding/engineers", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + ...payload, + email: normalizedEmail, + first_name: normalizedFirstName, + }), + }) + showToast(`Set up ${result.employee_name || result.user || normalizedEmail}`, "ok") + return result + } catch (error) { + if (error instanceof ApiRequestError && error.status === 409) { + const payload = error.payload as { matches?: Array<{ label?: string; email?: string }> } + const matches = payload.matches || [] + const matchLabel = matches + .map((match) => match.label || match.email) + .filter(Boolean) + .slice(0, 2) + .join(", ") + showToast( + matchLabel + ? `Similar account exists: ${matchLabel}` + : "Similar account exists; confirm before creating", + "error", + ) + } else { + showToast(error instanceof Error ? error.message : "Unable to set up engineer", "error") + } + return null + } finally { + setBusy("engineerSetup", false) + } + } + async function logout() { setBusy("logout", true) try { @@ -1630,6 +1704,7 @@ function App() { onSearch={loadOnboarding} onSort={(key) => handleSort("onboarding", key)} onAssign={assignOnboarder} + onSetupEngineer={setupEngineer} setOnboardingQuery={setOnboardingQuery} setOnboardingState={setOnboardingState} setOnboarderFilter={setOnboarderFilter} @@ -1650,6 +1725,7 @@ function App() { }} crmContactUrl={crmContactUrl} crmAttachmentUrl={crmAttachmentUrl} + canWrite={can("onboarding:write")} /> ) : null} @@ -1982,6 +2058,13 @@ function memberLabel(member: ProjectRosterMember) { return member.full_name || member.email || member.source_user_id || "Unknown" } +function optionalNumber(value: string) { + const normalized = value.trim() + if (!normalized) return undefined + const parsed = Number(normalized) + return Number.isFinite(parsed) ? parsed : undefined +} + function ProjectsView(props: { projects: Project[] selectedProject: Project | null @@ -2004,7 +2087,11 @@ function ProjectsView(props: { projectIds: string[], updates: { status?: string; project_type?: string }, ) => Promise - onAddUser: (projectId: string, user: string) => Promise + onAddUser: ( + projectId: string, + user: string, + rates?: { activity_type?: string; billing_rate?: number; costing_rate?: number }, + ) => Promise onAddHistoricalMember: ( projectId: string, person: string, @@ -2552,6 +2639,138 @@ function ProjectsView(props: { ) } +function ProjectRosterAddForm({ + projectId, + loading, + onAddUser, + onAddHistoricalMember, +}: { + projectId: string + loading: Record + onAddUser: ( + projectId: string, + user: string, + rates?: { activity_type?: string; billing_rate?: number; costing_rate?: number }, + ) => Promise + onAddHistoricalMember: ( + projectId: string, + person: string, + candidateId?: string, + ) => Promise +}) { + const [newUser, setNewUser] = useState("") + const [activityType, setActivityType] = useState("") + const [billingRate, setBillingRate] = useState("") + const [costingRate, setCostingRate] = useState("") + const normalizedUser = newUser.trim() + const hasRateFields = Boolean(activityType.trim() || billingRate.trim() || costingRate.trim()) + const parsedBillingRate = optionalNumber(billingRate) + const parsedCostingRate = optionalNumber(costingRate) + const hasPartialRate = Boolean((billingRate.trim() || costingRate.trim()) && !activityType.trim()) + const hasIncompleteRate = Boolean( + activityType.trim() && (!billingRate.trim() || !costingRate.trim()), + ) + const rateInvalid = + Boolean(billingRate.trim() && parsedBillingRate === undefined) || + Boolean(costingRate.trim() && parsedCostingRate === undefined) || + hasPartialRate || + hasIncompleteRate + + async function submitEngineer() { + const updated = await onAddUser( + projectId, + newUser, + hasRateFields + ? { + activity_type: activityType.trim(), + billing_rate: parsedBillingRate, + costing_rate: parsedCostingRate, + } + : undefined, + ) + if (updated) { + setNewUser("") + setActivityType("") + setBillingRate("") + setCostingRate("") + } + } + + return ( +
{ + event.preventDefault() + if (!rateInvalid) void submitEngineer() + }} + > +
+ + + + +
+
+ + +
+
+ ) +} + function ProjectDetailPage(props: { project: Project loading: Record @@ -2559,7 +2778,11 @@ function ProjectDetailPage(props: { crmContactUrl: (contactId?: string) => string onBack: () => void onUpdateStatus: (projectId: string, status: string) => void - onAddUser: (projectId: string, user: string) => Promise + onAddUser: ( + projectId: string, + user: string, + rates?: { activity_type?: string; billing_rate?: number; costing_rate?: number }, + ) => Promise onAddHistoricalMember: ( projectId: string, person: string, @@ -2568,7 +2791,6 @@ function ProjectDetailPage(props: { }) { const project = props.project const members = project.roster_members || [] - const [newUser, setNewUser] = useState("") const timeline = [ project.actual_start_date || project.expected_start_date, @@ -2692,50 +2914,13 @@ function ProjectDetailPage(props: { {props.canWrite ? ( - - - - + + ) : null}
@@ -3655,6 +3840,7 @@ function OnboardingView(props: { people: Person[] sort: { key: string; direction: SortDirection } loading: Record + canWrite: boolean onboardingQuery: string onboardingState: string onboarderFilter: string @@ -3665,6 +3851,7 @@ function OnboardingView(props: { onSearch: () => void onSort: (key: string) => void onAssign: (contactId: string | undefined, onboarder: string) => void + onSetupEngineer: (payload: EngineerSetupRequest) => Promise setOnboardingQuery: (value: string) => void setOnboardingState: (value: string) => void setOnboarderFilter: (value: string) => void @@ -3677,174 +3864,313 @@ function OnboardingView(props: { }) { const filterOptions = peopleFilterDefinitions[props.onboardingFilterKind]?.options || [] return ( - - - Onboarding queue - - {props.loading.onboarding ? "Loading" : `${props.people.length} shown`} - - -
- - -
-
- + -
- + + + props.onSort(key)} + /> + props.onSort(key)} + /> + props.onSort(key)} + /> + props.onSort(key)} + /> + Links + props.onSort(key)} + /> + + + + {props.people.map((person) => ( + + ))} + +
-
- -
- + + ) +} + +function EngineerSetupPanel({ + loading, + onSetup, +}: { + loading?: boolean + onSetup: (payload: EngineerSetupRequest) => Promise +}) { + const [email, setEmail] = useState("") + const [fullName, setFullName] = useState("") + const [country, setCountry] = useState("") + const [department, setDepartment] = useState("") + const [gender, setGender] = useState("") + const [dateOfBirth, setDateOfBirth] = useState("") + const [createUserPermission, setCreateUserPermission] = useState(true) + + async function submit() { + const normalizedName = fullName.trim() + const [first, ...rest] = normalizedName.split(/\s+/) + const result = await onSetup({ + email, + first_name: first || normalizedName, + last_name: rest.join(" "), + country, + department, + gender, + date_of_birth: dateOfBirth, + create_user_permission: createUserPermission, + }) + if (result) { + setEmail("") + setFullName("") + setCountry("") + setDepartment("") + setGender("") + setDateOfBirth("") + setCreateUserPermission(true) + } + } + + return ( + + + Engineer setup + + +
{ + event.preventDefault() + void submit() + }} > - - - props.onSort(key)} +
+ + + + +
+
+
-
+ +
+
+ + +
+ +
) } diff --git a/apps/api/src/five08/backend/api.py b/apps/api/src/five08/backend/api.py index aabde01f..6a7dd170 100644 --- a/apps/api/src/five08/backend/api.py +++ b/apps/api/src/five08/backend/api.py @@ -111,6 +111,14 @@ update_engagement_status, viewer_can_update_engagement, ) +from five08.engineer_onboarding import ( + ActivityCostRequest, + EngineerOnboardingDuplicateNameError, + EngineerOnboardingError, + EngineerSetupRequest, + add_engineer_to_project, + setup_engineer, +) from five08.projects import ( DEFAULT_WIKI_PROJECT_DOC_ID, PROJECT_WIKI_MATCH_CONFIRMED, @@ -208,6 +216,22 @@ class DashboardProjectUserRequest(BaseModel): """Payload for adding one ERPNext User to a Project roster.""" user: str + activity_type: str | None = None + billing_rate: float | None = None + costing_rate: float | None = None + + +class DashboardEngineerSetupRequest(BaseModel): + """Payload for setting up one ERPNext engineer account.""" + + email: str + first_name: str + last_name: str | None = None + country: str | None = None + department: str | None = None + gender: str | None = None + date_of_birth: str | None = None + create_user_permission: bool = True class DashboardProjectHistoricalMemberRequest(BaseModel): @@ -3115,13 +3139,50 @@ def _add_erpnext_project_user( *, external_project_id: str, user: str, + activity_type: str | None = None, + billing_rate: float | None = None, + costing_rate: float | None = None, ) -> dict[str, Any]: client = _erpnext_client() try: - client.add_project_user(external_project_id, user) + activity_cost_request = None + if activity_type or billing_rate is not None or costing_rate is not None: + activity_cost_request = ActivityCostRequest( + user=user, + activity_type=activity_type or "", + billing_rate=billing_rate, + costing_rate=costing_rate, + ) + result = add_engineer_to_project( + client, + project_id=external_project_id, + user=user, + activity_cost=activity_cost_request, + ) + finally: + client.close() + project = _refresh_cached_erpnext_project(external_project_id) + return {"project": project, "activity_cost": result.get("activity_cost")} + + +def _setup_erpnext_engineer(payload: DashboardEngineerSetupRequest) -> dict[str, Any]: + client = _erpnext_client() + try: + return setup_engineer( + client, + EngineerSetupRequest( + email=payload.email, + first_name=payload.first_name, + last_name=payload.last_name, + country=payload.country, + department=payload.department, + gender=payload.gender, + date_of_birth=payload.date_of_birth, + create_user_permission=payload.create_user_permission, + ), + ) finally: client.close() - return _refresh_cached_erpnext_project(external_project_id) async def _dashboard_cached_project_or_error( @@ -3385,6 +3446,76 @@ async def dashboard_bulk_update_projects_handler(request: Request) -> JSONRespon return JSONResponse(result) +async def dashboard_setup_engineer_handler(request: Request) -> JSONResponse: + """Set up one ERPNext engineer account from the dashboard.""" + session, error_response = await _dashboard_session_or_error( + request, + required_permission=DASHBOARD_PERMISSION_ONBOARDING_WRITE, + ) + if error_response is not None: + return error_response + assert session is not None + + csrf_error = _dashboard_same_origin_post_or_error(request) + if csrf_error is not None: + return csrf_error + + try: + body = await request.json() + payload = DashboardEngineerSetupRequest.model_validate(body) + except Exception: + return JSONResponse({"error": "invalid_payload"}, status_code=400) + + normalized_email = payload.email.strip().lower() + normalized_first_name = payload.first_name.strip() + if not normalized_email or not normalized_email.endswith("@508.dev"): + return JSONResponse({"error": "invalid_email"}, status_code=400) + if not normalized_first_name: + return JSONResponse({"error": "first_name_required"}, status_code=400) + + try: + result = await asyncio.to_thread(_setup_erpnext_engineer, payload) + except EngineerOnboardingDuplicateNameError as exc: + return JSONResponse( + { + "error": "similar_engineer_exists", + "detail": str(exc), + "matches": exc.matches, + }, + status_code=409, + ) + except EngineerOnboardingError as exc: + return JSONResponse( + {"error": "engineer_setup_failed", "detail": str(exc)}, + status_code=400, + ) + except ERPNextAPIError as exc: + return JSONResponse( + {"error": "erpnext_engineer_setup_failed", "detail": str(exc)}, + status_code=502, + ) + + actor_provider, actor_subject = _session_audit_actor(session) + await _write_auth_audit_event( + action="erpnext.engineer_setup", + result=AuditResult.SUCCESS, + actor_subject=actor_subject, + actor_display_name=session.display_name, + actor_provider=actor_provider, + resource_type="erpnext_user", + resource_id=normalized_email, + metadata={ + "source": "dashboard", + "user": result.get("user"), + "employee": result.get("employee"), + "supplier": result.get("supplier"), + "created": result.get("created"), + "updated": result.get("updated"), + }, + ) + return JSONResponse(result) + + async def dashboard_add_project_user_handler( request: Request, project_id: str, @@ -3416,13 +3547,40 @@ async def dashboard_add_project_user_handler( normalized_user = payload.user.strip() if not normalized_user or len(normalized_user) > 200: return JSONResponse({"error": "invalid_user"}, status_code=400) + has_activity_type = bool((payload.activity_type or "").strip()) + has_billing_rate = payload.billing_rate is not None + has_costing_rate = payload.costing_rate is not None + if (has_billing_rate or has_costing_rate) and not has_activity_type: + return JSONResponse({"error": "activity_type_required"}, status_code=400) + if has_activity_type and not (has_billing_rate and has_costing_rate): + return JSONResponse({"error": "activity_cost_rates_required"}, status_code=400) external_project_id = str(project["erpnext_project_id"]) try: - updated_project = await asyncio.to_thread( + add_user_kwargs: dict[str, Any] = { + "external_project_id": external_project_id, + "user": normalized_user, + } + if ( + payload.activity_type is not None + or payload.billing_rate is not None + or payload.costing_rate is not None + ): + add_user_kwargs.update( + { + "activity_type": payload.activity_type, + "billing_rate": payload.billing_rate, + "costing_rate": payload.costing_rate, + } + ) + project_user_result = await asyncio.to_thread( _add_erpnext_project_user, - external_project_id=external_project_id, - user=normalized_user, + **add_user_kwargs, + ) + except EngineerOnboardingError as exc: + return JSONResponse( + {"error": "activity_cost_update_failed", "detail": str(exc)}, + status_code=400, ) except ERPNextAPIError as exc: return JSONResponse( @@ -3443,9 +3601,12 @@ async def dashboard_add_project_user_handler( "source": "dashboard", "user": normalized_user, "local_project_id": project_id, + "activity_type": payload.activity_type, + "has_billing_rate": payload.billing_rate is not None, + "has_costing_rate": payload.costing_rate is not None, }, ) - return JSONResponse({"project": updated_project}) + return JSONResponse(project_user_result) async def dashboard_add_project_historical_member_handler( @@ -5617,6 +5778,11 @@ def create_app(*, run_lifespan: bool = True) -> FastAPI: dashboard_onboarding_handler, methods=["GET"], ) + app.add_api_route( + "/dashboard/api/onboarding/engineers", + dashboard_setup_engineer_handler, + methods=["POST"], + ) app.add_api_route( "/dashboard/api/onboarding/{contact_id}/onboarder", dashboard_assign_onboarder_handler, diff --git a/apps/api/src/five08/backend/static/dashboard/.vite/manifest.json b/apps/api/src/five08/backend/static/dashboard/.vite/manifest.json index 84f5f4ed..e8c53d11 100644 --- a/apps/api/src/five08/backend/static/dashboard/.vite/manifest.json +++ b/apps/api/src/five08/backend/static/dashboard/.vite/manifest.json @@ -1,11 +1,11 @@ { "index.html": { - "file": "assets/index-617IyoY5.js", + "file": "assets/index-CyCn29M4.js", "name": "index", "src": "index.html", "isEntry": true, "css": [ - "assets/index-Cjc8hvil.css" + "assets/index-Bu9GOZtL.css" ] } } \ No newline at end of file diff --git a/apps/api/src/five08/backend/static/dashboard/assets/index-617IyoY5.js b/apps/api/src/five08/backend/static/dashboard/assets/index-617IyoY5.js deleted file mode 100644 index 35889d8c..00000000 --- a/apps/api/src/five08/backend/static/dashboard/assets/index-617IyoY5.js +++ /dev/null @@ -1,9 +0,0 @@ -var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var t=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var ee=Array.isArray;function te(){}var S={H:null,A:null,T:null,S:null},ne=Object.prototype.hasOwnProperty;function re(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ie(e,t){return re(e.type,t,e.props)}function ae(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function oe(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var se=/\/+/g;function ce(e,t){return typeof e==`object`&&e&&e.key!=null?oe(``+e.key):t.toString(36)}function C(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(te,te):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function le(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,le(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ce(e,0):a,ee(o)?(i=``,c!=null&&(i=c.replace(se,`$&/`)+`/`),le(o,r,i,``,function(e){return e})):o!=null&&(ae(o)&&(o=ie(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(se,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(ee(e))for(var u=0;u{n.exports=t()})),r=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),i=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),a=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),o=e=>{let t=a(e);return t.charAt(0).toUpperCase()+t.slice(1)},s={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},c=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},l=n(),u=(0,l.createContext)({}),d=()=>(0,l.useContext)(u),f=(0,l.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:i,className:a=``,children:o,iconNode:u,...f},p)=>{let{size:m=24,strokeWidth:h=2,absoluteStrokeWidth:g=!1,color:_=`currentColor`,className:v=``}=d()??{},y=i??g?Number(n??h)*24/Number(t??m):n??h;return(0,l.createElement)(`svg`,{ref:p,...s,width:t??m??s.width,height:t??m??s.height,stroke:e??_,strokeWidth:y,className:r(`lucide`,v,a),...!o&&!c(f)&&{"aria-hidden":`true`},...f},[...u.map(([e,t])=>(0,l.createElement)(e,t)),...Array.isArray(o)?o:[o]])}),p=(e,t)=>{let n=(0,l.forwardRef)(({className:n,...a},s)=>(0,l.createElement)(f,{ref:s,iconNode:t,className:r(`lucide-${i(o(e))}`,`lucide-${e}`,n),...a}));return n.displayName=o(e),n},m=p(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),h=p(`bell`,[[`path`,{d:`M10.268 21a2 2 0 0 0 3.464 0`,key:`vwvbt9`}],[`path`,{d:`M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326`,key:`11g9vi`}]]),g=p(`briefcase-business`,[[`path`,{d:`M12 12h.01`,key:`1mp3jc`}],[`path`,{d:`M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2`,key:`1ksdt3`}],[`path`,{d:`M22 13a18.15 18.15 0 0 1-20 0`,key:`12hx5q`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`6`,rx:`2`,key:`i6l2r4`}]]),_=p(`clipboard-list`,[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`,key:`116196`}],[`path`,{d:`M12 11h4`,key:`1jrz19`}],[`path`,{d:`M12 16h4`,key:`n85exb`}],[`path`,{d:`M8 11h.01`,key:`1dfujw`}],[`path`,{d:`M8 16h.01`,key:`18s6g9`}]]),v=p(`external-link`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]),y=p(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),b=p(`folder-kanban`,[[`path`,{d:`M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z`,key:`1fr9dc`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M12 10v2`,key:`hh53o1`}],[`path`,{d:`M16 10v6`,key:`1d6xys`}]]),x=p(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),ee=p(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),te=p(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),S=p(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),ne=p(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),re=p(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),ie=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,ee||(ee=!0,ae());else{var t=n(l);t!==null&&ce(x,t.startTime-e)}}var ee=!1,te=-1,S=5,ne=-1;function re(){return g?!0:!(e.unstable_now()-net&&re());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ce(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?ae():ee=!1}}}var ae;if(typeof y==`function`)ae=function(){y(ie)};else if(typeof MessageChannel<`u`){var oe=new MessageChannel,se=oe.port2;oe.port1.onmessage=ie,ae=function(){se.postMessage(null)}}else ae=function(){_(ie,0)};function ce(t,n){te=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(te),te=-1):h=!0,ce(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,ae()))),r},e.unstable_shouldYield=re,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),ae=e(((e,t)=>{t.exports=ie()})),oe=e((e=>{var t=n();function r(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=oe()})),ce=e((e=>{var t=ae(),r=n(),i=se();function a(e){var t=`https://react.dev/errors/`+e;if(1me||(e.current=pe[me],pe[me]=null,me--)}function O(e,t){me++,pe[me]=e.current,e.current=t}var he=E(null),ge=E(null),_e=E(null),ve=E(null);function ye(e,t){switch(O(_e,t),O(ge,e),O(he,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}D(he),O(he,e)}function be(){D(he),D(ge),D(_e)}function xe(e){e.memoizedState!==null&&O(ve,e);var t=he.current,n=Hd(t,e.type);t!==n&&(O(ge,e),O(he,n))}function Se(e){ge.current===e&&(D(he),D(ge)),ve.current===e&&(D(ve),Qf._currentValue=fe)}var Ce,we;function k(e){if(Ce===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Ce=t&&t[1]||``,we=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Te=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?k(n):``}function De(e,t){switch(e.tag){case 26:case 27:case 5:return k(e.type);case 16:return k(`Lazy`);case 13:return e.child!==t&&t!==null?k(`Suspense Fallback`):k(`Suspense`);case 19:return k(`SuspenseList`);case 0:case 15:return Ee(e.type,!1);case 11:return Ee(e.type.render,!1);case 1:return Ee(e.type,!0);case 31:return k(`Activity`);default:return``}}function Oe(e){try{var t=``,n=null;do t+=De(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var ke=Object.prototype.hasOwnProperty,Ae=t.unstable_scheduleCallback,je=t.unstable_cancelCallback,Me=t.unstable_shouldYield,Ne=t.unstable_requestPaint,Pe=t.unstable_now,Fe=t.unstable_getCurrentPriorityLevel,Ie=t.unstable_ImmediatePriority,Le=t.unstable_UserBlockingPriority,Re=t.unstable_NormalPriority,ze=t.unstable_LowPriority,Be=t.unstable_IdlePriority,Ve=t.log,He=t.unstable_setDisableYieldValue,Ue=null,We=null;function Ge(e){if(typeof Ve==`function`&&He(e),We&&typeof We.setStrictMode==`function`)try{We.setStrictMode(Ue,e)}catch{}}var Ke=Math.clz32?Math.clz32:Ye,qe=Math.log,Je=Math.LN2;function Ye(e){return e>>>=0,e===0?32:31-(qe(e)/Je|0)|0}var Xe=256,A=262144,Ze=4194304;function Qe(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function $e(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Qe(n))):i=Qe(o):i=Qe(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Qe(n))):i=Qe(o)):i=Qe(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function et(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function tt(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function nt(){var e=Ze;return Ze<<=1,!(Ze&62914560)&&(Ze=4194304),e}function rt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function it(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function at(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),cn=!1;if(sn)try{var ln={};Object.defineProperty(ln,`passive`,{get:function(){cn=!0}}),window.addEventListener(`test`,ln,ln),window.removeEventListener(`test`,ln,ln)}catch{cn=!1}var un=null,dn=null,fn=null;function V(){if(fn)return fn;var e,t=dn,n=t.length,r,i=`value`in un?un.value:un.textContent,a=i.length;for(e=0;e=Un),Kn=` `,qn=!1;function Jn(e,t){switch(e){case`keyup`:return Vn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Yn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Xn=!1;function Zn(e,t){switch(e){case`compositionend`:return Yn(t);case`keypress`:return t.which===32?(qn=!0,Kn):null;case`textInput`:return e=t.data,e===Kn&&qn?null:e;default:return null}}function Qn(e,t){if(Xn)return e===`compositionend`||!Hn&&Jn(e,t)?(e=V(),fn=dn=un=null,Xn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=br(n)}}function Sr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Sr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Cr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=It(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=It(e.document)}return t}function wr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Tr=sn&&`documentMode`in document&&11>=document.documentMode,Er=null,Dr=null,Or=null,kr=!1;function Ar(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;kr||Er==null||Er!==It(r)||(r=Er,`selectionStart`in r&&wr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Or&&yr(Or,r)||(Or=r,r=Ed(Dr,`onSelect`),0>=o,i-=o,Si=1<<32-Ke(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),U&&wi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(i,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(i,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(i,h),U&&wi(i,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(i,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return U&&wi(i,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,i,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(i,e)}),U&&wi(i,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===_&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case h:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===_){if(r.tag===7){n(e,r.sibling),c=i(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===re&&wa(l)===r.type){n(e,r.sibling),c=i(r,o.props),ja(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===_?(c=li(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=ci(o.type,o.key,o.props,null,e.mode,c),ja(c,o),c.return=e,e=c)}return s(e);case g:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=i(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=fi(o,e.mode,c),c.return=e,e=c}return s(e);case re:return o=wa(o),b(e,r,o,c)}if(de(o))return v(e,r,o,c);if(C(o)){if(l=C(o),typeof l!=`function`)throw Error(a(150));return o=l.call(o),y(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Aa(o),c);if(o.$$typeof===x)return b(e,r,Qi(e,o),c);Ma(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=i(r,o),c.return=e,e=c):(n(e,r),c=ui(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ka=0;var i=b(e,t,n,r);return Oa=null,i}catch(t){if(t===va||t===ba)throw t;var a=ii(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Pa=Na(!0),Fa=Na(!1),Ia=!1;function La(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ra(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function za(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ba(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ti(e),ei(e,null,n),t}return Zr(e,r,t,n),ti(e)}function Va(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,st(e,n)}}function Ha(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ua=!1;function Wa(){if(Ua){var e=la;if(e!==null)throw e}}function Ga(e,t,n,r){Ua=!1;var i=e.updateQueue;Ia=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,m=f!==s.lane;if(m?(Y&f)===f:(r&f)===f){f!==0&&f===ca&&(Ua=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=p({},d,f);break a;case 2:Ia=!0}}f=s.callback,f!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[f]:m.push(f))}else m={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Ka(e,t){if(typeof e!=`function`)throw Error(a(191,e));e.call(t)}function qa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=w.T,s={};w.T=s,Ms(e,!1,t,n);try{var c=i(),l=w.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?js(e,t,fa(c,r),pu(e)):js(e,t,r,pu(e))}catch(n){js(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{T.p=a,o!==null&&s.types!==null&&(o.types=s.types),w.T=o}}function xs(){}function Ss(e,t,n,r){if(e.tag!==5)throw Error(a(476));var i=Cs(e).queue;bs(e,i,t,fe,n===null?xs:function(){return ws(e),n(r)})}function Cs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:fe,baseState:fe,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:fe},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ws(e){var t=Cs(e);t.next===null&&(t=e.alternate.memoizedState),js(e,t.next.queue,{},pu())}function Ts(){return Zi(Qf)}function Es(){return Oo().memoizedState}function Ds(){return Oo().memoizedState}function Os(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=za(n);var r=Ba(t,e,n);r!==null&&(hu(r,t,n),Va(r,t,n)),t={cache:ia()},e.payload=t;return}t=t.return}}function ks(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ns(e)?Ps(t,n):(n=Qr(e,t,n,r),n!==null&&(hu(n,e,r),Fs(n,t,r)))}function As(e,t,n){js(e,t,n,pu())}function js(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ns(e))Ps(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,vr(s,o))return Zr(e,t,i,0),q===null&&Xr(),!1}catch{}if(n=Qr(e,t,i,r),n!==null)return hu(n,e,r),Fs(n,t,r),!0}return!1}function Ms(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ns(e)){if(t)throw Error(a(479))}else t=Qr(e,n,r,2),t!==null&&hu(t,e,2)}function Ns(e){var t=e.alternate;return e===W||t!==null&&t===W}function Ps(e,t){fo=uo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Fs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,st(e,n)}}var Is={readContext:Zi,use:jo,useCallback:vo,useContext:vo,useEffect:vo,useImperativeHandle:vo,useLayoutEffect:vo,useInsertionEffect:vo,useMemo:vo,useReducer:vo,useRef:vo,useState:vo,useDebugValue:vo,useDeferredValue:vo,useTransition:vo,useSyncExternalStore:vo,useId:vo,useHostTransitionStatus:vo,useFormState:vo,useActionState:vo,useOptimistic:vo,useMemoCache:vo,useCacheRefresh:vo};Is.useEffectEvent=vo;var Ls={readContext:Zi,use:jo,useCallback:function(e,t){return Do().memoizedState=[e,t===void 0?null:t],e},useContext:Zi,useEffect:ss,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),as(4194308,4,ps.bind(null,t,e),n)},useLayoutEffect:function(e,t){return as(4194308,4,e,t)},useInsertionEffect:function(e,t){as(4,2,e,t)},useMemo:function(e,t){var n=Do();t=t===void 0?null:t;var r=e();if(po){Ge(!0);try{e()}finally{Ge(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Do();if(n!==void 0){var i=n(t);if(po){Ge(!0);try{n(t)}finally{Ge(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ks.bind(null,W,e),[r.memoizedState,e]},useRef:function(e){var t=Do();return e={current:e},t.memoizedState=e},useState:function(e){e=Uo(e);var t=e.queue,n=As.bind(null,W,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:hs,useDeferredValue:function(e,t){return vs(Do(),e,t)},useTransition:function(){var e=Uo(!1);return e=bs.bind(null,W,e.queue,!0,!1),Do().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=W,i=Do();if(U){if(n===void 0)throw Error(a(407));n=n()}else{if(n=t(),q===null)throw Error(a(349));Y&127||Ro(r,t,n)}i.memoizedState=n;var o={value:n,getSnapshot:t};return i.queue=o,ss(Bo.bind(null,r,o,e),[e]),r.flags|=2048,rs(9,{destroy:void 0},zo.bind(null,r,o,n,t),null),n},useId:function(){var e=Do(),t=q.identifierPrefix;if(U){var n=Ci,r=Si;n=(r&~(1<<32-Ke(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=mo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(i,{is:r.is}):s.createElement(i)}}o[N]=t,o[ft]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,i,r),i){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&jc(t)}}return Ic(t),Mc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&jc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(a(166));if(e=_e.current,Li(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,i=ki,i!==null)switch(i.tag){case 27:case 5:r=i.memoizedProps}e[N]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Pi(t,!0)}else e=Bd(e).createTextNode(r),e[N]=t,t.stateNode=e}return Ic(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Li(t),n!==null){if(e===null){if(!r)throw Error(a(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(a(557));e[N]=t}else Ri(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Ic(t),e=!1}else n=zi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(ao(t),t):(ao(t),null);if(t.flags&128)throw Error(a(558))}return Ic(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(i=Li(t),r!==null&&r.dehydrated!==null){if(e===null){if(!i)throw Error(a(318));if(i=t.memoizedState,i=i===null?null:i.dehydrated,!i)throw Error(a(317));i[N]=t}else Ri(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Ic(t),i=!1}else i=zi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=i),i=!0;if(!i)return t.flags&256?(ao(t),t):(ao(t),null)}return ao(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,i=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(i=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==i&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Pc(t,t.updateQueue),Ic(t),null);case 4:return be(),e===null&&Sd(t.stateNode.containerInfo),Ic(t),null;case 10:return Gi(t.type),Ic(t),null;case 19:if(D(oo),r=t.memoizedState,r===null)return Ic(t),null;if(i=(t.flags&128)!=0,o=r.rendering,o===null)if(i)Fc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=so(e),o!==null){for(t.flags|=128,Fc(r,!1),e=o.updateQueue,t.updateQueue=e,Pc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)si(n,e),n=n.sibling;return O(oo,oo.current&1|2),U&&wi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Pe()>tu&&(t.flags|=128,i=!0,Fc(r,!1),t.lanes=4194304)}else{if(!i)if(e=so(o),e!==null){if(t.flags|=128,i=!0,e=e.updateQueue,t.updateQueue=e,Pc(t,e),Fc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!U)return Ic(t),null}else 2*Pe()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,i=!0,Fc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Ic(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Pe(),e.sibling=null,n=oo.current,O(oo,i?n&1|2:n&1),U&&wi(t,r.treeForkCount),e);case 22:case 23:return ao(t),Qa(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Ic(t),t.subtreeFlags&6&&(t.flags|=8192)):Ic(t),n=t.updateQueue,n!==null&&Pc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&D(ma),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Gi(ra),Ic(t),null;case 25:return null;case 30:return null}throw Error(a(156,t.tag))}function Rc(e,t){switch(Di(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Gi(ra),be(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Se(t),null;case 31:if(t.memoizedState!==null){if(ao(t),t.alternate===null)throw Error(a(340));Ri()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(ao(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(a(340));Ri()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return D(oo),null;case 4:return be(),null;case 10:return Gi(t.type),null;case 22:case 23:return ao(t),Qa(),e!==null&&D(ma),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Gi(ra),null;case 25:return null;default:return null}}function zc(e,t){switch(Di(t),t.tag){case 3:Gi(ra),be();break;case 26:case 27:case 5:Se(t);break;case 4:be();break;case 31:t.memoizedState!==null&&ao(t);break;case 13:ao(t);break;case 19:D(oo);break;case 10:Gi(t.type);break;case 22:case 23:ao(t),Qa(),e!==null&&D(ma);break;case 24:Gi(ra)}}function Bc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Vc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Hc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{qa(t,n)}catch(t){Z(e,e.return,t)}}}function Uc(e,t,n){n.props=Ws(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Wc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Gc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function Kc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function qc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[ft]=t}catch(t){Z(e,e.return,t)}}function Jc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Yc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Jc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Xc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Zt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Xc(e,t,n),e=e.sibling;e!==null;)Xc(e,t,n),e=e.sibling}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[N]=e,t[ft]=n}catch(t){Z(e,e.return,t)}}var $c=!1,el=!1,tl=!1,nl=typeof WeakSet==`function`?WeakSet:Set,rl=null;function il(e,t){if(e=e.containerInfo,Rd=sp,e=Cr(e),wr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||i!==0&&f.nodeType!==3||(c=s+i),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===i&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,rl=t;rl!==null;)if(t=rl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,rl=e;else for(;rl!==null;){switch(t=rl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[N]=e,Ct(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,i).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=xr(s,h),v=xr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,w.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,K&6)throw Error(a(331));var c=K;if(K|=4,Pl(o.current),El(o,o.current,s,n),K=c,id(0,!1),We&&typeof We.onPostCommitFiberRoot==`function`)try{We.onPostCommitFiberRoot(Ue,o)}catch{}return!0}finally{T.p=i,w.T=r,Vu(e,t)}}function Wu(e,t,n){t=mi(n,t),t=Xs(e.stateNode,t,2),e=Ba(e,t,2),e!==null&&(it(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=mi(n,e),n=Zs(2),r=Ba(t,n,2),r!==null&&(Qs(n,r,t,e),it(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Rl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(Wl===4||Wl===3&&(Y&62914560)===Y&&300>Pe()-$l?!(K&2)&&Su(e,0):ql|=n,Yl===Y&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=nt()),e=$r(e,t),e!==null&&(it(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(a(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return Ae(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ke(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=Y,a=$e(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||et(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=Pe(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Rt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Rt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Rt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Rt(n.imageSizes)+`"]`)):i+=`[href="`+Rt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Rt(r)+`"][href="`+Rt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),Ct(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=St(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);Ct(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=_e.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=St(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=St(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=St(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Rt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),Ct(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Rt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Rt(n.href)+`"]`);if(r)return t.instance=r,Ct(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Ct(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,Ct(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),Ct(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,Ct(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),Ct(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Ct(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),Ct(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=ce()}))();function le(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`)if(Array.isArray(e)){var i=e.length;for(t=0;ttypeof e==`boolean`?`${e}`:e===0?`0`:e,w=ue,T=(e,t)=>n=>{if(t?.variants==null)return w(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=de(t)||de(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return w(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},fe=(e,t)=>{let n=Array(e.length+t.length);for(let t=0;t({classGroupId:e,validator:t}),me=(e=new Map,t=null,n)=>({nextPart:e,validators:t,classGroupId:n}),E=`-`,D=[],O=`arbitrary..`,he=e=>{let t=ve(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:e=>{if(e.startsWith(`[`)&&e.endsWith(`]`))return _e(e);let n=e.split(E);return ge(n,+(n[0]===``&&n.length>1),t)},getConflictingClassGroupIds:(e,t)=>{if(t){let t=r[e],i=n[e];return t?i?fe(i,t):t:i||D}return n[e]||D}}},ge=(e,t,n)=>{if(e.length-t===0)return n.classGroupId;let r=e[t],i=n.nextPart.get(r);if(i){let n=ge(e,t+1,i);if(n)return n}let a=n.validators;if(a===null)return;let o=t===0?e.join(E):e.slice(t).join(E),s=a.length;for(let e=0;ee.slice(1,-1).indexOf(`:`)===-1?void 0:(()=>{let t=e.slice(1,-1),n=t.indexOf(`:`),r=t.slice(0,n);return r?O+r:void 0})(),ve=e=>{let{theme:t,classGroups:n}=e;return ye(n,t)},ye=(e,t)=>{let n=me();for(let r in e){let i=e[r];be(i,n,r,t)}return n},be=(e,t,n,r)=>{let i=e.length;for(let a=0;a{if(typeof e==`string`){Se(e,t,n);return}if(typeof e==`function`){Ce(e,t,n,r);return}we(e,t,n,r)},Se=(e,t,n)=>{let r=e===``?t:k(t,e);r.classGroupId=n},Ce=(e,t,n,r)=>{if(Te(e)){be(e(r),t,n,r);return}t.validators===null&&(t.validators=[]),t.validators.push(pe(n,e))},we=(e,t,n,r)=>{let i=Object.entries(e),a=i.length;for(let e=0;e{let n=e,r=t.split(E),i=r.length;for(let e=0;e`isThemeGetter`in e&&e.isThemeGetter===!0,Ee=e=>{if(e<1)return{get:()=>void 0,set:()=>{}};let t=0,n=Object.create(null),r=Object.create(null),i=(i,a)=>{n[i]=a,t++,t>e&&(t=0,r=n,n=Object.create(null))};return{get(e){let t=n[e];if(t!==void 0)return t;if((t=r[e])!==void 0)return i(e,t),t},set(e,t){e in n?n[e]=t:i(e,t)}}},De=`!`,Oe=`:`,ke=[],Ae=(e,t,n,r,i)=>({modifiers:e,hasImportantModifier:t,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),je=e=>{let{prefix:t,experimentalParseClassName:n}=e,r=e=>{let t=[],n=0,r=0,i=0,a,o=e.length;for(let s=0;si?a-i:void 0;return Ae(t,l,c,u)};if(t){let e=t+Oe,n=r;r=t=>t.startsWith(e)?n(t.slice(e.length)):Ae(ke,!1,t,void 0,!0)}if(n){let e=r;r=t=>n({className:t,parseClassName:e})}return r},Me=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((e,n)=>{t.set(e,1e6+n)}),e=>{let n=[],r=[];for(let i=0;i0&&(r.sort(),n.push(...r),r=[]),n.push(a)):r.push(a)}return r.length>0&&(r.sort(),n.push(...r)),n}},Ne=e=>({cache:Ee(e.cacheSize),parseClassName:je(e),sortModifiers:Me(e),postfixLookupClassGroupIds:Pe(e),...he(e)}),Pe=e=>{let t=Object.create(null),n=e.postfixLookupClassGroups;if(n)for(let e=0;e{let{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a,postfixLookupClassGroupIds:o}=t,s=[],c=e.trim().split(Fe),l=``;for(let e=c.length-1;e>=0;--e){let t=c[e],{isExternal:u,modifiers:d,hasImportantModifier:f,baseClassName:p,maybePostfixModifierPosition:m}=n(t);if(u){l=t+(l.length>0?` `+l:l);continue}let h=!!m,g;if(h){g=r(p.substring(0,m));let e=g&&o[g]?r(p):void 0;e&&e!==g&&(g=e,h=!1)}else g=r(p);if(!g){if(!h){l=t+(l.length>0?` `+l:l);continue}if(g=r(p),!g){l=t+(l.length>0?` `+l:l);continue}h=!1}let _=d.length===0?``:d.length===1?d[0]:a(d).join(`:`),v=f?_+De:_,y=v+g;if(s.indexOf(y)>-1)continue;s.push(y);let b=i(g,h);for(let e=0;e0?` `+l:l)}return l},Le=(...e)=>{let t=0,n,r,i=``;for(;t{if(typeof e==`string`)return e;let t,n=``;for(let r=0;r{let n,r,i,a,o=o=>(n=Ne(t.reduce((e,t)=>t(e),e())),r=n.cache.get,i=n.cache.set,a=s,s(o)),s=e=>{let t=r(e);if(t)return t;let a=Ie(e,n);return i(e,a),a};return a=o,(...e)=>a(Le(...e))},Be=[],Ve=e=>{let t=t=>t[e]||Be;return t.isThemeGetter=!0,t},He=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ue=/^\((?:(\w[\w-]*):)?(.+)\)$/i,We=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,Ge=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Ke=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,qe=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Je=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Ye=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Xe=e=>We.test(e),A=e=>!!e&&!Number.isNaN(Number(e)),Ze=e=>!!e&&Number.isInteger(Number(e)),Qe=e=>e.endsWith(`%`)&&A(e.slice(0,-1)),$e=e=>Ge.test(e),et=()=>!0,tt=e=>Ke.test(e)&&!qe.test(e),nt=()=>!1,rt=e=>Je.test(e),it=e=>Ye.test(e),at=e=>!j(e)&&!P(e),ot=e=>e.startsWith(`@container`)&&(e[10]===`/`&&e[11]!==void 0||e[11]===`s`&&e[16]!==void 0&&e.startsWith(`-size/`,10)||e[11]===`n`&&e[18]!==void 0&&e.startsWith(`-normal/`,10)),st=e=>bt(e,wt,nt),j=e=>He.test(e),ct=e=>bt(e,Tt,tt),lt=e=>bt(e,Et,A),ut=e=>bt(e,Ot,et),dt=e=>bt(e,Dt,nt),M=e=>bt(e,St,nt),N=e=>bt(e,Ct,it),ft=e=>bt(e,kt,rt),P=e=>Ue.test(e),pt=e=>xt(e,Tt),mt=e=>xt(e,Dt),ht=e=>xt(e,St),gt=e=>xt(e,wt),_t=e=>xt(e,Ct),vt=e=>xt(e,kt,!0),yt=e=>xt(e,Ot,!0),bt=(e,t,n)=>{let r=He.exec(e);return r?r[1]?t(r[1]):n(r[2]):!1},xt=(e,t,n=!1)=>{let r=Ue.exec(e);return r?r[1]?t(r[1]):n:!1},St=e=>e===`position`||e===`percentage`,Ct=e=>e===`image`||e===`url`,wt=e=>e===`length`||e===`size`||e===`bg-size`,Tt=e=>e===`length`,Et=e=>e===`number`,Dt=e=>e===`family-name`,Ot=e=>e===`number`||e===`weight`,kt=e=>e===`shadow`,At=ze(()=>{let e=Ve(`color`),t=Ve(`font`),n=Ve(`text`),r=Ve(`font-weight`),i=Ve(`tracking`),a=Ve(`leading`),o=Ve(`breakpoint`),s=Ve(`container`),c=Ve(`spacing`),l=Ve(`radius`),u=Ve(`shadow`),d=Ve(`inset-shadow`),f=Ve(`text-shadow`),p=Ve(`drop-shadow`),m=Ve(`blur`),h=Ve(`perspective`),g=Ve(`aspect`),_=Ve(`ease`),v=Ve(`animate`),y=()=>[`auto`,`avoid`,`all`,`avoid-page`,`page`,`left`,`right`,`column`],b=()=>[`center`,`top`,`bottom`,`left`,`right`,`top-left`,`left-top`,`top-right`,`right-top`,`bottom-right`,`right-bottom`,`bottom-left`,`left-bottom`],x=()=>[...b(),P,j],ee=()=>[`auto`,`hidden`,`clip`,`visible`,`scroll`],te=()=>[`auto`,`contain`,`none`],S=()=>[P,j,c],ne=()=>[Xe,`full`,`auto`,...S()],re=()=>[Ze,`none`,`subgrid`,P,j],ie=()=>[`auto`,{span:[`full`,Ze,P,j]},Ze,P,j],ae=()=>[Ze,`auto`,P,j],oe=()=>[`auto`,`min`,`max`,`fr`,P,j],se=()=>[`start`,`end`,`center`,`between`,`around`,`evenly`,`stretch`,`baseline`,`center-safe`,`end-safe`],ce=()=>[`start`,`end`,`center`,`stretch`,`center-safe`,`end-safe`],C=()=>[`auto`,...S()],le=()=>[Xe,`auto`,`full`,`dvw`,`dvh`,`lvw`,`lvh`,`svw`,`svh`,`min`,`max`,`fit`,...S()],ue=()=>[Xe,`screen`,`full`,`dvw`,`lvw`,`svw`,`min`,`max`,`fit`,...S()],de=()=>[Xe,`screen`,`full`,`lh`,`dvh`,`lvh`,`svh`,`min`,`max`,`fit`,...S()],w=()=>[e,P,j],T=()=>[...b(),ht,M,{position:[P,j]}],fe=()=>[`no-repeat`,{repeat:[``,`x`,`y`,`space`,`round`]}],pe=()=>[`auto`,`cover`,`contain`,gt,st,{size:[P,j]}],me=()=>[Qe,pt,ct],E=()=>[``,`none`,`full`,l,P,j],D=()=>[``,A,pt,ct],O=()=>[`solid`,`dashed`,`dotted`,`double`],he=()=>[`normal`,`multiply`,`screen`,`overlay`,`darken`,`lighten`,`color-dodge`,`color-burn`,`hard-light`,`soft-light`,`difference`,`exclusion`,`hue`,`saturation`,`color`,`luminosity`],ge=()=>[A,Qe,ht,M],_e=()=>[``,`none`,m,P,j],ve=()=>[`none`,A,P,j],ye=()=>[`none`,A,P,j],be=()=>[A,P,j],xe=()=>[Xe,`full`,...S()];return{cacheSize:500,theme:{animate:[`spin`,`ping`,`pulse`,`bounce`],aspect:[`video`],blur:[$e],breakpoint:[$e],color:[et],container:[$e],"drop-shadow":[$e],ease:[`in`,`out`,`in-out`],font:[at],"font-weight":[`thin`,`extralight`,`light`,`normal`,`medium`,`semibold`,`bold`,`extrabold`,`black`],"inset-shadow":[$e],leading:[`none`,`tight`,`snug`,`normal`,`relaxed`,`loose`],perspective:[`dramatic`,`near`,`normal`,`midrange`,`distant`,`none`],radius:[$e],shadow:[$e],spacing:[`px`,A],text:[$e],"text-shadow":[$e],tracking:[`tighter`,`tight`,`normal`,`wide`,`wider`,`widest`]},classGroups:{aspect:[{aspect:[`auto`,`square`,Xe,j,P,g]}],container:[`container`],"container-type":[{"@container":[``,`normal`,`size`,P,j]}],"container-named":[ot],columns:[{columns:[A,j,P,s]}],"break-after":[{"break-after":y()}],"break-before":[{"break-before":y()}],"break-inside":[{"break-inside":[`auto`,`avoid`,`avoid-page`,`avoid-column`]}],"box-decoration":[{"box-decoration":[`slice`,`clone`]}],box:[{box:[`border`,`content`]}],display:[`block`,`inline-block`,`inline`,`flex`,`inline-flex`,`table`,`inline-table`,`table-caption`,`table-cell`,`table-column`,`table-column-group`,`table-footer-group`,`table-header-group`,`table-row-group`,`table-row`,`flow-root`,`grid`,`inline-grid`,`contents`,`list-item`,`hidden`],sr:[`sr-only`,`not-sr-only`],float:[{float:[`right`,`left`,`none`,`start`,`end`]}],clear:[{clear:[`left`,`right`,`both`,`none`,`start`,`end`]}],isolation:[`isolate`,`isolation-auto`],"object-fit":[{object:[`contain`,`cover`,`fill`,`none`,`scale-down`]}],"object-position":[{object:x()}],overflow:[{overflow:ee()}],"overflow-x":[{"overflow-x":ee()}],"overflow-y":[{"overflow-y":ee()}],overscroll:[{overscroll:te()}],"overscroll-x":[{"overscroll-x":te()}],"overscroll-y":[{"overscroll-y":te()}],position:[`static`,`fixed`,`absolute`,`relative`,`sticky`],inset:[{inset:ne()}],"inset-x":[{"inset-x":ne()}],"inset-y":[{"inset-y":ne()}],start:[{"inset-s":ne(),start:ne()}],end:[{"inset-e":ne(),end:ne()}],"inset-bs":[{"inset-bs":ne()}],"inset-be":[{"inset-be":ne()}],top:[{top:ne()}],right:[{right:ne()}],bottom:[{bottom:ne()}],left:[{left:ne()}],visibility:[`visible`,`invisible`,`collapse`],z:[{z:[Ze,`auto`,P,j]}],basis:[{basis:[Xe,`full`,`auto`,s,...S()]}],"flex-direction":[{flex:[`row`,`row-reverse`,`col`,`col-reverse`]}],"flex-wrap":[{flex:[`nowrap`,`wrap`,`wrap-reverse`]}],flex:[{flex:[A,Xe,`auto`,`initial`,`none`,j]}],grow:[{grow:[``,A,P,j]}],shrink:[{shrink:[``,A,P,j]}],order:[{order:[Ze,`first`,`last`,`none`,P,j]}],"grid-cols":[{"grid-cols":re()}],"col-start-end":[{col:ie()}],"col-start":[{"col-start":ae()}],"col-end":[{"col-end":ae()}],"grid-rows":[{"grid-rows":re()}],"row-start-end":[{row:ie()}],"row-start":[{"row-start":ae()}],"row-end":[{"row-end":ae()}],"grid-flow":[{"grid-flow":[`row`,`col`,`dense`,`row-dense`,`col-dense`]}],"auto-cols":[{"auto-cols":oe()}],"auto-rows":[{"auto-rows":oe()}],gap:[{gap:S()}],"gap-x":[{"gap-x":S()}],"gap-y":[{"gap-y":S()}],"justify-content":[{justify:[...se(),`normal`]}],"justify-items":[{"justify-items":[...ce(),`normal`]}],"justify-self":[{"justify-self":[`auto`,...ce()]}],"align-content":[{content:[`normal`,...se()]}],"align-items":[{items:[...ce(),{baseline:[``,`last`]}]}],"align-self":[{self:[`auto`,...ce(),{baseline:[``,`last`]}]}],"place-content":[{"place-content":se()}],"place-items":[{"place-items":[...ce(),`baseline`]}],"place-self":[{"place-self":[`auto`,...ce()]}],p:[{p:S()}],px:[{px:S()}],py:[{py:S()}],ps:[{ps:S()}],pe:[{pe:S()}],pbs:[{pbs:S()}],pbe:[{pbe:S()}],pt:[{pt:S()}],pr:[{pr:S()}],pb:[{pb:S()}],pl:[{pl:S()}],m:[{m:C()}],mx:[{mx:C()}],my:[{my:C()}],ms:[{ms:C()}],me:[{me:C()}],mbs:[{mbs:C()}],mbe:[{mbe:C()}],mt:[{mt:C()}],mr:[{mr:C()}],mb:[{mb:C()}],ml:[{ml:C()}],"space-x":[{"space-x":S()}],"space-x-reverse":[`space-x-reverse`],"space-y":[{"space-y":S()}],"space-y-reverse":[`space-y-reverse`],size:[{size:le()}],"inline-size":[{inline:[`auto`,...ue()]}],"min-inline-size":[{"min-inline":[`auto`,...ue()]}],"max-inline-size":[{"max-inline":[`none`,...ue()]}],"block-size":[{block:[`auto`,...de()]}],"min-block-size":[{"min-block":[`auto`,...de()]}],"max-block-size":[{"max-block":[`none`,...de()]}],w:[{w:[s,`screen`,...le()]}],"min-w":[{"min-w":[s,`screen`,`none`,...le()]}],"max-w":[{"max-w":[s,`screen`,`none`,`prose`,{screen:[o]},...le()]}],h:[{h:[`screen`,`lh`,...le()]}],"min-h":[{"min-h":[`screen`,`lh`,`none`,...le()]}],"max-h":[{"max-h":[`screen`,`lh`,...le()]}],"font-size":[{text:[`base`,n,pt,ct]}],"font-smoothing":[`antialiased`,`subpixel-antialiased`],"font-style":[`italic`,`not-italic`],"font-weight":[{font:[r,yt,ut]}],"font-stretch":[{"font-stretch":[`ultra-condensed`,`extra-condensed`,`condensed`,`semi-condensed`,`normal`,`semi-expanded`,`expanded`,`extra-expanded`,`ultra-expanded`,Qe,j]}],"font-family":[{font:[mt,dt,t]}],"font-features":[{"font-features":[j]}],"fvn-normal":[`normal-nums`],"fvn-ordinal":[`ordinal`],"fvn-slashed-zero":[`slashed-zero`],"fvn-figure":[`lining-nums`,`oldstyle-nums`],"fvn-spacing":[`proportional-nums`,`tabular-nums`],"fvn-fraction":[`diagonal-fractions`,`stacked-fractions`],tracking:[{tracking:[i,P,j]}],"line-clamp":[{"line-clamp":[A,`none`,P,lt]}],leading:[{leading:[a,...S()]}],"list-image":[{"list-image":[`none`,P,j]}],"list-style-position":[{list:[`inside`,`outside`]}],"list-style-type":[{list:[`disc`,`decimal`,`none`,P,j]}],"text-alignment":[{text:[`left`,`center`,`right`,`justify`,`start`,`end`]}],"placeholder-color":[{placeholder:w()}],"text-color":[{text:w()}],"text-decoration":[`underline`,`overline`,`line-through`,`no-underline`],"text-decoration-style":[{decoration:[...O(),`wavy`]}],"text-decoration-thickness":[{decoration:[A,`from-font`,`auto`,P,ct]}],"text-decoration-color":[{decoration:w()}],"underline-offset":[{"underline-offset":[A,`auto`,P,j]}],"text-transform":[`uppercase`,`lowercase`,`capitalize`,`normal-case`],"text-overflow":[`truncate`,`text-ellipsis`,`text-clip`],"text-wrap":[{text:[`wrap`,`nowrap`,`balance`,`pretty`]}],indent:[{indent:S()}],"tab-size":[{tab:[Ze,P,j]}],"vertical-align":[{align:[`baseline`,`top`,`middle`,`bottom`,`text-top`,`text-bottom`,`sub`,`super`,P,j]}],whitespace:[{whitespace:[`normal`,`nowrap`,`pre`,`pre-line`,`pre-wrap`,`break-spaces`]}],break:[{break:[`normal`,`words`,`all`,`keep`]}],wrap:[{wrap:[`break-word`,`anywhere`,`normal`]}],hyphens:[{hyphens:[`none`,`manual`,`auto`]}],content:[{content:[`none`,P,j]}],"bg-attachment":[{bg:[`fixed`,`local`,`scroll`]}],"bg-clip":[{"bg-clip":[`border`,`padding`,`content`,`text`]}],"bg-origin":[{"bg-origin":[`border`,`padding`,`content`]}],"bg-position":[{bg:T()}],"bg-repeat":[{bg:fe()}],"bg-size":[{bg:pe()}],"bg-image":[{bg:[`none`,{linear:[{to:[`t`,`tr`,`r`,`br`,`b`,`bl`,`l`,`tl`]},Ze,P,j],radial:[``,P,j],conic:[Ze,P,j]},_t,N]}],"bg-color":[{bg:w()}],"gradient-from-pos":[{from:me()}],"gradient-via-pos":[{via:me()}],"gradient-to-pos":[{to:me()}],"gradient-from":[{from:w()}],"gradient-via":[{via:w()}],"gradient-to":[{to:w()}],rounded:[{rounded:E()}],"rounded-s":[{"rounded-s":E()}],"rounded-e":[{"rounded-e":E()}],"rounded-t":[{"rounded-t":E()}],"rounded-r":[{"rounded-r":E()}],"rounded-b":[{"rounded-b":E()}],"rounded-l":[{"rounded-l":E()}],"rounded-ss":[{"rounded-ss":E()}],"rounded-se":[{"rounded-se":E()}],"rounded-ee":[{"rounded-ee":E()}],"rounded-es":[{"rounded-es":E()}],"rounded-tl":[{"rounded-tl":E()}],"rounded-tr":[{"rounded-tr":E()}],"rounded-br":[{"rounded-br":E()}],"rounded-bl":[{"rounded-bl":E()}],"border-w":[{border:D()}],"border-w-x":[{"border-x":D()}],"border-w-y":[{"border-y":D()}],"border-w-s":[{"border-s":D()}],"border-w-e":[{"border-e":D()}],"border-w-bs":[{"border-bs":D()}],"border-w-be":[{"border-be":D()}],"border-w-t":[{"border-t":D()}],"border-w-r":[{"border-r":D()}],"border-w-b":[{"border-b":D()}],"border-w-l":[{"border-l":D()}],"divide-x":[{"divide-x":D()}],"divide-x-reverse":[`divide-x-reverse`],"divide-y":[{"divide-y":D()}],"divide-y-reverse":[`divide-y-reverse`],"border-style":[{border:[...O(),`hidden`,`none`]}],"divide-style":[{divide:[...O(),`hidden`,`none`]}],"border-color":[{border:w()}],"border-color-x":[{"border-x":w()}],"border-color-y":[{"border-y":w()}],"border-color-s":[{"border-s":w()}],"border-color-e":[{"border-e":w()}],"border-color-bs":[{"border-bs":w()}],"border-color-be":[{"border-be":w()}],"border-color-t":[{"border-t":w()}],"border-color-r":[{"border-r":w()}],"border-color-b":[{"border-b":w()}],"border-color-l":[{"border-l":w()}],"divide-color":[{divide:w()}],"outline-style":[{outline:[...O(),`none`,`hidden`]}],"outline-offset":[{"outline-offset":[A,P,j]}],"outline-w":[{outline:[``,A,pt,ct]}],"outline-color":[{outline:w()}],shadow:[{shadow:[``,`none`,u,vt,ft]}],"shadow-color":[{shadow:w()}],"inset-shadow":[{"inset-shadow":[`none`,d,vt,ft]}],"inset-shadow-color":[{"inset-shadow":w()}],"ring-w":[{ring:D()}],"ring-w-inset":[`ring-inset`],"ring-color":[{ring:w()}],"ring-offset-w":[{"ring-offset":[A,ct]}],"ring-offset-color":[{"ring-offset":w()}],"inset-ring-w":[{"inset-ring":D()}],"inset-ring-color":[{"inset-ring":w()}],"text-shadow":[{"text-shadow":[`none`,f,vt,ft]}],"text-shadow-color":[{"text-shadow":w()}],opacity:[{opacity:[A,P,j]}],"mix-blend":[{"mix-blend":[...he(),`plus-darker`,`plus-lighter`]}],"bg-blend":[{"bg-blend":he()}],"mask-clip":[{"mask-clip":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]},`mask-no-clip`],"mask-composite":[{mask:[`add`,`subtract`,`intersect`,`exclude`]}],"mask-image-linear-pos":[{"mask-linear":[A]}],"mask-image-linear-from-pos":[{"mask-linear-from":ge()}],"mask-image-linear-to-pos":[{"mask-linear-to":ge()}],"mask-image-linear-from-color":[{"mask-linear-from":w()}],"mask-image-linear-to-color":[{"mask-linear-to":w()}],"mask-image-t-from-pos":[{"mask-t-from":ge()}],"mask-image-t-to-pos":[{"mask-t-to":ge()}],"mask-image-t-from-color":[{"mask-t-from":w()}],"mask-image-t-to-color":[{"mask-t-to":w()}],"mask-image-r-from-pos":[{"mask-r-from":ge()}],"mask-image-r-to-pos":[{"mask-r-to":ge()}],"mask-image-r-from-color":[{"mask-r-from":w()}],"mask-image-r-to-color":[{"mask-r-to":w()}],"mask-image-b-from-pos":[{"mask-b-from":ge()}],"mask-image-b-to-pos":[{"mask-b-to":ge()}],"mask-image-b-from-color":[{"mask-b-from":w()}],"mask-image-b-to-color":[{"mask-b-to":w()}],"mask-image-l-from-pos":[{"mask-l-from":ge()}],"mask-image-l-to-pos":[{"mask-l-to":ge()}],"mask-image-l-from-color":[{"mask-l-from":w()}],"mask-image-l-to-color":[{"mask-l-to":w()}],"mask-image-x-from-pos":[{"mask-x-from":ge()}],"mask-image-x-to-pos":[{"mask-x-to":ge()}],"mask-image-x-from-color":[{"mask-x-from":w()}],"mask-image-x-to-color":[{"mask-x-to":w()}],"mask-image-y-from-pos":[{"mask-y-from":ge()}],"mask-image-y-to-pos":[{"mask-y-to":ge()}],"mask-image-y-from-color":[{"mask-y-from":w()}],"mask-image-y-to-color":[{"mask-y-to":w()}],"mask-image-radial":[{"mask-radial":[P,j]}],"mask-image-radial-from-pos":[{"mask-radial-from":ge()}],"mask-image-radial-to-pos":[{"mask-radial-to":ge()}],"mask-image-radial-from-color":[{"mask-radial-from":w()}],"mask-image-radial-to-color":[{"mask-radial-to":w()}],"mask-image-radial-shape":[{"mask-radial":[`circle`,`ellipse`]}],"mask-image-radial-size":[{"mask-radial":[{closest:[`side`,`corner`],farthest:[`side`,`corner`]}]}],"mask-image-radial-pos":[{"mask-radial-at":b()}],"mask-image-conic-pos":[{"mask-conic":[A]}],"mask-image-conic-from-pos":[{"mask-conic-from":ge()}],"mask-image-conic-to-pos":[{"mask-conic-to":ge()}],"mask-image-conic-from-color":[{"mask-conic-from":w()}],"mask-image-conic-to-color":[{"mask-conic-to":w()}],"mask-mode":[{mask:[`alpha`,`luminance`,`match`]}],"mask-origin":[{"mask-origin":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]}],"mask-position":[{mask:T()}],"mask-repeat":[{mask:fe()}],"mask-size":[{mask:pe()}],"mask-type":[{"mask-type":[`alpha`,`luminance`]}],"mask-image":[{mask:[`none`,P,j]}],filter:[{filter:[``,`none`,P,j]}],blur:[{blur:_e()}],brightness:[{brightness:[A,P,j]}],contrast:[{contrast:[A,P,j]}],"drop-shadow":[{"drop-shadow":[``,`none`,p,vt,ft]}],"drop-shadow-color":[{"drop-shadow":w()}],grayscale:[{grayscale:[``,A,P,j]}],"hue-rotate":[{"hue-rotate":[A,P,j]}],invert:[{invert:[``,A,P,j]}],saturate:[{saturate:[A,P,j]}],sepia:[{sepia:[``,A,P,j]}],"backdrop-filter":[{"backdrop-filter":[``,`none`,P,j]}],"backdrop-blur":[{"backdrop-blur":_e()}],"backdrop-brightness":[{"backdrop-brightness":[A,P,j]}],"backdrop-contrast":[{"backdrop-contrast":[A,P,j]}],"backdrop-grayscale":[{"backdrop-grayscale":[``,A,P,j]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[A,P,j]}],"backdrop-invert":[{"backdrop-invert":[``,A,P,j]}],"backdrop-opacity":[{"backdrop-opacity":[A,P,j]}],"backdrop-saturate":[{"backdrop-saturate":[A,P,j]}],"backdrop-sepia":[{"backdrop-sepia":[``,A,P,j]}],"border-collapse":[{border:[`collapse`,`separate`]}],"border-spacing":[{"border-spacing":S()}],"border-spacing-x":[{"border-spacing-x":S()}],"border-spacing-y":[{"border-spacing-y":S()}],"table-layout":[{table:[`auto`,`fixed`]}],caption:[{caption:[`top`,`bottom`]}],transition:[{transition:[``,`all`,`colors`,`opacity`,`shadow`,`transform`,`none`,P,j]}],"transition-behavior":[{transition:[`normal`,`discrete`]}],duration:[{duration:[A,`initial`,P,j]}],ease:[{ease:[`linear`,`initial`,_,P,j]}],delay:[{delay:[A,P,j]}],animate:[{animate:[`none`,v,P,j]}],backface:[{backface:[`hidden`,`visible`]}],perspective:[{perspective:[h,P,j]}],"perspective-origin":[{"perspective-origin":x()}],rotate:[{rotate:ve()}],"rotate-x":[{"rotate-x":ve()}],"rotate-y":[{"rotate-y":ve()}],"rotate-z":[{"rotate-z":ve()}],scale:[{scale:ye()}],"scale-x":[{"scale-x":ye()}],"scale-y":[{"scale-y":ye()}],"scale-z":[{"scale-z":ye()}],"scale-3d":[`scale-3d`],skew:[{skew:be()}],"skew-x":[{"skew-x":be()}],"skew-y":[{"skew-y":be()}],transform:[{transform:[P,j,``,`none`,`gpu`,`cpu`]}],"transform-origin":[{origin:x()}],"transform-style":[{transform:[`3d`,`flat`]}],translate:[{translate:xe()}],"translate-x":[{"translate-x":xe()}],"translate-y":[{"translate-y":xe()}],"translate-z":[{"translate-z":xe()}],"translate-none":[`translate-none`],zoom:[{zoom:[Ze,P,j]}],accent:[{accent:w()}],appearance:[{appearance:[`none`,`auto`]}],"caret-color":[{caret:w()}],"color-scheme":[{scheme:[`normal`,`dark`,`light`,`light-dark`,`only-dark`,`only-light`]}],cursor:[{cursor:[`auto`,`default`,`pointer`,`wait`,`text`,`move`,`help`,`not-allowed`,`none`,`context-menu`,`progress`,`cell`,`crosshair`,`vertical-text`,`alias`,`copy`,`no-drop`,`grab`,`grabbing`,`all-scroll`,`col-resize`,`row-resize`,`n-resize`,`e-resize`,`s-resize`,`w-resize`,`ne-resize`,`nw-resize`,`se-resize`,`sw-resize`,`ew-resize`,`ns-resize`,`nesw-resize`,`nwse-resize`,`zoom-in`,`zoom-out`,P,j]}],"field-sizing":[{"field-sizing":[`fixed`,`content`]}],"pointer-events":[{"pointer-events":[`auto`,`none`]}],resize:[{resize:[`none`,``,`y`,`x`]}],"scroll-behavior":[{scroll:[`auto`,`smooth`]}],"scrollbar-thumb-color":[{"scrollbar-thumb":w()}],"scrollbar-track-color":[{"scrollbar-track":w()}],"scrollbar-gutter":[{"scrollbar-gutter":[`auto`,`stable`,`both`]}],"scrollbar-w":[{scrollbar:[`auto`,`thin`,`none`]}],"scroll-m":[{"scroll-m":S()}],"scroll-mx":[{"scroll-mx":S()}],"scroll-my":[{"scroll-my":S()}],"scroll-ms":[{"scroll-ms":S()}],"scroll-me":[{"scroll-me":S()}],"scroll-mbs":[{"scroll-mbs":S()}],"scroll-mbe":[{"scroll-mbe":S()}],"scroll-mt":[{"scroll-mt":S()}],"scroll-mr":[{"scroll-mr":S()}],"scroll-mb":[{"scroll-mb":S()}],"scroll-ml":[{"scroll-ml":S()}],"scroll-p":[{"scroll-p":S()}],"scroll-px":[{"scroll-px":S()}],"scroll-py":[{"scroll-py":S()}],"scroll-ps":[{"scroll-ps":S()}],"scroll-pe":[{"scroll-pe":S()}],"scroll-pbs":[{"scroll-pbs":S()}],"scroll-pbe":[{"scroll-pbe":S()}],"scroll-pt":[{"scroll-pt":S()}],"scroll-pr":[{"scroll-pr":S()}],"scroll-pb":[{"scroll-pb":S()}],"scroll-pl":[{"scroll-pl":S()}],"snap-align":[{snap:[`start`,`end`,`center`,`align-none`]}],"snap-stop":[{snap:[`normal`,`always`]}],"snap-type":[{snap:[`none`,`x`,`y`,`both`]}],"snap-strictness":[{snap:[`mandatory`,`proximity`]}],touch:[{touch:[`auto`,`none`,`manipulation`]}],"touch-x":[{"touch-pan":[`x`,`left`,`right`]}],"touch-y":[{"touch-pan":[`y`,`up`,`down`]}],"touch-pz":[`touch-pinch-zoom`],select:[{select:[`none`,`text`,`all`,`auto`]}],"will-change":[{"will-change":[`auto`,`scroll`,`contents`,`transform`,P,j]}],fill:[{fill:[`none`,...w()]}],"stroke-w":[{stroke:[A,pt,ct,lt]}],stroke:[{stroke:[`none`,...w()]}],"forced-color-adjust":[{"forced-color-adjust":[`auto`,`none`]}]},conflictingClassGroups:{"container-named":[`container-type`],overflow:[`overflow-x`,`overflow-y`],overscroll:[`overscroll-x`,`overscroll-y`],inset:[`inset-x`,`inset-y`,`inset-bs`,`inset-be`,`start`,`end`,`top`,`right`,`bottom`,`left`],"inset-x":[`right`,`left`],"inset-y":[`top`,`bottom`],flex:[`basis`,`grow`,`shrink`],gap:[`gap-x`,`gap-y`],p:[`px`,`py`,`ps`,`pe`,`pbs`,`pbe`,`pt`,`pr`,`pb`,`pl`],px:[`pr`,`pl`],py:[`pt`,`pb`],m:[`mx`,`my`,`ms`,`me`,`mbs`,`mbe`,`mt`,`mr`,`mb`,`ml`],mx:[`mr`,`ml`],my:[`mt`,`mb`],size:[`w`,`h`],"font-size":[`leading`],"fvn-normal":[`fvn-ordinal`,`fvn-slashed-zero`,`fvn-figure`,`fvn-spacing`,`fvn-fraction`],"fvn-ordinal":[`fvn-normal`],"fvn-slashed-zero":[`fvn-normal`],"fvn-figure":[`fvn-normal`],"fvn-spacing":[`fvn-normal`],"fvn-fraction":[`fvn-normal`],"line-clamp":[`display`,`overflow`],rounded:[`rounded-s`,`rounded-e`,`rounded-t`,`rounded-r`,`rounded-b`,`rounded-l`,`rounded-ss`,`rounded-se`,`rounded-ee`,`rounded-es`,`rounded-tl`,`rounded-tr`,`rounded-br`,`rounded-bl`],"rounded-s":[`rounded-ss`,`rounded-es`],"rounded-e":[`rounded-se`,`rounded-ee`],"rounded-t":[`rounded-tl`,`rounded-tr`],"rounded-r":[`rounded-tr`,`rounded-br`],"rounded-b":[`rounded-br`,`rounded-bl`],"rounded-l":[`rounded-tl`,`rounded-bl`],"border-spacing":[`border-spacing-x`,`border-spacing-y`],"border-w":[`border-w-x`,`border-w-y`,`border-w-s`,`border-w-e`,`border-w-bs`,`border-w-be`,`border-w-t`,`border-w-r`,`border-w-b`,`border-w-l`],"border-w-x":[`border-w-r`,`border-w-l`],"border-w-y":[`border-w-t`,`border-w-b`],"border-color":[`border-color-x`,`border-color-y`,`border-color-s`,`border-color-e`,`border-color-bs`,`border-color-be`,`border-color-t`,`border-color-r`,`border-color-b`,`border-color-l`],"border-color-x":[`border-color-r`,`border-color-l`],"border-color-y":[`border-color-t`,`border-color-b`],translate:[`translate-x`,`translate-y`,`translate-none`],"translate-none":[`translate`,`translate-x`,`translate-y`,`translate-z`],"scroll-m":[`scroll-mx`,`scroll-my`,`scroll-ms`,`scroll-me`,`scroll-mbs`,`scroll-mbe`,`scroll-mt`,`scroll-mr`,`scroll-mb`,`scroll-ml`],"scroll-mx":[`scroll-mr`,`scroll-ml`],"scroll-my":[`scroll-mt`,`scroll-mb`],"scroll-p":[`scroll-px`,`scroll-py`,`scroll-ps`,`scroll-pe`,`scroll-pbs`,`scroll-pbe`,`scroll-pt`,`scroll-pr`,`scroll-pb`,`scroll-pl`],"scroll-px":[`scroll-pr`,`scroll-pl`],"scroll-py":[`scroll-pt`,`scroll-pb`],touch:[`touch-x`,`touch-y`,`touch-pz`],"touch-x":[`touch`],"touch-y":[`touch`],"touch-pz":[`touch`]},conflictingClassGroupModifiers:{"font-size":[`leading`]},postfixLookupClassGroups:[`container-type`],orderSensitiveModifiers:[`*`,`**`,`after`,`backdrop`,`before`,`details-content`,`file`,`first-letter`,`first-line`,`marker`,`placeholder`,`selection`]}});function jt(...e){return At(ue(e))}var Mt=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),F=e(((e,t)=>{t.exports=Mt()}))(),Nt=T(`inline-flex min-h-[22px] items-center rounded-full border px-2 py-0.5 text-[11px] font-extrabold uppercase leading-tight`,{variants:{variant:{neutral:`border-border bg-secondary text-muted-foreground`,succeeded:`border-emerald-400/35 bg-emerald-500/15 text-emerald-300`,failed:`border-red-400/40 bg-red-500/15 text-red-300`,dead:`border-red-400/40 bg-red-500/15 text-red-300`,missing:`border-red-400/40 bg-red-500/15 text-red-300`,running:`border-amber-400/40 bg-amber-500/15 text-amber-300`,queued:`border-teal-400/40 bg-teal-500/15 text-teal-200`,canceled:`border-border bg-secondary text-muted-foreground`}},defaultVariants:{variant:`neutral`}});function I({className:e,variant:t,...n}){return(0,F.jsx)(`span`,{"data-slot":`badge`,className:jt(Nt({variant:t,className:e})),...n})}var Pt=T(`inline-flex min-h-9 shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md border text-sm font-semibold transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0`,{variants:{variant:{default:`border-primary bg-primary text-primary-foreground hover:bg-primary/90`,secondary:`border-border bg-secondary text-secondary-foreground hover:bg-secondary/80`,outline:`border-border bg-background hover:bg-accent hover:text-accent-foreground`,ghost:`border-transparent hover:bg-accent hover:text-accent-foreground`,destructive:`border-destructive bg-destructive text-white hover:bg-destructive/90`},size:{default:`h-9 px-4 py-2`,sm:`h-8 rounded-md px-3 text-xs`,icon:`size-9`}},defaultVariants:{variant:`secondary`,size:`default`}});function L({className:e,variant:t,size:n,type:r=`button`,...i}){return(0,F.jsx)(`button`,{"data-slot":`button`,type:r,className:jt(Pt({variant:t,size:n,className:e})),...i})}function R({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card`,className:jt(`rounded-lg border bg-card text-card-foreground shadow-[0_18px_44px_rgb(0_0_0/0.22)]`,e),...t})}function Ft({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card-header`,className:jt(`flex items-center justify-between gap-3 border-b px-4 py-3`,e),...t})}function It({className:e,...t}){return(0,F.jsx)(`h2`,{"data-slot":`card-title`,className:jt(`text-[15px] font-bold`,e),...t})}function Lt({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card-content`,className:jt(`p-4`,e),...t})}function Rt({className:e,type:t,...n}){return(0,F.jsx)(`input`,{"data-slot":`input`,type:t,className:jt(`flex min-h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,e),...n})}function zt({className:e,...t}){return(0,F.jsx)(`label`,{"data-slot":`label`,className:jt(`grid gap-1.5 text-xs font-bold text-muted-foreground`,e),...t})}function Bt({className:e,...t}){return(0,F.jsx)(`select`,{"data-slot":`select`,className:jt(`flex min-h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-xs transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,e),...t})}function Vt({className:e,...t}){return(0,F.jsx)(`table`,{"data-slot":`table`,className:jt(`w-full border-collapse text-sm`,e),...t})}function Ht({className:e,...t}){return(0,F.jsx)(`thead`,{"data-slot":`table-header`,className:e,...t})}function Ut({className:e,...t}){return(0,F.jsx)(`tbody`,{"data-slot":`table-body`,className:e,...t})}function Wt({className:e,...t}){return(0,F.jsx)(`tr`,{"data-slot":`table-row`,className:jt(`border-b transition-colors hover:bg-muted/45`,e),...t})}function z({className:e,...t}){return(0,F.jsx)(`th`,{"data-slot":`table-head`,className:jt(`bg-secondary px-3 py-3 text-left align-middle text-xs font-extrabold text-muted-foreground`,e),...t})}function B({className:e,...t}){return(0,F.jsx)(`td`,{"data-slot":`table-cell`,className:jt(`px-3 py-3 align-middle text-sm`,e),...t})}var Gt={pending:`Needs review`,selected:`Assigned to onboarder`,reachingout:`Reaching out`,awaitingcontribution:`Awaiting contribution`,onboarded:`Onboarded`,waitlist:`Waitlist`,rejected:`Rejected`};function Kt(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`})}function qt(e,t=new Date){if(!e)return null;let n=new Date(e);if(Number.isNaN(n.getTime()))return null;let r=t.getTime()-n.getTime();return r<0?0:Math.floor(r/864e5)}function Jt(e){return e==null?``:JSON.stringify(e,null,2)}function Yt(e){return e.onboarding_state||e.onboardingState||e.cOnboardingState||``}function Xt(e){let t=String(e||``).trim();if(!t)return`No status`;let n=t.toLowerCase();return Gt[n]?Gt[n]:t.replace(/[-_]+/g,` `).replace(/\s+/g,` `).trim().replace(/\b\w/g,e=>e.toUpperCase())}function Zt(e){let t=String(e||``).trim().toLowerCase();return!t||t===`pending`?`neutral`:t===`selected`?`queued`:t===`rejected`?`failed`:t===`onboarded`?`succeeded`:t===`waitlist`?`running`:`queued`}function Qt(e){let t=String(e||``).trim();return!t||t.toLowerCase()===`none`?``:t}function $t(e){let t=String(e||``).trim();return t?/^https?:\/\//i.test(t)?t:`https://${t.replace(/^\/+/,``)}`:``}function en(e){try{return new URL($t(e))}catch{return null}}function tn(e,t){let n=e.toLowerCase();return n===t||n.endsWith(`.${t}`)}function nn(e){return e.split(`/`).filter(Boolean).map(e=>encodeURIComponent(e)).join(`/`)}function rn(e){let t=String(e||``).trim();if(!t)return``;let n=en(t);if(n&&tn(n.hostname,`linkedin.com`))return n.href;if(/^https?:\/\//i.test(t))return``;let r=t.replace(/^@/,``).replace(/^\/+|\/+$/g,``).replace(/^in\//i,``);return r?`https://www.linkedin.com/in/${nn(r)}`:``}function an(e){let t=String(e||``).trim().replace(/^@/,``);if(!t)return``;let n=en(t);if(n&&tn(n.hostname,`github.com`))return n.href;if(/^https?:\/\//i.test(t))return``;let r=t.replace(/^\/+|\/+$/g,``);return r?`https://github.com/${nn(r)}`:``}var on={people:`/dashboard/people`,gigs:`/dashboard/gigs`,projects:`/dashboard/projects`,onboarding:`/dashboard/onboarding`,jobs:`/dashboard/jobs`,agent:`/dashboard/agent`,audit:`/dashboard/audit`},sn={people:`people:read`,gigs:`gigs:read`,projects:`projects:read`,onboarding:`onboarding:read`,jobs:`jobs:read`,agent:`audit:read`,audit:`audit:read`},cn={discord:{label:`Discord`,options:[[`linked`,`Linked`],[`missing`,`Missing`]]},email_508:{label:`508 email`,options:[[`present`,`Present`],[`missing`,`Missing`]]},resume:{label:`Resume`,options:[[`present`,`Present`],[`missing`,`Missing`]]},skills:{label:`Skills`,options:[[`present`,`Parsed`],[`missing`,`Not parsed`]]},sync_status:{label:`Sync status`,options:[[`active`,`Active`],[`conflict`,`Conflict`],[`missing_in_crm`,`Missing in CRM`]]}},ln=class extends Error{status;payload;constructor(e,t,n){super(e),this.name=`ApiRequestError`,this.status=t,this.payload=n}};function un(){return window.location.pathname.split(`/`).filter(Boolean)[1]||``}function dn(){let e=un();return Object.hasOwn(on,e)?e:`people`}function fn(e=`gigs`){let[,t,n]=window.location.pathname.split(`/`).filter(Boolean);if(t!==e||!n)return``;try{return decodeURIComponent(n)}catch{return``}}async function V(e,t={}){let n=new Headers(t.headers);n.set(`Accept`,`application/json`);let r=await fetch(e,{credentials:`same-origin`,...t,headers:n});if(r.status===401){let e=`${window.location.pathname}${window.location.search}`||`/dashboard`;throw window.location.assign(`/auth/login?next=${encodeURIComponent(e)}`),Error(`Session expired`)}if(!r.ok){let e=r.statusText,t=null;try{if(t=await r.json(),t&&typeof t==`object`){let n=t;e=n.detail||n.error||e}}catch{e=r.statusText}throw new ln(typeof e==`string`?e:JSON.stringify(e),r.status,t)}return r.json()}function pn(e,t,n){if(e===`gigs`){let e=t;if(n===`title`)return e.title||``;if(n===`status`)return e.status||``;if(n===`applications`)return Number(e.application_count||0);if(n===`activity`)return En(e)}if(e===`projects`){let e=t;if(n===`display_name`)return e.display_name||``;if(n===`customer`)return e.customer||``;if(n===`status`)return e.source_status||``;if(n===`roster_count`)return Number(e.roster_count||0);if(n===`modified`)return e.source_modified_at||e.last_synced_at||``}if(e===`onboarding`){let e=t,r=e.profile_status||{};if(n===`name`)return e.name||e.email_508||e.email||``;if(n===`onboarding_state`){let t=Yt(e);return t.toLowerCase()===`pending`?`zzz-${t}`:t}if(n===`onboarder`)return e.onboarder||``;if(n===`updated`)return e.onboarding_updated_at||``;if(n===`profile_gaps`)return[!r.discord_linked,!r.latest_resume,Number(r.skills_count||0)<=0].filter(Boolean).length}if(e===`people`){let e=t,r=e.profile_status||{};if(n===`name`)return e.name||e.email_508||e.email||``;if(n===`status`)return[r.crm_active,r.is_member,r.discord_linked,r.email_508,r.latest_resume].filter(Boolean).length;if(n===`discord`)return e.discord_username||e.discord_user_id||``;if(n===`resume`)return e.latest_resume_name||e.latest_resume_id||``}if(e===`audit`){let e=t;if(n===`actor`)return e.actor_display_name||e.actor_subject||e.actor_provider||``}return t[n]??``}function mn(e,t,n){let r=n.direction===`asc`?1:-1;return[...t].sort((t,i)=>{let a=pn(e,t,n.key),o=pn(e,i,n.key);return typeof a==`number`&&typeof o==`number`?(a-o)*r:String(a).localeCompare(String(o),void 0,{numeric:!0})*r})}function hn({label:e,scope:t,sort:n,sortKey:r,onSort:i}){let a=n.key===r,o=n.direction===`asc`?`↑`:`↓`;return(0,F.jsx)(`button`,{type:`button`,"data-sort-scope":t,"data-sort-key":r,className:`text-left font-[inherit] text-inherit hover:text-foreground`,onClick:()=>i(t,r),children:a?`${e} ${o}`:e})}function H({className:e,label:t,scope:n,sort:r,sortKey:i,onSort:a}){return(0,F.jsx)(z,{className:e,"aria-sort":r.key===i?r.direction===`asc`?`ascending`:`descending`:`none`,children:(0,F.jsx)(hn,{label:t,scope:n,sort:r,sortKey:i,onSort:a})})}function gn({label:e,value:t,id:n}){return(0,F.jsxs)(R,{className:`p-4`,children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:e}),(0,F.jsx)(`strong`,{id:n,className:`block text-2xl`,children:t})]})}function _n({children:e,hidden:t}){return t?null:(0,F.jsx)(`div`,{className:`px-4 py-7 text-center text-sm text-muted-foreground`,children:e})}function vn(){let e=fn(`projects`),[t,n]=(0,l.useState)(null),[r,i]=(0,l.useState)(dn()),[a,o]=(0,l.useState)({message:``}),[s,c]=(0,l.useState)([]),[u,d]=(0,l.useState)(``),[f,p]=(0,l.useState)([]),[m,v]=(0,l.useState)([]),[ee,te]=(0,l.useState)([]),[re,ie]=(0,l.useState)({}),[ae,oe]=(0,l.useState)(null),[se,ce]=(0,l.useState)(null),[C,le]=(0,l.useState)(fn()),[ue,de]=(0,l.useState)(e),[w,T]=(0,l.useState)([]),[fe,pe]=(0,l.useState)(!1),[me,E]=(0,l.useState)([]),[D,O]=(0,l.useState)([]),[he,ge]=(0,l.useState)([]),[_e,ve]=(0,l.useState)(null),[ye,be]=(0,l.useState)(null),[xe,Se]=(0,l.useState)({}),[Ce,we]=(0,l.useState)(null),[k,Te]=(0,l.useState)({onboarding:{key:`onboarding_state`,direction:`asc`},gigs:{key:`activity`,direction:`desc`},projects:{key:`display_name`,direction:`asc`},jobs:{key:`updated_at`,direction:`desc`},people:{key:`name`,direction:`asc`},agent:{key:`occurred_at`,direction:`desc`},audit:{key:`occurred_at`,direction:`desc`}}),[Ee,De]=(0,l.useState)(`60`),[Oe,ke]=(0,l.useState)(``),[Ae,je]=(0,l.useState)(``),[Me,Ne]=(0,l.useState)(``),[Pe,Fe]=(0,l.useState)(100),[Ie,Le]=(0,l.useState)(``),[Re,ze]=(0,l.useState)(e?``:`Open`),[Be,Ve]=(0,l.useState)(7),[He,Ue]=(0,l.useState)(``),[We,Ge]=(0,l.useState)(``),[Ke,qe]=(0,l.useState)({}),[Je,Ye]=(0,l.useState)(`discord`),[Xe,A]=(0,l.useState)(`linked`),[Ze,Qe]=(0,l.useState)(``),[$e,et]=(0,l.useState)(``),[tt,nt]=(0,l.useState)(``),[rt,it]=(0,l.useState)({}),[at,ot]=(0,l.useState)(`discord`),[st,j]=(0,l.useState)(`linked`),ct=(0,l.useRef)(()=>void 0);function lt(e){return s.includes(e)}function ut(e){return lt(sn[e])}function dt(){return Object.keys(on).find(e=>ut(e))||`people`}function M(e,t){o({message:e,tone:t})}function N(e,t){Se(n=>({...n,[e]:t}))}function ft(e,t=!1){let n=e;ut(n)||(M(`${n[0].toUpperCase()}${n.slice(1)} requires SSO validation`,`error`),n=dt()),n!==`gigs`&&le(``),n!==`projects`&&de(``),n===`gigs`&&t&&le(``),n===`projects`&&t&&de(``),i(n),t?window.history.pushState({view:n},``,on[n]):(!Object.hasOwn(on,un())||n!==e)&&window.history.replaceState({view:n},``,on[n])}ct.current=ft;function P(e){return!u||!e?``:`${u}/#Contact/view/${encodeURIComponent(e)}`}function pt(e){return!u||!e?``:`${u}/api/v1/Attachment/file/${encodeURIComponent(e)}`}function mt(e,t){Te(n=>{let r=n[e];return{...n,[e]:{key:t,direction:r.key===t&&r.direction===`asc`?`desc`:`asc`}}})}function ht(e){le(e),ce(m.find(t=>t.id===e)||null),i(`gigs`),window.history.pushState({view:`gigs`,gigId:e},``,`/dashboard/gigs/${encodeURIComponent(e)}`)}function gt(){le(``),ce(null),window.history.replaceState({view:`gigs`},``,on.gigs)}function _t(e){de(e),i(`projects`),window.history.pushState({view:`projects`,projectId:e},``,`/dashboard/projects/${encodeURIComponent(e)}`)}function vt(){de(``),window.history.replaceState({view:`projects`},``,on.projects)}async function yt(){let e=await V(`/dashboard/api/me`);n(e);let t=Array.isArray(e.permissions)?e.permissions:[];return c(t),d((e.crm_base_url||``).replace(/\/+$/,``)),t}function bt(){let e=new URLSearchParams({minutes:Ee,limit:`100`});return Oe&&e.set(`status`,Oe),Ae.trim()&&e.set(`type`,Ae.trim()),`/dashboard/api/jobs?${e.toString()}`}function xt(){let e=new URLSearchParams({limit:String(Pe)});return Me&&e.set(`status`,Me),`/dashboard/api/gigs?${e.toString()}`}function St(){let e=new URLSearchParams({limit:`100`,status:Re});return Ie.trim()&&e.set(`query`,Ie.trim()),`/dashboard/api/projects?${e.toString()}`}async function Ct(){N(`jobs`,!0),M(`Loading jobs`);try{let e=await V(bt());p(e),M(`Loaded ${e.length} jobs`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to load jobs`,`error`)}finally{N(`jobs`,!1)}}async function wt(){N(`gigs`,!0);try{let e=await V(xt());v(e),M(`Loaded ${e.length} gig${e.length===1?``:`s`}`,`ok`),R()}catch(e){M(e instanceof Error?e.message:`Unable to load gigs`,`error`)}finally{N(`gigs`,!1)}}async function Tt(){N(`projects`,!0);try{let e=await V(St());te(e.projects||[]),ie(e.summary||{}),M(`Loaded ${(e.projects||[]).length} project${(e.projects||[]).length===1?``:`s`}`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to load projects`,`error`)}finally{N(`projects`,!1)}}async function Et(){N(`syncProjects`,!0),M(`Queueing project sync`);try{M(`Queued project sync ${(await V(`/dashboard/api/sync/projects`,{method:`POST`})).job_id}`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to queue project sync`,`error`)}finally{N(`syncProjects`,!1)}}async function Dt(e,t){N(`project:${e}:status`,!0);try{let n=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t})});te(t=>t.map(t=>t.id===e?n.project:t)),M(`Updated project status`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to update project`,`error`)}finally{N(`project:${e}:status`,!1)}}async function Ot(e,t){if(e.length===0)return!1;N(`projectsBulkUpdate`,!0);try{let n=await V(`/dashboard/api/projects/bulk`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({project_ids:e,...t})}),r=n.projects||[];te(e=>e.map(e=>r.find(t=>t.id===e.id)||e));let i=n.failures||[];return M(i.length?`Updated ${r.length}; ${i.length} failed`:`Updated ${r.length} project${r.length===1?``:`s`}`,i.length?`error`:`ok`),i.length===0}catch(e){return M(e instanceof Error?e.message:`Unable to bulk update projects`,`error`),!1}finally{N(`projectsBulkUpdate`,!1)}}async function kt(e,t){let n=t.trim();if(!n)return!1;N(`project:${e}:user`,!0);try{let t=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/users`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({user:n})});return te(n=>n.map(n=>n.id===e?t.project:n)),M(`Added project user`,`ok`),!0}catch(e){return M(e instanceof Error?e.message:`Unable to add project user`,`error`),!1}finally{N(`project:${e}:user`,!1)}}async function At(e,t,n){let r=t.trim();if(!r)return!1;N(`project:${e}:historical`,!0);try{let t=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/historical-members`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({person:r,candidate_id:n})});return te(n=>n.map(n=>n.id===e?t.project:n)),we(null),M(`Added historical project member`,`ok`),!0}catch(t){if(t instanceof ln&&t.status===409){let n=t.payload?.candidates||[];if(n.length>0)return we({projectId:e,person:r,candidates:n}),M(`Choose the matching person record`,`error`),!1}return M(t instanceof Error?t.message:`Unable to add historical member`,`error`),!1}finally{N(`project:${e}:historical`,!1)}}async function Mt(e,t,n){N(`project:${e}:wiki`,!0);try{await V(`/dashboard/api/projects/${encodeURIComponent(e)}/wiki-match`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t,row_key:n})}),M(t===`no_row`?`Marked as no wiki row`:`Confirmed wiki match`,`ok`),await Nt()}catch(e){M(e instanceof Error?e.message:`Unable to save wiki match`,`error`)}finally{N(`project:${e}:wiki`,!1)}}async function Nt(){N(`wikiMatches`,!0);try{oe(await V(`/dashboard/api/projects/wiki-matches`)),M(`Loaded wiki match preview`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to load wiki matches`,`error`)}finally{N(`wikiMatches`,!1)}}async function I(e){N(`gig:${e}:detail`,!0);try{ce(await V(`/dashboard/api/gigs/${encodeURIComponent(e)}`))}catch(e){ce(null),M(e instanceof Error?e.message:`Unable to load gig`,`error`)}finally{N(`gig:${e}:detail`,!1)}}async function Pt(){await wt(),C&&await I(C)}async function R(){if(lt(`gigs:read`)){N(`notifications`,!0);try{let e=await V(`/dashboard/api/notifications?limit=20`);Ve(e.stale_days||7),T(e.notifications||[])}catch(e){M(e instanceof Error?e.message:`Unable to load notifications`,`error`)}finally{N(`notifications`,!1)}}}async function Ft(e,t){N(`gig:${e}:status`,!0);try{let n=(await V(`/dashboard/api/gigs/${encodeURIComponent(e)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t})})).discord_title_sync?.status;M(n===`error`?`Updated gig status; Discord title sync failed`:`Updated gig status`,n===`error`?`error`:`ok`),await wt(),C===e&&await I(e)}catch(e){M(e instanceof Error?e.message:`Unable to update gig`,`error`)}finally{N(`gig:${e}:status`,!1)}}async function It(e,t,n){N(`application:${t}:status`,!0);try{await V(`/dashboard/api/gigs/${encodeURIComponent(e)}/applications/${encodeURIComponent(t)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:n})}),M(`Updated candidate status`,`ok`),await wt(),C===e&&await I(e)}catch(e){M(e instanceof Error?e.message:`Unable to update candidate`,`error`)}finally{N(`application:${t}:status`,!1)}}function Lt(){let e=new URLSearchParams({limit:`25`});He.trim()&&e.set(`query`,He.trim()),We&&e.set(`is_member`,We);for(let[t,n]of Object.entries(Ke))n&&e.set(t,n);return`/dashboard/api/people?${e.toString()}`}async function Rt(){N(`people`,!0);try{E(await V(Lt()))}catch(e){M(e instanceof Error?e.message:`Unable to load people`,`error`)}finally{N(`people`,!1)}}function zt(){let e=new URLSearchParams({limit:`25`});Ze.trim()&&e.set(`query`,Ze.trim()),$e&&e.set(`onboarding_state`,$e),tt.trim()&&e.set(`onboarder`,tt.trim());for(let[t,n]of Object.entries(rt))n&&e.set(t,n);return`/dashboard/api/onboarding?${e.toString()}`}async function Bt(){N(`onboarding`,!0);try{O(await V(zt()))}catch(e){M(e instanceof Error?e.message:`Unable to load onboarding`,`error`)}finally{N(`onboarding`,!1)}}async function Vt(){N(`audit`,!0);try{ge(await V(`/dashboard/api/audit-events?limit=25`))}catch(e){M(e instanceof Error?e.message:`Unable to load audit events`,`error`)}finally{N(`audit`,!1)}}async function Ht(){N(`agent`,!0);try{ve(await V(`/dashboard/api/agent?limit=100`))}catch(e){M(e instanceof Error?e.message:`Unable to load agent report`,`error`)}finally{N(`agent`,!1)}}async function Ut(e){N(`detail:${e}`,!0),M(`Loading ${e}`);try{be(await V(`/dashboard/api/jobs/${encodeURIComponent(e)}`)),M(`Loaded ${e}`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to load job detail`,`error`)}finally{N(`detail:${e}`,!1)}}async function Wt(e){N(`rerun:${e}`,!0),M(`Rerunning ${e}`);try{M(`Queued rerun ${(await V(`/dashboard/api/jobs/${encodeURIComponent(e)}/rerun`,{method:`POST`})).job_id}`,`ok`),await Ct()}catch(e){M(e instanceof Error?e.message:`Unable to rerun job`,`error`)}finally{N(`rerun:${e}`,!1)}}async function z(){N(`syncPeople`,!0),M(`Queueing people sync`);try{M(`Queued people sync ${(await V(`/dashboard/api/sync/people`,{method:`POST`})).job_id}`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to queue people sync`,`error`)}finally{N(`syncPeople`,!1)}}async function B(e,t){let n=String(e||``).trim(),r=t.trim();if(!n){M(`Missing CRM contact id`,`error`);return}if(!r){M(`Enter a 508 username`,`error`);return}N(`onboarder:${n}`,!0),M(`Assigning ${r}`);try{let e=await V(`/dashboard/api/onboarding/${encodeURIComponent(n)}/onboarder`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({onboarder:r})});O(t=>t.map(t=>t.crm_contact_id===e.contact_id?{...t,onboarder:e.onboarder,onboarding_state:e.state_updated&&e.onboarding_state?e.onboarding_state:t.onboarding_state,onboarding_status_label:e.onboarding_status_label||(e.state_updated?void 0:t.onboarding_status_label)}:t)),M(`Assigned ${e.onboarder}`,`ok`)}catch(e){M(e instanceof Error?e.message:`Unable to assign onboarder`,`error`)}finally{N(`onboarder:${n}`,!1)}}async function Gt(){N(`logout`,!0);try{let e=await V(`/auth/logout`,{method:`POST`});window.location.assign(e.end_session_url||`/dashboard`)}catch(e){M(e instanceof Error?e.message:`Unable to log out`,`error`),N(`logout`,!1)}}(0,l.useEffect)(()=>{yt().then(e=>{let t=dn(),n=e.includes(sn[t])?t:Object.keys(on).find(t=>e.includes(sn[t]))||`people`;le(n===`gigs`?fn():``),de(n===`projects`?fn(`projects`):``),i(n),(!Object.hasOwn(on,un())||n!==t)&&window.history.replaceState({view:n},``,on[n])}).catch(e=>{M(e instanceof Error?e.message:`Dashboard failed to load`,`error`)})},[]),(0,l.useEffect)(()=>{let e=()=>{le(fn()),de(fn(`projects`)),ct.current(dn(),!1)};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]),(0,l.useEffect)(()=>{if(!a.message)return;let e=window.setTimeout(()=>o({message:``}),4500);return()=>window.clearTimeout(e)},[a.message]),(0,l.useEffect)(()=>{s.length!==0&&(lt(`gigs:read`)&&R(),r===`people`&&Rt(),r===`gigs`&&wt(),r===`projects`&&Tt(),r===`onboarding`&&Bt(),r===`jobs`&&Ct(),r===`agent`&&Ht(),r===`audit`&&Vt())},[r]),(0,l.useEffect)(()=>{s.length!==0&&(lt(`gigs:read`)&&R(),r===`people`&&Rt(),r===`gigs`&&wt(),r===`projects`&&Tt(),r===`onboarding`&&Bt(),r===`jobs`&&Ct(),r===`agent`&&Ht(),r===`audit`&&Vt())},[s]),(0,l.useEffect)(()=>{r===`jobs`&&s.length>0&&Ct()},[Ee,Oe]),(0,l.useEffect)(()=>{r===`gigs`&&s.length>0&&wt()},[Me,Pe]),(0,l.useEffect)(()=>{r===`projects`&&s.length>0&&Tt()},[Re]),(0,l.useEffect)(()=>{r===`gigs`&&C&&s.length>0&&I(C)},[r,C,s]),(0,l.useEffect)(()=>{r===`people`&&s.length>0&&Rt()},[We]),(0,l.useEffect)(()=>{r===`people`&&s.length>0&&Rt()},[Ke]),(0,l.useEffect)(()=>{r===`onboarding`&&s.length>0&&Bt()},[$e]),(0,l.useEffect)(()=>{r===`onboarding`&&s.length>0&&Bt()},[rt]);let Kt=(0,l.useMemo)(()=>mn(`jobs`,f,k.jobs),[f,k.jobs]),qt=(0,l.useMemo)(()=>mn(`people`,me,k.people),[me,k.people]),Jt=(0,l.useMemo)(()=>mn(`onboarding`,D,k.onboarding),[D,k.onboarding]),Yt=(0,l.useMemo)(()=>mn(`gigs`,m,k.gigs),[m,k.gigs]),Xt=(0,l.useMemo)(()=>mn(`projects`,ee,k.projects),[ee,k.projects]),Zt=(0,l.useMemo)(()=>se?.id===C?se:Yt.find(e=>e.id===C)||null,[se,C,Yt]),Qt=(0,l.useMemo)(()=>Xt.find(e=>e.id===ue)||null,[ue,Xt]),$t=(0,l.useMemo)(()=>mn(`audit`,he,k.audit),[he,k.audit]),en=(0,l.useMemo)(()=>f.reduce((e,t)=>(e[t.status]=(e[t.status]||0)+1,e),{}),[f]),tn=Object.keys(cn).filter(e=>!Ke[e]),nn=Object.keys(cn).filter(e=>e!==`sync_status`&&e!==`email_508`&&!rt[e]);function rn(e){e.type===`stale_recruiting_gig`&&(Ne(`recruiting`),ft(`gigs`,!0)),pe(!1)}(0,l.useEffect)(()=>{!tn.includes(Je)&&tn[0]&&Ye(tn[0])},[tn,Je]),(0,l.useEffect)(()=>{let e=cn[Je]?.options;e?.[0]&&!e.some(([e])=>e===Xe)&&A(e[0][0])},[Je,Xe]),(0,l.useEffect)(()=>{!nn.includes(at)&&nn[0]&&ot(nn[0])},[nn,at]),(0,l.useEffect)(()=>{let e=cn[at]?.options;e?.[0]&&!e.some(([e])=>e===st)&&j(e[0][0])},[at,st]);let an=[t?.email,t?.crm_contact_id?`CRM ${t.crm_contact_id}`:``,t?.actor_provider].filter(Boolean).join(` | `);return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsx)(`header`,{className:`sticky top-0 z-20 border-b bg-background/90 backdrop-blur`,children:(0,F.jsxs)(`div`,{className:`mx-auto flex max-w-7xl flex-col gap-4 px-5 py-4 md:flex-row md:items-center md:justify-between`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h1`,{className:`text-xl font-bold`,children:`508 Operations Dashboard`}),(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Operations view for authenticated 508 operators.`})]}),(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[lt(`gigs:read`)?(0,F.jsx)(`div`,{className:`relative`,children:(0,F.jsxs)(L,{id:`notifications`,type:`button`,variant:`outline`,size:`icon`,"aria-label":`Notifications`,"aria-expanded":fe,onClick:()=>pe(e=>!e),children:[(0,F.jsx)(h,{}),w.length>0?(0,F.jsx)(`span`,{className:`absolute -right-1 -top-1 grid min-h-5 min-w-5 place-items-center rounded-full bg-red-500 px-1 text-[11px] font-bold text-white`,children:w.length}):null]})}):null,(0,F.jsxs)(`div`,{className:`grid min-w-0 gap-0.5 text-right text-sm text-muted-foreground`,children:[(0,F.jsx)(`strong`,{id:`userName`,className:`truncate text-foreground`,children:t?.display_name||t?.email||t?.subject||`Loading user`}),(0,F.jsx)(`span`,{id:`userMeta`,className:`truncate`,children:an||`Checking session`})]}),(0,F.jsxs)(L,{id:`logout`,type:`button`,variant:`outline`,onClick:Gt,disabled:xe.logout,children:[(0,F.jsx)(x,{}),`Log out`]})]})]})}),(0,F.jsx)(yn,{open:fe,notifications:w,loading:xe.notifications,onClose:()=>pe(!1),onRefresh:R,onOpenNotification:rn}),(0,F.jsx)(xn,{toast:a}),(0,F.jsx)(bn,{choice:Ce,loading:!!(Ce&&xe[`project:${Ce.projectId}:historical`]),crmContactUrl:P,onClose:()=>we(null),onChoose:e=>{Ce&&At(Ce.projectId,Ce.person,e)}}),(0,F.jsxs)(`main`,{className:`mx-auto grid max-w-7xl grid-cols-1 gap-5 px-5 py-5 md:grid-cols-[190px_minmax(0,1fr)]`,children:[(0,F.jsx)(`nav`,{className:`grid content-start gap-1 md:sticky md:top-24`,"aria-label":`Dashboard sections`,children:[[`people`,`People`,ne],[`gigs`,`Gigs`,g],[`projects`,`Projects`,b],[`onboarding`,`Onboarding`,_],[`jobs`,`Jobs`,g],[`agent`,`Agent`,S],[`audit`,`Audit`,y]].filter(([e])=>ut(e)).map(([e,t,n])=>(0,F.jsxs)(`a`,{className:jt(`flex min-h-10 items-center gap-2 rounded-md border border-transparent px-3 text-sm font-extrabold text-muted-foreground hover:border-border hover:bg-secondary hover:text-foreground`,r===e&&`border-primary bg-accent text-accent-foreground`),"data-view-link":e,"data-permission":sn[e],href:on[e],"aria-current":r===e?`page`:void 0,onClick:t=>{t.preventDefault(),ft(e,!0)},children:[(0,F.jsx)(n,{className:`size-4`}),t]},e))}),(0,F.jsxs)(`div`,{className:`grid min-w-0 gap-5`,children:[r===`people`?(0,F.jsx)(Rn,{crmBaseUrl:u,people:qt,sort:k.people,canSync:lt(`people:sync`),loading:xe,peopleQuery:He,peopleMember:We,peopleFilters:Ke,peopleFilterKind:Je,peopleFilterValue:Xe,peopleFilterKeys:tn,onSearch:Rt,onSync:z,onSort:e=>mt(`people`,e),setPeopleQuery:Ue,setPeopleMember:Ge,setPeopleFilterKind:Ye,setPeopleFilterValue:A,addFilter:()=>{qe(e=>({...e,[Je]:Xe}))},removeFilter:e=>{qe(t=>{let n={...t};return delete n[e],n})},crmContactUrl:P,crmAttachmentUrl:pt}):null,r===`gigs`?(0,F.jsx)(Nn,{gigs:Yt,selectedGig:Zt,selectedGigId:C,sort:k.gigs,loading:xe,status:Me,limit:Pe,staleDays:Be,canWrite:lt(`gigs:write`),crmContactUrl:P,crmAttachmentUrl:pt,setStatus:Ne,setLimit:Fe,onRefresh:Pt,onSort:e=>mt(`gigs`,e),onOpenGig:ht,onCloseGig:gt,onUpdateStatus:Ft,onUpdateApplicationStatus:It}):null,r===`projects`?(0,F.jsx)(jn,{projects:Xt,selectedProject:Qt,selectedProjectId:ue,summary:re,wikiMatches:ae,sort:k.projects,loading:xe,query:Ie,status:Re,canSync:lt(`projects:sync`),canWrite:lt(`projects:write`),crmContactUrl:P,setQuery:Le,setStatus:ze,onSearch:Tt,onSync:Et,onUpdateStatus:Dt,onBulkUpdate:Ot,onAddUser:kt,onAddHistoricalMember:At,onUpdateWikiMatch:Mt,onWikiMatches:Nt,onOpenProject:_t,onCloseProject:vt,onSort:e=>mt(`projects`,e)}):null,r===`onboarding`?(0,F.jsx)(zn,{people:Jt,sort:k.onboarding,loading:xe,onboardingQuery:Ze,onboardingState:$e,onboarderFilter:tt,onboardingFilters:rt,onboardingFilterKind:at,onboardingFilterValue:st,onboardingFilterKeys:nn,onSearch:Bt,onSort:e=>mt(`onboarding`,e),onAssign:B,setOnboardingQuery:Qe,setOnboardingState:et,setOnboarderFilter:nt,setOnboardingFilterKind:ot,setOnboardingFilterValue:j,addFilter:()=>{it(e=>({...e,[at]:st}))},removeFilter:e=>{it(t=>{let n={...t};return delete n[e],n})},crmContactUrl:P,crmAttachmentUrl:pt}):null,r===`jobs`?(0,F.jsx)(Vn,{jobs:Kt,jobDetail:ye,sort:k.jobs,loading:xe,minutes:Ee,status:Oe,jobType:Ae,jobCounts:en,canWrite:lt(`jobs:write`),setMinutes:De,setStatus:ke,setJobType:je,onSearch:Ct,onSort:e=>mt(`jobs`,e),onDetail:Ut,onRerun:Wt}):null,r===`audit`?(0,F.jsx)(Hn,{events:$t,sort:k.audit,loading:xe,onRefresh:Vt,onSort:e=>mt(`audit`,e)}):null,r===`agent`?(0,F.jsx)(Un,{report:_e,loading:xe,onRefresh:Ht}):null]})]})]})}function yn({open:e,notifications:t,loading:n,onClose:r,onRefresh:i,onOpenNotification:a}){return e?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-40`,"aria-labelledby":`notificationsTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close notifications`,onClick:r}),(0,F.jsxs)(`aside`,{className:`absolute right-0 top-0 grid h-full w-full max-w-md grid-rows-[auto_minmax(0,1fr)] border-l bg-background shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-3 border-b p-4`,children:[(0,F.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,F.jsx)(`strong`,{id:`notificationsTitle`,className:`text-base`,children:`Notifications`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:t.length===0?`No active notifications`:`${t.length} active`})]}),(0,F.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`outline`,size:`sm`,onClick:i,disabled:n,children:[(0,F.jsx)(ee,{}),`Refresh`]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close`,onClick:r,children:(0,F.jsx)(re,{})})]})]}),(0,F.jsx)(`div`,{className:`min-h-0 overflow-auto p-4`,children:t.length===0?(0,F.jsx)(`div`,{className:`rounded-md border border-dashed p-6 text-sm text-muted-foreground`,children:`No active notifications.`}):(0,F.jsx)(`div`,{className:`grid gap-3`,children:t.map(e=>(0,F.jsxs)(`button`,{type:`button`,className:`grid gap-2 rounded-md border p-3 text-left hover:bg-secondary`,onClick:()=>a(e),children:[(0,F.jsx)(`span`,{className:`text-sm font-bold`,children:e.title}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.message})]},e.id))})})]})]}):null}function bn({choice:e,loading:t,crmContactUrl:n,onClose:r,onChoose:i}){return e?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-50 grid place-items-center p-4`,"aria-labelledby":`historicalPersonChoiceTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close person selection`,onClick:r}),(0,F.jsxs)(`div`,{className:`relative grid w-full max-w-2xl gap-4 rounded-md border bg-background p-5 shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`strong`,{id:`historicalPersonChoiceTitle`,className:`block text-base`,children:`Choose person record`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.person})]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close person selection`,onClick:r,children:(0,F.jsx)(re,{})})]}),(0,F.jsx)(`div`,{className:`grid gap-2`,children:e.candidates.map(e=>(0,F.jsxs)(`div`,{className:`grid gap-3 rounded-md border p-3 md:grid-cols-[minmax(0,1fr)_auto] md:items-center`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block truncate`,children:e.label||e.full_name||e.email||`Person`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1 text-sm text-muted-foreground`,children:[e.email?(0,F.jsx)(`span`,{children:e.email}):null,e.sources?.length?(0,F.jsx)(`span`,{children:e.sources.join(`, `)}):null,e.erpnext_user_id?(0,F.jsxs)(`span`,{children:[`ERP `,e.erpnext_user_id]}):null,e.supplier_erpnext_id?(0,F.jsxs)(`span`,{children:[`Supplier `,e.supplier_erpnext_id]}):null,e.crm_contact_id&&n(e.crm_contact_id)?(0,F.jsx)(`a`,{className:`font-semibold text-primary underline-offset-4 hover:underline`,href:n(e.crm_contact_id),target:`_blank`,rel:`noreferrer`,children:`CRM`}):null]})]}),(0,F.jsx)(L,{type:`button`,disabled:t,onClick:()=>i(e.candidate_id),children:`Select`})]},e.candidate_id))})]})]}):null}function xn({toast:e}){return e.message?(0,F.jsx)(`div`,{id:`toast`,role:`status`,className:jt(`fixed bottom-5 right-5 z-50 max-w-sm rounded-md border bg-background px-4 py-3 text-sm font-semibold shadow-lg`,e.tone===`ok`&&`border-emerald-500/40 text-emerald-300`,e.tone===`error`&&`border-red-500/40 text-red-300`),children:e.message}):null}function Sn({filters:e,onRemove:t,suffix:n=`filter`}){return(0,F.jsx)(`fieldset`,{className:`m-0 flex min-h-7 flex-wrap gap-2 border-0 p-0`,"aria-label":`Active filters`,children:Object.entries(e).map(([e,r])=>{let i=cn[e],a=i.options.find(([e])=>e===r),o=`${i.label}: ${a?a[1]:r}`;return(0,F.jsxs)(L,{type:`button`,variant:`outline`,size:`sm`,className:`rounded-full`,"aria-label":`Remove ${o} ${n}`,onClick:()=>t(e),children:[o,` x`]},e)})})}var Cn=[`recruiting`,`filled`,`unknown`,`lost`,`outdated`],wn=[`suggested`,`interested`,`reviewing`,`contacted`,`accepted`,`rejected`,`withdrawn`];function Tn(e){return String(e||``).replace(/[-_]+/g,` `).replace(/\s+/g,` `).trim().replace(/\b\w/g,e=>e.toUpperCase())}function En(e){let t=[e.last_activity_at,e.last_status_changed_at,e.posted_at,e.created_at].map(e=>e?new Date(e).getTime():NaN).filter(e=>!Number.isNaN(e));return t.length>0?new Date(Math.max(...t)).toISOString():``}function Dn(e,t){if(e.status!==`recruiting`)return null;let n=qt(En(e));return n===null||ne.projects.map(e=>e.id),[e.projects]),f=(0,l.useMemo)(()=>new Set(d),[d]),p=n.filter(e=>f.has(e)),h=e.projects.length>0&&p.length===e.projects.length;(0,l.useEffect)(()=>{r(e=>e.filter(e=>f.has(e)))},[f]);function g(e,t){r(n=>t?Array.from(new Set([...n,e])):n.filter(t=>t!==e))}async function _(){let t={};i&&(t.status=i),o&&(t.project_type=o),await e.onBulkUpdate(p,t)&&(r([]),a(``),s(``),u(!1))}let y=(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-[minmax(0,1fr)_180px_auto_auto_auto] md:items-end`,children:[(0,F.jsxs)(zt,{children:[`Search projects`,(0,F.jsx)(Rt,{id:`projectQuery`,value:e.query,autoComplete:`off`,placeholder:`Project, customer, ERP id`,onChange:t=>e.setQuery(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(zt,{children:[`Status`,(0,F.jsxs)(Bt,{id:`projectStatus`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:``,children:`Any status`})]})]}),(0,F.jsxs)(L,{id:`refreshProjects`,type:`button`,onClick:e.onSearch,disabled:e.loading.projects,children:[(0,F.jsx)(ee,{}),`Refresh`]}),e.canSync?(0,F.jsxs)(L,{id:`syncProjects`,type:`button`,variant:`outline`,onClick:e.onSync,disabled:e.loading.syncProjects,children:[(0,F.jsx)(ee,{}),`Sync ERP`]}):null,(0,F.jsxs)(L,{id:`wikiProjectMatches`,type:`button`,variant:`outline`,onClick:e.onWikiMatches,disabled:e.loading.wikiMatches,children:[(0,F.jsx)(te,{}),`Wiki match`]})]});return e.selectedProjectId&&!e.selectedProject&&e.loading.projects?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsx)(It,{children:`Project detail`})}),(0,F.jsx)(Lt,{className:`text-sm text-muted-foreground`,children:`Loading project.`})]})]}):e.selectedProjectId&&!e.selectedProject?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsx)(It,{children:`Project detail`})}),(0,F.jsxs)(Lt,{className:`grid gap-3`,children:[(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`This project is not in the current result set. Clear filters or refresh the project list.`}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onCloseProject,children:[(0,F.jsx)(m,{}),`Back to projects`]})]})]})]}):e.selectedProject?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsx)(Mn,{project:e.selectedProject,loading:e.loading,canWrite:e.canWrite,crmContactUrl:e.crmContactUrl,onBack:e.onCloseProject,onUpdateStatus:e.onUpdateStatus,onAddUser:e.onAddUser,onAddHistoricalMember:e.onAddHistoricalMember})]}):(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-2`,"aria-label":`Project summary`,children:[(0,F.jsx)(gn,{id:`projectMetricOpen`,label:`Open`,value:e.summary.open_project_count||0}),(0,F.jsx)(gn,{id:`projectMetricTotal`,label:`Projects`,value:e.summary.project_count||0})]}),e.canWrite?(0,F.jsxs)(R,{className:`flex flex-wrap items-center justify-between gap-3 p-4`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Selected`}),(0,F.jsxs)(`strong`,{className:`block`,children:[p.length,` project(s)`]})]}),(0,F.jsx)(L,{type:`button`,disabled:p.length===0,onClick:()=>u(!0),children:`Bulk edit`})]}):null,c?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-50 grid place-items-center p-4`,"aria-labelledby":`bulkProjectEditTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close bulk project edit`,onClick:()=>u(!1)}),(0,F.jsxs)(`div`,{className:`relative grid w-full max-w-lg gap-4 rounded-md border bg-background p-5 shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`strong`,{id:`bulkProjectEditTitle`,className:`block text-base`,children:`Bulk edit projects`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[p.length,` selected`]})]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close bulk project edit`,onClick:()=>u(!1),children:(0,F.jsx)(re,{})})]}),(0,F.jsxs)(`div`,{className:`grid gap-3`,children:[(0,F.jsx)(`strong`,{className:`text-sm`,children:`Changes`}),(0,F.jsxs)(zt,{children:[`Status`,(0,F.jsxs)(Bt,{value:i,onChange:e=>a(e.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`No change`}),(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:`Completed`,children:`Completed`}),(0,F.jsx)(`option`,{value:`Cancelled`,children:`Cancelled`})]})]}),(0,F.jsxs)(zt,{children:[`ERP Type`,(0,F.jsxs)(Bt,{value:o,onChange:e=>s(e.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`No change`}),(0,F.jsx)(`option`,{value:`Internal`,children:`Internal`}),(0,F.jsx)(`option`,{value:`External`,children:`External`})]})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,F.jsx)(L,{type:`button`,variant:`outline`,onClick:()=>u(!1),children:`Cancel`}),(0,F.jsx)(L,{type:`button`,disabled:e.loading.projectsBulkUpdate||p.length===0||!i&&!o,onClick:()=>void _(),children:`Apply changes`})]})]})]}):null,(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`ERP projects`}),(0,F.jsx)(`span`,{id:`projectsStatus`,className:`text-sm text-muted-foreground`,children:e.loading.projects?`Loading`:`${e.projects.length} shown | synced ${Kt(e.summary.last_synced_at)}`})]}),(0,F.jsx)(_n,{hidden:e.projects.length!==0,children:`No projects match this view. Sync ERP projects if the cache is empty.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`projectsTable`,className:jt(`min-w-[1100px]`,e.projects.length===0&&`hidden`),"aria-label":`ERP projects`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[e.canWrite?(0,F.jsx)(z,{className:`w-[48px]`,children:(0,F.jsx)(`input`,{type:`checkbox`,"aria-label":`Select all visible projects`,checked:h,onChange:e=>{r(e.target.checked?d:[])}})}):null,(0,F.jsx)(H,{className:`w-[24%]`,label:`Project`,scope:`projects`,sort:e.sort,sortKey:`display_name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[16%]`,label:`Customer`,scope:`projects`,sort:e.sort,sortKey:`customer`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[10%]`,label:`Status`,scope:`projects`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(z,{className:`w-[16%]`,children:`Timeline`}),(0,F.jsx)(H,{className:`w-[10%]`,label:`Roster`,scope:`projects`,sort:e.sort,sortKey:`roster_count`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[14%]`,label:`Modified`,scope:`projects`,sort:e.sort,sortKey:`modified`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(z,{children:`ERP`})]})}),(0,F.jsx)(Ut,{id:`projectsBody`,children:e.projects.map(t=>{let n=t.roster_members||[];return(0,F.jsxs)(Wt,{children:[e.canWrite?(0,F.jsx)(B,{children:(0,F.jsx)(`input`,{type:`checkbox`,"aria-label":`Select ${t.display_name}`,checked:p.includes(t.id),onChange:e=>g(t.id,e.target.checked)})}):null,(0,F.jsxs)(B,{children:[(0,F.jsx)(`button`,{type:`button`,className:`text-left font-bold text-primary underline-offset-4 hover:underline`,onClick:()=>e.onOpenProject(t.id),children:t.display_name}),(0,F.jsxs)(`div`,{className:`mt-1 flex flex-wrap items-center gap-1.5`,children:[t.project_type?(0,F.jsx)(I,{variant:`neutral`,children:t.project_type}):null,t.linked_engagement_count?(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[t.linked_engagement_count,` linked gig`]}):null]})]}),(0,F.jsx)(B,{children:t.customer_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.customer_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[t.customer,(0,F.jsx)(v,{className:`size-3.5`})]}):t.customer||`None`}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:On(t.source_status),children:t.source_status||`Unknown`})}),(0,F.jsx)(B,{children:[t.actual_start_date,t.actual_end_date].filter(Boolean).map(e=>kn(e)).join(` to `)||`Not set`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`grid gap-1`,children:[(0,F.jsx)(`strong`,{children:n.length}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[n.map(An).slice(0,4).join(`, `)||`No ERP roster`,n.length>4?` +${n.length-4}`:``]})]})}),(0,F.jsx)(B,{children:Kt(t.source_modified_at)}),(0,F.jsx)(B,{className:`text-xs`,children:t.erpnext_project_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-mono font-semibold text-primary underline-offset-4 hover:underline`,href:t.erpnext_project_url,target:`_blank`,rel:`noreferrer`,children:[t.erpnext_project_id,(0,F.jsx)(v,{className:`size-3.5`})]}):(0,F.jsx)(`span`,{className:`font-mono`,children:`Unlinked`})})]},t.id)})})]})})]}),e.wikiMatches?(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Wiki match preview`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[e.wikiMatches.document?.title||`Client & Project Info`,` |`,` `,Kt(e.wikiMatches.document?.updatedAt)]})]}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`wikiMatchesTable`,className:`min-w-[920px]`,"aria-label":`Wiki matches`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(z,{children:`ERP project`}),(0,F.jsx)(z,{children:`Best wiki row`}),(0,F.jsx)(z,{children:`Confidence`}),(0,F.jsx)(z,{children:`Section`}),(0,F.jsx)(z,{children:`Decision`})]})}),(0,F.jsx)(Ut,{children:t.map((t,n)=>{let r=t.project,i=t.best_match?.row||{},a=t.manual_match?.match_status||``,o=r?.id||i.row_key||[i.section,i.Client].filter(Boolean).join(`:`)||`wiki-match-${n}`;return(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:r?.display_name||`Unknown`}),(0,F.jsxs)(B,{children:[(0,F.jsx)(`strong`,{children:i.Client||`No match`}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:[i.DRI,i.Members].filter(Boolean).join(` | `)})]}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:t.best_match?.confidence===`high`?`succeeded`:t.best_match?.confidence===`medium`?`running`:`neutral`,children:t.best_match?`${t.best_match.confidence} ${t.best_match.score}`:`none`})}),(0,F.jsx)(B,{children:i.section||``}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[a?(0,F.jsx)(I,{variant:a===`confirmed`?`succeeded`:`neutral`,children:a===`no_row`?`No wiki row`:`Confirmed`}):null,e.canWrite&&r?.id?(0,F.jsxs)(F.Fragment,{children:[i.row_key?(0,F.jsx)(L,{type:`button`,variant:`outline`,size:`sm`,disabled:e.loading[`project:${r.id}:wiki`],onClick:()=>void e.onUpdateWikiMatch(r.id,`confirmed`,i.row_key),children:`Confirm`}):null,(0,F.jsx)(L,{type:`button`,variant:`outline`,size:`sm`,disabled:e.loading[`project:${r.id}:wiki`],onClick:()=>void e.onUpdateWikiMatch(r.id,`no_row`),children:`No row`})]}):null]})})]},o)})})]})})]}):null]})}function Mn(e){let t=e.project,n=t.roster_members||[],[r,i]=(0,l.useState)(``),a=[t.actual_start_date||t.expected_start_date,t.actual_end_date||t.expected_end_date].filter(Boolean).map(e=>kn(e)).join(` to `)||`Not set`,o=typeof t.percent_complete==`number`?`${Math.round(t.percent_complete)}%`:`Not set`;return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[auto_minmax(0,1fr)_auto] md:items-start`,children:[(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onBack,children:[(0,F.jsx)(m,{}),`Projects`]}),(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(It,{children:t.display_name}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-2 text-sm text-muted-foreground`,children:[(0,F.jsx)(I,{variant:On(t.source_status),children:t.source_status||`Unknown`}),t.erpnext_project_id?(0,F.jsx)(`span`,{className:`font-mono`,children:t.erpnext_project_id}):null,t.last_synced_at?(0,F.jsxs)(`span`,{children:[`Synced `,Kt(t.last_synced_at)]}):null]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-start gap-2 md:justify-end`,children:[e.canWrite?(0,F.jsxs)(Bt,{className:`w-[160px]`,"aria-label":`Status for ${t.display_name}`,value:t.source_status||``,disabled:e.loading[`project:${t.id}:status`],onChange:n=>e.onUpdateStatus(t.id,n.target.value),children:[(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:`Completed`,children:`Completed`}),(0,F.jsx)(`option`,{value:`Cancelled`,children:`Cancelled`})]}):null,t.erpnext_project_url?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:t.erpnext_project_url,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`ERP project`]}):null,t.customer_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:t.customer_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`ERP customer`]}):null]})]})}),(0,F.jsxs)(Lt,{className:`grid gap-4 md:grid-cols-2 lg:grid-cols-4`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Customer`}),(0,F.jsx)(`strong`,{className:`block`,children:t.customer||`None`})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Timeline`}),(0,F.jsx)(`strong`,{className:`block`,children:a})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Progress`}),(0,F.jsx)(`strong`,{className:`block`,children:o})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Linked Gigs`}),(0,F.jsx)(`strong`,{className:`block`,children:t.linked_engagement_count||0})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`ERP Type`}),(0,F.jsx)(`div`,{className:`mt-1`,children:t.project_type?(0,F.jsx)(I,{variant:`neutral`,children:t.project_type}):(0,F.jsx)(`strong`,{className:`block`,children:`Not set`})})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`ERP Modified`}),(0,F.jsx)(`strong`,{className:`block`,children:Kt(t.source_modified_at)})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Cache ID`}),(0,F.jsx)(`strong`,{className:`block break-all font-mono text-xs`,children:t.id})]})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Project roster`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:n.length?`${n.length} synced ERP user${n.length===1?``:`s`}`:`No ERP roster`})]}),e.canWrite?(0,F.jsxs)(Lt,{className:`grid gap-3 border-b md:grid-cols-[minmax(0,1fr)_auto_auto] md:items-end`,children:[(0,F.jsxs)(zt,{children:[`Roster person`,(0,F.jsx)(Rt,{value:r,autoComplete:`off`,placeholder:`name@508.dev or full name`,onChange:e=>i(e.target.value),onKeyDown:n=>{n.key===`Enter`&&(n.preventDefault(),e.onAddUser(t.id,r).then(e=>e&&i(``)))}})]}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,disabled:e.loading[`project:${t.id}:user`]||!r.trim(),onClick:()=>void e.onAddUser(t.id,r).then(e=>{e&&i(``)}),children:[(0,F.jsx)(ne,{}),`Add ERP user`]}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,disabled:e.loading[`project:${t.id}:historical`]||!r.trim(),onClick:()=>void e.onAddHistoricalMember(t.id,r).then(e=>{e&&i(``)}),children:[(0,F.jsx)(ne,{}),`Add historical`]})]}):null,(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{className:`min-w-[760px]`,"aria-label":`Project roster`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(z,{children:`Name`}),(0,F.jsx)(z,{children:`Email`}),(0,F.jsx)(z,{children:`ERP user`}),(0,F.jsx)(z,{children:`Links`}),(0,F.jsx)(z,{children:`Source`}),(0,F.jsx)(z,{children:`Last seen`})]})}),(0,F.jsx)(Ut,{children:n.length?n.map(t=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:(0,F.jsx)(`strong`,{children:t.full_name||t.email||t.source_user_id})}),(0,F.jsx)(B,{children:t.email||`None`}),(0,F.jsx)(B,{className:`font-mono text-xs`,children:t.erpnext_user_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.erpnext_user_url,target:`_blank`,rel:`noreferrer`,children:[t.source_user_id||`ERP user`,(0,F.jsx)(v,{className:`size-3.5`})]}):t.source_user_id||`Unknown`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[t.supplier_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.supplier_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[`Supplier`,(0,F.jsx)(v,{className:`size-3.5`})]}):null,t.crm_contact_id&&e.crmContactUrl(t.crm_contact_id)?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:e.crmContactUrl(t.crm_contact_id),target:`_blank`,rel:`noreferrer`,children:[`CRM`,(0,F.jsx)(v,{className:`size-3.5`})]}):null,!t.supplier_erpnext_url&&!(t.crm_contact_id&&e.crmContactUrl(t.crm_contact_id))?(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`None`}):null]})}),(0,F.jsx)(B,{children:t.roster_kind||t.source||`ERP`}),(0,F.jsx)(B,{children:Kt(t.last_seen_at)})]},`${t.source||``}:${t.source_user_id||t.email}`)):(0,F.jsx)(Wt,{children:(0,F.jsx)(B,{colSpan:6,className:`text-sm text-muted-foreground`,children:`No roster rows have been synced for this project.`})})})]})})]})]})}function Nn(e){let t=e.gigs.reduce((t,n)=>(t.total+=1,t.applications+=Number(n.application_count||0),t.interested+=Number(n.interested_count||0),Dn(n,e.staleDays)!==null&&(t.stale+=1),t),{total:0,applications:0,interested:0,stale:0}),n=(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-[minmax(160px,1fr)_auto_auto] md:items-end`,children:[(0,F.jsxs)(zt,{children:[`Status`,(0,F.jsxs)(Bt,{id:`gigStatus`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any status`}),Cn.map(e=>(0,F.jsx)(`option`,{value:e,children:Tn(e)},e))]})]}),(0,F.jsxs)(L,{id:`refreshGigs`,type:`button`,onClick:e.onRefresh,disabled:e.loading.gigs,children:[(0,F.jsx)(ee,{}),`Refresh gigs`]}),e.gigs.length>=e.limit?(0,F.jsx)(L,{type:`button`,variant:`outline`,onClick:()=>e.setLimit(Math.min(e.limit+100,500)),disabled:e.loading.gigs||e.limit>=500,children:`Load more`}):null]}),r=e.selectedGigId?e.loading[`gig:${e.selectedGigId}:detail`]:!1;return e.selectedGigId&&!e.selectedGig&&(e.loading.gigs||r)?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsx)(It,{children:`Gig detail`})}),(0,F.jsx)(Lt,{className:`text-sm text-muted-foreground`,children:`Loading gig.`})]})]}):e.selectedGigId&&!e.selectedGig?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsx)(It,{children:`Gig detail`})}),(0,F.jsxs)(Lt,{className:`grid gap-3`,children:[(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`This gig is not in the current result set. Clear filters or refresh the gig list.`}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onCloseGig,children:[(0,F.jsx)(m,{}),`Back to gigs`]})]})]})]}):e.selectedGig?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsx)(In,{gig:e.selectedGig,loading:e.loading,canWrite:e.canWrite,crmContactUrl:e.crmContactUrl,crmAttachmentUrl:e.crmAttachmentUrl,staleDays:e.staleDays,onBack:e.onCloseGig,onUpdateStatus:e.onUpdateStatus,onUpdateApplicationStatus:e.onUpdateApplicationStatus})]}):(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-4`,"aria-label":`Gig summary`,children:[(0,F.jsx)(gn,{id:`gigMetricTotal`,label:`Gigs`,value:t.total}),(0,F.jsx)(gn,{id:`gigMetricCandidates`,label:`Candidates`,value:t.applications}),(0,F.jsx)(gn,{id:`gigMetricInterested`,label:`Interested`,value:t.interested}),(0,F.jsx)(gn,{id:`gigMetricStale`,label:`Stale recruiting`,value:t.stale})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Discord gigs`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>e.onSort(`activity`),"aria-label":`Sort gigs by activity`,children:[`Activity`,` `,e.sort.key===`activity`?e.sort.direction===`asc`?`↑`:`↓`:``]}),(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>e.onSort(`title`),"aria-label":`Sort gigs by title`,children:[`Title `,e.sort.key===`title`?e.sort.direction===`asc`?`↑`:`↓`:``]}),(0,F.jsx)(`span`,{id:`gigsStatus`,className:`text-sm text-muted-foreground`,children:e.loading.gigs?`Loading`:`${e.gigs.length} shown`})]})]}),(0,F.jsx)(_n,{hidden:e.gigs.length!==0,children:`No gigs match this view.`}),(0,F.jsx)(`div`,{id:`gigsBody`,className:jt(`grid gap-3 p-4`,e.gigs.length===0&&`hidden`),children:e.gigs.map(t=>(0,F.jsx)(Pn,{gig:t,loading:e.loading,canWrite:e.canWrite,staleDays:e.staleDays,onOpenGig:e.onOpenGig,onUpdateStatus:e.onUpdateStatus},t.id))})]})]})}function Pn({gig:e,loading:t,canWrite:n,onOpenGig:r,onUpdateStatus:i,staleDays:a}){let o=Array.isArray(e.applications)?e.applications:[],s=e.discord_guild_id&&e.discord_thread_id?`https://discord.com/channels/${encodeURIComponent(e.discord_guild_id)}/${encodeURIComponent(e.discord_thread_id)}`:``,c=Dn(e,a);return(0,F.jsxs)(`article`,{className:`grid gap-4 rounded-md border bg-background p-4 lg:grid-cols-[minmax(0,1fr)_220px_180px] lg:items-start`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,F.jsx)(`a`,{className:`text-base font-extrabold text-primary`,href:`/dashboard/gigs/${encodeURIComponent(e.id)}`,onClick:t=>{t.preventDefault(),r(e.id)},children:e.title||`Untitled gig`}),(0,F.jsx)(I,{variant:e.status===`filled`?`succeeded`:e.status===`lost`?`failed`:`queued`,children:e.status_label||Tn(e.status)}),c===null?null:(0,F.jsxs)(I,{variant:`running`,children:[c,`d stale`]})]}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[e.posting_type?(0,F.jsx)(I,{variant:`neutral`,children:Tn(e.posting_type)}):null,e.discord_channel_name?(0,F.jsxs)(I,{variant:`neutral`,children:[`#`,e.discord_channel_name]}):null,(e.required_skills||[]).slice(0,5).map(e=>(0,F.jsx)(I,{variant:`queued`,children:e},e)),(e.preferred_skills||[]).slice(0,3).map(e=>(0,F.jsx)(I,{variant:`neutral`,children:e},e))]}),(0,F.jsxs)(`div`,{className:`mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground`,children:[(0,F.jsxs)(`span`,{children:[`Activity `,Kt(En(e))||`unknown`]}),(0,F.jsxs)(`span`,{children:[`Posted `,Kt(e.posted_at)||`unknown`]}),s?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:s,target:`_blank`,rel:`noreferrer`,children:`Open Discord thread`}):null]})]}),(0,F.jsxs)(`div`,{className:`grid grid-cols-2 gap-2 text-sm lg:grid-cols-1`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`block text-xs font-bold text-muted-foreground`,children:`People`}),(0,F.jsx)(`strong`,{children:e.application_count||o.length}),(0,F.jsxs)(`span`,{className:`ml-2 text-muted-foreground`,children:[Number(e.interested_count||0),` interested`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`block text-xs font-bold text-muted-foreground`,children:`Top candidates`}),(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:o.slice(0,3).map(e=>Fn(e)).join(`, `)||`None yet`})]})]}),(0,F.jsxs)(`div`,{className:`grid gap-2`,children:[n?(0,F.jsx)(Bt,{"aria-label":`Status for ${e.title||`gig`}`,value:e.status,disabled:t[`gig:${e.id}:status`],onChange:t=>i(e.id,t.target.value),children:Cn.map(e=>(0,F.jsx)(`option`,{value:e,children:Tn(e)},e))}):null,(0,F.jsx)(L,{type:`button`,onClick:()=>r(e.id),children:`Manage people`})]})]})}function Fn(e){return e.name||e.email_508||e.discord_username||(typeof e.evaluation?.discord_username==`string`?e.evaluation.discord_username:``)||`Candidate`}function In({gig:e,loading:t,canWrite:n,crmContactUrl:r,crmAttachmentUrl:i,staleDays:a,onBack:o,onUpdateStatus:s,onUpdateApplicationStatus:c}){let l=Array.isArray(e.applications)?e.applications:[],u=e.discord_guild_id&&e.discord_thread_id?`https://discord.com/channels/${encodeURIComponent(e.discord_guild_id)}/${encodeURIComponent(e.discord_thread_id)}`:``,d=Dn(e,a);return(0,F.jsxs)(`div`,{className:`grid gap-5`,children:[(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{className:`items-start`,children:[(0,F.jsxs)(`div`,{className:`grid gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,className:`w-fit`,onClick:o,children:[(0,F.jsx)(m,{}),`Back to gigs`]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(It,{className:`text-xl`,children:e.title||`Untitled gig`}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[(0,F.jsx)(I,{variant:e.status===`filled`?`succeeded`:e.status===`lost`?`failed`:`queued`,children:e.status_label||Tn(e.status)}),d===null?null:(0,F.jsxs)(I,{variant:`running`,children:[d,`d stale`]}),e.posting_type?(0,F.jsx)(I,{variant:`neutral`,children:Tn(e.posting_type)}):null,e.discord_channel_name?(0,F.jsxs)(I,{variant:`neutral`,children:[`#`,e.discord_channel_name]}):null,(e.required_skills||[]).map(e=>(0,F.jsx)(I,{variant:`queued`,children:e},e)),(e.preferred_skills||[]).map(e=>(0,F.jsx)(I,{variant:`neutral`,children:e},e))]})]})]}),(0,F.jsxs)(`div`,{className:`grid min-w-[190px] gap-2`,children:[n?(0,F.jsxs)(zt,{children:[`Gig status`,(0,F.jsx)(Bt,{"aria-label":`Status for ${e.title||`gig`}`,value:e.status,disabled:t[`gig:${e.id}:status`],onChange:t=>s(e.id,t.target.value),children:Cn.map(e=>(0,F.jsx)(`option`,{value:e,children:Tn(e)},e))})]}):null,u?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:u,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`Discord thread`]}):null]})]}),(0,F.jsxs)(Lt,{className:`grid gap-4 lg:grid-cols-[1fr_1fr_1fr]`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Activity`}),(0,F.jsx)(`strong`,{className:`block`,children:Kt(En(e))||`unknown`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[`Posted `,Kt(e.posted_at)||`unknown`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`People`}),(0,F.jsx)(`strong`,{className:`block`,children:e.application_count||l.length}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[Number(e.interested_count||0),` interested`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Discord`}),(0,F.jsx)(`strong`,{className:`block`,children:e.discord_channel_name||`No channel`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.discord_thread_id?`Thread ${e.discord_thread_id}`:`No thread`})]})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`People`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[l.length,` candidate`,l.length===1?``:`s`]})]}),(0,F.jsx)(_n,{hidden:l.length!==0,children:`No suggested or interested people yet.`}),(0,F.jsx)(`div`,{className:jt(`grid gap-3 p-4`,l.length===0&&`hidden`),children:l.map(a=>(0,F.jsx)(Ln,{gigId:e.id,application:a,loading:t,canWrite:n,crmContactUrl:r,crmAttachmentUrl:i,onUpdateApplicationStatus:c},a.id))})]})]})}function Ln({gigId:e,application:t,loading:n,canWrite:r,crmContactUrl:i,crmAttachmentUrl:a,onUpdateApplicationStatus:o}){let s=Fn(t),c=i(t.crm_contact_id),l=a(t.latest_resume_id),u=typeof t.fit_score==`number`?`${Math.round(t.fit_score)}/100`:typeof t.match_score==`number`?t.match_score.toFixed(1):``,d=typeof t.evaluation?.llm_summary==`string`?t.evaluation.llm_summary:``;return(0,F.jsxs)(`div`,{className:`grid gap-2 rounded-md border bg-background p-2`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[c?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:c,target:`_blank`,rel:`noopener noreferrer`,children:s}):(0,F.jsx)(`strong`,{children:s}),(0,F.jsx)(I,{variant:t.status===`interested`?`succeeded`:`neutral`,children:Tn(t.status)}),(0,F.jsx)(I,{variant:`neutral`,children:Tn(t.source||`manual_add`)}),u?(0,F.jsxs)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:[`Fit `,u]}):null,c?(0,F.jsx)(`a`,{className:`text-xs font-extrabold text-primary`,href:c,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`Open ${s} CRM profile`,children:`CRM profile`}):null,l?(0,F.jsx)(`a`,{className:`text-xs font-extrabold text-primary`,href:l,target:`_blank`,rel:`noopener noreferrer`,children:`Resume`}):null]}),d?(0,F.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:d}):null,r?(0,F.jsx)(Bt,{"aria-label":`Candidate status for ${s}`,value:t.status||`suggested`,disabled:n[`application:${t.id}:status`],onChange:n=>o(e,t.id,n.target.value),children:wn.map(e=>(0,F.jsx)(`option`,{value:e,children:Tn(e)},e))}):null]})}function Rn(e){let t=cn[e.peopleFilterKind]?.options||[];return(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`People lookup`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[e.canSync?(0,F.jsxs)(L,{id:`syncPeople`,"data-permission":`people:sync`,type:`button`,onClick:e.onSync,disabled:e.loading.syncPeople,children:[(0,F.jsx)(ee,{}),`Sync people`]}):null,e.crmBaseUrl?(0,F.jsx)(`a`,{id:`crmHomeLink`,className:`text-sm font-extrabold text-primary`,href:e.crmBaseUrl,target:`_blank`,rel:`noreferrer`,children:`Open CRM`}):null,(0,F.jsx)(`span`,{id:`peopleStatus`,className:`text-sm text-muted-foreground`,children:e.loading.people?`Loading`:`${e.people.length} shown`})]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b p-4 md:grid-cols-[minmax(0,1fr)_auto]`,children:[(0,F.jsxs)(zt,{children:[`Search CRM people cache`,(0,F.jsx)(Rt,{id:`peopleQuery`,value:e.peopleQuery,autoComplete:`off`,placeholder:`Name, email, CRM id, Discord, resume`,onChange:t=>e.setPeopleQuery(t.target.value),onKeyDown:t=>{t.key===`Enter`&&e.onSearch()}})]}),(0,F.jsxs)(L,{id:`searchPeople`,type:`button`,onClick:e.onSearch,disabled:e.loading.people,children:[(0,F.jsx)(te,{}),`Search`]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b bg-background p-4 md:grid-cols-[minmax(120px,.7fr)_minmax(150px,1fr)_minmax(150px,1fr)_auto]`,children:[(0,F.jsxs)(zt,{children:[`Member`,(0,F.jsxs)(Bt,{id:`peopleMember`,value:e.peopleMember,onChange:t=>e.setPeopleMember(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any`}),(0,F.jsx)(`option`,{value:`true`,children:`Member`}),(0,F.jsx)(`option`,{value:`false`,children:`Not member`})]})]}),(0,F.jsxs)(zt,{children:[`Add filter`,(0,F.jsx)(Bt,{id:`peopleFilterKind`,value:e.peopleFilterKind,disabled:e.peopleFilterKeys.length===0,onChange:t=>e.setPeopleFilterKind(t.target.value),children:e.peopleFilterKeys.map(e=>(0,F.jsx)(`option`,{value:e,children:cn[e].label},e))})]}),(0,F.jsxs)(zt,{children:[`Value`,(0,F.jsx)(Bt,{id:`peopleFilterValue`,value:e.peopleFilterValue,onChange:t=>e.setPeopleFilterValue(t.target.value),children:t.map(([e,t])=>(0,F.jsx)(`option`,{value:e,children:t},e))})]}),(0,F.jsx)(L,{id:`addPeopleFilter`,type:`button`,onClick:e.addFilter,disabled:e.peopleFilterKeys.length===0,children:`Add filter`}),(0,F.jsx)(`div`,{id:`activePeopleFilters`,className:`md:col-span-4`,children:(0,F.jsx)(Sn,{filters:e.peopleFilters,onRemove:e.removeFilter})})]}),(0,F.jsx)(_n,{hidden:e.people.length!==0,children:`No people match this lookup.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`peopleTable`,className:jt(`min-w-[900px]`,e.people.length===0&&`hidden`),"aria-label":`People lookup results`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[27%]`,label:`Name`,scope:`people`,sort:e.sort,sortKey:`name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Status`,scope:`people`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[20%]`,label:`Discord`,scope:`people`,sort:e.sort,sortKey:`discord`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[25%]`,label:`Resume / skills`,scope:`people`,sort:e.sort,sortKey:`resume`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`peopleBody`,children:e.people.map(t=>{let n=t.name||t.email_508||t.email||`CRM contact`,r=e.crmContactUrl(t.crm_contact_id),i=t.profile_status||{},a=Number(i.skills_count||0),o=e.crmAttachmentUrl(t.latest_resume_id);return(0,F.jsxs)(Wt,{children:[(0,F.jsxs)(B,{children:[r?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:r,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${n} in CRM`,children:n}):(0,F.jsx)(`strong`,{children:n}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:[t.email_508||t.email,t.contact_type].filter(Boolean).join(` | `)})]}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[i.crm_active?null:(0,F.jsx)(I,{variant:`missing`,children:t.sync_status||`CRM sync issue`}),(0,F.jsx)(I,{variant:i.is_member?`succeeded`:`missing`,children:i.is_member?`Member`:`Missing Member`}),(0,F.jsx)(I,{variant:i.discord_linked?`succeeded`:`missing`,children:i.discord_linked?`Discord`:`Missing Discord`}),(0,F.jsx)(I,{variant:i.email_508?`succeeded`:`missing`,children:i.email_508?`508 email`:`Missing 508 email`}),i.latest_resume?null:(0,F.jsx)(I,{variant:`missing`,children:`Missing Resume`})]})}),(0,F.jsx)(B,{children:[t.discord_username,t.discord_user_id].filter(Boolean).join(` | `)||`Not linked`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[o?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:o,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${n} resume`,children:`Resume`}):(0,F.jsx)(`span`,{children:t.latest_resume_name||t.latest_resume_id||`No resume`}),(0,F.jsx)(I,{variant:a>0?`succeeded`:`missing`,children:a>0?`Skills parsed`:`Skills not parsed`})]})})]},t.crm_contact_id||n)})})]})})]})}function zn(e){let t=cn[e.onboardingFilterKind]?.options||[];return(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Onboarding queue`}),(0,F.jsx)(`span`,{id:`onboardingStatus`,className:`text-sm text-muted-foreground`,children:e.loading.onboarding?`Loading`:`${e.people.length} shown`})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b p-4 md:grid-cols-[minmax(0,1fr)_auto]`,children:[(0,F.jsxs)(zt,{children:[`Search prospects`,(0,F.jsx)(Rt,{id:`onboardingQuery`,value:e.onboardingQuery,autoComplete:`off`,placeholder:`Name, email, Discord, onboarder`,onChange:t=>e.setOnboardingQuery(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(L,{id:`searchOnboarding`,type:`button`,onClick:e.onSearch,disabled:e.loading.onboarding,children:[(0,F.jsx)(te,{}),`Search`]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b bg-background p-4 md:grid-cols-[minmax(140px,.8fr)_minmax(150px,1fr)_minmax(150px,1fr)_minmax(120px,.7fr)_auto]`,children:[(0,F.jsxs)(zt,{children:[`Status`,(0,F.jsxs)(Bt,{id:`onboardingState`,value:e.onboardingState,onChange:t=>e.setOnboardingState(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any state`}),(0,F.jsx)(`option`,{value:`pending`,children:`Needs review`}),(0,F.jsx)(`option`,{value:`selected`,children:`Assigned to onboarder`}),(0,F.jsx)(`option`,{value:`reachingout`,children:`Reaching out`}),(0,F.jsx)(`option`,{value:`awaitingcontribution`,children:`Awaiting contribution`})]})]}),(0,F.jsxs)(zt,{children:[`Onboarder`,(0,F.jsx)(Rt,{id:`onboarderFilter`,value:e.onboarderFilter,autoComplete:`off`,placeholder:`Any onboarder`,onChange:t=>e.setOnboarderFilter(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(zt,{children:[`Add filter`,(0,F.jsx)(Bt,{id:`onboardingFilterKind`,value:e.onboardingFilterKind,disabled:e.onboardingFilterKeys.length===0,onChange:t=>e.setOnboardingFilterKind(t.target.value),children:e.onboardingFilterKeys.map(e=>(0,F.jsx)(`option`,{value:e,children:cn[e].label},e))})]}),(0,F.jsxs)(zt,{children:[`Value`,(0,F.jsx)(Bt,{id:`onboardingFilterValue`,value:e.onboardingFilterValue,onChange:t=>e.setOnboardingFilterValue(t.target.value),children:t.map(([e,t])=>(0,F.jsx)(`option`,{value:e,children:t},e))})]}),(0,F.jsx)(L,{id:`addOnboardingFilter`,type:`button`,onClick:e.addFilter,disabled:e.onboardingFilterKeys.length===0,children:`Add filter`}),(0,F.jsx)(`div`,{id:`activeOnboardingFilters`,className:`md:col-span-5`,children:(0,F.jsx)(Sn,{filters:e.onboardingFilters,onRemove:e.removeFilter,suffix:`onboarding filter`})})]}),(0,F.jsx)(_n,{hidden:e.people.length!==0,children:`No prospects match this queue view.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`onboardingTable`,className:jt(`min-w-[1180px]`,e.people.length===0&&`hidden`),"aria-label":`Onboarding queue`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[20%]`,label:`Name`,scope:`onboarding`,sort:e.sort,sortKey:`name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[13%]`,label:`Status`,scope:`onboarding`,sort:e.sort,sortKey:`onboarding_state`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[22%]`,label:`Onboarder`,scope:`onboarding`,sort:e.sort,sortKey:`onboarder`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[13%]`,label:`Updated`,scope:`onboarding`,sort:e.sort,sortKey:`updated`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(z,{className:`w-[15%]`,children:`Links`}),(0,F.jsx)(H,{className:`w-[17%]`,label:`Needs`,scope:`onboarding`,sort:e.sort,sortKey:`profile_gaps`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`onboardingBody`,children:e.people.map(t=>(0,F.jsx)(Bn,{person:t,loading:e.loading,onAssign:e.onAssign,crmContactUrl:e.crmContactUrl,crmAttachmentUrl:e.crmAttachmentUrl},t.crm_contact_id||t.name))})]})})]})}function Bn({person:e,loading:t,onAssign:n,crmContactUrl:r,crmAttachmentUrl:i}){let a=e.name||e.email_508||e.email||`CRM contact`,[o,s]=(0,l.useState)(Qt(e.onboarder));(0,l.useEffect)(()=>s(Qt(e.onboarder)),[e.onboarder]);let c=e.profile_status||{},u=[[`Discord`,c.discord_linked],[`Resume`,c.latest_resume],[`Skills`,Number(c.skills_count||0)>0]].filter(([,e])=>!e),d=r(e.crm_contact_id),f=i(e.latest_resume_id);return(0,F.jsxs)(Wt,{children:[(0,F.jsxs)(B,{children:[d?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:d,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} in CRM`,children:a}):(0,F.jsx)(`strong`,{children:a}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:e.email_508||e.email||``})]}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:Zt(Yt(e)),children:e.onboarding_status_label||Xt(Yt(e))})}),(0,F.jsx)(B,{children:(0,F.jsxs)(`form`,{className:`grid max-w-64 grid-cols-[minmax(100px,1fr)_auto] items-center gap-2`,onSubmit:t=>{t.preventDefault(),n(e.crm_contact_id,o)},children:[(0,F.jsx)(Rt,{"aria-label":`Onboarder for ${a}`,value:o,placeholder:`508 username`,onChange:e=>s(e.target.value)}),(0,F.jsx)(L,{type:`submit`,size:`sm`,"aria-label":`Save onboarder for ${a}`,disabled:t[`onboarder:${e.crm_contact_id}`],children:`Save`})]})}),(0,F.jsx)(B,{children:Kt(e.onboarding_updated_at)}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[f?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:f,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} resume`,children:`Resume`}):null,rn(e.linkedin)?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:rn(e.linkedin),target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} LinkedIn`,children:`LinkedIn`}):null,an(e.github_username)?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:an(e.github_username),target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} GitHub`,children:e.github_username||`GitHub`}):null,!f&&!rn(e.linkedin)&&!an(e.github_username)?`None`:null]})}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[u.map(([e])=>(0,F.jsxs)(I,{variant:`missing`,children:[`Missing `,e]},String(e))),u.length===0?`None`:null]})})]})}function Vn(e){return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-4 md:items-end`,children:[(0,F.jsxs)(zt,{children:[`Window`,(0,F.jsxs)(Bt,{id:`minutes`,value:e.minutes,onChange:t=>e.setMinutes(t.target.value),children:[(0,F.jsx)(`option`,{value:`15`,children:`15 minutes`}),(0,F.jsx)(`option`,{value:`60`,children:`1 hour`}),(0,F.jsx)(`option`,{value:`360`,children:`6 hours`}),(0,F.jsx)(`option`,{value:`1440`,children:`24 hours`})]})]}),(0,F.jsxs)(zt,{children:[`Status`,(0,F.jsxs)(Bt,{id:`status`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any status`}),(0,F.jsx)(`option`,{value:`queued`,children:`Queued`}),(0,F.jsx)(`option`,{value:`running`,children:`Running`}),(0,F.jsx)(`option`,{value:`succeeded`,children:`Succeeded`}),(0,F.jsx)(`option`,{value:`failed`,children:`Failed`}),(0,F.jsx)(`option`,{value:`dead`,children:`Dead`}),(0,F.jsx)(`option`,{value:`canceled`,children:`Canceled`})]})]}),(0,F.jsxs)(zt,{children:[`Type`,(0,F.jsx)(Rt,{id:`jobType`,value:e.jobType,autoComplete:`off`,placeholder:`Any type`,onChange:t=>e.setJobType(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(L,{id:`refreshJobs`,type:`button`,onClick:e.onSearch,disabled:e.loading.jobs,children:[(0,F.jsx)(ee,{}),`Refresh jobs`]})]}),(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-4`,"aria-label":`Job summary`,children:[(0,F.jsx)(gn,{id:`metricTotal`,label:`Total`,value:e.jobs.length}),(0,F.jsx)(gn,{id:`metricQueued`,label:`Queued`,value:e.jobCounts.queued||0}),(0,F.jsx)(gn,{id:`metricRunning`,label:`Running`,value:e.jobCounts.running||0}),(0,F.jsx)(gn,{id:`metricFailed`,label:`Failed`,value:(e.jobCounts.failed||0)+(e.jobCounts.dead||0)})]}),(0,F.jsxs)(R,{children:[(0,F.jsx)(Ft,{children:(0,F.jsx)(It,{children:`Recent jobs`})}),(0,F.jsx)(_n,{hidden:e.jobs.length!==0,children:`No jobs match these filters.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`jobsTable`,className:jt(`min-w-[980px]`,e.jobs.length===0&&`hidden`),"aria-label":`Recent jobs`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[22%]`,label:`Job id`,scope:`jobs`,sort:e.sort,sortKey:`job_id`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[24%]`,label:`Type`,scope:`jobs`,sort:e.sort,sortKey:`type`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[12%]`,label:`Status`,scope:`jobs`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[12%]`,label:`Attempts`,scope:`jobs`,sort:e.sort,sortKey:`attempts`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[18%]`,label:`Updated`,scope:`jobs`,sort:e.sort,sortKey:`updated_at`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(z,{children:`Actions`})]})}),(0,F.jsx)(Ut,{id:`jobsBody`,children:e.jobs.map(t=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{className:`font-mono`,children:t.job_id}),(0,F.jsx)(B,{children:t.type}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:t.status||`neutral`,children:t.status})}),(0,F.jsxs)(B,{children:[t.attempts,`/`,t.max_attempts]}),(0,F.jsx)(B,{children:Kt(t.updated_at)}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,F.jsx)(L,{type:`button`,size:`sm`,variant:`outline`,"aria-label":`View details for ${t.type} job ${t.job_id}`,onClick:()=>e.onDetail(t.job_id),disabled:e.loading[`detail:${t.job_id}`],children:`Details`}),e.canWrite?(0,F.jsx)(L,{type:`button`,size:`sm`,"aria-label":`Rerun ${t.type} job ${t.job_id}`,onClick:()=>e.onRerun(t.job_id),disabled:e.loading[`rerun:${t.job_id}`],children:`Rerun`}):null]})})]},t.job_id))})]})})]}),e.jobDetail?(0,F.jsxs)(R,{id:`jobDetailPanel`,children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Job detail`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.jobDetail.job_id})]}),(0,F.jsxs)(Lt,{className:`grid gap-4`,children:[(0,F.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:[[`Type`,e.jobDetail.type],[`Status`,e.jobDetail.status],[`Attempts`,`${e.jobDetail.attempts}/${e.jobDetail.max_attempts}`],[`Updated`,Kt(e.jobDetail.updated_at)],[`Created`,Kt(e.jobDetail.created_at)],[`Run after`,Kt(e.jobDetail.run_after)],[`Locked by`,e.jobDetail.locked_by||`None`],[`Last error`,e.jobDetail.last_error||`None`]].map(([e,t])=>(0,F.jsxs)(`div`,{className:`grid gap-1 rounded-md border bg-background p-3`,children:[(0,F.jsx)(`span`,{className:`text-[11px] font-extrabold uppercase text-muted-foreground`,children:e}),(0,F.jsx)(`strong`,{className:`break-words text-sm`,children:t})]},e))}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h2`,{className:`mb-2 text-[15px] font-bold`,children:`Payload`}),(0,F.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-background p-3 font-mono text-xs`,children:Jt(e.jobDetail.payload)||`No payload`})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h2`,{className:`mb-2 text-[15px] font-bold`,children:`Result`}),(0,F.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-background p-3 font-mono text-xs`,children:Jt(e.jobDetail.result)||`No result`})]})]})]}):null]})}function Hn(e){return(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Recent audit`}),(0,F.jsxs)(L,{id:`refreshAudit`,type:`button`,variant:`outline`,onClick:e.onRefresh,disabled:e.loading.audit,children:[(0,F.jsx)(ee,{}),`Refresh`]})]}),(0,F.jsx)(_n,{hidden:e.events.length!==0,children:`No audit events found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`auditTable`,className:jt(`min-w-[760px]`,e.events.length===0&&`hidden`),"aria-label":`Recent audit events`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[24%]`,label:`Time`,scope:`audit`,sort:e.sort,sortKey:`occurred_at`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Actor`,scope:`audit`,sort:e.sort,sortKey:`actor`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Action`,scope:`audit`,sort:e.sort,sortKey:`action`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[20%]`,label:`Result`,scope:`audit`,sort:e.sort,sortKey:`result`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`auditBody`,children:e.events.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:Kt(e.occurred_at)}),(0,F.jsx)(B,{children:e.actor_display_name||e.actor_subject||e.actor_provider}),(0,F.jsx)(B,{children:e.action}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:e.result===`success`?`succeeded`:`failed`,children:e.result})})]},e.id||`${e.occurred_at||``}-${e.actor_subject||``}-${e.action||``}`))})]})})]})}function Un({report:e,loading:t,onRefresh:n}){let r=e?.summary||{},i=[[`Status`,e?.status_counts||{}],[`Intent`,e?.intent_counts||{}],[`Planner`,e?.planner_counts||{}]].flatMap(([e,t])=>Object.entries(t).map(([t,n])=>({label:e,value:t,count:n}))).sort((e,t)=>t.count-e.count||e.label.localeCompare(t.label)),a=Array.isArray(e?.recent_unsupported)?e.recent_unsupported:[];return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Agent requests`}),(0,F.jsxs)(L,{id:`refreshAgent`,type:`button`,variant:`outline`,onClick:n,disabled:t.agent,children:[(0,F.jsx)(ee,{}),`Refresh`]})]}),(0,F.jsxs)(Lt,{className:`grid gap-3 md:grid-cols-5`,children:[(0,F.jsx)(gn,{id:`agentMetricTotal`,label:`Total`,value:r.total||0}),(0,F.jsx)(gn,{id:`agentMetricHandled`,label:`Handled`,value:r.handled||0}),(0,F.jsx)(gn,{id:`agentMetricConfirmations`,label:`Confirmations`,value:r.requires_confirmation||0}),(0,F.jsx)(gn,{id:`agentMetricClarifications`,label:`Clarifications`,value:r.needs_clarification||0}),(0,F.jsx)(gn,{id:`agentMetricUnsupported`,label:`Not understood`,value:r.unsupported||0})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Request mix`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`Recent agent.request audit events.`})]}),(0,F.jsx)(_n,{hidden:i.length!==0,children:`No agent request data found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`agentBreakdownTable`,className:jt(`min-w-[860px]`,i.length===0&&`hidden`),"aria-label":`Agent request breakdown`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(z,{children:`Dimension`}),(0,F.jsx)(z,{children:`Value`}),(0,F.jsx)(z,{children:`Count`})]})}),(0,F.jsx)(Ut,{id:`agentBreakdownBody`,children:i.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:e.label}),(0,F.jsx)(B,{children:e.value}),(0,F.jsx)(B,{children:e.count})]},`${e.label}-${e.value}`))})]})})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(Ft,{children:[(0,F.jsx)(It,{children:`Not understood`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`Sanitized request text only.`})]}),(0,F.jsx)(_n,{hidden:a.length!==0,children:`No unsupported agent requests found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`agentUnsupportedTable`,className:jt(`min-w-[860px]`,a.length===0&&`hidden`),"aria-label":`Unsupported agent requests`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(z,{children:`Time`}),(0,F.jsx)(z,{children:`Actor`}),(0,F.jsx)(z,{children:`Message`}),(0,F.jsx)(z,{children:`Result`})]})}),(0,F.jsx)(Ut,{id:`agentUnsupportedBody`,children:a.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:Kt(e.occurred_at)}),(0,F.jsx)(B,{children:e.actor}),(0,F.jsx)(B,{children:e.message_sanitized}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:e.result===`success`?`succeeded`:`failed`,children:e.result||`unknown`})})]},`${e.occurred_at||``}-${e.actor||``}-${e.message_sanitized||``}`))})]})})]})]})}var Wn=document.getElementById(`root`);if(!Wn)throw Error(`Missing #root container`);(0,C.createRoot)(Wn).render((0,F.jsx)(l.StrictMode,{children:(0,F.jsx)(vn,{})})); \ No newline at end of file diff --git a/apps/api/src/five08/backend/static/dashboard/assets/index-Cjc8hvil.css b/apps/api/src/five08/backend/static/dashboard/assets/index-Bu9GOZtL.css similarity index 78% rename from apps/api/src/five08/backend/static/dashboard/assets/index-Cjc8hvil.css rename to apps/api/src/five08/backend/static/dashboard/assets/index-Bu9GOZtL.css index d7360ff8..fb8817a0 100644 --- a/apps/api/src/five08/backend/static/dashboard/assets/index-Cjc8hvil.css +++ b/apps/api/src/five08/backend/static/dashboard/assets/index-Bu9GOZtL.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-teal-200:oklch(91% .096 180.426);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--leading-tight:1.25;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{margin:calc(var(--spacing) * 0);min-width:calc(var(--spacing) * 80);background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}button{cursor:pointer}button:disabled{cursor:not-allowed}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.-top-1{top:calc(var(--spacing) * -1)}.top-0{top:calc(var(--spacing) * 0)}.-right-1{right:calc(var(--spacing) * -1)}.right-0{right:calc(var(--spacing) * 0)}.right-5{right:calc(var(--spacing) * 5)}.bottom-5{bottom:calc(var(--spacing) * 5)}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-\[22px\]{min-height:22px}.w-\[10\%\]{width:10%}.w-\[12\%\]{width:12%}.w-\[13\%\]{width:13%}.w-\[14\%\]{width:14%}.w-\[15\%\]{width:15%}.w-\[16\%\]{width:16%}.w-\[17\%\]{width:17%}.w-\[18\%\]{width:18%}.w-\[20\%\]{width:20%}.w-\[22\%\]{width:22%}.w-\[24\%\]{width:24%}.w-\[25\%\]{width:25%}.w-\[27\%\]{width:27%}.w-\[28\%\]{width:28%}.w-\[48px\]{width:48px}.w-\[160px\]{width:160px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-\[190px\]{min-width:190px}.min-w-\[760px\]{min-width:760px}.min-w-\[860px\]{min-width:860px}.min-w-\[900px\]{min-width:900px}.min-w-\[920px\]{min-width:920px}.min-w-\[980px\]{min-width:980px}.min-w-\[1100px\]{min-width:1100px}.min-w-\[1180px\]{min-width:1180px}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-default{cursor:default}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[minmax\(100px\,1fr\)_auto\]{grid-template-columns:minmax(100px,1fr) auto}.grid-rows-\[auto_minmax\(0\,1fr\)\]{grid-template-rows:auto minmax(0,1fr)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.content-start{align-content:flex-start}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-400\/40{border-color:#fcbb0066}@supports (color:color-mix(in lab, red, red)){.border-amber-400\/40{border-color:color-mix(in oklab, var(--color-amber-400) 40%, transparent)}}.border-border{border-color:var(--border)}.border-destructive{border-color:var(--destructive)}.border-emerald-400\/35{border-color:#00d29459}@supports (color:color-mix(in lab, red, red)){.border-emerald-400\/35{border-color:color-mix(in oklab, var(--color-emerald-400) 35%, transparent)}}.border-emerald-500\/40{border-color:#00bb7f66}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/40{border-color:color-mix(in oklab, var(--color-emerald-500) 40%, transparent)}}.border-input{border-color:var(--input)}.border-primary{border-color:var(--primary)}.border-red-400\/40{border-color:#ff656866}@supports (color:color-mix(in lab, red, red)){.border-red-400\/40{border-color:color-mix(in oklab, var(--color-red-400) 40%, transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab, red, red)){.border-red-500\/40{border-color:color-mix(in oklab, var(--color-red-500) 40%, transparent)}}.border-teal-400\/40{border-color:#00d3bd66}@supports (color:color-mix(in lab, red, red)){.border-teal-400\/40{border-color:color-mix(in oklab, var(--color-teal-400) 40%, transparent)}}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--accent)}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/15{background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.bg-background,.bg-background\/90{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/90{background-color:color-mix(in oklab, var(--background) 90%, transparent)}}.bg-black\/45{background-color:#00000073}@supports (color:color-mix(in lab, red, red)){.bg-black\/45{background-color:color-mix(in oklab, var(--color-black) 45%, transparent)}}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-emerald-500\/15{background-color:#00bb7f26}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/15{background-color:color-mix(in oklab, var(--color-emerald-500) 15%, transparent)}}.bg-primary{background-color:var(--primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/15{background-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-teal-500\/15{background-color:#00baa726}@supports (color:color-mix(in lab, red, red)){.bg-teal-500\/15{background-color:color-mix(in oklab, var(--color-teal-500) 15%, transparent)}}.p-0{padding:calc(var(--spacing) * 0)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-7{padding-block:calc(var(--spacing) * 7)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-\[inherit\]{font-family:inherit}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[15px\]{font-size:15px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent-foreground{color:var(--accent-foreground)}.text-amber-300{color:var(--color-amber-300)}.text-card-foreground{color:var(--card-foreground)}.text-emerald-300{color:var(--color-emerald-300)}.text-foreground{color:var(--foreground)}.text-inherit{color:inherit}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-300{color:var(--color-red-300)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-teal-200{color:var(--color-teal-200)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.underline-offset-4{text-underline-offset:4px}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_18px_44px_rgb\(0_0_0\/0\.22\)\]{--tw-shadow:0 18px 44px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.running{animation-play-state:running}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:border-border:hover{border-color:var(--border)}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-muted\/45:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/45:hover{background-color:color-mix(in oklab, var(--muted) 45%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-secondary:hover,.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=48rem){.md\:sticky{position:sticky}.md\:top-24{top:calc(var(--spacing) * 24)}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-5{grid-column:span 5/span 5}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-\[190px_minmax\(0\,1fr\)\]{grid-template-columns:190px minmax(0,1fr)}.md\:grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.md\:grid-cols-\[minmax\(0\,1fr\)_180px_auto_auto_auto\]{grid-template-columns:minmax(0,1fr) 180px auto auto auto}.md\:grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.md\:grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.md\:grid-cols-\[minmax\(120px\,\.7fr\)_minmax\(150px\,1fr\)_minmax\(150px\,1fr\)_auto\]{grid-template-columns:minmax(120px,.7fr) minmax(150px,1fr) minmax(150px,1fr) auto}.md\:grid-cols-\[minmax\(140px\,\.8fr\)_minmax\(150px\,1fr\)_minmax\(150px\,1fr\)_minmax\(120px\,\.7fr\)_auto\]{grid-template-columns:minmax(140px,.8fr) minmax(150px,1fr) minmax(150px,1fr) minmax(120px,.7fr) auto}.md\:grid-cols-\[minmax\(160px\,1fr\)_auto_auto\]{grid-template-columns:minmax(160px,1fr) auto auto}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:items-end{align-items:flex-end}.md\:items-start{align-items:flex-start}.md\:justify-between{justify-content:space-between}.md\:justify-end{justify-content:flex-end}}@media (width>=64rem){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[1fr_1fr_1fr\]{grid-template-columns:1fr 1fr 1fr}.lg\:grid-cols-\[minmax\(0\,1fr\)_220px_180px\]{grid-template-columns:minmax(0,1fr) 220px 180px}.lg\:items-start{align-items:flex-start}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--radius:.5rem;--background:oklch(16% .006 160);--foreground:oklch(94% .008 125);--card:oklch(22% .007 155);--card-foreground:oklch(94% .008 125);--popover:oklch(22% .007 155);--popover-foreground:oklch(94% .008 125);--primary:oklch(73% .11 178);--primary-foreground:oklch(17% .018 178);--secondary:oklch(28% .012 155);--secondary-foreground:oklch(94% .008 125);--muted:oklch(28% .012 155);--muted-foreground:oklch(71% .016 135);--accent:oklch(30% .042 178);--accent-foreground:oklch(88% .064 178);--destructive:oklch(67% .18 23);--border:oklch(100% 0 0/.14);--input:oklch(100% 0 0/.16);--ring:oklch(73% .11 178)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false} +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-teal-200:oklch(91% .096 180.426);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--leading-tight:1.25;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{margin:calc(var(--spacing) * 0);min-width:calc(var(--spacing) * 80);background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}button{cursor:pointer}button:disabled{cursor:not-allowed}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.-top-1{top:calc(var(--spacing) * -1)}.top-0{top:calc(var(--spacing) * 0)}.-right-1{right:calc(var(--spacing) * -1)}.right-0{right:calc(var(--spacing) * 0)}.right-5{right:calc(var(--spacing) * 5)}.bottom-5{bottom:calc(var(--spacing) * 5)}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-\[22px\]{min-height:22px}.w-\[10\%\]{width:10%}.w-\[12\%\]{width:12%}.w-\[13\%\]{width:13%}.w-\[14\%\]{width:14%}.w-\[15\%\]{width:15%}.w-\[16\%\]{width:16%}.w-\[17\%\]{width:17%}.w-\[18\%\]{width:18%}.w-\[20\%\]{width:20%}.w-\[22\%\]{width:22%}.w-\[24\%\]{width:24%}.w-\[25\%\]{width:25%}.w-\[27\%\]{width:27%}.w-\[28\%\]{width:28%}.w-\[48px\]{width:48px}.w-\[160px\]{width:160px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-\[190px\]{min-width:190px}.min-w-\[760px\]{min-width:760px}.min-w-\[860px\]{min-width:860px}.min-w-\[900px\]{min-width:900px}.min-w-\[920px\]{min-width:920px}.min-w-\[980px\]{min-width:980px}.min-w-\[1100px\]{min-width:1100px}.min-w-\[1180px\]{min-width:1180px}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-default{cursor:default}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[minmax\(100px\,1fr\)_auto\]{grid-template-columns:minmax(100px,1fr) auto}.grid-rows-\[auto_minmax\(0\,1fr\)\]{grid-template-rows:auto minmax(0,1fr)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.content-start{align-content:flex-start}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-400\/40{border-color:#fcbb0066}@supports (color:color-mix(in lab, red, red)){.border-amber-400\/40{border-color:color-mix(in oklab, var(--color-amber-400) 40%, transparent)}}.border-border{border-color:var(--border)}.border-destructive{border-color:var(--destructive)}.border-emerald-400\/35{border-color:#00d29459}@supports (color:color-mix(in lab, red, red)){.border-emerald-400\/35{border-color:color-mix(in oklab, var(--color-emerald-400) 35%, transparent)}}.border-emerald-500\/40{border-color:#00bb7f66}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/40{border-color:color-mix(in oklab, var(--color-emerald-500) 40%, transparent)}}.border-input{border-color:var(--input)}.border-primary{border-color:var(--primary)}.border-red-400\/40{border-color:#ff656866}@supports (color:color-mix(in lab, red, red)){.border-red-400\/40{border-color:color-mix(in oklab, var(--color-red-400) 40%, transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab, red, red)){.border-red-500\/40{border-color:color-mix(in oklab, var(--color-red-500) 40%, transparent)}}.border-teal-400\/40{border-color:#00d3bd66}@supports (color:color-mix(in lab, red, red)){.border-teal-400\/40{border-color:color-mix(in oklab, var(--color-teal-400) 40%, transparent)}}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--accent)}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/15{background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.bg-background,.bg-background\/90{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/90{background-color:color-mix(in oklab, var(--background) 90%, transparent)}}.bg-black\/45{background-color:#00000073}@supports (color:color-mix(in lab, red, red)){.bg-black\/45{background-color:color-mix(in oklab, var(--color-black) 45%, transparent)}}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-emerald-500\/15{background-color:#00bb7f26}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/15{background-color:color-mix(in oklab, var(--color-emerald-500) 15%, transparent)}}.bg-primary{background-color:var(--primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/15{background-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-teal-500\/15{background-color:#00baa726}@supports (color:color-mix(in lab, red, red)){.bg-teal-500\/15{background-color:color-mix(in oklab, var(--color-teal-500) 15%, transparent)}}.p-0{padding:calc(var(--spacing) * 0)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-7{padding-block:calc(var(--spacing) * 7)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-\[inherit\]{font-family:inherit}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[15px\]{font-size:15px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent-foreground{color:var(--accent-foreground)}.text-amber-300{color:var(--color-amber-300)}.text-card-foreground{color:var(--card-foreground)}.text-emerald-300{color:var(--color-emerald-300)}.text-foreground{color:var(--foreground)}.text-inherit{color:inherit}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-300{color:var(--color-red-300)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-teal-200{color:var(--color-teal-200)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.underline-offset-4{text-underline-offset:4px}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_18px_44px_rgb\(0_0_0\/0\.22\)\]{--tw-shadow:0 18px 44px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.running{animation-play-state:running}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:border-border:hover{border-color:var(--border)}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-muted\/45:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/45:hover{background-color:color-mix(in oklab, var(--muted) 45%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-secondary:hover,.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=48rem){.md\:sticky{position:sticky}.md\:top-24{top:calc(var(--spacing) * 24)}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-5{grid-column:span 5/span 5}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-\[190px_minmax\(0\,1fr\)\]{grid-template-columns:190px minmax(0,1fr)}.md\:grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.md\:grid-cols-\[minmax\(0\,1fr\)_180px_auto_auto_auto\]{grid-template-columns:minmax(0,1fr) 180px auto auto auto}.md\:grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.md\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)_minmax\(130px\,\.6fr\)_minmax\(140px\,\.7fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(130px,.6fr) minmax(140px,.7fr)}.md\:grid-cols-\[minmax\(0\,1fr\)_minmax\(180px\,\.7fr\)_minmax\(130px\,\.45fr\)_minmax\(130px\,\.45fr\)\]{grid-template-columns:minmax(0,1fr) minmax(180px,.7fr) minmax(130px,.45fr) minmax(130px,.45fr)}.md\:grid-cols-\[minmax\(120px\,\.7fr\)_minmax\(150px\,1fr\)_minmax\(150px\,1fr\)_auto\]{grid-template-columns:minmax(120px,.7fr) minmax(150px,1fr) minmax(150px,1fr) auto}.md\:grid-cols-\[minmax\(140px\,\.8fr\)_minmax\(150px\,1fr\)_minmax\(150px\,1fr\)_minmax\(120px\,\.7fr\)_auto\]{grid-template-columns:minmax(140px,.8fr) minmax(150px,1fr) minmax(150px,1fr) minmax(120px,.7fr) auto}.md\:grid-cols-\[minmax\(160px\,1fr\)_auto_auto\]{grid-template-columns:minmax(160px,1fr) auto auto}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:items-end{align-items:flex-end}.md\:items-start{align-items:flex-start}.md\:justify-between{justify-content:space-between}.md\:justify-end{justify-content:flex-end}}@media (width>=64rem){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-\[1fr_1fr_1fr\]{grid-template-columns:1fr 1fr 1fr}.lg\:grid-cols-\[minmax\(0\,1fr\)_220px_180px\]{grid-template-columns:minmax(0,1fr) 220px 180px}.lg\:items-start{align-items:flex-start}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--radius:.5rem;--background:oklch(16% .006 160);--foreground:oklch(94% .008 125);--card:oklch(22% .007 155);--card-foreground:oklch(94% .008 125);--popover:oklch(22% .007 155);--popover-foreground:oklch(94% .008 125);--primary:oklch(73% .11 178);--primary-foreground:oklch(17% .018 178);--secondary:oklch(28% .012 155);--secondary-foreground:oklch(94% .008 125);--muted:oklch(28% .012 155);--muted-foreground:oklch(71% .016 135);--accent:oklch(30% .042 178);--accent-foreground:oklch(88% .064 178);--destructive:oklch(67% .18 23);--border:oklch(100% 0 0/.14);--input:oklch(100% 0 0/.16);--ring:oklch(73% .11 178)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false} diff --git a/apps/api/src/five08/backend/static/dashboard/assets/index-CyCn29M4.js b/apps/api/src/five08/backend/static/dashboard/assets/index-CyCn29M4.js new file mode 100644 index 00000000..e2a184fc --- /dev/null +++ b/apps/api/src/five08/backend/static/dashboard/assets/index-CyCn29M4.js @@ -0,0 +1,9 @@ +var e=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var t=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var ee=Array.isArray;function te(){}var S={H:null,A:null,T:null,S:null},ne=Object.prototype.hasOwnProperty;function re(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ie(e,t){return re(e.type,t,e.props)}function ae(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function oe(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var se=/\/+/g;function ce(e,t){return typeof e==`object`&&e&&e.key!=null?oe(``+e.key):t.toString(36)}function C(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(te,te):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function le(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,le(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ce(e,0):a,ee(o)?(i=``,c!=null&&(i=c.replace(se,`$&/`)+`/`),le(o,r,i,``,function(e){return e})):o!=null&&(ae(o)&&(o=ie(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(se,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(ee(e))for(var u=0;u{n.exports=t()})),r=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),i=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),a=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),o=e=>{let t=a(e);return t.charAt(0).toUpperCase()+t.slice(1)},s={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},c=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},l=n(),u=(0,l.createContext)({}),d=()=>(0,l.useContext)(u),f=(0,l.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:i,className:a=``,children:o,iconNode:u,...f},p)=>{let{size:m=24,strokeWidth:h=2,absoluteStrokeWidth:g=!1,color:_=`currentColor`,className:v=``}=d()??{},y=i??g?Number(n??h)*24/Number(t??m):n??h;return(0,l.createElement)(`svg`,{ref:p,...s,width:t??m??s.width,height:t??m??s.height,stroke:e??_,strokeWidth:y,className:r(`lucide`,v,a),...!o&&!c(f)&&{"aria-hidden":`true`},...f},[...u.map(([e,t])=>(0,l.createElement)(e,t)),...Array.isArray(o)?o:[o]])}),p=(e,t)=>{let n=(0,l.forwardRef)(({className:n,...a},s)=>(0,l.createElement)(f,{ref:s,iconNode:t,className:r(`lucide-${i(o(e))}`,`lucide-${e}`,n),...a}));return n.displayName=o(e),n},m=p(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),h=p(`bell`,[[`path`,{d:`M10.268 21a2 2 0 0 0 3.464 0`,key:`vwvbt9`}],[`path`,{d:`M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326`,key:`11g9vi`}]]),g=p(`briefcase-business`,[[`path`,{d:`M12 12h.01`,key:`1mp3jc`}],[`path`,{d:`M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2`,key:`1ksdt3`}],[`path`,{d:`M22 13a18.15 18.15 0 0 1-20 0`,key:`12hx5q`}],[`rect`,{width:`20`,height:`14`,x:`2`,y:`6`,rx:`2`,key:`i6l2r4`}]]),_=p(`clipboard-list`,[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`,key:`116196`}],[`path`,{d:`M12 11h4`,key:`1jrz19`}],[`path`,{d:`M12 16h4`,key:`n85exb`}],[`path`,{d:`M8 11h.01`,key:`1dfujw`}],[`path`,{d:`M8 16h.01`,key:`18s6g9`}]]),v=p(`external-link`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]),y=p(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),b=p(`folder-kanban`,[[`path`,{d:`M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z`,key:`1fr9dc`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M12 10v2`,key:`hh53o1`}],[`path`,{d:`M16 10v6`,key:`1d6xys`}]]),x=p(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),ee=p(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),te=p(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),S=p(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),ne=p(`user-plus`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}],[`line`,{x1:`19`,x2:`19`,y1:`8`,y2:`14`,key:`1bvyxn`}],[`line`,{x1:`22`,x2:`16`,y1:`11`,y2:`11`,key:`1shjgl`}]]),re=p(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),ie=p(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),ae=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,ee||(ee=!0,ae());else{var t=n(l);t!==null&&ce(x,t.startTime-e)}}var ee=!1,te=-1,S=5,ne=-1;function re(){return g?!0:!(e.unstable_now()-net&&re());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ce(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?ae():ee=!1}}}var ae;if(typeof y==`function`)ae=function(){y(ie)};else if(typeof MessageChannel<`u`){var oe=new MessageChannel,se=oe.port2;oe.port1.onmessage=ie,ae=function(){se.postMessage(null)}}else ae=function(){_(ie,0)};function ce(t,n){te=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(te),te=-1):h=!0,ce(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,ae()))),r},e.unstable_shouldYield=re,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),oe=e(((e,t)=>{t.exports=ae()})),se=e((e=>{var t=n();function r(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=se()})),C=e((e=>{var t=oe(),r=n(),i=ce();function a(e){var t=`https://react.dev/errors/`+e;if(1me||(e.current=pe[me],pe[me]=null,me--)}function O(e,t){me++,pe[me]=e.current,e.current=t}var he=E(null),ge=E(null),_e=E(null),ve=E(null);function ye(e,t){switch(O(_e,t),O(ge,e),O(he,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}D(he),O(he,e)}function be(){D(he),D(ge),D(_e)}function xe(e){e.memoizedState!==null&&O(ve,e);var t=he.current,n=Hd(t,e.type);t!==n&&(O(ge,e),O(he,n))}function Se(e){ge.current===e&&(D(he),D(ge)),ve.current===e&&(D(ve),Qf._currentValue=fe)}var Ce,we;function Te(e){if(Ce===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Ce=t&&t[1]||``,we=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Ee=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?Te(n):``}function Oe(e,t){switch(e.tag){case 26:case 27:case 5:return Te(e.type);case 16:return Te(`Lazy`);case 13:return e.child!==t&&t!==null?Te(`Suspense Fallback`):Te(`Suspense`);case 19:return Te(`SuspenseList`);case 0:case 15:return De(e.type,!1);case 11:return De(e.type.render,!1);case 1:return De(e.type,!0);case 31:return Te(`Activity`);default:return``}}function ke(e){try{var t=``,n=null;do t+=Oe(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var Ae=Object.prototype.hasOwnProperty,je=t.unstable_scheduleCallback,Me=t.unstable_cancelCallback,Ne=t.unstable_shouldYield,Pe=t.unstable_requestPaint,Fe=t.unstable_now,Ie=t.unstable_getCurrentPriorityLevel,Le=t.unstable_ImmediatePriority,Re=t.unstable_UserBlockingPriority,ze=t.unstable_NormalPriority,Be=t.unstable_LowPriority,Ve=t.unstable_IdlePriority,He=t.log,Ue=t.unstable_setDisableYieldValue,We=null,Ge=null;function Ke(e){if(typeof He==`function`&&Ue(e),Ge&&typeof Ge.setStrictMode==`function`)try{Ge.setStrictMode(We,e)}catch{}}var qe=Math.clz32?Math.clz32:Xe,Je=Math.log,Ye=Math.LN2;function Xe(e){return e>>>=0,e===0?32:31-(Je(e)/Ye|0)|0}var Ze=256,Qe=262144,k=4194304;function $e(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function et(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=$e(n))):i=$e(o):i=$e(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=$e(n))):i=$e(o)):i=$e(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function tt(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function nt(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function rt(){var e=k;return k<<=1,!(k&62914560)&&(k=4194304),e}function it(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function at(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function ot(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),cn=!1;if(sn)try{var ln={};Object.defineProperty(ln,`passive`,{get:function(){cn=!0}}),window.addEventListener(`test`,ln,ln),window.removeEventListener(`test`,ln,ln)}catch{cn=!1}var un=null,dn=null,fn=null;function pn(){if(fn)return fn;var e,t=dn,n=t.length,r,i=`value`in un?un.value:un.textContent,a=i.length;for(e=0;e=Un),Kn=` `,qn=!1;function Jn(e,t){switch(e){case`keyup`:return Vn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Yn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Xn=!1;function Zn(e,t){switch(e){case`compositionend`:return Yn(t);case`keypress`:return t.which===32?(qn=!0,Kn):null;case`textInput`:return e=t.data,e===Kn&&qn?null:e;default:return null}}function Qn(e,t){if(Xn)return e===`compositionend`||!Hn&&Jn(e,t)?(e=pn(),fn=dn=un=null,Xn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=br(n)}}function Sr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Sr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Cr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=It(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=It(e.document)}return t}function wr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Tr=sn&&`documentMode`in document&&11>=document.documentMode,Er=null,Dr=null,Or=null,kr=!1;function Ar(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;kr||Er==null||Er!==It(r)||(r=Er,`selectionStart`in r&&wr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Or&&yr(Or,r)||(Or=r,r=Ed(Dr,`onSelect`),0>=o,i-=o,Si=1<<32-qe(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),U&&wi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(i,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(i,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(i,h),U&&wi(i,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(i,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return U&&wi(i,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,i,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(i,e)}),U&&wi(i,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===_&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case h:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===_){if(r.tag===7){n(e,r.sibling),c=i(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===re&&wa(l)===r.type){n(e,r.sibling),c=i(r,o.props),ja(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===_?(c=li(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=ci(o.type,o.key,o.props,null,e.mode,c),ja(c,o),c.return=e,e=c)}return s(e);case g:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=i(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=fi(o,e.mode,c),c.return=e,e=c}return s(e);case re:return o=wa(o),b(e,r,o,c)}if(de(o))return v(e,r,o,c);if(C(o)){if(l=C(o),typeof l!=`function`)throw Error(a(150));return o=l.call(o),y(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Aa(o),c);if(o.$$typeof===x)return b(e,r,Qi(e,o),c);Ma(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=i(r,o),c.return=e,e=c):(n(e,r),c=ui(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ka=0;var i=b(e,t,n,r);return Oa=null,i}catch(t){if(t===va||t===ba)throw t;var a=ii(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Pa=Na(!0),Fa=Na(!1),Ia=!1;function La(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ra(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function za(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ba(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ti(e),ei(e,null,n),t}return Zr(e,r,t,n),ti(e)}function Va(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ct(e,n)}}function Ha(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ua=!1;function Wa(){if(Ua){var e=la;if(e!==null)throw e}}function Ga(e,t,n,r){Ua=!1;var i=e.updateQueue;Ia=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,m=f!==s.lane;if(m?(Y&f)===f:(r&f)===f){f!==0&&f===ca&&(Ua=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=p({},d,f);break a;case 2:Ia=!0}}f=s.callback,f!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[f]:m.push(f))}else m={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Ka(e,t){if(typeof e!=`function`)throw Error(a(191,e));e.call(t)}function qa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=w.T,s={};w.T=s,Ms(e,!1,t,n);try{var c=i(),l=w.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?js(e,t,fa(c,r),pu(e)):js(e,t,r,pu(e))}catch(n){js(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{T.p=a,o!==null&&s.types!==null&&(o.types=s.types),w.T=o}}function xs(){}function Ss(e,t,n,r){if(e.tag!==5)throw Error(a(476));var i=Cs(e).queue;bs(e,i,t,fe,n===null?xs:function(){return ws(e),n(r)})}function Cs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:fe,baseState:fe,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:fe},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:No,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ws(e){var t=Cs(e);t.next===null&&(t=e.alternate.memoizedState),js(e,t.next.queue,{},pu())}function Ts(){return Zi(Qf)}function Es(){return Oo().memoizedState}function Ds(){return Oo().memoizedState}function Os(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=za(n);var r=Ba(t,e,n);r!==null&&(hu(r,t,n),Va(r,t,n)),t={cache:ia()},e.payload=t;return}t=t.return}}function ks(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ns(e)?Ps(t,n):(n=Qr(e,t,n,r),n!==null&&(hu(n,e,r),Fs(n,t,r)))}function As(e,t,n){js(e,t,n,pu())}function js(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ns(e))Ps(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,vr(s,o))return Zr(e,t,i,0),q===null&&Xr(),!1}catch{}if(n=Qr(e,t,i,r),n!==null)return hu(n,e,r),Fs(n,t,r),!0}return!1}function Ms(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ns(e)){if(t)throw Error(a(479))}else t=Qr(e,n,r,2),t!==null&&hu(t,e,2)}function Ns(e){var t=e.alternate;return e===W||t!==null&&t===W}function Ps(e,t){fo=uo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Fs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ct(e,n)}}var Is={readContext:Zi,use:jo,useCallback:vo,useContext:vo,useEffect:vo,useImperativeHandle:vo,useLayoutEffect:vo,useInsertionEffect:vo,useMemo:vo,useReducer:vo,useRef:vo,useState:vo,useDebugValue:vo,useDeferredValue:vo,useTransition:vo,useSyncExternalStore:vo,useId:vo,useHostTransitionStatus:vo,useFormState:vo,useActionState:vo,useOptimistic:vo,useMemoCache:vo,useCacheRefresh:vo};Is.useEffectEvent=vo;var Ls={readContext:Zi,use:jo,useCallback:function(e,t){return Do().memoizedState=[e,t===void 0?null:t],e},useContext:Zi,useEffect:ss,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),as(4194308,4,ps.bind(null,t,e),n)},useLayoutEffect:function(e,t){return as(4194308,4,e,t)},useInsertionEffect:function(e,t){as(4,2,e,t)},useMemo:function(e,t){var n=Do();t=t===void 0?null:t;var r=e();if(po){Ke(!0);try{e()}finally{Ke(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Do();if(n!==void 0){var i=n(t);if(po){Ke(!0);try{n(t)}finally{Ke(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ks.bind(null,W,e),[r.memoizedState,e]},useRef:function(e){var t=Do();return e={current:e},t.memoizedState=e},useState:function(e){e=Uo(e);var t=e.queue,n=As.bind(null,W,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:hs,useDeferredValue:function(e,t){return vs(Do(),e,t)},useTransition:function(){var e=Uo(!1);return e=bs.bind(null,W,e.queue,!0,!1),Do().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=W,i=Do();if(U){if(n===void 0)throw Error(a(407));n=n()}else{if(n=t(),q===null)throw Error(a(349));Y&127||Ro(r,t,n)}i.memoizedState=n;var o={value:n,getSnapshot:t};return i.queue=o,ss(Bo.bind(null,r,o,e),[e]),r.flags|=2048,rs(9,{destroy:void 0},zo.bind(null,r,o,n,t),null),n},useId:function(){var e=Do(),t=q.identifierPrefix;if(U){var n=Ci,r=Si;n=(r&~(1<<32-qe(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=mo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(i,{is:r.is}):s.createElement(i)}}o[M]=t,o[pt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,i,r),i){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&jc(t)}}return Ic(t),Mc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&jc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(a(166));if(e=_e.current,Li(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,i=ki,i!==null)switch(i.tag){case 27:case 5:r=i.memoizedProps}e[M]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Pi(t,!0)}else e=Bd(e).createTextNode(r),e[M]=t,t.stateNode=e}return Ic(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Li(t),n!==null){if(e===null){if(!r)throw Error(a(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(a(557));e[M]=t}else Ri(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Ic(t),e=!1}else n=zi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(ao(t),t):(ao(t),null);if(t.flags&128)throw Error(a(558))}return Ic(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(i=Li(t),r!==null&&r.dehydrated!==null){if(e===null){if(!i)throw Error(a(318));if(i=t.memoizedState,i=i===null?null:i.dehydrated,!i)throw Error(a(317));i[M]=t}else Ri(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Ic(t),i=!1}else i=zi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=i),i=!0;if(!i)return t.flags&256?(ao(t),t):(ao(t),null)}return ao(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,i=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(i=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==i&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Pc(t,t.updateQueue),Ic(t),null);case 4:return be(),e===null&&Sd(t.stateNode.containerInfo),Ic(t),null;case 10:return Gi(t.type),Ic(t),null;case 19:if(D(oo),r=t.memoizedState,r===null)return Ic(t),null;if(i=(t.flags&128)!=0,o=r.rendering,o===null)if(i)Fc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=so(e),o!==null){for(t.flags|=128,Fc(r,!1),e=o.updateQueue,t.updateQueue=e,Pc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)si(n,e),n=n.sibling;return O(oo,oo.current&1|2),U&&wi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Fe()>tu&&(t.flags|=128,i=!0,Fc(r,!1),t.lanes=4194304)}else{if(!i)if(e=so(o),e!==null){if(t.flags|=128,i=!0,e=e.updateQueue,t.updateQueue=e,Pc(t,e),Fc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!U)return Ic(t),null}else 2*Fe()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,i=!0,Fc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Ic(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Fe(),e.sibling=null,n=oo.current,O(oo,i?n&1|2:n&1),U&&wi(t,r.treeForkCount),e);case 22:case 23:return ao(t),Qa(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Ic(t),t.subtreeFlags&6&&(t.flags|=8192)):Ic(t),n=t.updateQueue,n!==null&&Pc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&D(ma),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Gi(ra),Ic(t),null;case 25:return null;case 30:return null}throw Error(a(156,t.tag))}function Rc(e,t){switch(Di(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Gi(ra),be(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Se(t),null;case 31:if(t.memoizedState!==null){if(ao(t),t.alternate===null)throw Error(a(340));Ri()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(ao(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(a(340));Ri()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return D(oo),null;case 4:return be(),null;case 10:return Gi(t.type),null;case 22:case 23:return ao(t),Qa(),e!==null&&D(ma),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Gi(ra),null;case 25:return null;default:return null}}function zc(e,t){switch(Di(t),t.tag){case 3:Gi(ra),be();break;case 26:case 27:case 5:Se(t);break;case 4:be();break;case 31:t.memoizedState!==null&&ao(t);break;case 13:ao(t);break;case 19:D(oo);break;case 10:Gi(t.type);break;case 22:case 23:ao(t),Qa(),e!==null&&D(ma);break;case 24:Gi(ra)}}function Bc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Vc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Hc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{qa(t,n)}catch(t){Z(e,e.return,t)}}}function Uc(e,t,n){n.props=Ws(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Wc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Gc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function Kc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function qc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[pt]=t}catch(t){Z(e,e.return,t)}}function Jc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Yc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Jc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Xc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Zt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Xc(e,t,n),e=e.sibling;e!==null;)Xc(e,t,n),e=e.sibling}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[M]=e,t[pt]=n}catch(t){Z(e,e.return,t)}}var $c=!1,el=!1,tl=!1,nl=typeof WeakSet==`function`?WeakSet:Set,rl=null;function il(e,t){if(e=e.containerInfo,Rd=sp,e=Cr(e),wr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||i!==0&&f.nodeType!==3||(c=s+i),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===i&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,rl=t;rl!==null;)if(t=rl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,rl=e;else for(;rl!==null;){switch(t=rl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[M]=e,wt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,i).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=xr(s,h),v=xr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,w.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,K&6)throw Error(a(331));var c=K;if(K|=4,Pl(o.current),El(o,o.current,s,n),K=c,id(0,!1),Ge&&typeof Ge.onPostCommitFiberRoot==`function`)try{Ge.onPostCommitFiberRoot(We,o)}catch{}return!0}finally{T.p=i,w.T=r,Vu(e,t)}}function Wu(e,t,n){t=mi(n,t),t=Xs(e.stateNode,t,2),e=Ba(e,t,2),e!==null&&(at(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=mi(n,e),n=Zs(2),r=Ba(t,n,2),r!==null&&(Qs(n,r,t,e),at(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Rl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(Wl===4||Wl===3&&(Y&62914560)===Y&&300>Fe()-$l?!(K&2)&&Su(e,0):ql|=n,Yl===Y&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=rt()),e=$r(e,t),e!==null&&(at(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(a(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return je(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-qe(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=Y,a=et(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||tt(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=Fe(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Rt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),wt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Rt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Rt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Rt(n.imageSizes)+`"]`)):i+=`[href="`+Rt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),wt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Rt(r)+`"][href="`+Rt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),wt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=Ct(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);wt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),wt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),wt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=_e.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=Ct(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=Ct(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=Ct(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Rt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),wt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Rt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Rt(n.href)+`"]`);if(r)return t.instance=r,wt(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),wt(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,wt(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),wt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,wt(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),wt(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,wt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),wt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=C()}))();function ue(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`)if(Array.isArray(e)){var i=e.length;for(t=0;ttypeof e==`boolean`?`${e}`:e===0?`0`:e,T=de,fe=(e,t)=>n=>{if(t?.variants==null)return T(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=w(t)||w(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return T(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},pe=(e,t)=>{let n=Array(e.length+t.length);for(let t=0;t({classGroupId:e,validator:t}),E=(e=new Map,t=null,n)=>({nextPart:e,validators:t,classGroupId:n}),D=`-`,O=[],he=`arbitrary..`,ge=e=>{let t=ye(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:e=>{if(e.startsWith(`[`)&&e.endsWith(`]`))return ve(e);let n=e.split(D);return _e(n,+(n[0]===``&&n.length>1),t)},getConflictingClassGroupIds:(e,t)=>{if(t){let t=r[e],i=n[e];return t?i?pe(i,t):t:i||O}return n[e]||O}}},_e=(e,t,n)=>{if(e.length-t===0)return n.classGroupId;let r=e[t],i=n.nextPart.get(r);if(i){let n=_e(e,t+1,i);if(n)return n}let a=n.validators;if(a===null)return;let o=t===0?e.join(D):e.slice(t).join(D),s=a.length;for(let e=0;ee.slice(1,-1).indexOf(`:`)===-1?void 0:(()=>{let t=e.slice(1,-1),n=t.indexOf(`:`),r=t.slice(0,n);return r?he+r:void 0})(),ye=e=>{let{theme:t,classGroups:n}=e;return be(n,t)},be=(e,t)=>{let n=E();for(let r in e){let i=e[r];xe(i,n,r,t)}return n},xe=(e,t,n,r)=>{let i=e.length;for(let a=0;a{if(typeof e==`string`){Ce(e,t,n);return}if(typeof e==`function`){we(e,t,n,r);return}Te(e,t,n,r)},Ce=(e,t,n)=>{let r=e===``?t:Ee(t,e);r.classGroupId=n},we=(e,t,n,r)=>{if(De(e)){xe(e(r),t,n,r);return}t.validators===null&&(t.validators=[]),t.validators.push(me(n,e))},Te=(e,t,n,r)=>{let i=Object.entries(e),a=i.length;for(let e=0;e{let n=e,r=t.split(D),i=r.length;for(let e=0;e`isThemeGetter`in e&&e.isThemeGetter===!0,Oe=e=>{if(e<1)return{get:()=>void 0,set:()=>{}};let t=0,n=Object.create(null),r=Object.create(null),i=(i,a)=>{n[i]=a,t++,t>e&&(t=0,r=n,n=Object.create(null))};return{get(e){let t=n[e];if(t!==void 0)return t;if((t=r[e])!==void 0)return i(e,t),t},set(e,t){e in n?n[e]=t:i(e,t)}}},ke=`!`,Ae=`:`,je=[],Me=(e,t,n,r,i)=>({modifiers:e,hasImportantModifier:t,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),Ne=e=>{let{prefix:t,experimentalParseClassName:n}=e,r=e=>{let t=[],n=0,r=0,i=0,a,o=e.length;for(let s=0;si?a-i:void 0;return Me(t,l,c,u)};if(t){let e=t+Ae,n=r;r=t=>t.startsWith(e)?n(t.slice(e.length)):Me(je,!1,t,void 0,!0)}if(n){let e=r;r=t=>n({className:t,parseClassName:e})}return r},Pe=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((e,n)=>{t.set(e,1e6+n)}),e=>{let n=[],r=[];for(let i=0;i0&&(r.sort(),n.push(...r),r=[]),n.push(a)):r.push(a)}return r.length>0&&(r.sort(),n.push(...r)),n}},Fe=e=>({cache:Oe(e.cacheSize),parseClassName:Ne(e),sortModifiers:Pe(e),postfixLookupClassGroupIds:Ie(e),...ge(e)}),Ie=e=>{let t=Object.create(null),n=e.postfixLookupClassGroups;if(n)for(let e=0;e{let{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a,postfixLookupClassGroupIds:o}=t,s=[],c=e.trim().split(Le),l=``;for(let e=c.length-1;e>=0;--e){let t=c[e],{isExternal:u,modifiers:d,hasImportantModifier:f,baseClassName:p,maybePostfixModifierPosition:m}=n(t);if(u){l=t+(l.length>0?` `+l:l);continue}let h=!!m,g;if(h){g=r(p.substring(0,m));let e=g&&o[g]?r(p):void 0;e&&e!==g&&(g=e,h=!1)}else g=r(p);if(!g){if(!h){l=t+(l.length>0?` `+l:l);continue}if(g=r(p),!g){l=t+(l.length>0?` `+l:l);continue}h=!1}let _=d.length===0?``:d.length===1?d[0]:a(d).join(`:`),v=f?_+ke:_,y=v+g;if(s.indexOf(y)>-1)continue;s.push(y);let b=i(g,h);for(let e=0;e0?` `+l:l)}return l},ze=(...e)=>{let t=0,n,r,i=``;for(;t{if(typeof e==`string`)return e;let t,n=``;for(let r=0;r{let n,r,i,a,o=o=>(n=Fe(t.reduce((e,t)=>t(e),e())),r=n.cache.get,i=n.cache.set,a=s,s(o)),s=e=>{let t=r(e);if(t)return t;let a=Re(e,n);return i(e,a),a};return a=o,(...e)=>a(ze(...e))},He=[],Ue=e=>{let t=t=>t[e]||He;return t.isThemeGetter=!0,t},We=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ge=/^\((?:(\w[\w-]*):)?(.+)\)$/i,Ke=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,qe=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Je=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Ye=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Xe=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Ze=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,Qe=e=>Ke.test(e),k=e=>!!e&&!Number.isNaN(Number(e)),$e=e=>!!e&&Number.isInteger(Number(e)),et=e=>e.endsWith(`%`)&&k(e.slice(0,-1)),tt=e=>qe.test(e),nt=()=>!0,rt=e=>Je.test(e)&&!Ye.test(e),it=()=>!1,at=e=>Xe.test(e),ot=e=>Ze.test(e),st=e=>!A(e)&&!N(e),ct=e=>e.startsWith(`@container`)&&(e[10]===`/`&&e[11]!==void 0||e[11]===`s`&&e[16]!==void 0&&e.startsWith(`-size/`,10)||e[11]===`n`&&e[18]!==void 0&&e.startsWith(`-normal/`,10)),lt=e=>St(e,Et,it),A=e=>We.test(e),ut=e=>St(e,Dt,rt),dt=e=>St(e,Ot,k),ft=e=>St(e,At,nt),j=e=>St(e,kt,it),M=e=>St(e,wt,it),pt=e=>St(e,Tt,ot),mt=e=>St(e,jt,at),N=e=>Ge.test(e),ht=e=>Ct(e,Dt),gt=e=>Ct(e,kt),_t=e=>Ct(e,wt),vt=e=>Ct(e,Et),yt=e=>Ct(e,Tt),bt=e=>Ct(e,jt,!0),xt=e=>Ct(e,At,!0),St=(e,t,n)=>{let r=We.exec(e);return r?r[1]?t(r[1]):n(r[2]):!1},Ct=(e,t,n=!1)=>{let r=Ge.exec(e);return r?r[1]?t(r[1]):n:!1},wt=e=>e===`position`||e===`percentage`,Tt=e=>e===`image`||e===`url`,Et=e=>e===`length`||e===`size`||e===`bg-size`,Dt=e=>e===`length`,Ot=e=>e===`number`,kt=e=>e===`family-name`,At=e=>e===`number`||e===`weight`,jt=e=>e===`shadow`,Mt=Ve(()=>{let e=Ue(`color`),t=Ue(`font`),n=Ue(`text`),r=Ue(`font-weight`),i=Ue(`tracking`),a=Ue(`leading`),o=Ue(`breakpoint`),s=Ue(`container`),c=Ue(`spacing`),l=Ue(`radius`),u=Ue(`shadow`),d=Ue(`inset-shadow`),f=Ue(`text-shadow`),p=Ue(`drop-shadow`),m=Ue(`blur`),h=Ue(`perspective`),g=Ue(`aspect`),_=Ue(`ease`),v=Ue(`animate`),y=()=>[`auto`,`avoid`,`all`,`avoid-page`,`page`,`left`,`right`,`column`],b=()=>[`center`,`top`,`bottom`,`left`,`right`,`top-left`,`left-top`,`top-right`,`right-top`,`bottom-right`,`right-bottom`,`bottom-left`,`left-bottom`],x=()=>[...b(),N,A],ee=()=>[`auto`,`hidden`,`clip`,`visible`,`scroll`],te=()=>[`auto`,`contain`,`none`],S=()=>[N,A,c],ne=()=>[Qe,`full`,`auto`,...S()],re=()=>[$e,`none`,`subgrid`,N,A],ie=()=>[`auto`,{span:[`full`,$e,N,A]},$e,N,A],ae=()=>[$e,`auto`,N,A],oe=()=>[`auto`,`min`,`max`,`fr`,N,A],se=()=>[`start`,`end`,`center`,`between`,`around`,`evenly`,`stretch`,`baseline`,`center-safe`,`end-safe`],ce=()=>[`start`,`end`,`center`,`stretch`,`center-safe`,`end-safe`],C=()=>[`auto`,...S()],le=()=>[Qe,`auto`,`full`,`dvw`,`dvh`,`lvw`,`lvh`,`svw`,`svh`,`min`,`max`,`fit`,...S()],ue=()=>[Qe,`screen`,`full`,`dvw`,`lvw`,`svw`,`min`,`max`,`fit`,...S()],de=()=>[Qe,`screen`,`full`,`lh`,`dvh`,`lvh`,`svh`,`min`,`max`,`fit`,...S()],w=()=>[e,N,A],T=()=>[...b(),_t,M,{position:[N,A]}],fe=()=>[`no-repeat`,{repeat:[``,`x`,`y`,`space`,`round`]}],pe=()=>[`auto`,`cover`,`contain`,vt,lt,{size:[N,A]}],me=()=>[et,ht,ut],E=()=>[``,`none`,`full`,l,N,A],D=()=>[``,k,ht,ut],O=()=>[`solid`,`dashed`,`dotted`,`double`],he=()=>[`normal`,`multiply`,`screen`,`overlay`,`darken`,`lighten`,`color-dodge`,`color-burn`,`hard-light`,`soft-light`,`difference`,`exclusion`,`hue`,`saturation`,`color`,`luminosity`],ge=()=>[k,et,_t,M],_e=()=>[``,`none`,m,N,A],ve=()=>[`none`,k,N,A],ye=()=>[`none`,k,N,A],be=()=>[k,N,A],xe=()=>[Qe,`full`,...S()];return{cacheSize:500,theme:{animate:[`spin`,`ping`,`pulse`,`bounce`],aspect:[`video`],blur:[tt],breakpoint:[tt],color:[nt],container:[tt],"drop-shadow":[tt],ease:[`in`,`out`,`in-out`],font:[st],"font-weight":[`thin`,`extralight`,`light`,`normal`,`medium`,`semibold`,`bold`,`extrabold`,`black`],"inset-shadow":[tt],leading:[`none`,`tight`,`snug`,`normal`,`relaxed`,`loose`],perspective:[`dramatic`,`near`,`normal`,`midrange`,`distant`,`none`],radius:[tt],shadow:[tt],spacing:[`px`,k],text:[tt],"text-shadow":[tt],tracking:[`tighter`,`tight`,`normal`,`wide`,`wider`,`widest`]},classGroups:{aspect:[{aspect:[`auto`,`square`,Qe,A,N,g]}],container:[`container`],"container-type":[{"@container":[``,`normal`,`size`,N,A]}],"container-named":[ct],columns:[{columns:[k,A,N,s]}],"break-after":[{"break-after":y()}],"break-before":[{"break-before":y()}],"break-inside":[{"break-inside":[`auto`,`avoid`,`avoid-page`,`avoid-column`]}],"box-decoration":[{"box-decoration":[`slice`,`clone`]}],box:[{box:[`border`,`content`]}],display:[`block`,`inline-block`,`inline`,`flex`,`inline-flex`,`table`,`inline-table`,`table-caption`,`table-cell`,`table-column`,`table-column-group`,`table-footer-group`,`table-header-group`,`table-row-group`,`table-row`,`flow-root`,`grid`,`inline-grid`,`contents`,`list-item`,`hidden`],sr:[`sr-only`,`not-sr-only`],float:[{float:[`right`,`left`,`none`,`start`,`end`]}],clear:[{clear:[`left`,`right`,`both`,`none`,`start`,`end`]}],isolation:[`isolate`,`isolation-auto`],"object-fit":[{object:[`contain`,`cover`,`fill`,`none`,`scale-down`]}],"object-position":[{object:x()}],overflow:[{overflow:ee()}],"overflow-x":[{"overflow-x":ee()}],"overflow-y":[{"overflow-y":ee()}],overscroll:[{overscroll:te()}],"overscroll-x":[{"overscroll-x":te()}],"overscroll-y":[{"overscroll-y":te()}],position:[`static`,`fixed`,`absolute`,`relative`,`sticky`],inset:[{inset:ne()}],"inset-x":[{"inset-x":ne()}],"inset-y":[{"inset-y":ne()}],start:[{"inset-s":ne(),start:ne()}],end:[{"inset-e":ne(),end:ne()}],"inset-bs":[{"inset-bs":ne()}],"inset-be":[{"inset-be":ne()}],top:[{top:ne()}],right:[{right:ne()}],bottom:[{bottom:ne()}],left:[{left:ne()}],visibility:[`visible`,`invisible`,`collapse`],z:[{z:[$e,`auto`,N,A]}],basis:[{basis:[Qe,`full`,`auto`,s,...S()]}],"flex-direction":[{flex:[`row`,`row-reverse`,`col`,`col-reverse`]}],"flex-wrap":[{flex:[`nowrap`,`wrap`,`wrap-reverse`]}],flex:[{flex:[k,Qe,`auto`,`initial`,`none`,A]}],grow:[{grow:[``,k,N,A]}],shrink:[{shrink:[``,k,N,A]}],order:[{order:[$e,`first`,`last`,`none`,N,A]}],"grid-cols":[{"grid-cols":re()}],"col-start-end":[{col:ie()}],"col-start":[{"col-start":ae()}],"col-end":[{"col-end":ae()}],"grid-rows":[{"grid-rows":re()}],"row-start-end":[{row:ie()}],"row-start":[{"row-start":ae()}],"row-end":[{"row-end":ae()}],"grid-flow":[{"grid-flow":[`row`,`col`,`dense`,`row-dense`,`col-dense`]}],"auto-cols":[{"auto-cols":oe()}],"auto-rows":[{"auto-rows":oe()}],gap:[{gap:S()}],"gap-x":[{"gap-x":S()}],"gap-y":[{"gap-y":S()}],"justify-content":[{justify:[...se(),`normal`]}],"justify-items":[{"justify-items":[...ce(),`normal`]}],"justify-self":[{"justify-self":[`auto`,...ce()]}],"align-content":[{content:[`normal`,...se()]}],"align-items":[{items:[...ce(),{baseline:[``,`last`]}]}],"align-self":[{self:[`auto`,...ce(),{baseline:[``,`last`]}]}],"place-content":[{"place-content":se()}],"place-items":[{"place-items":[...ce(),`baseline`]}],"place-self":[{"place-self":[`auto`,...ce()]}],p:[{p:S()}],px:[{px:S()}],py:[{py:S()}],ps:[{ps:S()}],pe:[{pe:S()}],pbs:[{pbs:S()}],pbe:[{pbe:S()}],pt:[{pt:S()}],pr:[{pr:S()}],pb:[{pb:S()}],pl:[{pl:S()}],m:[{m:C()}],mx:[{mx:C()}],my:[{my:C()}],ms:[{ms:C()}],me:[{me:C()}],mbs:[{mbs:C()}],mbe:[{mbe:C()}],mt:[{mt:C()}],mr:[{mr:C()}],mb:[{mb:C()}],ml:[{ml:C()}],"space-x":[{"space-x":S()}],"space-x-reverse":[`space-x-reverse`],"space-y":[{"space-y":S()}],"space-y-reverse":[`space-y-reverse`],size:[{size:le()}],"inline-size":[{inline:[`auto`,...ue()]}],"min-inline-size":[{"min-inline":[`auto`,...ue()]}],"max-inline-size":[{"max-inline":[`none`,...ue()]}],"block-size":[{block:[`auto`,...de()]}],"min-block-size":[{"min-block":[`auto`,...de()]}],"max-block-size":[{"max-block":[`none`,...de()]}],w:[{w:[s,`screen`,...le()]}],"min-w":[{"min-w":[s,`screen`,`none`,...le()]}],"max-w":[{"max-w":[s,`screen`,`none`,`prose`,{screen:[o]},...le()]}],h:[{h:[`screen`,`lh`,...le()]}],"min-h":[{"min-h":[`screen`,`lh`,`none`,...le()]}],"max-h":[{"max-h":[`screen`,`lh`,...le()]}],"font-size":[{text:[`base`,n,ht,ut]}],"font-smoothing":[`antialiased`,`subpixel-antialiased`],"font-style":[`italic`,`not-italic`],"font-weight":[{font:[r,xt,ft]}],"font-stretch":[{"font-stretch":[`ultra-condensed`,`extra-condensed`,`condensed`,`semi-condensed`,`normal`,`semi-expanded`,`expanded`,`extra-expanded`,`ultra-expanded`,et,A]}],"font-family":[{font:[gt,j,t]}],"font-features":[{"font-features":[A]}],"fvn-normal":[`normal-nums`],"fvn-ordinal":[`ordinal`],"fvn-slashed-zero":[`slashed-zero`],"fvn-figure":[`lining-nums`,`oldstyle-nums`],"fvn-spacing":[`proportional-nums`,`tabular-nums`],"fvn-fraction":[`diagonal-fractions`,`stacked-fractions`],tracking:[{tracking:[i,N,A]}],"line-clamp":[{"line-clamp":[k,`none`,N,dt]}],leading:[{leading:[a,...S()]}],"list-image":[{"list-image":[`none`,N,A]}],"list-style-position":[{list:[`inside`,`outside`]}],"list-style-type":[{list:[`disc`,`decimal`,`none`,N,A]}],"text-alignment":[{text:[`left`,`center`,`right`,`justify`,`start`,`end`]}],"placeholder-color":[{placeholder:w()}],"text-color":[{text:w()}],"text-decoration":[`underline`,`overline`,`line-through`,`no-underline`],"text-decoration-style":[{decoration:[...O(),`wavy`]}],"text-decoration-thickness":[{decoration:[k,`from-font`,`auto`,N,ut]}],"text-decoration-color":[{decoration:w()}],"underline-offset":[{"underline-offset":[k,`auto`,N,A]}],"text-transform":[`uppercase`,`lowercase`,`capitalize`,`normal-case`],"text-overflow":[`truncate`,`text-ellipsis`,`text-clip`],"text-wrap":[{text:[`wrap`,`nowrap`,`balance`,`pretty`]}],indent:[{indent:S()}],"tab-size":[{tab:[$e,N,A]}],"vertical-align":[{align:[`baseline`,`top`,`middle`,`bottom`,`text-top`,`text-bottom`,`sub`,`super`,N,A]}],whitespace:[{whitespace:[`normal`,`nowrap`,`pre`,`pre-line`,`pre-wrap`,`break-spaces`]}],break:[{break:[`normal`,`words`,`all`,`keep`]}],wrap:[{wrap:[`break-word`,`anywhere`,`normal`]}],hyphens:[{hyphens:[`none`,`manual`,`auto`]}],content:[{content:[`none`,N,A]}],"bg-attachment":[{bg:[`fixed`,`local`,`scroll`]}],"bg-clip":[{"bg-clip":[`border`,`padding`,`content`,`text`]}],"bg-origin":[{"bg-origin":[`border`,`padding`,`content`]}],"bg-position":[{bg:T()}],"bg-repeat":[{bg:fe()}],"bg-size":[{bg:pe()}],"bg-image":[{bg:[`none`,{linear:[{to:[`t`,`tr`,`r`,`br`,`b`,`bl`,`l`,`tl`]},$e,N,A],radial:[``,N,A],conic:[$e,N,A]},yt,pt]}],"bg-color":[{bg:w()}],"gradient-from-pos":[{from:me()}],"gradient-via-pos":[{via:me()}],"gradient-to-pos":[{to:me()}],"gradient-from":[{from:w()}],"gradient-via":[{via:w()}],"gradient-to":[{to:w()}],rounded:[{rounded:E()}],"rounded-s":[{"rounded-s":E()}],"rounded-e":[{"rounded-e":E()}],"rounded-t":[{"rounded-t":E()}],"rounded-r":[{"rounded-r":E()}],"rounded-b":[{"rounded-b":E()}],"rounded-l":[{"rounded-l":E()}],"rounded-ss":[{"rounded-ss":E()}],"rounded-se":[{"rounded-se":E()}],"rounded-ee":[{"rounded-ee":E()}],"rounded-es":[{"rounded-es":E()}],"rounded-tl":[{"rounded-tl":E()}],"rounded-tr":[{"rounded-tr":E()}],"rounded-br":[{"rounded-br":E()}],"rounded-bl":[{"rounded-bl":E()}],"border-w":[{border:D()}],"border-w-x":[{"border-x":D()}],"border-w-y":[{"border-y":D()}],"border-w-s":[{"border-s":D()}],"border-w-e":[{"border-e":D()}],"border-w-bs":[{"border-bs":D()}],"border-w-be":[{"border-be":D()}],"border-w-t":[{"border-t":D()}],"border-w-r":[{"border-r":D()}],"border-w-b":[{"border-b":D()}],"border-w-l":[{"border-l":D()}],"divide-x":[{"divide-x":D()}],"divide-x-reverse":[`divide-x-reverse`],"divide-y":[{"divide-y":D()}],"divide-y-reverse":[`divide-y-reverse`],"border-style":[{border:[...O(),`hidden`,`none`]}],"divide-style":[{divide:[...O(),`hidden`,`none`]}],"border-color":[{border:w()}],"border-color-x":[{"border-x":w()}],"border-color-y":[{"border-y":w()}],"border-color-s":[{"border-s":w()}],"border-color-e":[{"border-e":w()}],"border-color-bs":[{"border-bs":w()}],"border-color-be":[{"border-be":w()}],"border-color-t":[{"border-t":w()}],"border-color-r":[{"border-r":w()}],"border-color-b":[{"border-b":w()}],"border-color-l":[{"border-l":w()}],"divide-color":[{divide:w()}],"outline-style":[{outline:[...O(),`none`,`hidden`]}],"outline-offset":[{"outline-offset":[k,N,A]}],"outline-w":[{outline:[``,k,ht,ut]}],"outline-color":[{outline:w()}],shadow:[{shadow:[``,`none`,u,bt,mt]}],"shadow-color":[{shadow:w()}],"inset-shadow":[{"inset-shadow":[`none`,d,bt,mt]}],"inset-shadow-color":[{"inset-shadow":w()}],"ring-w":[{ring:D()}],"ring-w-inset":[`ring-inset`],"ring-color":[{ring:w()}],"ring-offset-w":[{"ring-offset":[k,ut]}],"ring-offset-color":[{"ring-offset":w()}],"inset-ring-w":[{"inset-ring":D()}],"inset-ring-color":[{"inset-ring":w()}],"text-shadow":[{"text-shadow":[`none`,f,bt,mt]}],"text-shadow-color":[{"text-shadow":w()}],opacity:[{opacity:[k,N,A]}],"mix-blend":[{"mix-blend":[...he(),`plus-darker`,`plus-lighter`]}],"bg-blend":[{"bg-blend":he()}],"mask-clip":[{"mask-clip":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]},`mask-no-clip`],"mask-composite":[{mask:[`add`,`subtract`,`intersect`,`exclude`]}],"mask-image-linear-pos":[{"mask-linear":[k]}],"mask-image-linear-from-pos":[{"mask-linear-from":ge()}],"mask-image-linear-to-pos":[{"mask-linear-to":ge()}],"mask-image-linear-from-color":[{"mask-linear-from":w()}],"mask-image-linear-to-color":[{"mask-linear-to":w()}],"mask-image-t-from-pos":[{"mask-t-from":ge()}],"mask-image-t-to-pos":[{"mask-t-to":ge()}],"mask-image-t-from-color":[{"mask-t-from":w()}],"mask-image-t-to-color":[{"mask-t-to":w()}],"mask-image-r-from-pos":[{"mask-r-from":ge()}],"mask-image-r-to-pos":[{"mask-r-to":ge()}],"mask-image-r-from-color":[{"mask-r-from":w()}],"mask-image-r-to-color":[{"mask-r-to":w()}],"mask-image-b-from-pos":[{"mask-b-from":ge()}],"mask-image-b-to-pos":[{"mask-b-to":ge()}],"mask-image-b-from-color":[{"mask-b-from":w()}],"mask-image-b-to-color":[{"mask-b-to":w()}],"mask-image-l-from-pos":[{"mask-l-from":ge()}],"mask-image-l-to-pos":[{"mask-l-to":ge()}],"mask-image-l-from-color":[{"mask-l-from":w()}],"mask-image-l-to-color":[{"mask-l-to":w()}],"mask-image-x-from-pos":[{"mask-x-from":ge()}],"mask-image-x-to-pos":[{"mask-x-to":ge()}],"mask-image-x-from-color":[{"mask-x-from":w()}],"mask-image-x-to-color":[{"mask-x-to":w()}],"mask-image-y-from-pos":[{"mask-y-from":ge()}],"mask-image-y-to-pos":[{"mask-y-to":ge()}],"mask-image-y-from-color":[{"mask-y-from":w()}],"mask-image-y-to-color":[{"mask-y-to":w()}],"mask-image-radial":[{"mask-radial":[N,A]}],"mask-image-radial-from-pos":[{"mask-radial-from":ge()}],"mask-image-radial-to-pos":[{"mask-radial-to":ge()}],"mask-image-radial-from-color":[{"mask-radial-from":w()}],"mask-image-radial-to-color":[{"mask-radial-to":w()}],"mask-image-radial-shape":[{"mask-radial":[`circle`,`ellipse`]}],"mask-image-radial-size":[{"mask-radial":[{closest:[`side`,`corner`],farthest:[`side`,`corner`]}]}],"mask-image-radial-pos":[{"mask-radial-at":b()}],"mask-image-conic-pos":[{"mask-conic":[k]}],"mask-image-conic-from-pos":[{"mask-conic-from":ge()}],"mask-image-conic-to-pos":[{"mask-conic-to":ge()}],"mask-image-conic-from-color":[{"mask-conic-from":w()}],"mask-image-conic-to-color":[{"mask-conic-to":w()}],"mask-mode":[{mask:[`alpha`,`luminance`,`match`]}],"mask-origin":[{"mask-origin":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]}],"mask-position":[{mask:T()}],"mask-repeat":[{mask:fe()}],"mask-size":[{mask:pe()}],"mask-type":[{"mask-type":[`alpha`,`luminance`]}],"mask-image":[{mask:[`none`,N,A]}],filter:[{filter:[``,`none`,N,A]}],blur:[{blur:_e()}],brightness:[{brightness:[k,N,A]}],contrast:[{contrast:[k,N,A]}],"drop-shadow":[{"drop-shadow":[``,`none`,p,bt,mt]}],"drop-shadow-color":[{"drop-shadow":w()}],grayscale:[{grayscale:[``,k,N,A]}],"hue-rotate":[{"hue-rotate":[k,N,A]}],invert:[{invert:[``,k,N,A]}],saturate:[{saturate:[k,N,A]}],sepia:[{sepia:[``,k,N,A]}],"backdrop-filter":[{"backdrop-filter":[``,`none`,N,A]}],"backdrop-blur":[{"backdrop-blur":_e()}],"backdrop-brightness":[{"backdrop-brightness":[k,N,A]}],"backdrop-contrast":[{"backdrop-contrast":[k,N,A]}],"backdrop-grayscale":[{"backdrop-grayscale":[``,k,N,A]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[k,N,A]}],"backdrop-invert":[{"backdrop-invert":[``,k,N,A]}],"backdrop-opacity":[{"backdrop-opacity":[k,N,A]}],"backdrop-saturate":[{"backdrop-saturate":[k,N,A]}],"backdrop-sepia":[{"backdrop-sepia":[``,k,N,A]}],"border-collapse":[{border:[`collapse`,`separate`]}],"border-spacing":[{"border-spacing":S()}],"border-spacing-x":[{"border-spacing-x":S()}],"border-spacing-y":[{"border-spacing-y":S()}],"table-layout":[{table:[`auto`,`fixed`]}],caption:[{caption:[`top`,`bottom`]}],transition:[{transition:[``,`all`,`colors`,`opacity`,`shadow`,`transform`,`none`,N,A]}],"transition-behavior":[{transition:[`normal`,`discrete`]}],duration:[{duration:[k,`initial`,N,A]}],ease:[{ease:[`linear`,`initial`,_,N,A]}],delay:[{delay:[k,N,A]}],animate:[{animate:[`none`,v,N,A]}],backface:[{backface:[`hidden`,`visible`]}],perspective:[{perspective:[h,N,A]}],"perspective-origin":[{"perspective-origin":x()}],rotate:[{rotate:ve()}],"rotate-x":[{"rotate-x":ve()}],"rotate-y":[{"rotate-y":ve()}],"rotate-z":[{"rotate-z":ve()}],scale:[{scale:ye()}],"scale-x":[{"scale-x":ye()}],"scale-y":[{"scale-y":ye()}],"scale-z":[{"scale-z":ye()}],"scale-3d":[`scale-3d`],skew:[{skew:be()}],"skew-x":[{"skew-x":be()}],"skew-y":[{"skew-y":be()}],transform:[{transform:[N,A,``,`none`,`gpu`,`cpu`]}],"transform-origin":[{origin:x()}],"transform-style":[{transform:[`3d`,`flat`]}],translate:[{translate:xe()}],"translate-x":[{"translate-x":xe()}],"translate-y":[{"translate-y":xe()}],"translate-z":[{"translate-z":xe()}],"translate-none":[`translate-none`],zoom:[{zoom:[$e,N,A]}],accent:[{accent:w()}],appearance:[{appearance:[`none`,`auto`]}],"caret-color":[{caret:w()}],"color-scheme":[{scheme:[`normal`,`dark`,`light`,`light-dark`,`only-dark`,`only-light`]}],cursor:[{cursor:[`auto`,`default`,`pointer`,`wait`,`text`,`move`,`help`,`not-allowed`,`none`,`context-menu`,`progress`,`cell`,`crosshair`,`vertical-text`,`alias`,`copy`,`no-drop`,`grab`,`grabbing`,`all-scroll`,`col-resize`,`row-resize`,`n-resize`,`e-resize`,`s-resize`,`w-resize`,`ne-resize`,`nw-resize`,`se-resize`,`sw-resize`,`ew-resize`,`ns-resize`,`nesw-resize`,`nwse-resize`,`zoom-in`,`zoom-out`,N,A]}],"field-sizing":[{"field-sizing":[`fixed`,`content`]}],"pointer-events":[{"pointer-events":[`auto`,`none`]}],resize:[{resize:[`none`,``,`y`,`x`]}],"scroll-behavior":[{scroll:[`auto`,`smooth`]}],"scrollbar-thumb-color":[{"scrollbar-thumb":w()}],"scrollbar-track-color":[{"scrollbar-track":w()}],"scrollbar-gutter":[{"scrollbar-gutter":[`auto`,`stable`,`both`]}],"scrollbar-w":[{scrollbar:[`auto`,`thin`,`none`]}],"scroll-m":[{"scroll-m":S()}],"scroll-mx":[{"scroll-mx":S()}],"scroll-my":[{"scroll-my":S()}],"scroll-ms":[{"scroll-ms":S()}],"scroll-me":[{"scroll-me":S()}],"scroll-mbs":[{"scroll-mbs":S()}],"scroll-mbe":[{"scroll-mbe":S()}],"scroll-mt":[{"scroll-mt":S()}],"scroll-mr":[{"scroll-mr":S()}],"scroll-mb":[{"scroll-mb":S()}],"scroll-ml":[{"scroll-ml":S()}],"scroll-p":[{"scroll-p":S()}],"scroll-px":[{"scroll-px":S()}],"scroll-py":[{"scroll-py":S()}],"scroll-ps":[{"scroll-ps":S()}],"scroll-pe":[{"scroll-pe":S()}],"scroll-pbs":[{"scroll-pbs":S()}],"scroll-pbe":[{"scroll-pbe":S()}],"scroll-pt":[{"scroll-pt":S()}],"scroll-pr":[{"scroll-pr":S()}],"scroll-pb":[{"scroll-pb":S()}],"scroll-pl":[{"scroll-pl":S()}],"snap-align":[{snap:[`start`,`end`,`center`,`align-none`]}],"snap-stop":[{snap:[`normal`,`always`]}],"snap-type":[{snap:[`none`,`x`,`y`,`both`]}],"snap-strictness":[{snap:[`mandatory`,`proximity`]}],touch:[{touch:[`auto`,`none`,`manipulation`]}],"touch-x":[{"touch-pan":[`x`,`left`,`right`]}],"touch-y":[{"touch-pan":[`y`,`up`,`down`]}],"touch-pz":[`touch-pinch-zoom`],select:[{select:[`none`,`text`,`all`,`auto`]}],"will-change":[{"will-change":[`auto`,`scroll`,`contents`,`transform`,N,A]}],fill:[{fill:[`none`,...w()]}],"stroke-w":[{stroke:[k,ht,ut,dt]}],stroke:[{stroke:[`none`,...w()]}],"forced-color-adjust":[{"forced-color-adjust":[`auto`,`none`]}]},conflictingClassGroups:{"container-named":[`container-type`],overflow:[`overflow-x`,`overflow-y`],overscroll:[`overscroll-x`,`overscroll-y`],inset:[`inset-x`,`inset-y`,`inset-bs`,`inset-be`,`start`,`end`,`top`,`right`,`bottom`,`left`],"inset-x":[`right`,`left`],"inset-y":[`top`,`bottom`],flex:[`basis`,`grow`,`shrink`],gap:[`gap-x`,`gap-y`],p:[`px`,`py`,`ps`,`pe`,`pbs`,`pbe`,`pt`,`pr`,`pb`,`pl`],px:[`pr`,`pl`],py:[`pt`,`pb`],m:[`mx`,`my`,`ms`,`me`,`mbs`,`mbe`,`mt`,`mr`,`mb`,`ml`],mx:[`mr`,`ml`],my:[`mt`,`mb`],size:[`w`,`h`],"font-size":[`leading`],"fvn-normal":[`fvn-ordinal`,`fvn-slashed-zero`,`fvn-figure`,`fvn-spacing`,`fvn-fraction`],"fvn-ordinal":[`fvn-normal`],"fvn-slashed-zero":[`fvn-normal`],"fvn-figure":[`fvn-normal`],"fvn-spacing":[`fvn-normal`],"fvn-fraction":[`fvn-normal`],"line-clamp":[`display`,`overflow`],rounded:[`rounded-s`,`rounded-e`,`rounded-t`,`rounded-r`,`rounded-b`,`rounded-l`,`rounded-ss`,`rounded-se`,`rounded-ee`,`rounded-es`,`rounded-tl`,`rounded-tr`,`rounded-br`,`rounded-bl`],"rounded-s":[`rounded-ss`,`rounded-es`],"rounded-e":[`rounded-se`,`rounded-ee`],"rounded-t":[`rounded-tl`,`rounded-tr`],"rounded-r":[`rounded-tr`,`rounded-br`],"rounded-b":[`rounded-br`,`rounded-bl`],"rounded-l":[`rounded-tl`,`rounded-bl`],"border-spacing":[`border-spacing-x`,`border-spacing-y`],"border-w":[`border-w-x`,`border-w-y`,`border-w-s`,`border-w-e`,`border-w-bs`,`border-w-be`,`border-w-t`,`border-w-r`,`border-w-b`,`border-w-l`],"border-w-x":[`border-w-r`,`border-w-l`],"border-w-y":[`border-w-t`,`border-w-b`],"border-color":[`border-color-x`,`border-color-y`,`border-color-s`,`border-color-e`,`border-color-bs`,`border-color-be`,`border-color-t`,`border-color-r`,`border-color-b`,`border-color-l`],"border-color-x":[`border-color-r`,`border-color-l`],"border-color-y":[`border-color-t`,`border-color-b`],translate:[`translate-x`,`translate-y`,`translate-none`],"translate-none":[`translate`,`translate-x`,`translate-y`,`translate-z`],"scroll-m":[`scroll-mx`,`scroll-my`,`scroll-ms`,`scroll-me`,`scroll-mbs`,`scroll-mbe`,`scroll-mt`,`scroll-mr`,`scroll-mb`,`scroll-ml`],"scroll-mx":[`scroll-mr`,`scroll-ml`],"scroll-my":[`scroll-mt`,`scroll-mb`],"scroll-p":[`scroll-px`,`scroll-py`,`scroll-ps`,`scroll-pe`,`scroll-pbs`,`scroll-pbe`,`scroll-pt`,`scroll-pr`,`scroll-pb`,`scroll-pl`],"scroll-px":[`scroll-pr`,`scroll-pl`],"scroll-py":[`scroll-pt`,`scroll-pb`],touch:[`touch-x`,`touch-y`,`touch-pz`],"touch-x":[`touch`],"touch-y":[`touch`],"touch-pz":[`touch`]},conflictingClassGroupModifiers:{"font-size":[`leading`]},postfixLookupClassGroups:[`container-type`],orderSensitiveModifiers:[`*`,`**`,`after`,`backdrop`,`before`,`details-content`,`file`,`first-letter`,`first-line`,`marker`,`placeholder`,`selection`]}});function P(...e){return Mt(de(e))}var Nt=e((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),F=e(((e,t)=>{t.exports=Nt()}))(),Pt=fe(`inline-flex min-h-[22px] items-center rounded-full border px-2 py-0.5 text-[11px] font-extrabold uppercase leading-tight`,{variants:{variant:{neutral:`border-border bg-secondary text-muted-foreground`,succeeded:`border-emerald-400/35 bg-emerald-500/15 text-emerald-300`,failed:`border-red-400/40 bg-red-500/15 text-red-300`,dead:`border-red-400/40 bg-red-500/15 text-red-300`,missing:`border-red-400/40 bg-red-500/15 text-red-300`,running:`border-amber-400/40 bg-amber-500/15 text-amber-300`,queued:`border-teal-400/40 bg-teal-500/15 text-teal-200`,canceled:`border-border bg-secondary text-muted-foreground`}},defaultVariants:{variant:`neutral`}});function I({className:e,variant:t,...n}){return(0,F.jsx)(`span`,{"data-slot":`badge`,className:P(Pt({variant:t,className:e})),...n})}var Ft=fe(`inline-flex min-h-9 shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md border text-sm font-semibold transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0`,{variants:{variant:{default:`border-primary bg-primary text-primary-foreground hover:bg-primary/90`,secondary:`border-border bg-secondary text-secondary-foreground hover:bg-secondary/80`,outline:`border-border bg-background hover:bg-accent hover:text-accent-foreground`,ghost:`border-transparent hover:bg-accent hover:text-accent-foreground`,destructive:`border-destructive bg-destructive text-white hover:bg-destructive/90`},size:{default:`h-9 px-4 py-2`,sm:`h-8 rounded-md px-3 text-xs`,icon:`size-9`}},defaultVariants:{variant:`secondary`,size:`default`}});function L({className:e,variant:t,size:n,type:r=`button`,...i}){return(0,F.jsx)(`button`,{"data-slot":`button`,type:r,className:P(Ft({variant:t,size:n,className:e})),...i})}function R({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card`,className:P(`rounded-lg border bg-card text-card-foreground shadow-[0_18px_44px_rgb(0_0_0/0.22)]`,e),...t})}function It({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card-header`,className:P(`flex items-center justify-between gap-3 border-b px-4 py-3`,e),...t})}function Lt({className:e,...t}){return(0,F.jsx)(`h2`,{"data-slot":`card-title`,className:P(`text-[15px] font-bold`,e),...t})}function Rt({className:e,...t}){return(0,F.jsx)(`div`,{"data-slot":`card-content`,className:P(`p-4`,e),...t})}function zt({className:e,type:t,...n}){return(0,F.jsx)(`input`,{"data-slot":`input`,type:t,className:P(`flex min-h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,e),...n})}function z({className:e,...t}){return(0,F.jsx)(`label`,{"data-slot":`label`,className:P(`grid gap-1.5 text-xs font-bold text-muted-foreground`,e),...t})}function Bt({className:e,...t}){return(0,F.jsx)(`select`,{"data-slot":`select`,className:P(`flex min-h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-xs transition-colors focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,e),...t})}function Vt({className:e,...t}){return(0,F.jsx)(`table`,{"data-slot":`table`,className:P(`w-full border-collapse text-sm`,e),...t})}function Ht({className:e,...t}){return(0,F.jsx)(`thead`,{"data-slot":`table-header`,className:e,...t})}function Ut({className:e,...t}){return(0,F.jsx)(`tbody`,{"data-slot":`table-body`,className:e,...t})}function Wt({className:e,...t}){return(0,F.jsx)(`tr`,{"data-slot":`table-row`,className:P(`border-b transition-colors hover:bg-muted/45`,e),...t})}function Gt({className:e,...t}){return(0,F.jsx)(`th`,{"data-slot":`table-head`,className:P(`bg-secondary px-3 py-3 text-left align-middle text-xs font-extrabold text-muted-foreground`,e),...t})}function B({className:e,...t}){return(0,F.jsx)(`td`,{"data-slot":`table-cell`,className:P(`px-3 py-3 align-middle text-sm`,e),...t})}var Kt={pending:`Needs review`,selected:`Assigned to onboarder`,reachingout:`Reaching out`,awaitingcontribution:`Awaiting contribution`,onboarded:`Onboarded`,waitlist:`Waitlist`,rejected:`Rejected`};function qt(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`})}function Jt(e,t=new Date){if(!e)return null;let n=new Date(e);if(Number.isNaN(n.getTime()))return null;let r=t.getTime()-n.getTime();return r<0?0:Math.floor(r/864e5)}function Yt(e){return e==null?``:JSON.stringify(e,null,2)}function Xt(e){return e.onboarding_state||e.onboardingState||e.cOnboardingState||``}function Zt(e){let t=String(e||``).trim();if(!t)return`No status`;let n=t.toLowerCase();return Kt[n]?Kt[n]:t.replace(/[-_]+/g,` `).replace(/\s+/g,` `).trim().replace(/\b\w/g,e=>e.toUpperCase())}function Qt(e){let t=String(e||``).trim().toLowerCase();return!t||t===`pending`?`neutral`:t===`selected`?`queued`:t===`rejected`?`failed`:t===`onboarded`?`succeeded`:t===`waitlist`?`running`:`queued`}function $t(e){let t=String(e||``).trim();return!t||t.toLowerCase()===`none`?``:t}function en(e){let t=String(e||``).trim();return t?/^https?:\/\//i.test(t)?t:`https://${t.replace(/^\/+/,``)}`:``}function tn(e){try{return new URL(en(e))}catch{return null}}function nn(e,t){let n=e.toLowerCase();return n===t||n.endsWith(`.${t}`)}function rn(e){return e.split(`/`).filter(Boolean).map(e=>encodeURIComponent(e)).join(`/`)}function an(e){let t=String(e||``).trim();if(!t)return``;let n=tn(t);if(n&&nn(n.hostname,`linkedin.com`))return n.href;if(/^https?:\/\//i.test(t))return``;let r=t.replace(/^@/,``).replace(/^\/+|\/+$/g,``).replace(/^in\//i,``);return r?`https://www.linkedin.com/in/${rn(r)}`:``}function on(e){let t=String(e||``).trim().replace(/^@/,``);if(!t)return``;let n=tn(t);if(n&&nn(n.hostname,`github.com`))return n.href;if(/^https?:\/\//i.test(t))return``;let r=t.replace(/^\/+|\/+$/g,``);return r?`https://github.com/${rn(r)}`:``}var sn={people:`/dashboard/people`,gigs:`/dashboard/gigs`,projects:`/dashboard/projects`,onboarding:`/dashboard/onboarding`,jobs:`/dashboard/jobs`,agent:`/dashboard/agent`,audit:`/dashboard/audit`},cn={people:`people:read`,gigs:`gigs:read`,projects:`projects:read`,onboarding:`onboarding:read`,jobs:`jobs:read`,agent:`audit:read`,audit:`audit:read`},ln={discord:{label:`Discord`,options:[[`linked`,`Linked`],[`missing`,`Missing`]]},email_508:{label:`508 email`,options:[[`present`,`Present`],[`missing`,`Missing`]]},resume:{label:`Resume`,options:[[`present`,`Present`],[`missing`,`Missing`]]},skills:{label:`Skills`,options:[[`present`,`Parsed`],[`missing`,`Not parsed`]]},sync_status:{label:`Sync status`,options:[[`active`,`Active`],[`conflict`,`Conflict`],[`missing_in_crm`,`Missing in CRM`]]}},un=class extends Error{status;payload;constructor(e,t,n){super(e),this.name=`ApiRequestError`,this.status=t,this.payload=n}};function dn(){return window.location.pathname.split(`/`).filter(Boolean)[1]||``}function fn(){let e=dn();return Object.hasOwn(sn,e)?e:`people`}function pn(e=`gigs`){let[,t,n]=window.location.pathname.split(`/`).filter(Boolean);if(t!==e||!n)return``;try{return decodeURIComponent(n)}catch{return``}}async function V(e,t={}){let n=new Headers(t.headers);n.set(`Accept`,`application/json`);let r=await fetch(e,{credentials:`same-origin`,...t,headers:n});if(r.status===401){let e=`${window.location.pathname}${window.location.search}`||`/dashboard`;throw window.location.assign(`/auth/login?next=${encodeURIComponent(e)}`),Error(`Session expired`)}if(!r.ok){let e=r.statusText,t=null;try{if(t=await r.json(),t&&typeof t==`object`){let n=t;e=n.detail||n.error||e}}catch{e=r.statusText}throw new un(typeof e==`string`?e:JSON.stringify(e),r.status,t)}return r.json()}function mn(e,t,n){if(e===`gigs`){let e=t;if(n===`title`)return e.title||``;if(n===`status`)return e.status||``;if(n===`applications`)return Number(e.application_count||0);if(n===`activity`)return Dn(e)}if(e===`projects`){let e=t;if(n===`display_name`)return e.display_name||``;if(n===`customer`)return e.customer||``;if(n===`status`)return e.source_status||``;if(n===`roster_count`)return Number(e.roster_count||0);if(n===`modified`)return e.source_modified_at||e.last_synced_at||``}if(e===`onboarding`){let e=t,r=e.profile_status||{};if(n===`name`)return e.name||e.email_508||e.email||``;if(n===`onboarding_state`){let t=Xt(e);return t.toLowerCase()===`pending`?`zzz-${t}`:t}if(n===`onboarder`)return e.onboarder||``;if(n===`updated`)return e.onboarding_updated_at||``;if(n===`profile_gaps`)return[!r.discord_linked,!r.latest_resume,Number(r.skills_count||0)<=0].filter(Boolean).length}if(e===`people`){let e=t,r=e.profile_status||{};if(n===`name`)return e.name||e.email_508||e.email||``;if(n===`status`)return[r.crm_active,r.is_member,r.discord_linked,r.email_508,r.latest_resume].filter(Boolean).length;if(n===`discord`)return e.discord_username||e.discord_user_id||``;if(n===`resume`)return e.latest_resume_name||e.latest_resume_id||``}if(e===`audit`){let e=t;if(n===`actor`)return e.actor_display_name||e.actor_subject||e.actor_provider||``}return t[n]??``}function hn(e,t,n){let r=n.direction===`asc`?1:-1;return[...t].sort((t,i)=>{let a=mn(e,t,n.key),o=mn(e,i,n.key);return typeof a==`number`&&typeof o==`number`?(a-o)*r:String(a).localeCompare(String(o),void 0,{numeric:!0})*r})}function gn({label:e,scope:t,sort:n,sortKey:r,onSort:i}){let a=n.key===r,o=n.direction===`asc`?`↑`:`↓`;return(0,F.jsx)(`button`,{type:`button`,"data-sort-scope":t,"data-sort-key":r,className:`text-left font-[inherit] text-inherit hover:text-foreground`,onClick:()=>i(t,r),children:a?`${e} ${o}`:e})}function H({className:e,label:t,scope:n,sort:r,sortKey:i,onSort:a}){return(0,F.jsx)(Gt,{className:e,"aria-sort":r.key===i?r.direction===`asc`?`ascending`:`descending`:`none`,children:(0,F.jsx)(gn,{label:t,scope:n,sort:r,sortKey:i,onSort:a})})}function _n({label:e,value:t,id:n}){return(0,F.jsxs)(R,{className:`p-4`,children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:e}),(0,F.jsx)(`strong`,{id:n,className:`block text-2xl`,children:t})]})}function vn({children:e,hidden:t}){return t?null:(0,F.jsx)(`div`,{className:`px-4 py-7 text-center text-sm text-muted-foreground`,children:e})}function yn(){let e=pn(`projects`),[t,n]=(0,l.useState)(null),[r,i]=(0,l.useState)(fn()),[a,o]=(0,l.useState)({message:``}),[s,c]=(0,l.useState)([]),[u,d]=(0,l.useState)(``),[f,p]=(0,l.useState)([]),[m,v]=(0,l.useState)([]),[ee,te]=(0,l.useState)([]),[ne,ie]=(0,l.useState)({}),[ae,oe]=(0,l.useState)(null),[se,ce]=(0,l.useState)(null),[C,le]=(0,l.useState)(pn()),[ue,de]=(0,l.useState)(e),[w,T]=(0,l.useState)([]),[fe,pe]=(0,l.useState)(!1),[me,E]=(0,l.useState)([]),[D,O]=(0,l.useState)([]),[he,ge]=(0,l.useState)([]),[_e,ve]=(0,l.useState)(null),[ye,be]=(0,l.useState)(null),[xe,Se]=(0,l.useState)({}),[Ce,we]=(0,l.useState)(null),[Te,Ee]=(0,l.useState)({onboarding:{key:`onboarding_state`,direction:`asc`},gigs:{key:`activity`,direction:`desc`},projects:{key:`display_name`,direction:`asc`},jobs:{key:`updated_at`,direction:`desc`},people:{key:`name`,direction:`asc`},agent:{key:`occurred_at`,direction:`desc`},audit:{key:`occurred_at`,direction:`desc`}}),[De,Oe]=(0,l.useState)(`60`),[ke,Ae]=(0,l.useState)(``),[je,Me]=(0,l.useState)(``),[Ne,Pe]=(0,l.useState)(``),[Fe,Ie]=(0,l.useState)(100),[Le,Re]=(0,l.useState)(``),[ze,Be]=(0,l.useState)(e?``:`Open`),[Ve,He]=(0,l.useState)(7),[Ue,We]=(0,l.useState)(``),[Ge,Ke]=(0,l.useState)(``),[qe,Je]=(0,l.useState)({}),[Ye,Xe]=(0,l.useState)(`discord`),[Ze,Qe]=(0,l.useState)(`linked`),[k,$e]=(0,l.useState)(``),[et,tt]=(0,l.useState)(``),[nt,rt]=(0,l.useState)(``),[it,at]=(0,l.useState)({}),[ot,st]=(0,l.useState)(`discord`),[ct,lt]=(0,l.useState)(`linked`),A=(0,l.useRef)(()=>void 0);function ut(e){return s.includes(e)}function dt(e){return ut(cn[e])}function ft(){return Object.keys(sn).find(e=>dt(e))||`people`}function j(e,t){o({message:e,tone:t})}function M(e,t){Se(n=>({...n,[e]:t}))}function pt(e,t=!1){let n=e;dt(n)||(j(`${n[0].toUpperCase()}${n.slice(1)} requires SSO validation`,`error`),n=ft()),n!==`gigs`&&le(``),n!==`projects`&&de(``),n===`gigs`&&t&&le(``),n===`projects`&&t&&de(``),i(n),t?window.history.pushState({view:n},``,sn[n]):(!Object.hasOwn(sn,dn())||n!==e)&&window.history.replaceState({view:n},``,sn[n])}A.current=pt;function mt(e){return!u||!e?``:`${u}/#Contact/view/${encodeURIComponent(e)}`}function N(e){return!u||!e?``:`${u}/api/v1/Attachment/file/${encodeURIComponent(e)}`}function ht(e,t){Ee(n=>{let r=n[e];return{...n,[e]:{key:t,direction:r.key===t&&r.direction===`asc`?`desc`:`asc`}}})}function gt(e){le(e),ce(m.find(t=>t.id===e)||null),i(`gigs`),window.history.pushState({view:`gigs`,gigId:e},``,`/dashboard/gigs/${encodeURIComponent(e)}`)}function _t(){le(``),ce(null),window.history.replaceState({view:`gigs`},``,sn.gigs)}function vt(e){de(e),i(`projects`),window.history.pushState({view:`projects`,projectId:e},``,`/dashboard/projects/${encodeURIComponent(e)}`)}function yt(){de(``),window.history.replaceState({view:`projects`},``,sn.projects)}async function bt(){let e=await V(`/dashboard/api/me`);n(e);let t=Array.isArray(e.permissions)?e.permissions:[];return c(t),d((e.crm_base_url||``).replace(/\/+$/,``)),t}function xt(){let e=new URLSearchParams({minutes:De,limit:`100`});return ke&&e.set(`status`,ke),je.trim()&&e.set(`type`,je.trim()),`/dashboard/api/jobs?${e.toString()}`}function St(){let e=new URLSearchParams({limit:String(Fe)});return Ne&&e.set(`status`,Ne),`/dashboard/api/gigs?${e.toString()}`}function Ct(){let e=new URLSearchParams({limit:`100`,status:ze});return Le.trim()&&e.set(`query`,Le.trim()),`/dashboard/api/projects?${e.toString()}`}async function wt(){M(`jobs`,!0),j(`Loading jobs`);try{let e=await V(xt());p(e),j(`Loaded ${e.length} jobs`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to load jobs`,`error`)}finally{M(`jobs`,!1)}}async function Tt(){M(`gigs`,!0);try{let e=await V(St());v(e),j(`Loaded ${e.length} gig${e.length===1?``:`s`}`,`ok`),Ft()}catch(e){j(e instanceof Error?e.message:`Unable to load gigs`,`error`)}finally{M(`gigs`,!1)}}async function Et(){M(`projects`,!0);try{let e=await V(Ct());te(e.projects||[]),ie(e.summary||{}),j(`Loaded ${(e.projects||[]).length} project${(e.projects||[]).length===1?``:`s`}`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to load projects`,`error`)}finally{M(`projects`,!1)}}async function Dt(){M(`syncProjects`,!0),j(`Queueing project sync`);try{j(`Queued project sync ${(await V(`/dashboard/api/sync/projects`,{method:`POST`})).job_id}`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to queue project sync`,`error`)}finally{M(`syncProjects`,!1)}}async function Ot(e,t){M(`project:${e}:status`,!0);try{let n=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t})});te(t=>t.map(t=>t.id===e?n.project:t)),j(`Updated project status`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to update project`,`error`)}finally{M(`project:${e}:status`,!1)}}async function kt(e,t){if(e.length===0)return!1;M(`projectsBulkUpdate`,!0);try{let n=await V(`/dashboard/api/projects/bulk`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({project_ids:e,...t})}),r=n.projects||[];te(e=>e.map(e=>r.find(t=>t.id===e.id)||e));let i=n.failures||[];return j(i.length?`Updated ${r.length}; ${i.length} failed`:`Updated ${r.length} project${r.length===1?``:`s`}`,i.length?`error`:`ok`),i.length===0}catch(e){return j(e instanceof Error?e.message:`Unable to bulk update projects`,`error`),!1}finally{M(`projectsBulkUpdate`,!1)}}async function At(e,t,n){let r=t.trim();if(!r)return!1;M(`project:${e}:user`,!0);try{let t=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/users`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({user:r,...n||{}})});return te(n=>n.map(n=>n.id===e?t.project:n)),j(t.activity_cost?`Added project user and rate`:`Added project user`,`ok`),!0}catch(e){return j(e instanceof Error?e.message:`Unable to add project user`,`error`),!1}finally{M(`project:${e}:user`,!1)}}async function jt(e,t,n){let r=t.trim();if(!r)return!1;M(`project:${e}:historical`,!0);try{let t=await V(`/dashboard/api/projects/${encodeURIComponent(e)}/historical-members`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({person:r,candidate_id:n})});return te(n=>n.map(n=>n.id===e?t.project:n)),we(null),j(`Added historical project member`,`ok`),!0}catch(t){if(t instanceof un&&t.status===409){let n=t.payload?.candidates||[];if(n.length>0)return we({projectId:e,person:r,candidates:n}),j(`Choose the matching person record`,`error`),!1}return j(t instanceof Error?t.message:`Unable to add historical member`,`error`),!1}finally{M(`project:${e}:historical`,!1)}}async function Mt(e,t,n){M(`project:${e}:wiki`,!0);try{await V(`/dashboard/api/projects/${encodeURIComponent(e)}/wiki-match`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t,row_key:n})}),j(t===`no_row`?`Marked as no wiki row`:`Confirmed wiki match`,`ok`),await Nt()}catch(e){j(e instanceof Error?e.message:`Unable to save wiki match`,`error`)}finally{M(`project:${e}:wiki`,!1)}}async function Nt(){M(`wikiMatches`,!0);try{oe(await V(`/dashboard/api/projects/wiki-matches`)),j(`Loaded wiki match preview`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to load wiki matches`,`error`)}finally{M(`wikiMatches`,!1)}}async function Pt(e){M(`gig:${e}:detail`,!0);try{ce(await V(`/dashboard/api/gigs/${encodeURIComponent(e)}`))}catch(e){ce(null),j(e instanceof Error?e.message:`Unable to load gig`,`error`)}finally{M(`gig:${e}:detail`,!1)}}async function I(){await Tt(),C&&await Pt(C)}async function Ft(){if(ut(`gigs:read`)){M(`notifications`,!0);try{let e=await V(`/dashboard/api/notifications?limit=20`);He(e.stale_days||7),T(e.notifications||[])}catch(e){j(e instanceof Error?e.message:`Unable to load notifications`,`error`)}finally{M(`notifications`,!1)}}}async function R(e,t){M(`gig:${e}:status`,!0);try{let n=(await V(`/dashboard/api/gigs/${encodeURIComponent(e)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:t})})).discord_title_sync?.status;j(n===`error`?`Updated gig status; Discord title sync failed`:`Updated gig status`,n===`error`?`error`:`ok`),await Tt(),C===e&&await Pt(e)}catch(e){j(e instanceof Error?e.message:`Unable to update gig`,`error`)}finally{M(`gig:${e}:status`,!1)}}async function It(e,t,n){M(`application:${t}:status`,!0);try{await V(`/dashboard/api/gigs/${encodeURIComponent(e)}/applications/${encodeURIComponent(t)}/status`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({status:n})}),j(`Updated candidate status`,`ok`),await Tt(),C===e&&await Pt(e)}catch(e){j(e instanceof Error?e.message:`Unable to update candidate`,`error`)}finally{M(`application:${t}:status`,!1)}}function Lt(){let e=new URLSearchParams({limit:`25`});Ue.trim()&&e.set(`query`,Ue.trim()),Ge&&e.set(`is_member`,Ge);for(let[t,n]of Object.entries(qe))n&&e.set(t,n);return`/dashboard/api/people?${e.toString()}`}async function Rt(){M(`people`,!0);try{E(await V(Lt()))}catch(e){j(e instanceof Error?e.message:`Unable to load people`,`error`)}finally{M(`people`,!1)}}function zt(){let e=new URLSearchParams({limit:`25`});k.trim()&&e.set(`query`,k.trim()),et&&e.set(`onboarding_state`,et),nt.trim()&&e.set(`onboarder`,nt.trim());for(let[t,n]of Object.entries(it))n&&e.set(t,n);return`/dashboard/api/onboarding?${e.toString()}`}async function z(){M(`onboarding`,!0);try{O(await V(zt()))}catch(e){j(e instanceof Error?e.message:`Unable to load onboarding`,`error`)}finally{M(`onboarding`,!1)}}async function Bt(){M(`audit`,!0);try{ge(await V(`/dashboard/api/audit-events?limit=25`))}catch(e){j(e instanceof Error?e.message:`Unable to load audit events`,`error`)}finally{M(`audit`,!1)}}async function Vt(){M(`agent`,!0);try{ve(await V(`/dashboard/api/agent?limit=100`))}catch(e){j(e instanceof Error?e.message:`Unable to load agent report`,`error`)}finally{M(`agent`,!1)}}async function Ht(e){M(`detail:${e}`,!0),j(`Loading ${e}`);try{be(await V(`/dashboard/api/jobs/${encodeURIComponent(e)}`)),j(`Loaded ${e}`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to load job detail`,`error`)}finally{M(`detail:${e}`,!1)}}async function Ut(e){M(`rerun:${e}`,!0),j(`Rerunning ${e}`);try{j(`Queued rerun ${(await V(`/dashboard/api/jobs/${encodeURIComponent(e)}/rerun`,{method:`POST`})).job_id}`,`ok`),await wt()}catch(e){j(e instanceof Error?e.message:`Unable to rerun job`,`error`)}finally{M(`rerun:${e}`,!1)}}async function Wt(){M(`syncPeople`,!0),j(`Queueing people sync`);try{j(`Queued people sync ${(await V(`/dashboard/api/sync/people`,{method:`POST`})).job_id}`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to queue people sync`,`error`)}finally{M(`syncPeople`,!1)}}async function Gt(e,t){let n=String(e||``).trim(),r=t.trim();if(!n){j(`Missing CRM contact id`,`error`);return}if(!r){j(`Enter a 508 username`,`error`);return}M(`onboarder:${n}`,!0),j(`Assigning ${r}`);try{let e=await V(`/dashboard/api/onboarding/${encodeURIComponent(n)}/onboarder`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({onboarder:r})});O(t=>t.map(t=>t.crm_contact_id===e.contact_id?{...t,onboarder:e.onboarder,onboarding_state:e.state_updated&&e.onboarding_state?e.onboarding_state:t.onboarding_state,onboarding_status_label:e.onboarding_status_label||(e.state_updated?void 0:t.onboarding_status_label)}:t)),j(`Assigned ${e.onboarder}`,`ok`)}catch(e){j(e instanceof Error?e.message:`Unable to assign onboarder`,`error`)}finally{M(`onboarder:${n}`,!1)}}async function B(e){let t=e.email.trim().toLowerCase(),n=e.first_name.trim();if(!t?.endsWith(`@508.dev`))return j(`Enter the engineer's @508.dev email`,`error`),null;if(!n)return j(`Enter the engineer name`,`error`),null;M(`engineerSetup`,!0);try{let r=await V(`/dashboard/api/onboarding/engineers`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({...e,email:t,first_name:n})});return j(`Set up ${r.employee_name||r.user||t}`,`ok`),r}catch(e){if(e instanceof un&&e.status===409){let t=(e.payload.matches||[]).map(e=>e.label||e.email).filter(Boolean).slice(0,2).join(`, `);j(t?`Similar account exists: ${t}`:`Similar account exists; confirm before creating`,`error`)}else j(e instanceof Error?e.message:`Unable to set up engineer`,`error`);return null}finally{M(`engineerSetup`,!1)}}async function Kt(){M(`logout`,!0);try{let e=await V(`/auth/logout`,{method:`POST`});window.location.assign(e.end_session_url||`/dashboard`)}catch(e){j(e instanceof Error?e.message:`Unable to log out`,`error`),M(`logout`,!1)}}(0,l.useEffect)(()=>{bt().then(e=>{let t=fn(),n=e.includes(cn[t])?t:Object.keys(sn).find(t=>e.includes(cn[t]))||`people`;le(n===`gigs`?pn():``),de(n===`projects`?pn(`projects`):``),i(n),(!Object.hasOwn(sn,dn())||n!==t)&&window.history.replaceState({view:n},``,sn[n])}).catch(e=>{j(e instanceof Error?e.message:`Dashboard failed to load`,`error`)})},[]),(0,l.useEffect)(()=>{let e=()=>{le(pn()),de(pn(`projects`)),A.current(fn(),!1)};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]),(0,l.useEffect)(()=>{if(!a.message)return;let e=window.setTimeout(()=>o({message:``}),4500);return()=>window.clearTimeout(e)},[a.message]),(0,l.useEffect)(()=>{s.length!==0&&(ut(`gigs:read`)&&Ft(),r===`people`&&Rt(),r===`gigs`&&Tt(),r===`projects`&&Et(),r===`onboarding`&&z(),r===`jobs`&&wt(),r===`agent`&&Vt(),r===`audit`&&Bt())},[r]),(0,l.useEffect)(()=>{s.length!==0&&(ut(`gigs:read`)&&Ft(),r===`people`&&Rt(),r===`gigs`&&Tt(),r===`projects`&&Et(),r===`onboarding`&&z(),r===`jobs`&&wt(),r===`agent`&&Vt(),r===`audit`&&Bt())},[s]),(0,l.useEffect)(()=>{r===`jobs`&&s.length>0&&wt()},[De,ke]),(0,l.useEffect)(()=>{r===`gigs`&&s.length>0&&Tt()},[Ne,Fe]),(0,l.useEffect)(()=>{r===`projects`&&s.length>0&&Et()},[ze]),(0,l.useEffect)(()=>{r===`gigs`&&C&&s.length>0&&Pt(C)},[r,C,s]),(0,l.useEffect)(()=>{r===`people`&&s.length>0&&Rt()},[Ge]),(0,l.useEffect)(()=>{r===`people`&&s.length>0&&Rt()},[qe]),(0,l.useEffect)(()=>{r===`onboarding`&&s.length>0&&z()},[et]),(0,l.useEffect)(()=>{r===`onboarding`&&s.length>0&&z()},[it]);let qt=(0,l.useMemo)(()=>hn(`jobs`,f,Te.jobs),[f,Te.jobs]),Jt=(0,l.useMemo)(()=>hn(`people`,me,Te.people),[me,Te.people]),Yt=(0,l.useMemo)(()=>hn(`onboarding`,D,Te.onboarding),[D,Te.onboarding]),Xt=(0,l.useMemo)(()=>hn(`gigs`,m,Te.gigs),[m,Te.gigs]),Zt=(0,l.useMemo)(()=>hn(`projects`,ee,Te.projects),[ee,Te.projects]),Qt=(0,l.useMemo)(()=>se?.id===C?se:Xt.find(e=>e.id===C)||null,[se,C,Xt]),$t=(0,l.useMemo)(()=>Zt.find(e=>e.id===ue)||null,[ue,Zt]),en=(0,l.useMemo)(()=>hn(`audit`,he,Te.audit),[he,Te.audit]),tn=(0,l.useMemo)(()=>f.reduce((e,t)=>(e[t.status]=(e[t.status]||0)+1,e),{}),[f]),nn=Object.keys(ln).filter(e=>!qe[e]),rn=Object.keys(ln).filter(e=>e!==`sync_status`&&e!==`email_508`&&!it[e]);function an(e){e.type===`stale_recruiting_gig`&&(Pe(`recruiting`),pt(`gigs`,!0)),pe(!1)}(0,l.useEffect)(()=>{!nn.includes(Ye)&&nn[0]&&Xe(nn[0])},[nn,Ye]),(0,l.useEffect)(()=>{let e=ln[Ye]?.options;e?.[0]&&!e.some(([e])=>e===Ze)&&Qe(e[0][0])},[Ye,Ze]),(0,l.useEffect)(()=>{!rn.includes(ot)&&rn[0]&&st(rn[0])},[rn,ot]),(0,l.useEffect)(()=>{let e=ln[ot]?.options;e?.[0]&&!e.some(([e])=>e===ct)&<(e[0][0])},[ot,ct]);let on=[t?.email,t?.crm_contact_id?`CRM ${t.crm_contact_id}`:``,t?.actor_provider].filter(Boolean).join(` | `);return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsx)(`header`,{className:`sticky top-0 z-20 border-b bg-background/90 backdrop-blur`,children:(0,F.jsxs)(`div`,{className:`mx-auto flex max-w-7xl flex-col gap-4 px-5 py-4 md:flex-row md:items-center md:justify-between`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h1`,{className:`text-xl font-bold`,children:`508 Operations Dashboard`}),(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Operations view for authenticated 508 operators.`})]}),(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[ut(`gigs:read`)?(0,F.jsx)(`div`,{className:`relative`,children:(0,F.jsxs)(L,{id:`notifications`,type:`button`,variant:`outline`,size:`icon`,"aria-label":`Notifications`,"aria-expanded":fe,onClick:()=>pe(e=>!e),children:[(0,F.jsx)(h,{}),w.length>0?(0,F.jsx)(`span`,{className:`absolute -right-1 -top-1 grid min-h-5 min-w-5 place-items-center rounded-full bg-red-500 px-1 text-[11px] font-bold text-white`,children:w.length}):null]})}):null,(0,F.jsxs)(`div`,{className:`grid min-w-0 gap-0.5 text-right text-sm text-muted-foreground`,children:[(0,F.jsx)(`strong`,{id:`userName`,className:`truncate text-foreground`,children:t?.display_name||t?.email||t?.subject||`Loading user`}),(0,F.jsx)(`span`,{id:`userMeta`,className:`truncate`,children:on||`Checking session`})]}),(0,F.jsxs)(L,{id:`logout`,type:`button`,variant:`outline`,onClick:Kt,disabled:xe.logout,children:[(0,F.jsx)(x,{}),`Log out`]})]})]})}),(0,F.jsx)(bn,{open:fe,notifications:w,loading:xe.notifications,onClose:()=>pe(!1),onRefresh:Ft,onOpenNotification:an}),(0,F.jsx)(Sn,{toast:a}),(0,F.jsx)(xn,{choice:Ce,loading:!!(Ce&&xe[`project:${Ce.projectId}:historical`]),crmContactUrl:mt,onClose:()=>we(null),onChoose:e=>{Ce&&jt(Ce.projectId,Ce.person,e)}}),(0,F.jsxs)(`main`,{className:`mx-auto grid max-w-7xl grid-cols-1 gap-5 px-5 py-5 md:grid-cols-[190px_minmax(0,1fr)]`,children:[(0,F.jsx)(`nav`,{className:`grid content-start gap-1 md:sticky md:top-24`,"aria-label":`Dashboard sections`,children:[[`people`,`People`,re],[`gigs`,`Gigs`,g],[`projects`,`Projects`,b],[`onboarding`,`Onboarding`,_],[`jobs`,`Jobs`,g],[`agent`,`Agent`,S],[`audit`,`Audit`,y]].filter(([e])=>dt(e)).map(([e,t,n])=>(0,F.jsxs)(`a`,{className:P(`flex min-h-10 items-center gap-2 rounded-md border border-transparent px-3 text-sm font-extrabold text-muted-foreground hover:border-border hover:bg-secondary hover:text-foreground`,r===e&&`border-primary bg-accent text-accent-foreground`),"data-view-link":e,"data-permission":cn[e],href:sn[e],"aria-current":r===e?`page`:void 0,onClick:t=>{t.preventDefault(),pt(e,!0)},children:[(0,F.jsx)(n,{className:`size-4`}),t]},e))}),(0,F.jsxs)(`div`,{className:`grid min-w-0 gap-5`,children:[r===`people`?(0,F.jsx)(Vn,{crmBaseUrl:u,people:Jt,sort:Te.people,canSync:ut(`people:sync`),loading:xe,peopleQuery:Ue,peopleMember:Ge,peopleFilters:qe,peopleFilterKind:Ye,peopleFilterValue:Ze,peopleFilterKeys:nn,onSearch:Rt,onSync:Wt,onSort:e=>ht(`people`,e),setPeopleQuery:We,setPeopleMember:Ke,setPeopleFilterKind:Xe,setPeopleFilterValue:Qe,addFilter:()=>{Je(e=>({...e,[Ye]:Ze}))},removeFilter:e=>{Je(t=>{let n={...t};return delete n[e],n})},crmContactUrl:mt,crmAttachmentUrl:N}):null,r===`gigs`?(0,F.jsx)(In,{gigs:Xt,selectedGig:Qt,selectedGigId:C,sort:Te.gigs,loading:xe,status:Ne,limit:Fe,staleDays:Ve,canWrite:ut(`gigs:write`),crmContactUrl:mt,crmAttachmentUrl:N,setStatus:Pe,setLimit:Ie,onRefresh:I,onSort:e=>ht(`gigs`,e),onOpenGig:gt,onCloseGig:_t,onUpdateStatus:R,onUpdateApplicationStatus:It}):null,r===`projects`?(0,F.jsx)(Nn,{projects:Zt,selectedProject:$t,selectedProjectId:ue,summary:ne,wikiMatches:ae,sort:Te.projects,loading:xe,query:Le,status:ze,canSync:ut(`projects:sync`),canWrite:ut(`projects:write`),crmContactUrl:mt,setQuery:Re,setStatus:Be,onSearch:Et,onSync:Dt,onUpdateStatus:Ot,onBulkUpdate:kt,onAddUser:At,onAddHistoricalMember:jt,onUpdateWikiMatch:Mt,onWikiMatches:Nt,onOpenProject:vt,onCloseProject:yt,onSort:e=>ht(`projects`,e)}):null,r===`onboarding`?(0,F.jsx)(Hn,{people:Yt,sort:Te.onboarding,loading:xe,onboardingQuery:k,onboardingState:et,onboarderFilter:nt,onboardingFilters:it,onboardingFilterKind:ot,onboardingFilterValue:ct,onboardingFilterKeys:rn,onSearch:z,onSort:e=>ht(`onboarding`,e),onAssign:Gt,onSetupEngineer:B,setOnboardingQuery:$e,setOnboardingState:tt,setOnboarderFilter:rt,setOnboardingFilterKind:st,setOnboardingFilterValue:lt,addFilter:()=>{at(e=>({...e,[ot]:ct}))},removeFilter:e=>{at(t=>{let n={...t};return delete n[e],n})},crmContactUrl:mt,crmAttachmentUrl:N,canWrite:ut(`onboarding:write`)}):null,r===`jobs`?(0,F.jsx)(Gn,{jobs:qt,jobDetail:ye,sort:Te.jobs,loading:xe,minutes:De,status:ke,jobType:je,jobCounts:tn,canWrite:ut(`jobs:write`),setMinutes:Oe,setStatus:Ae,setJobType:Me,onSearch:wt,onSort:e=>ht(`jobs`,e),onDetail:Ht,onRerun:Ut}):null,r===`audit`?(0,F.jsx)(Kn,{events:en,sort:Te.audit,loading:xe,onRefresh:Bt,onSort:e=>ht(`audit`,e)}):null,r===`agent`?(0,F.jsx)(qn,{report:_e,loading:xe,onRefresh:Vt}):null]})]})]})}function bn({open:e,notifications:t,loading:n,onClose:r,onRefresh:i,onOpenNotification:a}){return e?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-40`,"aria-labelledby":`notificationsTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close notifications`,onClick:r}),(0,F.jsxs)(`aside`,{className:`absolute right-0 top-0 grid h-full w-full max-w-md grid-rows-[auto_minmax(0,1fr)] border-l bg-background shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-3 border-b p-4`,children:[(0,F.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,F.jsx)(`strong`,{id:`notificationsTitle`,className:`text-base`,children:`Notifications`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:t.length===0?`No active notifications`:`${t.length} active`})]}),(0,F.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`outline`,size:`sm`,onClick:i,disabled:n,children:[(0,F.jsx)(ee,{}),`Refresh`]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close`,onClick:r,children:(0,F.jsx)(ie,{})})]})]}),(0,F.jsx)(`div`,{className:`min-h-0 overflow-auto p-4`,children:t.length===0?(0,F.jsx)(`div`,{className:`rounded-md border border-dashed p-6 text-sm text-muted-foreground`,children:`No active notifications.`}):(0,F.jsx)(`div`,{className:`grid gap-3`,children:t.map(e=>(0,F.jsxs)(`button`,{type:`button`,className:`grid gap-2 rounded-md border p-3 text-left hover:bg-secondary`,onClick:()=>a(e),children:[(0,F.jsx)(`span`,{className:`text-sm font-bold`,children:e.title}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.message})]},e.id))})})]})]}):null}function xn({choice:e,loading:t,crmContactUrl:n,onClose:r,onChoose:i}){return e?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-50 grid place-items-center p-4`,"aria-labelledby":`historicalPersonChoiceTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close person selection`,onClick:r}),(0,F.jsxs)(`div`,{className:`relative grid w-full max-w-2xl gap-4 rounded-md border bg-background p-5 shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`strong`,{id:`historicalPersonChoiceTitle`,className:`block text-base`,children:`Choose person record`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.person})]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close person selection`,onClick:r,children:(0,F.jsx)(ie,{})})]}),(0,F.jsx)(`div`,{className:`grid gap-2`,children:e.candidates.map(e=>(0,F.jsxs)(`div`,{className:`grid gap-3 rounded-md border p-3 md:grid-cols-[minmax(0,1fr)_auto] md:items-center`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block truncate`,children:e.label||e.full_name||e.email||`Person`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1 text-sm text-muted-foreground`,children:[e.email?(0,F.jsx)(`span`,{children:e.email}):null,e.sources?.length?(0,F.jsx)(`span`,{children:e.sources.join(`, `)}):null,e.erpnext_user_id?(0,F.jsxs)(`span`,{children:[`ERP `,e.erpnext_user_id]}):null,e.supplier_erpnext_id?(0,F.jsxs)(`span`,{children:[`Supplier `,e.supplier_erpnext_id]}):null,e.crm_contact_id&&n(e.crm_contact_id)?(0,F.jsx)(`a`,{className:`font-semibold text-primary underline-offset-4 hover:underline`,href:n(e.crm_contact_id),target:`_blank`,rel:`noreferrer`,children:`CRM`}):null]})]}),(0,F.jsx)(L,{type:`button`,disabled:t,onClick:()=>i(e.candidate_id),children:`Select`})]},e.candidate_id))})]})]}):null}function Sn({toast:e}){return e.message?(0,F.jsx)(`div`,{id:`toast`,role:`status`,className:P(`fixed bottom-5 right-5 z-50 max-w-sm rounded-md border bg-background px-4 py-3 text-sm font-semibold shadow-lg`,e.tone===`ok`&&`border-emerald-500/40 text-emerald-300`,e.tone===`error`&&`border-red-500/40 text-red-300`),children:e.message}):null}function Cn({filters:e,onRemove:t,suffix:n=`filter`}){return(0,F.jsx)(`fieldset`,{className:`m-0 flex min-h-7 flex-wrap gap-2 border-0 p-0`,"aria-label":`Active filters`,children:Object.entries(e).map(([e,r])=>{let i=ln[e],a=i.options.find(([e])=>e===r),o=`${i.label}: ${a?a[1]:r}`;return(0,F.jsxs)(L,{type:`button`,variant:`outline`,size:`sm`,className:`rounded-full`,"aria-label":`Remove ${o} ${n}`,onClick:()=>t(e),children:[o,` x`]},e)})})}var wn=[`recruiting`,`filled`,`unknown`,`lost`,`outdated`],Tn=[`suggested`,`interested`,`reviewing`,`contacted`,`accepted`,`rejected`,`withdrawn`];function En(e){return String(e||``).replace(/[-_]+/g,` `).replace(/\s+/g,` `).trim().replace(/\b\w/g,e=>e.toUpperCase())}function Dn(e){let t=[e.last_activity_at,e.last_status_changed_at,e.posted_at,e.created_at].map(e=>e?new Date(e).getTime():NaN).filter(e=>!Number.isNaN(e));return t.length>0?new Date(Math.max(...t)).toISOString():``}function On(e,t){if(e.status!==`recruiting`)return null;let n=Jt(Dn(e));return n===null||ne.projects.map(e=>e.id),[e.projects]),f=(0,l.useMemo)(()=>new Set(d),[d]),p=n.filter(e=>f.has(e)),h=e.projects.length>0&&p.length===e.projects.length;(0,l.useEffect)(()=>{r(e=>e.filter(e=>f.has(e)))},[f]);function g(e,t){r(n=>t?Array.from(new Set([...n,e])):n.filter(t=>t!==e))}async function _(){let t={};i&&(t.status=i),o&&(t.project_type=o),await e.onBulkUpdate(p,t)&&(r([]),a(``),s(``),u(!1))}let y=(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-[minmax(0,1fr)_180px_auto_auto_auto] md:items-end`,children:[(0,F.jsxs)(z,{children:[`Search projects`,(0,F.jsx)(zt,{id:`projectQuery`,value:e.query,autoComplete:`off`,placeholder:`Project, customer, ERP id`,onChange:t=>e.setQuery(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(z,{children:[`Status`,(0,F.jsxs)(Bt,{id:`projectStatus`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:``,children:`Any status`})]})]}),(0,F.jsxs)(L,{id:`refreshProjects`,type:`button`,onClick:e.onSearch,disabled:e.loading.projects,children:[(0,F.jsx)(ee,{}),`Refresh`]}),e.canSync?(0,F.jsxs)(L,{id:`syncProjects`,type:`button`,variant:`outline`,onClick:e.onSync,disabled:e.loading.syncProjects,children:[(0,F.jsx)(ee,{}),`Sync ERP`]}):null,(0,F.jsxs)(L,{id:`wikiProjectMatches`,type:`button`,variant:`outline`,onClick:e.onWikiMatches,disabled:e.loading.wikiMatches,children:[(0,F.jsx)(te,{}),`Wiki match`]})]});return e.selectedProjectId&&!e.selectedProject&&e.loading.projects?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Project detail`})}),(0,F.jsx)(Rt,{className:`text-sm text-muted-foreground`,children:`Loading project.`})]})]}):e.selectedProjectId&&!e.selectedProject?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Project detail`})}),(0,F.jsxs)(Rt,{className:`grid gap-3`,children:[(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`This project is not in the current result set. Clear filters or refresh the project list.`}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onCloseProject,children:[(0,F.jsx)(m,{}),`Back to projects`]})]})]})]}):e.selectedProject?(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsx)(Fn,{project:e.selectedProject,loading:e.loading,canWrite:e.canWrite,crmContactUrl:e.crmContactUrl,onBack:e.onCloseProject,onUpdateStatus:e.onUpdateStatus,onAddUser:e.onAddUser,onAddHistoricalMember:e.onAddHistoricalMember})]}):(0,F.jsxs)(F.Fragment,{children:[y,(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-2`,"aria-label":`Project summary`,children:[(0,F.jsx)(_n,{id:`projectMetricOpen`,label:`Open`,value:e.summary.open_project_count||0}),(0,F.jsx)(_n,{id:`projectMetricTotal`,label:`Projects`,value:e.summary.project_count||0})]}),e.canWrite?(0,F.jsxs)(R,{className:`flex flex-wrap items-center justify-between gap-3 p-4`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Selected`}),(0,F.jsxs)(`strong`,{className:`block`,children:[p.length,` project(s)`]})]}),(0,F.jsx)(L,{type:`button`,disabled:p.length===0,onClick:()=>u(!0),children:`Bulk edit`})]}):null,c?(0,F.jsxs)(`div`,{className:`fixed inset-0 z-50 grid place-items-center p-4`,"aria-labelledby":`bulkProjectEditTitle`,"aria-modal":`true`,role:`dialog`,children:[(0,F.jsx)(`button`,{type:`button`,className:`absolute inset-0 cursor-default bg-black/45`,"aria-label":`Close bulk project edit`,onClick:()=>u(!1)}),(0,F.jsxs)(`div`,{className:`relative grid w-full max-w-lg gap-4 rounded-md border bg-background p-5 shadow-2xl`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`strong`,{id:`bulkProjectEditTitle`,className:`block text-base`,children:`Bulk edit projects`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[p.length,` selected`]})]}),(0,F.jsx)(L,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Close bulk project edit`,onClick:()=>u(!1),children:(0,F.jsx)(ie,{})})]}),(0,F.jsxs)(`div`,{className:`grid gap-3`,children:[(0,F.jsx)(`strong`,{className:`text-sm`,children:`Changes`}),(0,F.jsxs)(z,{children:[`Status`,(0,F.jsxs)(Bt,{value:i,onChange:e=>a(e.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`No change`}),(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:`Completed`,children:`Completed`}),(0,F.jsx)(`option`,{value:`Cancelled`,children:`Cancelled`})]})]}),(0,F.jsxs)(z,{children:[`ERP Type`,(0,F.jsxs)(Bt,{value:o,onChange:e=>s(e.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`No change`}),(0,F.jsx)(`option`,{value:`Internal`,children:`Internal`}),(0,F.jsx)(`option`,{value:`External`,children:`External`})]})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,F.jsx)(L,{type:`button`,variant:`outline`,onClick:()=>u(!1),children:`Cancel`}),(0,F.jsx)(L,{type:`button`,disabled:e.loading.projectsBulkUpdate||p.length===0||!i&&!o,onClick:()=>void _(),children:`Apply changes`})]})]})]}):null,(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`ERP projects`}),(0,F.jsx)(`span`,{id:`projectsStatus`,className:`text-sm text-muted-foreground`,children:e.loading.projects?`Loading`:`${e.projects.length} shown | synced ${qt(e.summary.last_synced_at)}`})]}),(0,F.jsx)(vn,{hidden:e.projects.length!==0,children:`No projects match this view. Sync ERP projects if the cache is empty.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`projectsTable`,className:P(`min-w-[1100px]`,e.projects.length===0&&`hidden`),"aria-label":`ERP projects`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[e.canWrite?(0,F.jsx)(Gt,{className:`w-[48px]`,children:(0,F.jsx)(`input`,{type:`checkbox`,"aria-label":`Select all visible projects`,checked:h,onChange:e=>{r(e.target.checked?d:[])}})}):null,(0,F.jsx)(H,{className:`w-[24%]`,label:`Project`,scope:`projects`,sort:e.sort,sortKey:`display_name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[16%]`,label:`Customer`,scope:`projects`,sort:e.sort,sortKey:`customer`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[10%]`,label:`Status`,scope:`projects`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(Gt,{className:`w-[16%]`,children:`Timeline`}),(0,F.jsx)(H,{className:`w-[10%]`,label:`Roster`,scope:`projects`,sort:e.sort,sortKey:`roster_count`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[14%]`,label:`Modified`,scope:`projects`,sort:e.sort,sortKey:`modified`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(Gt,{children:`ERP`})]})}),(0,F.jsx)(Ut,{id:`projectsBody`,children:e.projects.map(t=>{let n=t.roster_members||[];return(0,F.jsxs)(Wt,{children:[e.canWrite?(0,F.jsx)(B,{children:(0,F.jsx)(`input`,{type:`checkbox`,"aria-label":`Select ${t.display_name}`,checked:p.includes(t.id),onChange:e=>g(t.id,e.target.checked)})}):null,(0,F.jsxs)(B,{children:[(0,F.jsx)(`button`,{type:`button`,className:`text-left font-bold text-primary underline-offset-4 hover:underline`,onClick:()=>e.onOpenProject(t.id),children:t.display_name}),(0,F.jsxs)(`div`,{className:`mt-1 flex flex-wrap items-center gap-1.5`,children:[t.project_type?(0,F.jsx)(I,{variant:`neutral`,children:t.project_type}):null,t.linked_engagement_count?(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[t.linked_engagement_count,` linked gig`]}):null]})]}),(0,F.jsx)(B,{children:t.customer_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.customer_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[t.customer,(0,F.jsx)(v,{className:`size-3.5`})]}):t.customer||`None`}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:kn(t.source_status),children:t.source_status||`Unknown`})}),(0,F.jsx)(B,{children:[t.actual_start_date,t.actual_end_date].filter(Boolean).map(e=>An(e)).join(` to `)||`Not set`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`grid gap-1`,children:[(0,F.jsx)(`strong`,{children:n.length}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[n.map(jn).slice(0,4).join(`, `)||`No ERP roster`,n.length>4?` +${n.length-4}`:``]})]})}),(0,F.jsx)(B,{children:qt(t.source_modified_at)}),(0,F.jsx)(B,{className:`text-xs`,children:t.erpnext_project_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-mono font-semibold text-primary underline-offset-4 hover:underline`,href:t.erpnext_project_url,target:`_blank`,rel:`noreferrer`,children:[t.erpnext_project_id,(0,F.jsx)(v,{className:`size-3.5`})]}):(0,F.jsx)(`span`,{className:`font-mono`,children:`Unlinked`})})]},t.id)})})]})})]}),e.wikiMatches?(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Wiki match preview`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[e.wikiMatches.document?.title||`Client & Project Info`,` |`,` `,qt(e.wikiMatches.document?.updatedAt)]})]}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`wikiMatchesTable`,className:`min-w-[920px]`,"aria-label":`Wiki matches`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(Gt,{children:`ERP project`}),(0,F.jsx)(Gt,{children:`Best wiki row`}),(0,F.jsx)(Gt,{children:`Confidence`}),(0,F.jsx)(Gt,{children:`Section`}),(0,F.jsx)(Gt,{children:`Decision`})]})}),(0,F.jsx)(Ut,{children:t.map((t,n)=>{let r=t.project,i=t.best_match?.row||{},a=t.manual_match?.match_status||``,o=r?.id||i.row_key||[i.section,i.Client].filter(Boolean).join(`:`)||`wiki-match-${n}`;return(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:r?.display_name||`Unknown`}),(0,F.jsxs)(B,{children:[(0,F.jsx)(`strong`,{children:i.Client||`No match`}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:[i.DRI,i.Members].filter(Boolean).join(` | `)})]}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:t.best_match?.confidence===`high`?`succeeded`:t.best_match?.confidence===`medium`?`running`:`neutral`,children:t.best_match?`${t.best_match.confidence} ${t.best_match.score}`:`none`})}),(0,F.jsx)(B,{children:i.section||``}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[a?(0,F.jsx)(I,{variant:a===`confirmed`?`succeeded`:`neutral`,children:a===`no_row`?`No wiki row`:`Confirmed`}):null,e.canWrite&&r?.id?(0,F.jsxs)(F.Fragment,{children:[i.row_key?(0,F.jsx)(L,{type:`button`,variant:`outline`,size:`sm`,disabled:e.loading[`project:${r.id}:wiki`],onClick:()=>void e.onUpdateWikiMatch(r.id,`confirmed`,i.row_key),children:`Confirm`}):null,(0,F.jsx)(L,{type:`button`,variant:`outline`,size:`sm`,disabled:e.loading[`project:${r.id}:wiki`],onClick:()=>void e.onUpdateWikiMatch(r.id,`no_row`),children:`No row`})]}):null]})})]},o)})})]})})]}):null]})}function Pn({projectId:e,loading:t,onAddUser:n,onAddHistoricalMember:r}){let[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(``),[d,f]=(0,l.useState)(``),p=i.trim(),m=!!(o.trim()||c.trim()||d.trim()),h=Mn(c),g=Mn(d),_=!!((c.trim()||d.trim())&&!o.trim()),v=!!(o.trim()&&(!c.trim()||!d.trim())),y=!!(c.trim()&&h===void 0)||!!(d.trim()&&g===void 0)||_||v;async function b(){await n(e,i,m?{activity_type:o.trim(),billing_rate:h,costing_rate:g}:void 0)&&(a(``),s(``),u(``),f(``))}return(0,F.jsxs)(`form`,{className:`grid gap-3`,onSubmit:e=>{e.preventDefault(),y||b()},children:[(0,F.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[minmax(0,1fr)_minmax(180px,.7fr)_minmax(130px,.45fr)_minmax(130px,.45fr)]`,children:[(0,F.jsxs)(z,{children:[`ERP user`,(0,F.jsx)(zt,{value:i,autoComplete:`off`,placeholder:`engineer@508.dev`,onChange:e=>a(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Activity Type`,(0,F.jsx)(zt,{value:o,autoComplete:`off`,placeholder:`Optional rate step`,onChange:e=>s(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Billing rate`,(0,F.jsx)(zt,{value:c,inputMode:`decimal`,autoComplete:`off`,placeholder:`USD/hr`,onChange:e=>u(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Costing rate`,(0,F.jsx)(zt,{value:d,inputMode:`decimal`,autoComplete:`off`,placeholder:`USD/hr`,onChange:e=>f(e.target.value)})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,F.jsxs)(L,{type:`submit`,variant:`outline`,disabled:t[`project:${e}:user`]||!p||y,children:[(0,F.jsx)(re,{}),`Add engineer`]}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,disabled:t[`project:${e}:historical`]||!p,onClick:()=>void r(e,i).then(e=>{e&&a(``)}),children:[(0,F.jsx)(re,{}),`Add historical`]})]})]})}function Fn(e){let t=e.project,n=t.roster_members||[],r=[t.actual_start_date||t.expected_start_date,t.actual_end_date||t.expected_end_date].filter(Boolean).map(e=>An(e)).join(` to `)||`Not set`,i=typeof t.percent_complete==`number`?`${Math.round(t.percent_complete)}%`:`Not set`;return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[auto_minmax(0,1fr)_auto] md:items-start`,children:[(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onBack,children:[(0,F.jsx)(m,{}),`Projects`]}),(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(Lt,{children:t.display_name}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-2 text-sm text-muted-foreground`,children:[(0,F.jsx)(I,{variant:kn(t.source_status),children:t.source_status||`Unknown`}),t.erpnext_project_id?(0,F.jsx)(`span`,{className:`font-mono`,children:t.erpnext_project_id}):null,t.last_synced_at?(0,F.jsxs)(`span`,{children:[`Synced `,qt(t.last_synced_at)]}):null]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-start gap-2 md:justify-end`,children:[e.canWrite?(0,F.jsxs)(Bt,{className:`w-[160px]`,"aria-label":`Status for ${t.display_name}`,value:t.source_status||``,disabled:e.loading[`project:${t.id}:status`],onChange:n=>e.onUpdateStatus(t.id,n.target.value),children:[(0,F.jsx)(`option`,{value:`Open`,children:`Open`}),(0,F.jsx)(`option`,{value:`Completed`,children:`Completed`}),(0,F.jsx)(`option`,{value:`Cancelled`,children:`Cancelled`})]}):null,t.erpnext_project_url?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:t.erpnext_project_url,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`ERP project`]}):null,t.customer_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:t.customer_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`ERP customer`]}):null]})]})}),(0,F.jsxs)(Rt,{className:`grid gap-4 md:grid-cols-2 lg:grid-cols-4`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Customer`}),(0,F.jsx)(`strong`,{className:`block`,children:t.customer||`None`})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Timeline`}),(0,F.jsx)(`strong`,{className:`block`,children:r})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Progress`}),(0,F.jsx)(`strong`,{className:`block`,children:i})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Linked Gigs`}),(0,F.jsx)(`strong`,{className:`block`,children:t.linked_engagement_count||0})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`ERP Type`}),(0,F.jsx)(`div`,{className:`mt-1`,children:t.project_type?(0,F.jsx)(I,{variant:`neutral`,children:t.project_type}):(0,F.jsx)(`strong`,{className:`block`,children:`Not set`})})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`ERP Modified`}),(0,F.jsx)(`strong`,{className:`block`,children:qt(t.source_modified_at)})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Cache ID`}),(0,F.jsx)(`strong`,{className:`block break-all font-mono text-xs`,children:t.id})]})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Project roster`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:n.length?`${n.length} synced ERP user${n.length===1?``:`s`}`:`No ERP roster`})]}),e.canWrite?(0,F.jsx)(Rt,{className:`grid gap-4 border-b`,children:(0,F.jsx)(Pn,{projectId:t.id,loading:e.loading,onAddUser:e.onAddUser,onAddHistoricalMember:e.onAddHistoricalMember})}):null,(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{className:`min-w-[760px]`,"aria-label":`Project roster`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(Gt,{children:`Name`}),(0,F.jsx)(Gt,{children:`Email`}),(0,F.jsx)(Gt,{children:`ERP user`}),(0,F.jsx)(Gt,{children:`Links`}),(0,F.jsx)(Gt,{children:`Source`}),(0,F.jsx)(Gt,{children:`Last seen`})]})}),(0,F.jsx)(Ut,{children:n.length?n.map(t=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:(0,F.jsx)(`strong`,{children:t.full_name||t.email||t.source_user_id})}),(0,F.jsx)(B,{children:t.email||`None`}),(0,F.jsx)(B,{className:`font-mono text-xs`,children:t.erpnext_user_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.erpnext_user_url,target:`_blank`,rel:`noreferrer`,children:[t.source_user_id||`ERP user`,(0,F.jsx)(v,{className:`size-3.5`})]}):t.source_user_id||`Unknown`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[t.supplier_erpnext_url?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:t.supplier_erpnext_url,target:`_blank`,rel:`noreferrer`,children:[`Supplier`,(0,F.jsx)(v,{className:`size-3.5`})]}):null,t.crm_contact_id&&e.crmContactUrl(t.crm_contact_id)?(0,F.jsxs)(`a`,{className:`inline-flex items-center gap-1 font-semibold text-primary underline-offset-4 hover:underline`,href:e.crmContactUrl(t.crm_contact_id),target:`_blank`,rel:`noreferrer`,children:[`CRM`,(0,F.jsx)(v,{className:`size-3.5`})]}):null,!t.supplier_erpnext_url&&!(t.crm_contact_id&&e.crmContactUrl(t.crm_contact_id))?(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`None`}):null]})}),(0,F.jsx)(B,{children:t.roster_kind||t.source||`ERP`}),(0,F.jsx)(B,{children:qt(t.last_seen_at)})]},`${t.source||``}:${t.source_user_id||t.email}`)):(0,F.jsx)(Wt,{children:(0,F.jsx)(B,{colSpan:6,className:`text-sm text-muted-foreground`,children:`No roster rows have been synced for this project.`})})})]})})]})]})}function In(e){let t=e.gigs.reduce((t,n)=>(t.total+=1,t.applications+=Number(n.application_count||0),t.interested+=Number(n.interested_count||0),On(n,e.staleDays)!==null&&(t.stale+=1),t),{total:0,applications:0,interested:0,stale:0}),n=(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-[minmax(160px,1fr)_auto_auto] md:items-end`,children:[(0,F.jsxs)(z,{children:[`Status`,(0,F.jsxs)(Bt,{id:`gigStatus`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any status`}),wn.map(e=>(0,F.jsx)(`option`,{value:e,children:En(e)},e))]})]}),(0,F.jsxs)(L,{id:`refreshGigs`,type:`button`,onClick:e.onRefresh,disabled:e.loading.gigs,children:[(0,F.jsx)(ee,{}),`Refresh gigs`]}),e.gigs.length>=e.limit?(0,F.jsx)(L,{type:`button`,variant:`outline`,onClick:()=>e.setLimit(Math.min(e.limit+100,500)),disabled:e.loading.gigs||e.limit>=500,children:`Load more`}):null]}),r=e.selectedGigId?e.loading[`gig:${e.selectedGigId}:detail`]:!1;return e.selectedGigId&&!e.selectedGig&&(e.loading.gigs||r)?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Gig detail`})}),(0,F.jsx)(Rt,{className:`text-sm text-muted-foreground`,children:`Loading gig.`})]})]}):e.selectedGigId&&!e.selectedGig?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Gig detail`})}),(0,F.jsxs)(Rt,{className:`grid gap-3`,children:[(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`This gig is not in the current result set. Clear filters or refresh the gig list.`}),(0,F.jsxs)(L,{type:`button`,variant:`outline`,onClick:e.onCloseGig,children:[(0,F.jsx)(m,{}),`Back to gigs`]})]})]})]}):e.selectedGig?(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsx)(zn,{gig:e.selectedGig,loading:e.loading,canWrite:e.canWrite,crmContactUrl:e.crmContactUrl,crmAttachmentUrl:e.crmAttachmentUrl,staleDays:e.staleDays,onBack:e.onCloseGig,onUpdateStatus:e.onUpdateStatus,onUpdateApplicationStatus:e.onUpdateApplicationStatus})]}):(0,F.jsxs)(F.Fragment,{children:[n,(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-4`,"aria-label":`Gig summary`,children:[(0,F.jsx)(_n,{id:`gigMetricTotal`,label:`Gigs`,value:t.total}),(0,F.jsx)(_n,{id:`gigMetricCandidates`,label:`Candidates`,value:t.applications}),(0,F.jsx)(_n,{id:`gigMetricInterested`,label:`Interested`,value:t.interested}),(0,F.jsx)(_n,{id:`gigMetricStale`,label:`Stale recruiting`,value:t.stale})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Discord gigs`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>e.onSort(`activity`),"aria-label":`Sort gigs by activity`,children:[`Activity`,` `,e.sort.key===`activity`?e.sort.direction===`asc`?`↑`:`↓`:``]}),(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>e.onSort(`title`),"aria-label":`Sort gigs by title`,children:[`Title `,e.sort.key===`title`?e.sort.direction===`asc`?`↑`:`↓`:``]}),(0,F.jsx)(`span`,{id:`gigsStatus`,className:`text-sm text-muted-foreground`,children:e.loading.gigs?`Loading`:`${e.gigs.length} shown`})]})]}),(0,F.jsx)(vn,{hidden:e.gigs.length!==0,children:`No gigs match this view.`}),(0,F.jsx)(`div`,{id:`gigsBody`,className:P(`grid gap-3 p-4`,e.gigs.length===0&&`hidden`),children:e.gigs.map(t=>(0,F.jsx)(Ln,{gig:t,loading:e.loading,canWrite:e.canWrite,staleDays:e.staleDays,onOpenGig:e.onOpenGig,onUpdateStatus:e.onUpdateStatus},t.id))})]})]})}function Ln({gig:e,loading:t,canWrite:n,onOpenGig:r,onUpdateStatus:i,staleDays:a}){let o=Array.isArray(e.applications)?e.applications:[],s=e.discord_guild_id&&e.discord_thread_id?`https://discord.com/channels/${encodeURIComponent(e.discord_guild_id)}/${encodeURIComponent(e.discord_thread_id)}`:``,c=On(e,a);return(0,F.jsxs)(`article`,{className:`grid gap-4 rounded-md border bg-background p-4 lg:grid-cols-[minmax(0,1fr)_220px_180px] lg:items-start`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,F.jsx)(`a`,{className:`text-base font-extrabold text-primary`,href:`/dashboard/gigs/${encodeURIComponent(e.id)}`,onClick:t=>{t.preventDefault(),r(e.id)},children:e.title||`Untitled gig`}),(0,F.jsx)(I,{variant:e.status===`filled`?`succeeded`:e.status===`lost`?`failed`:`queued`,children:e.status_label||En(e.status)}),c===null?null:(0,F.jsxs)(I,{variant:`running`,children:[c,`d stale`]})]}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[e.posting_type?(0,F.jsx)(I,{variant:`neutral`,children:En(e.posting_type)}):null,e.discord_channel_name?(0,F.jsxs)(I,{variant:`neutral`,children:[`#`,e.discord_channel_name]}):null,(e.required_skills||[]).slice(0,5).map(e=>(0,F.jsx)(I,{variant:`queued`,children:e},e)),(e.preferred_skills||[]).slice(0,3).map(e=>(0,F.jsx)(I,{variant:`neutral`,children:e},e))]}),(0,F.jsxs)(`div`,{className:`mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground`,children:[(0,F.jsxs)(`span`,{children:[`Activity `,qt(Dn(e))||`unknown`]}),(0,F.jsxs)(`span`,{children:[`Posted `,qt(e.posted_at)||`unknown`]}),s?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:s,target:`_blank`,rel:`noreferrer`,children:`Open Discord thread`}):null]})]}),(0,F.jsxs)(`div`,{className:`grid grid-cols-2 gap-2 text-sm lg:grid-cols-1`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`block text-xs font-bold text-muted-foreground`,children:`People`}),(0,F.jsx)(`strong`,{children:e.application_count||o.length}),(0,F.jsxs)(`span`,{className:`ml-2 text-muted-foreground`,children:[Number(e.interested_count||0),` interested`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`block text-xs font-bold text-muted-foreground`,children:`Top candidates`}),(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:o.slice(0,3).map(e=>Rn(e)).join(`, `)||`None yet`})]})]}),(0,F.jsxs)(`div`,{className:`grid gap-2`,children:[n?(0,F.jsx)(Bt,{"aria-label":`Status for ${e.title||`gig`}`,value:e.status,disabled:t[`gig:${e.id}:status`],onChange:t=>i(e.id,t.target.value),children:wn.map(e=>(0,F.jsx)(`option`,{value:e,children:En(e)},e))}):null,(0,F.jsx)(L,{type:`button`,onClick:()=>r(e.id),children:`Manage people`})]})]})}function Rn(e){return e.name||e.email_508||e.discord_username||(typeof e.evaluation?.discord_username==`string`?e.evaluation.discord_username:``)||`Candidate`}function zn({gig:e,loading:t,canWrite:n,crmContactUrl:r,crmAttachmentUrl:i,staleDays:a,onBack:o,onUpdateStatus:s,onUpdateApplicationStatus:c}){let l=Array.isArray(e.applications)?e.applications:[],u=e.discord_guild_id&&e.discord_thread_id?`https://discord.com/channels/${encodeURIComponent(e.discord_guild_id)}/${encodeURIComponent(e.discord_thread_id)}`:``,d=On(e,a);return(0,F.jsxs)(`div`,{className:`grid gap-5`,children:[(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{className:`items-start`,children:[(0,F.jsxs)(`div`,{className:`grid gap-2`,children:[(0,F.jsxs)(L,{type:`button`,variant:`ghost`,size:`sm`,className:`w-fit`,onClick:o,children:[(0,F.jsx)(m,{}),`Back to gigs`]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(Lt,{className:`text-xl`,children:e.title||`Untitled gig`}),(0,F.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[(0,F.jsx)(I,{variant:e.status===`filled`?`succeeded`:e.status===`lost`?`failed`:`queued`,children:e.status_label||En(e.status)}),d===null?null:(0,F.jsxs)(I,{variant:`running`,children:[d,`d stale`]}),e.posting_type?(0,F.jsx)(I,{variant:`neutral`,children:En(e.posting_type)}):null,e.discord_channel_name?(0,F.jsxs)(I,{variant:`neutral`,children:[`#`,e.discord_channel_name]}):null,(e.required_skills||[]).map(e=>(0,F.jsx)(I,{variant:`queued`,children:e},e)),(e.preferred_skills||[]).map(e=>(0,F.jsx)(I,{variant:`neutral`,children:e},e))]})]})]}),(0,F.jsxs)(`div`,{className:`grid min-w-[190px] gap-2`,children:[n?(0,F.jsxs)(z,{children:[`Gig status`,(0,F.jsx)(Bt,{"aria-label":`Status for ${e.title||`gig`}`,value:e.status,disabled:t[`gig:${e.id}:status`],onChange:t=>s(e.id,t.target.value),children:wn.map(e=>(0,F.jsx)(`option`,{value:e,children:En(e)},e))})]}):null,u?(0,F.jsxs)(`a`,{className:`inline-flex min-h-9 items-center justify-center gap-2 rounded-md border bg-secondary px-3 text-sm font-semibold`,href:u,target:`_blank`,rel:`noreferrer`,children:[(0,F.jsx)(v,{className:`size-4`}),`Discord thread`]}):null]})]}),(0,F.jsxs)(Rt,{className:`grid gap-4 lg:grid-cols-[1fr_1fr_1fr]`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Activity`}),(0,F.jsx)(`strong`,{className:`block`,children:qt(Dn(e))||`unknown`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[`Posted `,qt(e.posted_at)||`unknown`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`People`}),(0,F.jsx)(`strong`,{className:`block`,children:e.application_count||l.length}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[Number(e.interested_count||0),` interested`]})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:`Discord`}),(0,F.jsx)(`strong`,{className:`block`,children:e.discord_channel_name||`No channel`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.discord_thread_id?`Thread ${e.discord_thread_id}`:`No thread`})]})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`People`}),(0,F.jsxs)(`span`,{className:`text-sm text-muted-foreground`,children:[l.length,` candidate`,l.length===1?``:`s`]})]}),(0,F.jsx)(vn,{hidden:l.length!==0,children:`No suggested or interested people yet.`}),(0,F.jsx)(`div`,{className:P(`grid gap-3 p-4`,l.length===0&&`hidden`),children:l.map(a=>(0,F.jsx)(Bn,{gigId:e.id,application:a,loading:t,canWrite:n,crmContactUrl:r,crmAttachmentUrl:i,onUpdateApplicationStatus:c},a.id))})]})]})}function Bn({gigId:e,application:t,loading:n,canWrite:r,crmContactUrl:i,crmAttachmentUrl:a,onUpdateApplicationStatus:o}){let s=Rn(t),c=i(t.crm_contact_id),l=a(t.latest_resume_id),u=typeof t.fit_score==`number`?`${Math.round(t.fit_score)}/100`:typeof t.match_score==`number`?t.match_score.toFixed(1):``,d=typeof t.evaluation?.llm_summary==`string`?t.evaluation.llm_summary:``;return(0,F.jsxs)(`div`,{className:`grid gap-2 rounded-md border bg-background p-2`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[c?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:c,target:`_blank`,rel:`noopener noreferrer`,children:s}):(0,F.jsx)(`strong`,{children:s}),(0,F.jsx)(I,{variant:t.status===`interested`?`succeeded`:`neutral`,children:En(t.status)}),(0,F.jsx)(I,{variant:`neutral`,children:En(t.source||`manual_add`)}),u?(0,F.jsxs)(`span`,{className:`text-xs font-bold text-muted-foreground`,children:[`Fit `,u]}):null,c?(0,F.jsx)(`a`,{className:`text-xs font-extrabold text-primary`,href:c,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`Open ${s} CRM profile`,children:`CRM profile`}):null,l?(0,F.jsx)(`a`,{className:`text-xs font-extrabold text-primary`,href:l,target:`_blank`,rel:`noopener noreferrer`,children:`Resume`}):null]}),d?(0,F.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:d}):null,r?(0,F.jsx)(Bt,{"aria-label":`Candidate status for ${s}`,value:t.status||`suggested`,disabled:n[`application:${t.id}:status`],onChange:n=>o(e,t.id,n.target.value),children:Tn.map(e=>(0,F.jsx)(`option`,{value:e,children:En(e)},e))}):null]})}function Vn(e){let t=ln[e.peopleFilterKind]?.options||[];return(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`People lookup`}),(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center justify-end gap-2`,children:[e.canSync?(0,F.jsxs)(L,{id:`syncPeople`,"data-permission":`people:sync`,type:`button`,onClick:e.onSync,disabled:e.loading.syncPeople,children:[(0,F.jsx)(ee,{}),`Sync people`]}):null,e.crmBaseUrl?(0,F.jsx)(`a`,{id:`crmHomeLink`,className:`text-sm font-extrabold text-primary`,href:e.crmBaseUrl,target:`_blank`,rel:`noreferrer`,children:`Open CRM`}):null,(0,F.jsx)(`span`,{id:`peopleStatus`,className:`text-sm text-muted-foreground`,children:e.loading.people?`Loading`:`${e.people.length} shown`})]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b p-4 md:grid-cols-[minmax(0,1fr)_auto]`,children:[(0,F.jsxs)(z,{children:[`Search CRM people cache`,(0,F.jsx)(zt,{id:`peopleQuery`,value:e.peopleQuery,autoComplete:`off`,placeholder:`Name, email, CRM id, Discord, resume`,onChange:t=>e.setPeopleQuery(t.target.value),onKeyDown:t=>{t.key===`Enter`&&e.onSearch()}})]}),(0,F.jsxs)(L,{id:`searchPeople`,type:`button`,onClick:e.onSearch,disabled:e.loading.people,children:[(0,F.jsx)(te,{}),`Search`]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b bg-background p-4 md:grid-cols-[minmax(120px,.7fr)_minmax(150px,1fr)_minmax(150px,1fr)_auto]`,children:[(0,F.jsxs)(z,{children:[`Member`,(0,F.jsxs)(Bt,{id:`peopleMember`,value:e.peopleMember,onChange:t=>e.setPeopleMember(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any`}),(0,F.jsx)(`option`,{value:`true`,children:`Member`}),(0,F.jsx)(`option`,{value:`false`,children:`Not member`})]})]}),(0,F.jsxs)(z,{children:[`Add filter`,(0,F.jsx)(Bt,{id:`peopleFilterKind`,value:e.peopleFilterKind,disabled:e.peopleFilterKeys.length===0,onChange:t=>e.setPeopleFilterKind(t.target.value),children:e.peopleFilterKeys.map(e=>(0,F.jsx)(`option`,{value:e,children:ln[e].label},e))})]}),(0,F.jsxs)(z,{children:[`Value`,(0,F.jsx)(Bt,{id:`peopleFilterValue`,value:e.peopleFilterValue,onChange:t=>e.setPeopleFilterValue(t.target.value),children:t.map(([e,t])=>(0,F.jsx)(`option`,{value:e,children:t},e))})]}),(0,F.jsx)(L,{id:`addPeopleFilter`,type:`button`,onClick:e.addFilter,disabled:e.peopleFilterKeys.length===0,children:`Add filter`}),(0,F.jsx)(`div`,{id:`activePeopleFilters`,className:`md:col-span-4`,children:(0,F.jsx)(Cn,{filters:e.peopleFilters,onRemove:e.removeFilter})})]}),(0,F.jsx)(vn,{hidden:e.people.length!==0,children:`No people match this lookup.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`peopleTable`,className:P(`min-w-[900px]`,e.people.length===0&&`hidden`),"aria-label":`People lookup results`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[27%]`,label:`Name`,scope:`people`,sort:e.sort,sortKey:`name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Status`,scope:`people`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[20%]`,label:`Discord`,scope:`people`,sort:e.sort,sortKey:`discord`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[25%]`,label:`Resume / skills`,scope:`people`,sort:e.sort,sortKey:`resume`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`peopleBody`,children:e.people.map(t=>{let n=t.name||t.email_508||t.email||`CRM contact`,r=e.crmContactUrl(t.crm_contact_id),i=t.profile_status||{},a=Number(i.skills_count||0),o=e.crmAttachmentUrl(t.latest_resume_id);return(0,F.jsxs)(Wt,{children:[(0,F.jsxs)(B,{children:[r?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:r,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${n} in CRM`,children:n}):(0,F.jsx)(`strong`,{children:n}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:[t.email_508||t.email,t.contact_type].filter(Boolean).join(` | `)})]}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[i.crm_active?null:(0,F.jsx)(I,{variant:`missing`,children:t.sync_status||`CRM sync issue`}),(0,F.jsx)(I,{variant:i.is_member?`succeeded`:`missing`,children:i.is_member?`Member`:`Missing Member`}),(0,F.jsx)(I,{variant:i.discord_linked?`succeeded`:`missing`,children:i.discord_linked?`Discord`:`Missing Discord`}),(0,F.jsx)(I,{variant:i.email_508?`succeeded`:`missing`,children:i.email_508?`508 email`:`Missing 508 email`}),i.latest_resume?null:(0,F.jsx)(I,{variant:`missing`,children:`Missing Resume`})]})}),(0,F.jsx)(B,{children:[t.discord_username,t.discord_user_id].filter(Boolean).join(` | `)||`Not linked`}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[o?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:o,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${n} resume`,children:`Resume`}):(0,F.jsx)(`span`,{children:t.latest_resume_name||t.latest_resume_id||`No resume`}),(0,F.jsx)(I,{variant:a>0?`succeeded`:`missing`,children:a>0?`Skills parsed`:`Skills not parsed`})]})})]},t.crm_contact_id||n)})})]})})]})}function Hn(e){let t=ln[e.onboardingFilterKind]?.options||[];return(0,F.jsxs)(F.Fragment,{children:[e.canWrite?(0,F.jsx)(Un,{loading:e.loading.engineerSetup,onSetup:e.onSetupEngineer}):null,(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Onboarding queue`}),(0,F.jsx)(`span`,{id:`onboardingStatus`,className:`text-sm text-muted-foreground`,children:e.loading.onboarding?`Loading`:`${e.people.length} shown`})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b p-4 md:grid-cols-[minmax(0,1fr)_auto]`,children:[(0,F.jsxs)(z,{children:[`Search prospects`,(0,F.jsx)(zt,{id:`onboardingQuery`,value:e.onboardingQuery,autoComplete:`off`,placeholder:`Name, email, Discord, onboarder`,onChange:t=>e.setOnboardingQuery(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(L,{id:`searchOnboarding`,type:`button`,onClick:e.onSearch,disabled:e.loading.onboarding,children:[(0,F.jsx)(te,{}),`Search`]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 border-b bg-background p-4 md:grid-cols-[minmax(140px,.8fr)_minmax(150px,1fr)_minmax(150px,1fr)_minmax(120px,.7fr)_auto]`,children:[(0,F.jsxs)(z,{children:[`Status`,(0,F.jsxs)(Bt,{id:`onboardingState`,value:e.onboardingState,onChange:t=>e.setOnboardingState(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any state`}),(0,F.jsx)(`option`,{value:`pending`,children:`Needs review`}),(0,F.jsx)(`option`,{value:`selected`,children:`Assigned to onboarder`}),(0,F.jsx)(`option`,{value:`reachingout`,children:`Reaching out`}),(0,F.jsx)(`option`,{value:`awaitingcontribution`,children:`Awaiting contribution`})]})]}),(0,F.jsxs)(z,{children:[`Onboarder`,(0,F.jsx)(zt,{id:`onboarderFilter`,value:e.onboarderFilter,autoComplete:`off`,placeholder:`Any onboarder`,onChange:t=>e.setOnboarderFilter(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(z,{children:[`Add filter`,(0,F.jsx)(Bt,{id:`onboardingFilterKind`,value:e.onboardingFilterKind,disabled:e.onboardingFilterKeys.length===0,onChange:t=>e.setOnboardingFilterKind(t.target.value),children:e.onboardingFilterKeys.map(e=>(0,F.jsx)(`option`,{value:e,children:ln[e].label},e))})]}),(0,F.jsxs)(z,{children:[`Value`,(0,F.jsx)(Bt,{id:`onboardingFilterValue`,value:e.onboardingFilterValue,onChange:t=>e.setOnboardingFilterValue(t.target.value),children:t.map(([e,t])=>(0,F.jsx)(`option`,{value:e,children:t},e))})]}),(0,F.jsx)(L,{id:`addOnboardingFilter`,type:`button`,onClick:e.addFilter,disabled:e.onboardingFilterKeys.length===0,children:`Add filter`}),(0,F.jsx)(`div`,{id:`activeOnboardingFilters`,className:`md:col-span-5`,children:(0,F.jsx)(Cn,{filters:e.onboardingFilters,onRemove:e.removeFilter,suffix:`onboarding filter`})})]}),(0,F.jsx)(vn,{hidden:e.people.length!==0,children:`No prospects match this queue view.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`onboardingTable`,className:P(`min-w-[1180px]`,e.people.length===0&&`hidden`),"aria-label":`Onboarding queue`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[20%]`,label:`Name`,scope:`onboarding`,sort:e.sort,sortKey:`name`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[13%]`,label:`Status`,scope:`onboarding`,sort:e.sort,sortKey:`onboarding_state`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[22%]`,label:`Onboarder`,scope:`onboarding`,sort:e.sort,sortKey:`onboarder`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[13%]`,label:`Updated`,scope:`onboarding`,sort:e.sort,sortKey:`updated`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(Gt,{className:`w-[15%]`,children:`Links`}),(0,F.jsx)(H,{className:`w-[17%]`,label:`Needs`,scope:`onboarding`,sort:e.sort,sortKey:`profile_gaps`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`onboardingBody`,children:e.people.map(t=>(0,F.jsx)(Wn,{person:t,loading:e.loading,onAssign:e.onAssign,crmContactUrl:e.crmContactUrl,crmAttachmentUrl:e.crmAttachmentUrl},t.crm_contact_id||t.name))})]})})]})]})}function Un({loading:e,onSetup:t}){let[n,r]=(0,l.useState)(``),[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(``),[d,f]=(0,l.useState)(``),[p,m]=(0,l.useState)(``),[h,g]=(0,l.useState)(!0);async function _(){let e=i.trim(),[l,..._]=e.split(/\s+/);await t({email:n,first_name:l||e,last_name:_.join(` `),country:o,department:c,gender:d,date_of_birth:p,create_user_permission:h})&&(r(``),a(``),s(``),u(``),f(``),m(``),g(!0))}return(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Engineer setup`})}),(0,F.jsx)(Rt,{children:(0,F.jsxs)(`form`,{className:`grid gap-3`,onSubmit:e=>{e.preventDefault(),_()},children:[(0,F.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(130px,.6fr)_minmax(140px,.7fr)]`,children:[(0,F.jsxs)(z,{children:[`508 email`,(0,F.jsx)(zt,{value:n,autoComplete:`off`,placeholder:`engineer@508.dev`,onChange:e=>r(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Name`,(0,F.jsx)(zt,{value:i,autoComplete:`off`,placeholder:`First Last`,onChange:e=>a(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Country`,(0,F.jsx)(zt,{value:o,autoComplete:`off`,placeholder:`Taiwan`,onChange:e=>s(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Department`,(0,F.jsx)(zt,{value:c,autoComplete:`off`,placeholder:`Optional`,onChange:e=>u(e.target.value)})]})]}),(0,F.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:[(0,F.jsxs)(z,{children:[`Gender`,(0,F.jsx)(zt,{value:d,autoComplete:`off`,placeholder:`Optional`,onChange:e=>f(e.target.value)})]}),(0,F.jsxs)(z,{children:[`Date of birth`,(0,F.jsx)(zt,{value:p,type:`date`,autoComplete:`off`,onChange:e=>m(e.target.value)})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,F.jsxs)(`label`,{className:`flex min-h-9 items-center gap-2 text-sm font-semibold`,children:[(0,F.jsx)(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.target.checked)}),`Create User Permission`]}),(0,F.jsxs)(L,{id:`setupEngineer`,type:`submit`,disabled:e||!n.trim()||!i.trim()||!o.trim(),children:[(0,F.jsx)(ne,{}),`Set up engineer`]})]})]})})]})}function Wn({person:e,loading:t,onAssign:n,crmContactUrl:r,crmAttachmentUrl:i}){let a=e.name||e.email_508||e.email||`CRM contact`,[o,s]=(0,l.useState)($t(e.onboarder));(0,l.useEffect)(()=>s($t(e.onboarder)),[e.onboarder]);let c=e.profile_status||{},u=[[`Discord`,c.discord_linked],[`Resume`,c.latest_resume],[`Skills`,Number(c.skills_count||0)>0]].filter(([,e])=>!e),d=r(e.crm_contact_id),f=i(e.latest_resume_id);return(0,F.jsxs)(Wt,{children:[(0,F.jsxs)(B,{children:[d?(0,F.jsx)(`a`,{className:`font-extrabold text-primary`,href:d,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} in CRM`,children:a}):(0,F.jsx)(`strong`,{children:a}),(0,F.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:e.email_508||e.email||``})]}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:Qt(Xt(e)),children:e.onboarding_status_label||Zt(Xt(e))})}),(0,F.jsx)(B,{children:(0,F.jsxs)(`form`,{className:`grid max-w-64 grid-cols-[minmax(100px,1fr)_auto] items-center gap-2`,onSubmit:t=>{t.preventDefault(),n(e.crm_contact_id,o)},children:[(0,F.jsx)(zt,{"aria-label":`Onboarder for ${a}`,value:o,placeholder:`508 username`,onChange:e=>s(e.target.value)}),(0,F.jsx)(L,{type:`submit`,size:`sm`,"aria-label":`Save onboarder for ${a}`,disabled:t[`onboarder:${e.crm_contact_id}`],children:`Save`})]})}),(0,F.jsx)(B,{children:qt(e.onboarding_updated_at)}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[f?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:f,target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} resume`,children:`Resume`}):null,an(e.linkedin)?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:an(e.linkedin),target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} LinkedIn`,children:`LinkedIn`}):null,on(e.github_username)?(0,F.jsx)(`a`,{className:`inline-flex min-h-7 items-center rounded-md border bg-secondary px-2 text-xs font-extrabold`,href:on(e.github_username),target:`_blank`,rel:`noreferrer`,"aria-label":`Open ${a} GitHub`,children:e.github_username||`GitHub`}):null,!f&&!an(e.linkedin)&&!on(e.github_username)?`None`:null]})}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[u.map(([e])=>(0,F.jsxs)(I,{variant:`missing`,children:[`Missing `,e]},String(e))),u.length===0?`None`:null]})})]})}function Gn(e){return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{className:`grid gap-3 p-4 md:grid-cols-4 md:items-end`,children:[(0,F.jsxs)(z,{children:[`Window`,(0,F.jsxs)(Bt,{id:`minutes`,value:e.minutes,onChange:t=>e.setMinutes(t.target.value),children:[(0,F.jsx)(`option`,{value:`15`,children:`15 minutes`}),(0,F.jsx)(`option`,{value:`60`,children:`1 hour`}),(0,F.jsx)(`option`,{value:`360`,children:`6 hours`}),(0,F.jsx)(`option`,{value:`1440`,children:`24 hours`})]})]}),(0,F.jsxs)(z,{children:[`Status`,(0,F.jsxs)(Bt,{id:`status`,value:e.status,onChange:t=>e.setStatus(t.target.value),children:[(0,F.jsx)(`option`,{value:``,children:`Any status`}),(0,F.jsx)(`option`,{value:`queued`,children:`Queued`}),(0,F.jsx)(`option`,{value:`running`,children:`Running`}),(0,F.jsx)(`option`,{value:`succeeded`,children:`Succeeded`}),(0,F.jsx)(`option`,{value:`failed`,children:`Failed`}),(0,F.jsx)(`option`,{value:`dead`,children:`Dead`}),(0,F.jsx)(`option`,{value:`canceled`,children:`Canceled`})]})]}),(0,F.jsxs)(z,{children:[`Type`,(0,F.jsx)(zt,{id:`jobType`,value:e.jobType,autoComplete:`off`,placeholder:`Any type`,onChange:t=>e.setJobType(t.target.value),onKeyDown:t=>t.key===`Enter`&&e.onSearch()})]}),(0,F.jsxs)(L,{id:`refreshJobs`,type:`button`,onClick:e.onSearch,disabled:e.loading.jobs,children:[(0,F.jsx)(ee,{}),`Refresh jobs`]})]}),(0,F.jsxs)(`section`,{className:`grid gap-3 md:grid-cols-4`,"aria-label":`Job summary`,children:[(0,F.jsx)(_n,{id:`metricTotal`,label:`Total`,value:e.jobs.length}),(0,F.jsx)(_n,{id:`metricQueued`,label:`Queued`,value:e.jobCounts.queued||0}),(0,F.jsx)(_n,{id:`metricRunning`,label:`Running`,value:e.jobCounts.running||0}),(0,F.jsx)(_n,{id:`metricFailed`,label:`Failed`,value:(e.jobCounts.failed||0)+(e.jobCounts.dead||0)})]}),(0,F.jsxs)(R,{children:[(0,F.jsx)(It,{children:(0,F.jsx)(Lt,{children:`Recent jobs`})}),(0,F.jsx)(vn,{hidden:e.jobs.length!==0,children:`No jobs match these filters.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`jobsTable`,className:P(`min-w-[980px]`,e.jobs.length===0&&`hidden`),"aria-label":`Recent jobs`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[22%]`,label:`Job id`,scope:`jobs`,sort:e.sort,sortKey:`job_id`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[24%]`,label:`Type`,scope:`jobs`,sort:e.sort,sortKey:`type`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[12%]`,label:`Status`,scope:`jobs`,sort:e.sort,sortKey:`status`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[12%]`,label:`Attempts`,scope:`jobs`,sort:e.sort,sortKey:`attempts`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[18%]`,label:`Updated`,scope:`jobs`,sort:e.sort,sortKey:`updated_at`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(Gt,{children:`Actions`})]})}),(0,F.jsx)(Ut,{id:`jobsBody`,children:e.jobs.map(t=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{className:`font-mono`,children:t.job_id}),(0,F.jsx)(B,{children:t.type}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:t.status||`neutral`,children:t.status})}),(0,F.jsxs)(B,{children:[t.attempts,`/`,t.max_attempts]}),(0,F.jsx)(B,{children:qt(t.updated_at)}),(0,F.jsx)(B,{children:(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,F.jsx)(L,{type:`button`,size:`sm`,variant:`outline`,"aria-label":`View details for ${t.type} job ${t.job_id}`,onClick:()=>e.onDetail(t.job_id),disabled:e.loading[`detail:${t.job_id}`],children:`Details`}),e.canWrite?(0,F.jsx)(L,{type:`button`,size:`sm`,"aria-label":`Rerun ${t.type} job ${t.job_id}`,onClick:()=>e.onRerun(t.job_id),disabled:e.loading[`rerun:${t.job_id}`],children:`Rerun`}):null]})})]},t.job_id))})]})})]}),e.jobDetail?(0,F.jsxs)(R,{id:`jobDetailPanel`,children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Job detail`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:e.jobDetail.job_id})]}),(0,F.jsxs)(Rt,{className:`grid gap-4`,children:[(0,F.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:[[`Type`,e.jobDetail.type],[`Status`,e.jobDetail.status],[`Attempts`,`${e.jobDetail.attempts}/${e.jobDetail.max_attempts}`],[`Updated`,qt(e.jobDetail.updated_at)],[`Created`,qt(e.jobDetail.created_at)],[`Run after`,qt(e.jobDetail.run_after)],[`Locked by`,e.jobDetail.locked_by||`None`],[`Last error`,e.jobDetail.last_error||`None`]].map(([e,t])=>(0,F.jsxs)(`div`,{className:`grid gap-1 rounded-md border bg-background p-3`,children:[(0,F.jsx)(`span`,{className:`text-[11px] font-extrabold uppercase text-muted-foreground`,children:e}),(0,F.jsx)(`strong`,{className:`break-words text-sm`,children:t})]},e))}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h2`,{className:`mb-2 text-[15px] font-bold`,children:`Payload`}),(0,F.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-background p-3 font-mono text-xs`,children:Yt(e.jobDetail.payload)||`No payload`})]}),(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h2`,{className:`mb-2 text-[15px] font-bold`,children:`Result`}),(0,F.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md border bg-background p-3 font-mono text-xs`,children:Yt(e.jobDetail.result)||`No result`})]})]})]}):null]})}function Kn(e){return(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Recent audit`}),(0,F.jsxs)(L,{id:`refreshAudit`,type:`button`,variant:`outline`,onClick:e.onRefresh,disabled:e.loading.audit,children:[(0,F.jsx)(ee,{}),`Refresh`]})]}),(0,F.jsx)(vn,{hidden:e.events.length!==0,children:`No audit events found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`auditTable`,className:P(`min-w-[760px]`,e.events.length===0&&`hidden`),"aria-label":`Recent audit events`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(H,{className:`w-[24%]`,label:`Time`,scope:`audit`,sort:e.sort,sortKey:`occurred_at`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Actor`,scope:`audit`,sort:e.sort,sortKey:`actor`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[28%]`,label:`Action`,scope:`audit`,sort:e.sort,sortKey:`action`,onSort:(t,n)=>e.onSort(n)}),(0,F.jsx)(H,{className:`w-[20%]`,label:`Result`,scope:`audit`,sort:e.sort,sortKey:`result`,onSort:(t,n)=>e.onSort(n)})]})}),(0,F.jsx)(Ut,{id:`auditBody`,children:e.events.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:qt(e.occurred_at)}),(0,F.jsx)(B,{children:e.actor_display_name||e.actor_subject||e.actor_provider}),(0,F.jsx)(B,{children:e.action}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:e.result===`success`?`succeeded`:`failed`,children:e.result})})]},e.id||`${e.occurred_at||``}-${e.actor_subject||``}-${e.action||``}`))})]})})]})}function qn({report:e,loading:t,onRefresh:n}){let r=e?.summary||{},i=[[`Status`,e?.status_counts||{}],[`Intent`,e?.intent_counts||{}],[`Planner`,e?.planner_counts||{}]].flatMap(([e,t])=>Object.entries(t).map(([t,n])=>({label:e,value:t,count:n}))).sort((e,t)=>t.count-e.count||e.label.localeCompare(t.label)),a=Array.isArray(e?.recent_unsupported)?e.recent_unsupported:[];return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Agent requests`}),(0,F.jsxs)(L,{id:`refreshAgent`,type:`button`,variant:`outline`,onClick:n,disabled:t.agent,children:[(0,F.jsx)(ee,{}),`Refresh`]})]}),(0,F.jsxs)(Rt,{className:`grid gap-3 md:grid-cols-5`,children:[(0,F.jsx)(_n,{id:`agentMetricTotal`,label:`Total`,value:r.total||0}),(0,F.jsx)(_n,{id:`agentMetricHandled`,label:`Handled`,value:r.handled||0}),(0,F.jsx)(_n,{id:`agentMetricConfirmations`,label:`Confirmations`,value:r.requires_confirmation||0}),(0,F.jsx)(_n,{id:`agentMetricClarifications`,label:`Clarifications`,value:r.needs_clarification||0}),(0,F.jsx)(_n,{id:`agentMetricUnsupported`,label:`Not understood`,value:r.unsupported||0})]})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Request mix`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`Recent agent.request audit events.`})]}),(0,F.jsx)(vn,{hidden:i.length!==0,children:`No agent request data found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`agentBreakdownTable`,className:P(`min-w-[860px]`,i.length===0&&`hidden`),"aria-label":`Agent request breakdown`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(Gt,{children:`Dimension`}),(0,F.jsx)(Gt,{children:`Value`}),(0,F.jsx)(Gt,{children:`Count`})]})}),(0,F.jsx)(Ut,{id:`agentBreakdownBody`,children:i.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:e.label}),(0,F.jsx)(B,{children:e.value}),(0,F.jsx)(B,{children:e.count})]},`${e.label}-${e.value}`))})]})})]}),(0,F.jsxs)(R,{children:[(0,F.jsxs)(It,{children:[(0,F.jsx)(Lt,{children:`Not understood`}),(0,F.jsx)(`span`,{className:`text-sm text-muted-foreground`,children:`Sanitized request text only.`})]}),(0,F.jsx)(vn,{hidden:a.length!==0,children:`No unsupported agent requests found.`}),(0,F.jsx)(`div`,{className:`overflow-x-auto`,children:(0,F.jsxs)(Vt,{id:`agentUnsupportedTable`,className:P(`min-w-[860px]`,a.length===0&&`hidden`),"aria-label":`Unsupported agent requests`,children:[(0,F.jsx)(Ht,{children:(0,F.jsxs)(Wt,{children:[(0,F.jsx)(Gt,{children:`Time`}),(0,F.jsx)(Gt,{children:`Actor`}),(0,F.jsx)(Gt,{children:`Message`}),(0,F.jsx)(Gt,{children:`Result`})]})}),(0,F.jsx)(Ut,{id:`agentUnsupportedBody`,children:a.map(e=>(0,F.jsxs)(Wt,{children:[(0,F.jsx)(B,{children:qt(e.occurred_at)}),(0,F.jsx)(B,{children:e.actor}),(0,F.jsx)(B,{children:e.message_sanitized}),(0,F.jsx)(B,{children:(0,F.jsx)(I,{variant:e.result===`success`?`succeeded`:`failed`,children:e.result||`unknown`})})]},`${e.occurred_at||``}-${e.actor||``}-${e.message_sanitized||``}`))})]})})]})]})}var Jn=document.getElementById(`root`);if(!Jn)throw Error(`Missing #root container`);(0,le.createRoot)(Jn).render((0,F.jsx)(l.StrictMode,{children:(0,F.jsx)(yn,{})})); \ No newline at end of file diff --git a/apps/api/src/five08/backend/static/dashboard/index.html b/apps/api/src/five08/backend/static/dashboard/index.html index a1dd3d70..f9f687ad 100644 --- a/apps/api/src/five08/backend/static/dashboard/index.html +++ b/apps/api/src/five08/backend/static/dashboard/index.html @@ -4,8 +4,8 @@ 508 Operations Dashboard - - + +
diff --git a/apps/discord_bot/src/five08/discord_bot/cogs/engineer_onboarding.py b/apps/discord_bot/src/five08/discord_bot/cogs/engineer_onboarding.py new file mode 100644 index 00000000..13c4138f --- /dev/null +++ b/apps/discord_bot/src/five08/discord_bot/cogs/engineer_onboarding.py @@ -0,0 +1,335 @@ +"""Discord commands for ERPNext engineer onboarding.""" + +from __future__ import annotations + +import asyncio +import logging +from typing import Any + +import discord +from discord import app_commands +from discord.ext import commands + +from five08.clients.erpnext import ERPNextAPIError, ERPNextClient +from five08.discord_bot.config import settings +from five08.discord_bot.utils.audit import DiscordAuditCogMixin +from five08.discord_bot.utils.role_decorators import require_role +from five08.engineer_onboarding import ( + ActivityCostRequest, + EngineerOnboardingDuplicateNameError, + EngineerOnboardingError, + EngineerSetupRequest, + add_engineer_to_project, + setup_engineer, +) + +logger = logging.getLogger(__name__) + + +class EngineerOnboardingCog(DiscordAuditCogMixin, commands.Cog): + """ERPNext engineer setup and project assignment commands.""" + + def __init__(self, bot: commands.Bot) -> None: + self.bot = bot + self._init_audit_logger() + + def _erpnext_client(self) -> ERPNextClient: + base_url = (settings.erpnext_base_url or "").strip() + api_key = (settings.erpnext_api_key or "").strip() + if not base_url or not api_key: + raise ValueError("ERPNext API settings are required.") + return ERPNextClient( + base_url=base_url, + api_key=api_key, + timeout_seconds=settings.erpnext_api_timeout_seconds, + ) + + def _setup_engineer(self, request: EngineerSetupRequest) -> dict[str, Any]: + client = self._erpnext_client() + try: + return setup_engineer(client, request) + finally: + client.close() + + def _add_engineer_to_project( + self, + *, + project_id: str, + user: str, + activity_cost: ActivityCostRequest | None, + ) -> dict[str, Any]: + client = self._erpnext_client() + try: + return add_engineer_to_project( + client, + project_id=project_id, + user=user, + activity_cost=activity_cost, + ) + finally: + client.close() + + @app_commands.command( + name="setup-engineer", + description="Create or link ERPNext User, Employee, and Supplier for an engineer.", + ) + @app_commands.describe( + email="The engineer's 508.dev email address.", + name="The engineer's first and last name.", + country="Supplier country.", + department="Optional Employee department.", + gender="Optional Employee gender value if ERPNext requires it.", + date_of_birth="Optional Employee DOB if ERPNext requires it, YYYY-MM-DD.", + create_user_permission="Restrict permissions to this engineer's own records.", + ) + @require_role("Steering Committee") + async def setup_engineer_command( + self, + interaction: discord.Interaction, + email: str, + name: str, + country: str, + department: str | None = None, + gender: str | None = None, + date_of_birth: str | None = None, + create_user_permission: bool = True, + ) -> None: + """Set up one engineer in ERPNext.""" + await interaction.response.defer(ephemeral=True) + normalized_email = email.strip().lower() + normalized_name = " ".join(name.strip().split()) + if not normalized_email or not normalized_email.endswith("@508.dev"): + await interaction.followup.send( + "❌ Enter a valid @508.dev email.", + ephemeral=True, + ) + return + if not normalized_name: + await interaction.followup.send( + "❌ Enter the engineer name.", ephemeral=True + ) + return + first_name, _, last_name = normalized_name.partition(" ") + + try: + result = await asyncio.to_thread( + self._setup_engineer, + EngineerSetupRequest( + email=normalized_email, + first_name=first_name, + last_name=last_name or None, + country=country, + department=department, + gender=gender, + date_of_birth=date_of_birth, + create_user_permission=create_user_permission, + ), + ) + except EngineerOnboardingDuplicateNameError as exc: + self._audit_command_safe( + interaction=interaction, + action="erpnext.engineer_setup", + result="denied", + metadata={ + "email": normalized_email, + "error": str(exc), + "matches": exc.matches, + }, + resource_type="erpnext_user", + resource_id=normalized_email, + ) + matches = [ + str(match.get("label") or match.get("email") or match.get("name")) + for match in exc.matches[:5] + ] + await interaction.followup.send( + "⚠️ Similar ERPNext account exists. Confirm the intended person first:\n" + + "\n".join(f"- {match}" for match in matches if match), + ephemeral=True, + ) + return + except (EngineerOnboardingError, ValueError) as exc: + self._audit_command_safe( + interaction=interaction, + action="erpnext.engineer_setup", + result="denied", + metadata={"email": normalized_email, "error": str(exc)}, + resource_type="erpnext_user", + resource_id=normalized_email, + ) + await interaction.followup.send(f"⚠️ {exc}", ephemeral=True) + return + except ERPNextAPIError as exc: + logger.error("ERPNext engineer setup failed: %s", exc) + self._audit_command_safe( + interaction=interaction, + action="erpnext.engineer_setup", + result="error", + metadata={"email": normalized_email, "error": str(exc)}, + resource_type="erpnext_user", + resource_id=normalized_email, + ) + await interaction.followup.send( + "❌ ERPNext engineer setup failed.", ephemeral=True + ) + return + + self._audit_command_safe( + interaction=interaction, + action="erpnext.engineer_setup", + result="success", + metadata={ + "email": normalized_email, + "employee": result.get("employee"), + "supplier": result.get("supplier"), + "created": result.get("created"), + "updated": result.get("updated"), + }, + resource_type="erpnext_user", + resource_id=normalized_email, + ) + await interaction.followup.send( + "\n".join( + [ + "✅ Engineer setup complete.", + f"User: `{result.get('user')}`", + f"Employee: `{result.get('employee')}`", + f"Supplier: `{result.get('supplier')}`", + ] + ), + ephemeral=True, + ) + + @app_commands.command( + name="add-engineer-to-project", + description="Add an ERPNext User to a Project and optionally configure rates.", + ) + @app_commands.describe( + project_id="ERPNext Project id.", + user="ERPNext User email.", + activity_type="Optional Activity Type for project-specific rates.", + billing_rate="Optional client bill rate in USD/hr.", + costing_rate="Optional engineer cost rate in USD/hr.", + ) + @require_role("Steering Committee") + async def add_engineer_to_project_command( + self, + interaction: discord.Interaction, + project_id: str, + user: str, + activity_type: str | None = None, + billing_rate: float | None = None, + costing_rate: float | None = None, + ) -> None: + """Add one engineer to an ERPNext Project roster.""" + await interaction.response.defer(ephemeral=True) + normalized_project_id = project_id.strip() + normalized_user = user.strip().lower() + normalized_activity_type = (activity_type or "").strip() + if not normalized_project_id: + await interaction.followup.send( + "❌ Enter an ERPNext Project id.", ephemeral=True + ) + return + if not normalized_user.endswith("@508.dev"): + await interaction.followup.send( + "❌ Enter the engineer's @508.dev ERPNext User email.", + ephemeral=True, + ) + return + has_billing_rate = billing_rate is not None + has_costing_rate = costing_rate is not None + if (has_billing_rate or has_costing_rate) and not normalized_activity_type: + await interaction.followup.send( + "❌ Activity Type is required when setting bill or cost rates.", + ephemeral=True, + ) + return + if normalized_activity_type and not (has_billing_rate and has_costing_rate): + await interaction.followup.send( + "❌ Billing rate and costing rate are required with Activity Type.", + ephemeral=True, + ) + return + + activity_cost = None + if normalized_activity_type: + activity_cost = ActivityCostRequest( + user=normalized_user, + activity_type=normalized_activity_type, + billing_rate=billing_rate, + costing_rate=costing_rate, + ) + + try: + result = await asyncio.to_thread( + self._add_engineer_to_project, + project_id=normalized_project_id, + user=normalized_user, + activity_cost=activity_cost, + ) + except (EngineerOnboardingError, ValueError) as exc: + self._audit_command_safe( + interaction=interaction, + action="erpnext.project_engineer_add", + result="denied", + metadata={ + "project_id": normalized_project_id, + "user": normalized_user, + "activity_type": normalized_activity_type, + "error": str(exc), + }, + resource_type="erpnext_project", + resource_id=normalized_project_id, + ) + await interaction.followup.send(f"⚠️ {exc}", ephemeral=True) + return + except ERPNextAPIError as exc: + logger.error("ERPNext project engineer add failed: %s", exc) + self._audit_command_safe( + interaction=interaction, + action="erpnext.project_engineer_add", + result="error", + metadata={ + "project_id": normalized_project_id, + "user": normalized_user, + "activity_type": normalized_activity_type, + "error": str(exc), + }, + resource_type="erpnext_project", + resource_id=normalized_project_id, + ) + await interaction.followup.send( + "❌ ERPNext project engineer update failed.", + ephemeral=True, + ) + return + + activity_cost_result = result.get("activity_cost") + lines = [ + "✅ Engineer added to project.", + f"Project: `{normalized_project_id}`", + f"User: `{normalized_user}`", + ] + if isinstance(activity_cost_result, dict): + lines.append( + f"Activity Cost: `{activity_cost_result.get('activity_cost')}`" + ) + self._audit_command_safe( + interaction=interaction, + action="erpnext.project_engineer_add", + result="success", + metadata={ + "project_id": normalized_project_id, + "user": normalized_user, + "activity_type": normalized_activity_type, + "activity_cost": activity_cost_result, + }, + resource_type="erpnext_project", + resource_id=normalized_project_id, + ) + await interaction.followup.send("\n".join(lines), ephemeral=True) + + +async def setup(bot: commands.Bot) -> None: + await bot.add_cog(EngineerOnboardingCog(bot)) diff --git a/packages/shared/src/five08/clients/erpnext.py b/packages/shared/src/five08/clients/erpnext.py index 519e1faa..e0c40677 100644 --- a/packages/shared/src/five08/clients/erpnext.py +++ b/packages/shared/src/five08/clients/erpnext.py @@ -153,6 +153,92 @@ def list_records( ) return [row for row in rows if isinstance(row, dict)] + def get_record(self, doctype: str, record_id: str) -> dict[str, Any]: + """Read one generic ERPNext document.""" + normalized_doctype = doctype.strip() + normalized_id = record_id.strip() + if not normalized_doctype: + raise ERPNextAPIError("DocType is required") + if not normalized_id: + raise ERPNextAPIError(f"{normalized_doctype} id is required") + data = self.request( + "GET", + ( + f"/api/resource/{quote(normalized_doctype, safe='')}/" + f"{quote(normalized_id, safe='')}" + ), + ) + row = data.get("data") + if not isinstance(row, dict): + raise ERPNextAPIError( + f"ERPNext {normalized_doctype} detail is not an object" + ) + return row + + def create_record(self, doctype: str, fields: dict[str, Any]) -> dict[str, Any]: + """Create one generic ERPNext document.""" + normalized_doctype = doctype.strip() + if not normalized_doctype: + raise ERPNextAPIError("DocType is required") + payload = {"doctype": normalized_doctype, **fields} + data = self.request( + "POST", + f"/api/resource/{quote(normalized_doctype, safe='')}", + payload=payload, + ) + row = data.get("data") + if not isinstance(row, dict): + raise ERPNextAPIError( + f"ERPNext {normalized_doctype} create response is not an object" + ) + return row + + def update_record( + self, + doctype: str, + record_id: str, + fields: dict[str, Any], + ) -> dict[str, Any]: + """Update one generic ERPNext document.""" + normalized_doctype = doctype.strip() + normalized_id = record_id.strip() + if not normalized_doctype: + raise ERPNextAPIError("DocType is required") + if not normalized_id: + raise ERPNextAPIError(f"{normalized_doctype} id is required") + if not fields: + return self.get_record(normalized_doctype, normalized_id) + data = self.request( + "PUT", + ( + f"/api/resource/{quote(normalized_doctype, safe='')}/" + f"{quote(normalized_id, safe='')}" + ), + payload=fields, + ) + row = data.get("data") + if isinstance(row, dict): + return row + return self.get_record(normalized_doctype, normalized_id) + + def call_method( + self, + method: str, + *, + params: dict[str, Any] | None = None, + payload: dict[str, Any] | None = None, + ) -> dict[str, Any]: + """Call one whitelisted Frappe method.""" + normalized_method = method.strip() + if not normalized_method: + raise ERPNextAPIError("Frappe method is required") + return self.request( + "POST" if payload is not None else "GET", + f"/api/method/{quote(normalized_method, safe='.')}", + params=params, + payload=payload, + ) + def search_users(self, query: str, *, limit: int = 10) -> list[dict[str, Any]]: """Search ERPNext User records by email, id, or full name.""" normalized_query = query.strip() diff --git a/packages/shared/src/five08/engineer_onboarding.py b/packages/shared/src/five08/engineer_onboarding.py new file mode 100644 index 00000000..56e6dc1d --- /dev/null +++ b/packages/shared/src/five08/engineer_onboarding.py @@ -0,0 +1,550 @@ +"""ERPNext engineer onboarding orchestration.""" + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import date +from typing import Any + +from five08.clients.erpnext import ERPNextAPIError, ERPNextClient + +ENGINEER_ROLE_PROFILE = "Engineer" +EMPLOYEE_ROLE = "Employee" +DEFAULT_SUPPLIER_GROUP = "Subcontractors" +DEFAULT_SUPPLIER_CURRENCY = "USD" + + +class EngineerOnboardingError(ValueError): + """Raised for expected engineer onboarding validation failures.""" + + +class EngineerOnboardingDuplicateNameError(EngineerOnboardingError): + """Raised when a new engineer name resembles an existing account.""" + + def __init__(self, message: str, *, matches: list[dict[str, Any]]) -> None: + super().__init__(message) + self.matches = matches + + +@dataclass(frozen=True) +class EngineerSetupRequest: + """Inputs for setting up an existing ERPNext User as an engineer.""" + + email: str + first_name: str + last_name: str | None = None + country: str | None = None + department: str | None = None + gender: str | None = None + date_of_birth: str | None = None + create_user_permission: bool = True + + +@dataclass(frozen=True) +class ActivityCostRequest: + """Inputs for configuring one engineer Activity Cost row.""" + + user: str + activity_type: str + billing_rate: float | None = None + costing_rate: float | None = None + + +def setup_engineer( + client: ERPNextClient, + request: EngineerSetupRequest, +) -> dict[str, Any]: + """Create or link the ERPNext records needed for one engineer.""" + email = _normalize_508_email(request.email) + first_name = _required_text(request.first_name, "first_name") + last_name = _optional_text(request.last_name) + full_name = " ".join(part for part in (first_name, last_name) if part) + if not full_name: + raise EngineerOnboardingError("Engineer name is required") + + user_exists = _record_exists(client, "User", email) + if not user_exists: + ensure_no_similar_engineer_name(client, email=email, full_name=full_name) + + user, user_created = ensure_user(client, email=email, full_name=full_name) + user, role_result = ensure_engineer_role(client, user) + employee, employee_created = ensure_employee( + client, + email=email, + first_name=first_name, + last_name=last_name, + full_name=full_name, + department=_optional_text(request.department), + gender=_optional_text(request.gender), + date_of_birth=_optional_text(request.date_of_birth), + create_user_permission=request.create_user_permission, + ) + employee_name = _optional_text(employee.get("employee_name")) or full_name + supplier, supplier_created, portal_user_added = ensure_supplier( + client, + supplier_name=employee_name, + user=email, + country=_optional_text(request.country), + ) + employee, supplier_linked = ensure_employee_supplier( + client, + employee=employee, + supplier=str(supplier.get("name") or employee_name), + ) + + return { + "user": user.get("name") or email, + "employee": employee.get("name"), + "employee_name": employee_name, + "supplier": supplier.get("name"), + "role": role_result, + "created": { + "user": user_created, + "employee": employee_created, + "supplier": supplier_created, + }, + "updated": { + "supplier_portal_user": portal_user_added, + "employee_supplier": supplier_linked, + }, + } + + +def ensure_user( + client: ERPNextClient, + *, + email: str, + full_name: str, +) -> tuple[dict[str, Any], bool]: + """Find or create the ERPNext User for an engineer.""" + normalized_email = _normalize_508_email(email) + normalized_full_name = _required_text(full_name, "full_name") + try: + return client.get_record("User", normalized_email), False + except ERPNextAPIError: + # ERPNext operator convention: put the engineer's full name in User.first_name. + fields = { + "email": normalized_email, + "first_name": normalized_full_name, + "last_name": "", + "enabled": 1, + "send_welcome_email": 1, + "role_profile_name": ENGINEER_ROLE_PROFILE, + } + try: + return client.create_record("User", fields), True + except ERPNextAPIError: + fields.pop("role_profile_name", None) + fields["roles"] = [{"role": EMPLOYEE_ROLE}] + return client.create_record("User", fields), True + + +def ensure_engineer_role( + client: ERPNextClient, + user: dict[str, Any], +) -> tuple[dict[str, Any], str]: + """Ensure the User has Engineer role access.""" + user_id = _required_text(user.get("name") or user.get("email"), "user") + if _optional_text(user.get("role_profile_name")) == ENGINEER_ROLE_PROFILE: + return user, "role_profile_exists" + + try: + updated = client.update_record( + "User", + user_id, + {"role_profile_name": ENGINEER_ROLE_PROFILE}, + ) + return updated, "role_profile_assigned" + except ERPNextAPIError: + pass + + roles = _normalized_child_rows(user.get("roles")) + if any(_optional_text(role.get("role")) == EMPLOYEE_ROLE for role in roles): + return user, "employee_role_exists" + + roles.append({"role": EMPLOYEE_ROLE}) + updated = client.update_record("User", user_id, {"roles": roles}) + return updated, "employee_role_assigned" + + +def ensure_employee( + client: ERPNextClient, + *, + email: str, + first_name: str, + last_name: str | None, + full_name: str, + department: str | None = None, + gender: str | None = None, + date_of_birth: str | None = None, + create_user_permission: bool = True, +) -> tuple[dict[str, Any], bool]: + """Find or create an ERPNext Employee linked to a User.""" + normalized_email = _normalize_508_email(email) + existing = client.list_records( + "Employee", + fields=["name", "employee_name", "user_id"], + filters=[["Employee", "user_id", "=", normalized_email]], + limit=1, + ) + if existing: + return client.get_record("Employee", str(existing[0]["name"])), False + + company = default_company(client) + if not company: + raise EngineerOnboardingError( + "ERPNext default company is required before creating Employee records." + ) + + fields: dict[str, Any] = { + "first_name": first_name, + "last_name": last_name or "", + "employee_name": full_name, + "user_id": normalized_email, + "status": "Active", + "date_of_joining": date.today().isoformat(), + "company": company, + "create_user_permission": 1 if create_user_permission else 0, + } + if department: + fields["department"] = department + if gender: + fields["gender"] = gender + if date_of_birth: + fields["date_of_birth"] = date_of_birth + try: + return client.create_record("Employee", fields), True + except ERPNextAPIError as exc: + raise EngineerOnboardingError( + "ERPNext Employee creation failed. Check required Employee fields " + f"and defaults: {exc}" + ) from exc + + +def ensure_supplier( + client: ERPNextClient, + *, + supplier_name: str, + user: str, + country: str | None, +) -> tuple[dict[str, Any], bool, bool]: + """Find or create the matching Supplier and add the portal user.""" + normalized_supplier_name = _required_text(supplier_name, "supplier_name") + normalized_user = _normalize_508_email(user) + supplier = supplier_by_supplier_name(client, normalized_supplier_name) + created = False + if supplier is None: + normalized_country = _optional_text(country) + if normalized_country is None: + raise EngineerOnboardingError( + "Country is required when creating a new Supplier." + ) + supplier = client.create_record( + "Supplier", + { + "supplier_name": normalized_supplier_name, + "supplier_type": "Individual", + "supplier_group": DEFAULT_SUPPLIER_GROUP, + "country": normalized_country, + "default_currency": DEFAULT_SUPPLIER_CURRENCY, + "portal_users": [{"user": normalized_user}], + }, + ) + return supplier, True, True + + portal_users = _normalized_child_rows(supplier.get("portal_users")) + if any(_optional_text(row.get("user")) == normalized_user for row in portal_users): + return supplier, created, False + + portal_users.append({"user": normalized_user}) + updated = client.update_record( + "Supplier", + str(supplier.get("name") or normalized_supplier_name), + {"portal_users": portal_users}, + ) + return updated, created, True + + +def supplier_by_supplier_name( + client: ERPNextClient, + supplier_name: str, +) -> dict[str, Any] | None: + """Return Supplier matching its display name, including naming-series sites.""" + normalized_supplier_name = _required_text(supplier_name, "supplier_name") + matches = client.list_records( + "Supplier", + fields=["name", "supplier_name", "email_id"], + filters=[["Supplier", "supplier_name", "=", normalized_supplier_name]], + limit=1, + ) + if matches: + return client.get_record("Supplier", str(matches[0]["name"])) + try: + return client.get_record("Supplier", normalized_supplier_name) + except ERPNextAPIError: + return None + + +def ensure_employee_supplier( + client: ERPNextClient, + *, + employee: dict[str, Any], + supplier: str, +) -> tuple[dict[str, Any], bool]: + """Ensure Employee.supplier points at the matching Supplier.""" + employee_id = _required_text(employee.get("name"), "employee") + normalized_supplier = _required_text(supplier, "supplier") + if _optional_text(employee.get("supplier")) == normalized_supplier: + return employee, False + updated = client.update_record( + "Employee", + employee_id, + {"supplier": normalized_supplier}, + ) + return updated, True + + +def configure_engineer_activity_cost( + client: ERPNextClient, + request: ActivityCostRequest, +) -> dict[str, Any]: + """Create or update Activity Cost for an already set-up engineer.""" + user = _normalize_508_email(request.user) + activity_type = _required_text(request.activity_type, "activity_type") + if request.billing_rate is None or request.costing_rate is None: + raise EngineerOnboardingError( + "Billing rate and costing rate are required for Activity Cost." + ) + + employee = employee_for_user(client, user) + if employee is None: + raise EngineerOnboardingError( + f"Employee linked to ERPNext User {user} was not found. Run setup first." + ) + employee_id = _required_text(employee.get("name"), "employee") + existing = client.list_records( + "Activity Cost", + fields=["name", "employee", "activity_type", "billing_rate", "costing_rate"], + filters=[ + ["Activity Cost", "employee", "=", employee_id], + ["Activity Cost", "activity_type", "=", activity_type], + ], + limit=1, + ) + + fields = _activity_cost_rate_fields(request) + if existing: + name = _required_text(existing[0].get("name"), "activity_cost") + activity_cost = client.update_record("Activity Cost", name, fields) + created = False + else: + create_fields = { + "employee": employee_id, + "activity_type": activity_type, + "billing_rate": float(request.billing_rate), + "costing_rate": float(request.costing_rate), + } + activity_cost = client.create_record("Activity Cost", create_fields) + created = True + + return { + "activity_cost": activity_cost.get("name"), + "employee": employee_id, + "activity_type": activity_type, + "billing_rate": activity_cost.get("billing_rate", request.billing_rate), + "costing_rate": activity_cost.get("costing_rate", request.costing_rate), + "created": created, + } + + +def add_engineer_to_project( + client: ERPNextClient, + *, + project_id: str, + user: str, + activity_cost: ActivityCostRequest | None = None, +) -> dict[str, Any]: + """Add an ERPNext User to Project.users and optionally configure rates.""" + normalized_project_id = _required_text(project_id, "project_id") + normalized_user = _normalize_508_email(user) + activity_cost_result = None + if activity_cost is not None: + activity_cost_result = configure_engineer_activity_cost(client, activity_cost) + project = client.add_project_user(normalized_project_id, normalized_user) + return {"project": project, "activity_cost": activity_cost_result} + + +def employee_for_user(client: ERPNextClient, user: str) -> dict[str, Any] | None: + """Return the Employee document linked to a User, if present.""" + normalized_user = _normalize_508_email(user) + employees = client.list_records( + "Employee", + fields=["name", "employee_name", "user_id"], + filters=[["Employee", "user_id", "=", normalized_user]], + limit=1, + ) + if not employees: + return None + return client.get_record("Employee", str(employees[0]["name"])) + + +def ensure_no_similar_engineer_name( + client: ERPNextClient, + *, + email: str, + full_name: str, +) -> None: + """Reject new setup when the name resembles another ERP account.""" + normalized_email = _normalize_508_email(email) + normalized_full_name = _required_text(full_name, "full_name") + like_name = f"%{normalized_full_name}%" + matches: list[dict[str, Any]] = [] + + for user in client.list_records( + "User", + fields=["name", "email", "full_name", "enabled"], + or_filters=[ + ["User", "full_name", "like", like_name], + ["User", "first_name", "like", like_name], + ], + limit=5, + ): + user_email = _optional_text(user.get("email") or user.get("name")) + if user_email and user_email.casefold() == normalized_email.casefold(): + continue + matches.append( + { + "doctype": "User", + "name": user.get("name"), + "email": user_email, + "label": user.get("full_name") or user.get("name"), + } + ) + + for employee in client.list_records( + "Employee", + fields=["name", "employee_name", "user_id"], + filters=[["Employee", "employee_name", "like", like_name]], + limit=5, + ): + user_email = _optional_text(employee.get("user_id")) + if user_email and user_email.casefold() == normalized_email.casefold(): + continue + matches.append( + { + "doctype": "Employee", + "name": employee.get("name"), + "email": user_email, + "label": employee.get("employee_name") or employee.get("name"), + } + ) + + for supplier in client.list_records( + "Supplier", + fields=["name", "supplier_name", "email_id"], + or_filters=[ + ["Supplier", "name", "like", like_name], + ["Supplier", "supplier_name", "like", like_name], + ], + limit=5, + ): + matches.append( + { + "doctype": "Supplier", + "name": supplier.get("name"), + "email": supplier.get("email_id"), + "label": supplier.get("supplier_name") or supplier.get("name"), + } + ) + + if matches: + raise EngineerOnboardingDuplicateNameError( + "A similar ERPNext account already exists. Confirm the intended " + "person before creating a new engineer.", + matches=matches[:10], + ) + + +def default_company(client: ERPNextClient) -> str | None: + """Return ERPNext's configured default company, falling back to first Company.""" + try: + response = client.call_method( + "frappe.client.get_value", + params={ + "doctype": "Global Defaults", + "fieldname": "default_company", + }, + ) + value = _extract_frappe_value(response.get("message"), "default_company") + if value: + return value + except ERPNextAPIError: + pass + + companies = client.list_records("Company", fields=["name"], limit=1) + if companies: + return _optional_text(companies[0].get("name")) + return None + + +def _activity_cost_rate_fields(request: ActivityCostRequest) -> dict[str, float]: + fields: dict[str, float] = {} + if request.billing_rate is not None: + fields["billing_rate"] = float(request.billing_rate) + if request.costing_rate is not None: + fields["costing_rate"] = float(request.costing_rate) + return fields + + +def _record_exists(client: ERPNextClient, doctype: str, record_id: str) -> bool: + try: + client.get_record(doctype, record_id) + except ERPNextAPIError: + return False + return True + + +def _normalized_child_rows(value: Any) -> list[dict[str, Any]]: + if not isinstance(value, list): + return [] + rows: list[dict[str, Any]] = [] + for item in value: + if not isinstance(item, dict): + continue + row = dict(item) + row.pop("doctype", None) + rows.append(row) + return rows + + +def _extract_frappe_value(message: Any, fieldname: str) -> str | None: + if isinstance(message, dict): + return _optional_text(message.get(fieldname) or message.get("value")) + if isinstance(message, str): + return _optional_text(message) + if isinstance(message, list) and message: + return _extract_frappe_value(message[0], fieldname) + return None + + +def _required_text(value: Any, field_name: str) -> str: + normalized = _optional_text(value) + if normalized is None: + raise EngineerOnboardingError(f"{field_name} is required") + if len(normalized) > 200: + raise EngineerOnboardingError(f"{field_name} is too long") + return normalized + + +def _normalize_508_email(value: Any) -> str: + email = _required_text(value, "email").lower() + if not email.endswith("@508.dev"): + raise EngineerOnboardingError("Engineer email must be a @508.dev address") + return email + + +def _optional_text(value: Any) -> str | None: + if value is None: + return None + text = str(value).strip() + return text or None diff --git a/tests/unit/test_backend_api.py b/tests/unit/test_backend_api.py index edd52b4a..8545f48d 100644 --- a/tests/unit/test_backend_api.py +++ b/tests/unit/test_backend_api.py @@ -3085,7 +3085,7 @@ def test_dashboard_add_project_user_uses_erpnext_record_id( ), patch( "five08.backend.api._add_erpnext_project_user", - return_value=updated_project, + return_value={"project": updated_project, "activity_cost": None}, ) as mock_add_user, patch( "five08.backend.api._write_auth_audit_event", @@ -3098,7 +3098,7 @@ def test_dashboard_add_project_user_uses_erpnext_record_id( ) assert response.status_code == 200 - assert response.json() == {"project": updated_project} + assert response.json() == {"project": updated_project, "activity_cost": None} mock_add_user.assert_called_once_with( external_project_id="PROJ-0033", user="member@508.dev", @@ -3106,6 +3106,52 @@ def test_dashboard_add_project_user_uses_erpnext_record_id( mock_audit.assert_awaited_once() +def test_dashboard_add_project_user_rejects_activity_type_without_rate( + client: TestClient, +) -> None: + project_id = "11111111-1111-4111-8111-111111111111" + session = api.AuthSession( + subject="steering-1", + email="steering@508.dev", + display_name="Steering User", + groups=["Steering Committee"], + is_admin=False, + id_token="", + expires_at=4_102_444_800, + actor_provider=api.ActorProvider.DISCORD.value, + ) + cached_project = { + "id": project_id, + "display_name": "Visible Project", + "erpnext_project_id": "PROJ-0033", + "roster_members": [], + } + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", session), + ), + patch( + "five08.backend.api._cached_dashboard_project_by_id", + return_value=cached_project, + ), + patch("five08.backend.api._add_erpnext_project_user") as mock_add_user, + ): + response = client.post( + f"/dashboard/api/projects/{project_id}/users", + json={ + "user": "member@508.dev", + "activity_type": "Engineering for Visible Project", + }, + ) + + assert response.status_code == 400 + assert response.json() == {"error": "activity_cost_rates_required"} + mock_add_user.assert_not_called() + + def test_dashboard_add_project_historical_member_updates_local_roster( client: TestClient, ) -> None: diff --git a/tests/unit/test_engineer_onboarding.py b/tests/unit/test_engineer_onboarding.py new file mode 100644 index 00000000..7c859ff1 --- /dev/null +++ b/tests/unit/test_engineer_onboarding.py @@ -0,0 +1,284 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from five08.clients.erpnext import ERPNextAPIError +from five08.engineer_onboarding import ( + ActivityCostRequest, + EngineerOnboardingDuplicateNameError, + EngineerOnboardingError, + EngineerSetupRequest, + add_engineer_to_project, + configure_engineer_activity_cost, + ensure_supplier, + setup_engineer, +) + + +class FakeERPNextClient: + def __init__(self) -> None: + self.records: dict[str, dict[str, dict[str, Any]]] = { + "Role Profile": {"Engineer": {"name": "Engineer"}}, + "Company": {"508.dev": {"name": "508.dev"}}, + "User": {}, + "Employee": {}, + "Supplier": {}, + "Activity Cost": {}, + "Project": { + "PROJ-001": { + "name": "PROJ-001", + "project_name": "Test Project", + "users": [], + } + }, + } + self.created: list[tuple[str, dict[str, Any]]] = [] + + def get_record(self, doctype: str, record_id: str) -> dict[str, Any]: + try: + return dict(self.records[doctype][record_id]) + except KeyError as exc: + raise ERPNextAPIError(f"{doctype} {record_id} not found") from exc + + def create_record(self, doctype: str, fields: dict[str, Any]) -> dict[str, Any]: + name = str( + fields.get("name") + or fields.get("email") + or fields.get("supplier_name") + or "" + ) + if not name and doctype == "Employee": + name = f"HR-EMP-{len(self.records[doctype]) + 1:05d}" + if not name and doctype == "Activity Cost": + name = f"ACT-COST-{len(self.records[doctype]) + 1:05d}" + record = {"name": name, **fields} + self.records.setdefault(doctype, {})[name] = record + self.created.append((doctype, record)) + return dict(record) + + def update_record( + self, + doctype: str, + record_id: str, + fields: dict[str, Any], + ) -> dict[str, Any]: + record = self.records[doctype][record_id] + record.update(fields) + return dict(record) + + def list_records( + self, + doctype: str, + *, + fields: list[str], + filters: list[Any] | None = None, + or_filters: list[Any] | None = None, + limit: int = 20, + ) -> list[dict[str, Any]]: + del fields + rows = list(self.records.get(doctype, {}).values()) + matched = [ + row + for row in rows + if self._matches(row, filters or [], require_all=True) + and (not or_filters or self._matches(row, or_filters, require_all=False)) + ] + return [dict(row) for row in matched[:limit]] + + def add_project_user(self, project_id: str, user: str) -> dict[str, Any]: + project = self.records["Project"][project_id] + users = project.setdefault("users", []) + if not any(row.get("user") == user for row in users): + users.append({"user": user, "view_attachments": 0, "hide_timesheets": 0}) + return dict(project) + + def call_method( + self, + method: str, + *, + params: dict[str, Any] | None = None, + payload: dict[str, Any] | None = None, + ) -> dict[str, Any]: + del params, payload + if method == "frappe.client.get_value": + return {"message": {"default_company": "508.dev"}} + return {"message": None} + + @staticmethod + def _matches( + row: dict[str, Any], + filters: list[Any], + *, + require_all: bool, + ) -> bool: + if not filters: + return True + results = [] + for item in filters: + if len(item) != 4: + continue + _doctype, field, op, expected = item + actual = str(row.get(field) or "") + if op == "=": + results.append(actual == str(expected)) + elif op == "like": + token = str(expected).replace("%", "").casefold() + results.append(token in actual.casefold()) + return all(results) if require_all else any(results) + + +def test_setup_engineer_creates_user_employee_supplier_and_links_supplier() -> None: + client = FakeERPNextClient() + + result = setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + assert result["user"] == "jane@508.dev" + assert result["employee"] == "HR-EMP-00001" + assert result["supplier"] == "Jane Engineer" + assert client.records["Employee"]["HR-EMP-00001"]["supplier"] == "Jane Engineer" + assert client.records["User"]["jane@508.dev"]["role_profile_name"] == "Engineer" + assert client.records["User"]["jane@508.dev"]["first_name"] == "Jane Engineer" + assert client.records["Employee"]["HR-EMP-00001"]["create_user_permission"] == 1 + + +def test_setup_engineer_requires_508_email() -> None: + with pytest.raises(EngineerOnboardingError, match="@508.dev"): + setup_engineer( + FakeERPNextClient(), # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@example.com", + first_name="Jane", + country="Taiwan", + ), + ) + + +def test_setup_engineer_blocks_similar_name_for_new_email() -> None: + client = FakeERPNextClient() + client.records["User"]["jane.old@508.dev"] = { + "name": "jane.old@508.dev", + "email": "jane.old@508.dev", + "full_name": "Jane Engineer", + } + + with pytest.raises(EngineerOnboardingDuplicateNameError) as exc: + setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + assert exc.value.matches[0]["doctype"] == "User" + assert exc.value.matches[0]["email"] == "jane.old@508.dev" + + +def test_ensure_supplier_reuses_supplier_matched_by_supplier_name() -> None: + client = FakeERPNextClient() + client.records["Supplier"]["SUP-0001"] = { + "name": "SUP-0001", + "supplier_name": "Jane Engineer", + "portal_users": [], + } + + supplier, created, portal_user_added = ensure_supplier( + client, # type: ignore[arg-type] + supplier_name="Jane Engineer", + user="jane@508.dev", + country="Taiwan", + ) + + assert supplier["name"] == "SUP-0001" + assert created is False + assert portal_user_added is True + assert "Jane Engineer" not in client.records["Supplier"] + assert client.records["Supplier"]["SUP-0001"]["portal_users"] == [ + {"user": "jane@508.dev"} + ] + + +def test_add_engineer_to_project_optionally_configures_activity_cost() -> None: + client = FakeERPNextClient() + setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + result = add_engineer_to_project( + client, # type: ignore[arg-type] + project_id="PROJ-001", + user="jane@508.dev", + activity_cost=ActivityCostRequest( + user="jane@508.dev", + activity_type="Engineering for Test Project", + billing_rate=150, + costing_rate=100, + ), + ) + + assert result["project"]["users"] == [ + {"user": "jane@508.dev", "view_attachments": 0, "hide_timesheets": 0} + ] + assert result["activity_cost"]["activity_cost"] == "ACT-COST-00001" + assert client.records["Activity Cost"]["ACT-COST-00001"]["billing_rate"] == 150 + assert client.records["Activity Cost"]["ACT-COST-00001"]["costing_rate"] == 100 + + +def test_configure_engineer_activity_cost_requires_both_rates() -> None: + client = FakeERPNextClient() + setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + with pytest.raises(EngineerOnboardingError, match="Billing rate and costing rate"): + configure_engineer_activity_cost( + client, # type: ignore[arg-type] + ActivityCostRequest( + user="jane@508.dev", + activity_type="Engineering for Test Project", + billing_rate=150, + ), + ) + + +def test_add_engineer_to_project_validates_activity_cost_before_roster_update() -> None: + client = FakeERPNextClient() + + with pytest.raises(EngineerOnboardingError, match="Employee linked"): + add_engineer_to_project( + client, # type: ignore[arg-type] + project_id="PROJ-001", + user="missing@508.dev", + activity_cost=ActivityCostRequest( + user="missing@508.dev", + activity_type="Engineering for Test Project", + billing_rate=150, + costing_rate=100, + ), + ) + + assert client.records["Project"]["PROJ-001"]["users"] == [] From 784f3a81bb711db29e5b50815c7063c10d7a50ea Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Wed, 20 May 2026 10:32:16 +0800 Subject: [PATCH 02/14] Address engineer onboarding review feedback --- apps/api/src/five08/backend/api.py | 15 +- .../shared/src/five08/engineer_onboarding.py | 5 +- tests/unit/test_backend_api.py | 286 ++++++++++++++++++ tests/unit/test_engineer_onboarding.py | 25 ++ tests/unit/test_erpnext_client.py | 109 +++++++ 5 files changed, 431 insertions(+), 9 deletions(-) diff --git a/apps/api/src/five08/backend/api.py b/apps/api/src/five08/backend/api.py index 256fdaaa..ae7e97ce 100644 --- a/apps/api/src/five08/backend/api.py +++ b/apps/api/src/five08/backend/api.py @@ -3577,10 +3577,13 @@ async def dashboard_add_project_user_handler( except Exception: return JSONResponse({"error": "invalid_payload"}, status_code=400) - normalized_user = payload.user.strip() + normalized_user = payload.user.strip().lower() if not normalized_user or len(normalized_user) > 200: return JSONResponse({"error": "invalid_user"}, status_code=400) - has_activity_type = bool((payload.activity_type or "").strip()) + if not normalized_user.endswith("@508.dev"): + return JSONResponse({"error": "invalid_user_email"}, status_code=400) + normalized_activity_type = _text_or_none(payload.activity_type) + has_activity_type = normalized_activity_type is not None has_billing_rate = payload.billing_rate is not None has_costing_rate = payload.costing_rate is not None if (has_billing_rate or has_costing_rate) and not has_activity_type: @@ -3594,14 +3597,10 @@ async def dashboard_add_project_user_handler( "external_project_id": external_project_id, "user": normalized_user, } - if ( - payload.activity_type is not None - or payload.billing_rate is not None - or payload.costing_rate is not None - ): + if has_activity_type or has_billing_rate or has_costing_rate: add_user_kwargs.update( { - "activity_type": payload.activity_type, + "activity_type": normalized_activity_type, "billing_rate": payload.billing_rate, "costing_rate": payload.costing_rate, } diff --git a/packages/shared/src/five08/engineer_onboarding.py b/packages/shared/src/five08/engineer_onboarding.py index 56e6dc1d..14e80c15 100644 --- a/packages/shared/src/five08/engineer_onboarding.py +++ b/packages/shared/src/five08/engineer_onboarding.py @@ -448,11 +448,14 @@ def ensure_no_similar_engineer_name( ], limit=5, ): + supplier_email = _optional_text(supplier.get("email_id")) + if supplier_email and supplier_email.casefold() == normalized_email.casefold(): + continue matches.append( { "doctype": "Supplier", "name": supplier.get("name"), - "email": supplier.get("email_id"), + "email": supplier_email, "label": supplier.get("supplier_name") or supplier.get("name"), } ) diff --git a/tests/unit/test_backend_api.py b/tests/unit/test_backend_api.py index 23c8db36..7544ad47 100644 --- a/tests/unit/test_backend_api.py +++ b/tests/unit/test_backend_api.py @@ -3,6 +3,7 @@ import asyncio import re from datetime import datetime, timedelta, timezone +from typing import Any from unittest.mock import AsyncMock, Mock, patch import pytest @@ -84,6 +85,19 @@ def client(app: api.FastAPI) -> TestClient: return TestClient(app) +def _dashboard_write_session() -> api.AuthSession: + return api.AuthSession( + subject="steering-1", + email="steering@508.dev", + display_name="Steering User", + groups=["Steering Committee"], + is_admin=False, + id_token="", + expires_at=4_102_444_800, + actor_provider=api.ActorProvider.DISCORD.value, + ) + + def test_health_handler_healthy(client: TestClient) -> None: """Health endpoint should report healthy when Redis pings.""" with patch("five08.backend.api.is_postgres_healthy", return_value=True): @@ -3048,6 +3062,161 @@ def test_bulk_update_erpnext_projects_fetches_project_refs_once() -> None: mock_cached_project.assert_called_once_with(project_id) +def test_dashboard_setup_engineer_returns_setup_result(client: TestClient) -> None: + result = { + "user": "jane@508.dev", + "employee": "HR-EMP-00001", + "supplier": "SUP-0001", + "created": {"user": True, "employee": True, "supplier": False}, + "updated": {"supplier_portal_user": True, "employee_supplier": True}, + } + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._setup_erpnext_engineer", + return_value=result, + ) as mock_setup, + patch( + "five08.backend.api._write_auth_audit_event", + new_callable=AsyncMock, + ) as mock_audit, + ): + response = client.post( + "/dashboard/api/onboarding/engineers", + json={ + "email": " jane@508.dev ", + "first_name": "Jane", + "last_name": "Engineer", + "country": "Taiwan", + }, + ) + + assert response.status_code == 200 + assert response.json() == result + setup_payload = mock_setup.call_args.args[0] + assert setup_payload.email == " jane@508.dev " + assert setup_payload.first_name == "Jane" + mock_audit.assert_awaited_once() + + +@pytest.mark.parametrize( + ("body", "expected_error"), + [ + ({}, "invalid_payload"), + ({"email": "jane@example.com", "first_name": "Jane"}, "invalid_email"), + ({"email": "jane@508.dev", "first_name": " "}, "first_name_required"), + ], +) +def test_dashboard_setup_engineer_rejects_invalid_inputs( + client: TestClient, + body: dict[str, Any], + expected_error: str, +) -> None: + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch("five08.backend.api._setup_erpnext_engineer") as mock_setup, + ): + response = client.post("/dashboard/api/onboarding/engineers", json=body) + + assert response.status_code == 400 + assert response.json() == {"error": expected_error} + mock_setup.assert_not_called() + + +def test_dashboard_setup_engineer_maps_duplicate_name_to_conflict( + client: TestClient, +) -> None: + duplicate_error = api.EngineerOnboardingDuplicateNameError( + "similar person exists", + matches=[{"doctype": "Supplier", "name": "SUP-0001"}], + ) + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._setup_erpnext_engineer", + side_effect=duplicate_error, + ), + patch("five08.backend.api._write_auth_audit_event", new_callable=AsyncMock), + ): + response = client.post( + "/dashboard/api/onboarding/engineers", + json={"email": "jane@508.dev", "first_name": "Jane"}, + ) + + assert response.status_code == 409 + assert response.json() == { + "error": "similar_engineer_exists", + "detail": "similar person exists", + "matches": [{"doctype": "Supplier", "name": "SUP-0001"}], + } + + +def test_dashboard_setup_engineer_maps_onboarding_error_to_bad_request( + client: TestClient, +) -> None: + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._setup_erpnext_engineer", + side_effect=api.EngineerOnboardingError("Country is required"), + ), + ): + response = client.post( + "/dashboard/api/onboarding/engineers", + json={"email": "jane@508.dev", "first_name": "Jane"}, + ) + + assert response.status_code == 400 + assert response.json() == { + "error": "engineer_setup_failed", + "detail": "Country is required", + } + + +def test_dashboard_setup_engineer_maps_erpnext_error_to_bad_gateway( + client: TestClient, +) -> None: + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._setup_erpnext_engineer", + side_effect=api.ERPNextAPIError("ERP unavailable"), + ), + ): + response = client.post( + "/dashboard/api/onboarding/engineers", + json={"email": "jane@508.dev", "first_name": "Jane"}, + ) + + assert response.status_code == 502 + assert response.json() == { + "error": "erpnext_engineer_setup_failed", + "detail": "ERP unavailable", + } + + def test_dashboard_add_project_user_uses_erpnext_record_id( client: TestClient, ) -> None: @@ -3152,6 +3321,123 @@ def test_dashboard_add_project_user_rejects_activity_type_without_rate( mock_add_user.assert_not_called() +def test_dashboard_add_project_user_rejects_non_508_email( + client: TestClient, +) -> None: + project_id = "11111111-1111-4111-8111-111111111111" + cached_project = { + "id": project_id, + "display_name": "Visible Project", + "erpnext_project_id": "PROJ-0033", + "roster_members": [], + } + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._cached_dashboard_project_by_id", + return_value=cached_project, + ), + patch("five08.backend.api._add_erpnext_project_user") as mock_add_user, + ): + response = client.post( + f"/dashboard/api/projects/{project_id}/users", + json={"user": "member@example.com"}, + ) + + assert response.status_code == 400 + assert response.json() == {"error": "invalid_user_email"} + mock_add_user.assert_not_called() + + +def test_dashboard_add_project_user_treats_blank_activity_type_as_absent( + client: TestClient, +) -> None: + project_id = "11111111-1111-4111-8111-111111111111" + cached_project = { + "id": project_id, + "display_name": "Visible Project", + "erpnext_project_id": "PROJ-0033", + "roster_members": [], + } + updated_project = { + **cached_project, + "roster_members": [{"email": "member@508.dev"}], + } + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._cached_dashboard_project_by_id", + return_value=cached_project, + ), + patch( + "five08.backend.api._add_erpnext_project_user", + return_value={"project": updated_project, "activity_cost": None}, + ) as mock_add_user, + patch( + "five08.backend.api._write_auth_audit_event", + new_callable=AsyncMock, + ), + ): + response = client.post( + f"/dashboard/api/projects/{project_id}/users", + json={"user": "MEMBER@508.dev", "activity_type": " "}, + ) + + assert response.status_code == 200 + mock_add_user.assert_called_once_with( + external_project_id="PROJ-0033", + user="member@508.dev", + ) + + +def test_dashboard_add_project_user_rejects_rates_with_blank_activity_type( + client: TestClient, +) -> None: + project_id = "11111111-1111-4111-8111-111111111111" + cached_project = { + "id": project_id, + "display_name": "Visible Project", + "erpnext_project_id": "PROJ-0033", + "roster_members": [], + } + + with ( + patch( + "five08.backend.api._current_session", + new_callable=AsyncMock, + return_value=("session-1", _dashboard_write_session()), + ), + patch( + "five08.backend.api._cached_dashboard_project_by_id", + return_value=cached_project, + ), + patch("five08.backend.api._add_erpnext_project_user") as mock_add_user, + ): + response = client.post( + f"/dashboard/api/projects/{project_id}/users", + json={ + "user": "member@508.dev", + "activity_type": " ", + "billing_rate": 150, + "costing_rate": 100, + }, + ) + + assert response.status_code == 400 + assert response.json() == {"error": "activity_type_required"} + mock_add_user.assert_not_called() + + def test_dashboard_add_project_historical_member_updates_local_roster( client: TestClient, ) -> None: diff --git a/tests/unit/test_engineer_onboarding.py b/tests/unit/test_engineer_onboarding.py index 7c859ff1..56675964 100644 --- a/tests/unit/test_engineer_onboarding.py +++ b/tests/unit/test_engineer_onboarding.py @@ -186,6 +186,31 @@ def test_setup_engineer_blocks_similar_name_for_new_email() -> None: assert exc.value.matches[0]["email"] == "jane.old@508.dev" +def test_setup_engineer_allows_existing_supplier_with_same_email() -> None: + client = FakeERPNextClient() + client.records["Supplier"]["SUP-0001"] = { + "name": "SUP-0001", + "supplier_name": "Jane Engineer", + "email_id": "jane@508.dev", + "portal_users": [], + } + + result = setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + assert result["supplier"] == "SUP-0001" + assert client.records["Supplier"]["SUP-0001"]["portal_users"] == [ + {"user": "jane@508.dev"} + ] + + def test_ensure_supplier_reuses_supplier_matched_by_supplier_name() -> None: client = FakeERPNextClient() client.records["Supplier"]["SUP-0001"] = { diff --git a/tests/unit/test_erpnext_client.py b/tests/unit/test_erpnext_client.py index f83504a4..210c0415 100644 --- a/tests/unit/test_erpnext_client.py +++ b/tests/unit/test_erpnext_client.py @@ -24,6 +24,30 @@ def request( return self.response +class CaptureERPNextClient(FakeERPNextClient): + def __init__(self, response: dict[str, Any]) -> None: + super().__init__(response) + self.calls: list[dict[str, Any]] = [] + + def request( + self, + method: str, + path: str, + *, + params: dict[str, Any] | None = None, + payload: dict[str, Any] | None = None, + ) -> dict[str, Any]: + self.calls.append( + { + "method": method, + "path": path, + "params": params, + "payload": payload, + } + ) + return self.response + + def test_list_projects_rejects_missing_data_rows() -> None: client = FakeERPNextClient({}) @@ -61,3 +85,88 @@ def request( filters = json.loads(params["filters"]) assert ["Supplier", "disabled", "=", 0] in filters assert ["Supplier", "is_frozen", "=", 0] in filters + + +def test_get_record_validates_inputs_and_response_shape() -> None: + client = FakeERPNextClient({"data": None}) + + with pytest.raises(ERPNextAPIError, match="DocType is required"): + client.get_record(" ", "USER-001") + with pytest.raises(ERPNextAPIError, match="User id is required"): + client.get_record("User", " ") + with pytest.raises(ERPNextAPIError, match="detail is not an object"): + client.get_record("User", "USER-001") + + +def test_create_record_validates_inputs_and_response_shape() -> None: + client = CaptureERPNextClient({"data": []}) + + with pytest.raises(ERPNextAPIError, match="DocType is required"): + client.create_record(" ", {}) + with pytest.raises(ERPNextAPIError, match="create response is not an object"): + client.create_record("User", {"email": "member@508.dev"}) + + assert client.calls[0]["method"] == "POST" + assert client.calls[0]["path"] == "/api/resource/User" + assert client.calls[0]["payload"] == { + "doctype": "User", + "email": "member@508.dev", + } + + +def test_update_record_validates_inputs_and_falls_back_to_detail() -> None: + client = CaptureERPNextClient({"data": {"name": "USER-001"}}) + + with pytest.raises(ERPNextAPIError, match="DocType is required"): + client.update_record(" ", "USER-001", {"enabled": 1}) + with pytest.raises(ERPNextAPIError, match="User id is required"): + client.update_record("User", " ", {"enabled": 1}) + + assert client.update_record("User", "USER-001", {}) == {"name": "USER-001"} + assert client.calls[-1]["method"] == "GET" + assert client.calls[-1]["path"] == "/api/resource/User/USER-001" + + +def test_update_record_fetches_detail_when_update_response_has_invalid_data() -> None: + class UpdateThenGetClient(CaptureERPNextClient): + def request( + self, + method: str, + path: str, + *, + params: dict[str, Any] | None = None, + payload: dict[str, Any] | None = None, + ) -> dict[str, Any]: + self.calls.append( + { + "method": method, + "path": path, + "params": params, + "payload": payload, + } + ) + if method == "PUT": + return {"data": None} + return {"data": {"name": "USER-001", "enabled": 1}} + + client = UpdateThenGetClient({}) + + assert client.update_record("User", "USER-001", {"enabled": 1}) == { + "name": "USER-001", + "enabled": 1, + } + assert [call["method"] for call in client.calls] == ["PUT", "GET"] + + +def test_call_method_validates_method_name_and_selects_http_method() -> None: + client = CaptureERPNextClient({"message": {"value": "ok"}}) + + with pytest.raises(ERPNextAPIError, match="Frappe method is required"): + client.call_method(" ") + + assert client.call_method("frappe.client.get_value", params={"doctype": "User"}) + assert client.call_method("frappe.client.set_value", payload={"value": "ok"}) + assert client.calls[0]["method"] == "GET" + assert client.calls[0]["path"] == "/api/method/frappe.client.get_value" + assert client.calls[1]["method"] == "POST" + assert client.calls[1]["path"] == "/api/method/frappe.client.set_value" From 6b17591c529e651aee09341183ad2b09d98a7b9d Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Wed, 20 May 2026 10:59:04 +0800 Subject: [PATCH 03/14] Avoid partial activity cost writes --- .../shared/src/five08/engineer_onboarding.py | 47 ++++++++++++------- tests/unit/test_engineer_onboarding.py | 33 +++++++++++++ 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/packages/shared/src/five08/engineer_onboarding.py b/packages/shared/src/five08/engineer_onboarding.py index 14e80c15..5ef4a9b0 100644 --- a/packages/shared/src/five08/engineer_onboarding.py +++ b/packages/shared/src/five08/engineer_onboarding.py @@ -247,6 +247,7 @@ def ensure_supplier( "supplier_group": DEFAULT_SUPPLIER_GROUP, "country": normalized_country, "default_currency": DEFAULT_SUPPLIER_CURRENCY, + "email_id": normalized_user, "portal_users": [{"user": normalized_user}], }, ) @@ -309,19 +310,11 @@ def configure_engineer_activity_cost( request: ActivityCostRequest, ) -> dict[str, Any]: """Create or update Activity Cost for an already set-up engineer.""" - user = _normalize_508_email(request.user) - activity_type = _required_text(request.activity_type, "activity_type") - if request.billing_rate is None or request.costing_rate is None: - raise EngineerOnboardingError( - "Billing rate and costing rate are required for Activity Cost." - ) - - employee = employee_for_user(client, user) - if employee is None: - raise EngineerOnboardingError( - f"Employee linked to ERPNext User {user} was not found. Run setup first." - ) - employee_id = _required_text(employee.get("name"), "employee") + _user, activity_type, employee_id = _activity_cost_preconditions(client, request) + billing_rate = request.billing_rate + costing_rate = request.costing_rate + assert billing_rate is not None + assert costing_rate is not None existing = client.list_records( "Activity Cost", fields=["name", "employee", "activity_type", "billing_rate", "costing_rate"], @@ -341,8 +334,8 @@ def configure_engineer_activity_cost( create_fields = { "employee": employee_id, "activity_type": activity_type, - "billing_rate": float(request.billing_rate), - "costing_rate": float(request.costing_rate), + "billing_rate": float(billing_rate), + "costing_rate": float(costing_rate), } activity_cost = client.create_record("Activity Cost", create_fields) created = True @@ -357,6 +350,26 @@ def configure_engineer_activity_cost( } +def _activity_cost_preconditions( + client: ERPNextClient, + request: ActivityCostRequest, +) -> tuple[str, str, str]: + """Validate Activity Cost inputs without mutating financial records.""" + user = _normalize_508_email(request.user) + activity_type = _required_text(request.activity_type, "activity_type") + if request.billing_rate is None or request.costing_rate is None: + raise EngineerOnboardingError( + "Billing rate and costing rate are required for Activity Cost." + ) + + employee = employee_for_user(client, user) + if employee is None: + raise EngineerOnboardingError( + f"Employee linked to ERPNext User {user} was not found. Run setup first." + ) + return user, activity_type, _required_text(employee.get("name"), "employee") + + def add_engineer_to_project( client: ERPNextClient, *, @@ -369,8 +382,10 @@ def add_engineer_to_project( normalized_user = _normalize_508_email(user) activity_cost_result = None if activity_cost is not None: - activity_cost_result = configure_engineer_activity_cost(client, activity_cost) + _activity_cost_preconditions(client, activity_cost) project = client.add_project_user(normalized_project_id, normalized_user) + if activity_cost is not None: + activity_cost_result = configure_engineer_activity_cost(client, activity_cost) return {"project": project, "activity_cost": activity_cost_result} diff --git a/tests/unit/test_engineer_onboarding.py b/tests/unit/test_engineer_onboarding.py index 56675964..b42119a5 100644 --- a/tests/unit/test_engineer_onboarding.py +++ b/tests/unit/test_engineer_onboarding.py @@ -149,6 +149,7 @@ def test_setup_engineer_creates_user_employee_supplier_and_links_supplier() -> N assert client.records["User"]["jane@508.dev"]["role_profile_name"] == "Engineer" assert client.records["User"]["jane@508.dev"]["first_name"] == "Jane Engineer" assert client.records["Employee"]["HR-EMP-00001"]["create_user_permission"] == 1 + assert client.records["Supplier"]["Jane Engineer"]["email_id"] == "jane@508.dev" def test_setup_engineer_requires_508_email() -> None: @@ -307,3 +308,35 @@ def test_add_engineer_to_project_validates_activity_cost_before_roster_update() ) assert client.records["Project"]["PROJ-001"]["users"] == [] + + +def test_add_engineer_to_project_adds_roster_before_activity_cost_write() -> None: + class FailingProjectClient(FakeERPNextClient): + def add_project_user(self, project_id: str, user: str) -> dict[str, Any]: + raise ERPNextAPIError("project not found") + + client = FailingProjectClient() + setup_engineer( + client, # type: ignore[arg-type] + EngineerSetupRequest( + email="jane@508.dev", + first_name="Jane", + last_name="Engineer", + country="Taiwan", + ), + ) + + with pytest.raises(ERPNextAPIError, match="project not found"): + add_engineer_to_project( + client, # type: ignore[arg-type] + project_id="PROJ-MISSING", + user="jane@508.dev", + activity_cost=ActivityCostRequest( + user="jane@508.dev", + activity_type="Engineering for Test Project", + billing_rate=150, + costing_rate=100, + ), + ) + + assert client.records["Activity Cost"] == {} From 254dc32982d4683578dac6018db3145eca5c295a Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Wed, 20 May 2026 11:36:53 +0800 Subject: [PATCH 04/14] Address onboarding partial success feedback --- apps/admin_dashboard/src/main.tsx | 36 ++++++----- apps/api/src/five08/backend/api.py | 1 + .../static/dashboard/.vite/manifest.json | 2 +- .../{index-aHk8Wc3I.js => index-CkDvLqms.js} | 2 +- .../backend/static/dashboard/index.html | 2 +- .../shared/src/five08/engineer_onboarding.py | 38 +++++++++++- tests/unit/test_backend_api.py | 61 +++++++++++++++++++ tests/unit/test_engineer_onboarding.py | 59 +++++++++++++++++- 8 files changed, 182 insertions(+), 19 deletions(-) rename apps/api/src/five08/backend/static/dashboard/assets/{index-aHk8Wc3I.js => index-CkDvLqms.js} (73%) diff --git a/apps/admin_dashboard/src/main.tsx b/apps/admin_dashboard/src/main.tsx index 646be3f6..13032dee 100644 --- a/apps/admin_dashboard/src/main.tsx +++ b/apps/admin_dashboard/src/main.tsx @@ -1186,22 +1186,30 @@ function App() { if (!normalizedUser || !normalizedCandidateId) return false setBusy(`project:${projectId}:user`, true) try { - const payload = await requestJson<{ project: Project; activity_cost?: object | null }>( - `/dashboard/api/projects/${encodeURIComponent(projectId)}/users`, - { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - user: normalizedUser, - candidate_id: normalizedCandidateId, - ...(rates || {}), - }), - }, - ) + const payload = await requestJson<{ + project: Project + activity_cost?: object | null + activity_cost_error?: string | null + }>(`/dashboard/api/projects/${encodeURIComponent(projectId)}/users`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + user: normalizedUser, + candidate_id: normalizedCandidateId, + ...(rates || {}), + }), + }) setProjects((current) => current.map((project) => (project.id === projectId ? payload.project : project)), ) - showToast(payload.activity_cost ? "Added project user and rate" : "Added project user", "ok") + showToast( + payload.activity_cost_error + ? "Added project user; rate failed" + : payload.activity_cost + ? "Added project user and rate" + : "Added project user", + payload.activity_cost_error ? "error" : "ok", + ) return true } catch (error) { showError(error, "Unable to add project user") @@ -5495,7 +5503,7 @@ function EngineerSetupPanel({ + {crmError ? ( + {crmError} + ) : null} + {crmMatches.length > 0 ? ( +
+ {crmMatches.map((person) => { + const label = + person.name || person.email_508 || person.email || person.crm_contact_id + const detail = [person.email_508 || person.email, person.contact_type] + .filter(Boolean) + .join(" | ") + return ( + + ) + })} +
+ ) : null} +
-
+
+
+ Advanced options +
+ + + + + +
+