@camstack/addon-admin-ui 1.2.34 → 1.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AddLocationWizard-DzP-CYOi.js → AddLocationWizard-BpkZ7g8M.js} +1 -1
- package/dist/assets/{AddonCollectionPage-B5t3SHZE.js → AddonCollectionPage-CqEMePgW.js} +1 -1
- package/dist/assets/Addons-cCLSqWfM.js +1 -0
- package/dist/assets/{AdminTabs-DTECFIAe.js → AdminTabs-BzqgdZo8.js} +1 -1
- package/dist/assets/{AiProfiles-D0jpUF4v.js → AiProfiles-Du2Gut1p.js} +1 -1
- package/dist/assets/{Automation-BX0bNbpp.js → Automation-CryfmheY.js} +2 -2
- package/dist/assets/{BrokerForm-CROZPAB-.js → BrokerForm-en5xEKn5.js} +1 -1
- package/dist/assets/{Capabilities-DIGQ9fiv.js → Capabilities-DOVICQ71.js} +1 -1
- package/dist/assets/{CapabilityBadges-B4vHw0qw.js → CapabilityBadges-2-jFnJcJ.js} +1 -1
- package/dist/assets/Cluster-DSXKolnm.js +1 -0
- package/dist/assets/{ClusterRecordingTab-BVkyOEdI.js → ClusterRecordingTab-BdEH4zMe.js} +1 -1
- package/dist/assets/{Dashboard-BlkR2NIh.js → Dashboard-Bi7LNLdP.js} +1 -1
- package/dist/assets/{Data-CECcPfPj.js → Data-CTCmNwJC.js} +1 -1
- package/dist/assets/DetectionIntelligence-3cLwl4I3.js +1 -0
- package/dist/assets/{DeviceAggregateSection-CbCIksD2.js → DeviceAggregateSection-D8oQ4avR.js} +1 -1
- package/dist/assets/DeviceDetail-BcRXDqYg.js +2 -0
- package/dist/assets/{Devices-COMVrlGU.js → Devices-BmmGXj4K.js} +1 -1
- package/dist/assets/{EmbedPlayerPage-B4Y1MxZ9.js → EmbedPlayerPage-CRkfP_Ng.js} +1 -1
- package/dist/assets/Events-CRvWzt-T.js +1 -0
- package/dist/assets/{FormBuilder-Cogt0U0A.js → FormBuilder-D36jBkTY.js} +1 -1
- package/dist/assets/{Identity-i_LhUVHo.js → Identity-D6X1Vx5c.js} +1 -1
- package/dist/assets/IntegrationDetail-Kd39JHzv.js +1 -0
- package/dist/assets/Integrations-BUaA-BHV.js +1 -0
- package/dist/assets/{Integrations-qNIS4emE.js → Integrations-CsuR-wnp.js} +1 -1
- package/dist/assets/{Logs-rH1aVfpt.js → Logs-D-v1pY1C.js} +1 -1
- package/dist/assets/{MotionZonesSettings-DDSnsNc9.js → MotionZonesSettings-DSAuUczY.js} +1 -1
- package/dist/assets/{MyAccess-J8p1dKF3.js → MyAccess-CSduDxGh.js} +1 -1
- package/dist/assets/Network-D2GsfRiT.js +1 -0
- package/dist/assets/{NodeAddonsSettingsPanel-6Dzcc5in.js → NodeAddonsSettingsPanel-0BTA46bg.js} +1 -1
- package/dist/assets/{NodeInferenceDevices-DraQNeS_.js → NodeInferenceDevices-FEzIpBGg.js} +1 -1
- package/dist/assets/Notifications-C2xW5T2d.js +1 -0
- package/dist/assets/Pipeline-BAy-OSuJ.js +1 -0
- package/dist/assets/Plates-B-enbHRO.js +1 -0
- package/dist/assets/{PrivacyMaskSettings-ByZ6t3aH.js → PrivacyMaskSettings-CfGREDOs.js} +1 -1
- package/dist/assets/{ProviderIcon-9BELU-vo.js → ProviderIcon-mSy1d917.js} +1 -1
- package/dist/assets/{Recordings-OoJn-xbL.js → Recordings-CVuEjle9.js} +1 -1
- package/dist/assets/Retrain-B38fDPkv.js +1 -0
- package/dist/assets/{ScanNetworkModal-DGnLpsYA.js → ScanNetworkModal-DsEiGH4q.js} +1 -1
- package/dist/assets/{Settings-DhIPBQcW.js → Settings-_QzMAEQz.js} +1 -1
- package/dist/assets/{Showroom-C7QnFCQp.js → Showroom-BrqmuRQr.js} +1 -1
- package/dist/assets/{Terminal-DVjWHgq3.js → Terminal-D6ADzUw6.js} +2 -2
- package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DkbcXBBJ.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-D6JCOoeB.js} +1 -1
- package/dist/assets/{build-cluster-graph-BDFGSfk8.js → build-cluster-graph-DK8tHUpQ.js} +2 -2
- package/dist/assets/circle-check-big-CmRUug-s.js +1 -0
- package/dist/assets/clock-CbQ_m2UA.js +1 -0
- package/dist/assets/{copy-oDpB_CYv.js → copy-CiHOHvWK.js} +1 -1
- package/dist/assets/debounced-invalidate-CS1Zql4g.js +1 -0
- package/dist/assets/{dist-Dx0ACB1O.js → dist-CD_UFqu_.js} +1 -1
- package/dist/assets/dist-DyDQKWiO.js +7 -0
- package/dist/assets/{download-c60BtWes.js → download-BbJFh_GP.js} +1 -1
- package/dist/assets/{face-bbox-nkg8OmFa.js → face-bbox-DFwfVPg5.js} +1 -1
- package/dist/assets/{hostInit-BpyXzSDR.js → hostInit-Gt7MZSrm.js} +1 -1
- package/dist/assets/image-off-CePvOw2Z.js +1 -0
- package/dist/assets/index-D4VDD87s.css +2 -0
- package/dist/assets/index-DzefosH4.js +4 -0
- package/dist/assets/{key-round-BlSZq_ro.js → key-round-wDYpv-03.js} +1 -1
- package/dist/assets/{mf-entry-bootstrap-0-3845b4a0.js → mf-entry-bootstrap-0-eafb02b4.js} +2 -2
- package/dist/assets/{pencil-DUgcFYZU.js → pencil-CGcp1H_S.js} +1 -1
- package/dist/assets/{player-overlays-CzjKRHin.js → player-overlays-DnLMvF2y.js} +1 -1
- package/dist/assets/plus-CWclgqCc.js +1 -0
- package/dist/assets/{radio-eY0YHItP.js → radio-DejuKcx3.js} +1 -1
- package/dist/assets/{refresh-cw-D_fKxMIe.js → refresh-cw-CW_Ljqdp.js} +1 -1
- package/dist/assets/remoteEntry-DNdwEnrY.js +1 -0
- package/dist/assets/{rotate-ccw-DU4_rBQq.js → rotate-ccw-RsWJHCWz.js} +1 -1
- package/dist/assets/rotate-cw-Bj3NywrT.js +1 -0
- package/dist/assets/search-kZ6MJ1BT.js +1 -0
- package/dist/assets/{send-B9r8Lohp.js → send-CJWIa1yB.js} +1 -1
- package/dist/assets/{server-BhdxNAPC.js → server-DLCgy7fU.js} +1 -1
- package/dist/assets/square-I9BIO4a-.js +1 -0
- package/dist/assets/{square-check-big-DMenPwwp.js → square-check-big-C1eD-s2U.js} +1 -1
- package/dist/assets/{src-BBe6PrXe.js → src-C2KiI31z.js} +10 -10
- package/dist/assets/src-DREH726E.js +7 -0
- package/dist/assets/undo-2-B2bADvVZ.js +1 -0
- package/dist/assets/{upload-AwB-upJP.js → upload-DeJAhsSx.js} +1 -1
- package/dist/assets/{useEventInvalidation-qhbuBjhg.js → useEventInvalidation-BuTU98fj.js} +1 -1
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CPcVkZQ0.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CwEvP83T.js} +2 -2
- package/dist/assets/{wifi-DyeEKGI-.js → wifi-BuwizIJA.js} +1 -1
- package/dist/assets/{zap-C32Ix0E1.js → zap-CWuo4dzD.js} +1 -1
- package/dist/index.html +6 -6
- package/dist/server/addon.js +380 -4
- package/package.json +1 -1
- package/dist/assets/Addons-DCR8DMgD.js +0 -1
- package/dist/assets/Cluster-BnTT5Wsb.js +0 -1
- package/dist/assets/DetectionIntelligence-CzMadCA-.js +0 -1
- package/dist/assets/DeviceDetail-oWNRSfva.js +0 -2
- package/dist/assets/Events-BIZWrXMY.js +0 -1
- package/dist/assets/IntegrationDetail-CPE4VRwU.js +0 -1
- package/dist/assets/Integrations-DhMaG2V3.js +0 -1
- package/dist/assets/Network-C6bXHvxd.js +0 -1
- package/dist/assets/Notifications-BL4Cp1b2.js +0 -1
- package/dist/assets/Pipeline-Bf8P_Drx.js +0 -1
- package/dist/assets/Plates-BkYxLI16.js +0 -1
- package/dist/assets/circle-check-big-DX7P42Tw.js +0 -1
- package/dist/assets/clock-DMJpZrGI.js +0 -1
- package/dist/assets/debounced-invalidate-CPxCM-Lt.js +0 -1
- package/dist/assets/dist-CekX4Hra.js +0 -7
- package/dist/assets/index-2QX2zxyn.js +0 -4
- package/dist/assets/index-BIqRUg3I.css +0 -2
- package/dist/assets/plus-C7qYd7DF.js +0 -1
- package/dist/assets/remoteEntry-CFMi51wk.js +0 -1
- package/dist/assets/rotate-cw-CktlNgLW.js +0 -1
- package/dist/assets/search-CY5Hv7Yv.js +0 -1
- package/dist/assets/square-S_5NH0Gl.js +0 -1
- package/dist/assets/src-DSZBcu6j.js +0 -7
package/dist/server/addon.js
CHANGED
|
@@ -14749,6 +14749,60 @@ var TrackFlagsSchema = object({
|
|
|
14749
14749
|
* `trained` without a re-fetch. */
|
|
14750
14750
|
retrainStatus: RetrainStatusSchema
|
|
14751
14751
|
});
|
|
14752
|
+
union([literal(1), literal(2)]);
|
|
14753
|
+
/**
|
|
14754
|
+
* WHO decided a label, and when. Carried per tier so a value can be traced to
|
|
14755
|
+
* the step and model that produced it — which is what makes the write rule
|
|
14756
|
+
* arguable after the fact ("why is 592's label `dog` and not `Canis lupus`?")
|
|
14757
|
+
* and what lets a migrated, UNATTRIBUTED value be told apart from a real one.
|
|
14758
|
+
*
|
|
14759
|
+
* `stepId` is the pipeline step id (`animal-classifier`, `bird-classifier`,
|
|
14760
|
+
* `plate-ocr`, `face-embedding`, `object-detection`), or the sentinel
|
|
14761
|
+
* `migration:4g` for a value the 4g migration moved from the single-slot era —
|
|
14762
|
+
* that value has no provenance, and the write rule lets ANY properly-attributed
|
|
14763
|
+
* write of the same tier replace it regardless of score.
|
|
14764
|
+
*/
|
|
14765
|
+
var LabelAttributionSchema = object({
|
|
14766
|
+
stepId: string(),
|
|
14767
|
+
modelId: string().optional(),
|
|
14768
|
+
decidedAt: number()
|
|
14769
|
+
});
|
|
14770
|
+
/**
|
|
14771
|
+
* The TIERED label model (roadmap 4g), spread into `TrackSchema` and
|
|
14772
|
+
* `ObjectEventSchema` from ONE place so the two surfaces cannot drift — a
|
|
14773
|
+
* track and its events always answer the same question the same way.
|
|
14774
|
+
*
|
|
14775
|
+
* Two scalar columns, not an array: every consumer wants "the coarse one" or
|
|
14776
|
+
* "the fine one", and an array made both a scan. `label` is tier 1, `subLabel`
|
|
14777
|
+
* is tier 2, and each carries its own score + attribution.
|
|
14778
|
+
*
|
|
14779
|
+
* **Reading it.** What a human should be shown is `subLabel ?? label` — the
|
|
14780
|
+
* finest thing known. Before 4g the single `label` column held the finest
|
|
14781
|
+
* value, so a consumer that has not been updated reads the tier-1 slot and
|
|
14782
|
+
* shows nothing on a species-only row; that is why the migration puts every
|
|
14783
|
+
* pre-4g value in tier 2 (it cannot regress a display that reads the fallback)
|
|
14784
|
+
* and why the read surfaces were changed in the same train.
|
|
14785
|
+
*
|
|
14786
|
+
* **Writing it.** The slots are independent, which is the whole point: a
|
|
14787
|
+
* tier-1 write (`bird`) can never overwrite a tier-2 value (`Turdus
|
|
14788
|
+
* migratorius`), so fineness cannot regress by construction. Within a tier the
|
|
14789
|
+
* higher score wins. One rule, one implementation — see
|
|
14790
|
+
* `pipeline/label-tier.ts` in addon-post-analysis.
|
|
14791
|
+
*/
|
|
14792
|
+
var TieredLabelFields = {
|
|
14793
|
+
/** Tier 1 — the sub-class. See {@link LabelTierSchema}. */
|
|
14794
|
+
label: string().optional(),
|
|
14795
|
+
/** Confidence of the tier-1 value, as reported by the deciding step. */
|
|
14796
|
+
labelScore: number().optional(),
|
|
14797
|
+
/** Provenance of the tier-1 value. See {@link LabelAttributionSchema}. */
|
|
14798
|
+
labelMeta: LabelAttributionSchema.optional(),
|
|
14799
|
+
/** Tier 2 — the instance. See {@link LabelTierSchema}. */
|
|
14800
|
+
subLabel: string().optional(),
|
|
14801
|
+
/** Confidence of the tier-2 value, as reported by the deciding step. */
|
|
14802
|
+
subLabelScore: number().optional(),
|
|
14803
|
+
/** Provenance of the tier-2 value. See {@link LabelAttributionSchema}. */
|
|
14804
|
+
subLabelMeta: LabelAttributionSchema.optional()
|
|
14805
|
+
};
|
|
14752
14806
|
/** Per-camera slice of a training-export estimate. */
|
|
14753
14807
|
var TrainingExportDeviceTotalsSchema = object({
|
|
14754
14808
|
deviceId: number(),
|
|
@@ -14773,7 +14827,7 @@ var TrackSchema = object({
|
|
|
14773
14827
|
trackId: string(),
|
|
14774
14828
|
deviceId: number(),
|
|
14775
14829
|
className: string(),
|
|
14776
|
-
|
|
14830
|
+
...TieredLabelFields,
|
|
14777
14831
|
producingDeviceName: string().optional(),
|
|
14778
14832
|
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
14779
14833
|
source: TrackSourceSchema.optional(),
|
|
@@ -14886,7 +14940,7 @@ var ObjectEventSchema = object({
|
|
|
14886
14940
|
/** Omitted in slim projection. */
|
|
14887
14941
|
trackId: string().optional(),
|
|
14888
14942
|
className: string(),
|
|
14889
|
-
|
|
14943
|
+
...TieredLabelFields,
|
|
14890
14944
|
/** Omitted in slim projection. */
|
|
14891
14945
|
confidence: number().optional(),
|
|
14892
14946
|
/** Heavy JSON — omitted in slim projection. */
|
|
@@ -14967,6 +15021,173 @@ var MediaFileSchema = object({
|
|
|
14967
15021
|
* stored blob and a `?variant=thumb` rendering without fetching either.
|
|
14968
15022
|
*/
|
|
14969
15023
|
var MediaFileInfoSchema = MediaFileSchema.omit({ base64: true });
|
|
15024
|
+
/**
|
|
15025
|
+
* The MACRO tier of an annotation — a CLOSED set.
|
|
15026
|
+
*
|
|
15027
|
+
* This is what the exported detector predicts, so a typo here is a new class
|
|
15028
|
+
* with one example in it. `label` and `subLabel` are open strings by contrast:
|
|
15029
|
+
* the whole point of the page is teaching the model things it does not know
|
|
15030
|
+
* yet, and constraining that vocabulary would make it useless.
|
|
15031
|
+
*
|
|
15032
|
+
* A macro class is NEVER a label. The provider refuses a write whose `label` or
|
|
15033
|
+
* `subLabel` is one of these values, in any casing, because once `person`
|
|
15034
|
+
* exists in both tiers "every person box" stops being answerable without
|
|
15035
|
+
* knowing every string anyone ever typed — and the damage is retroactive.
|
|
15036
|
+
*/
|
|
15037
|
+
var RetrainMacroClassSchema = _enum([
|
|
15038
|
+
"person",
|
|
15039
|
+
"vehicle",
|
|
15040
|
+
"animal",
|
|
15041
|
+
"package",
|
|
15042
|
+
"face",
|
|
15043
|
+
"plate"
|
|
15044
|
+
]);
|
|
15045
|
+
/** A subject to learn, or a phantom to unlearn (taught by OMISSION). */
|
|
15046
|
+
var RetrainAnnotationKindSchema = _enum(["subject", "model_error"]);
|
|
15047
|
+
/** Did a human draw this box, or did the assist propose it? */
|
|
15048
|
+
var RetrainAnnotationSourceSchema = _enum(["operator", "assist"]);
|
|
15049
|
+
/** Normalised `[0,1]` rectangle against the FULL frame — the canonical form. */
|
|
15050
|
+
var RetrainBboxSchema = object({
|
|
15051
|
+
x: number(),
|
|
15052
|
+
y: number(),
|
|
15053
|
+
w: number(),
|
|
15054
|
+
h: number()
|
|
15055
|
+
});
|
|
15056
|
+
/**
|
|
15057
|
+
* One annotated subject.
|
|
15058
|
+
*
|
|
15059
|
+
* `bbox` is normalised against the full frame, ALWAYS. The per-model shapes
|
|
15060
|
+
* (letterboxed root / zone-cropped package / subject-cropped classifier) are
|
|
15061
|
+
* derived from it at export and never stored — storing them is how one feature
|
|
15062
|
+
* space ends up holding two crops of the same subject (D52).
|
|
15063
|
+
*/
|
|
15064
|
+
var RetrainAnnotationSchema = object({
|
|
15065
|
+
id: string(),
|
|
15066
|
+
trackId: string(),
|
|
15067
|
+
deviceId: number(),
|
|
15068
|
+
/** The COPY in retrain storage — never the source track's media key. */
|
|
15069
|
+
mediaKey: string(),
|
|
15070
|
+
bbox: RetrainBboxSchema,
|
|
15071
|
+
macroClass: RetrainMacroClassSchema,
|
|
15072
|
+
label: string().optional(),
|
|
15073
|
+
subLabel: string().optional(),
|
|
15074
|
+
kind: RetrainAnnotationKindSchema,
|
|
15075
|
+
source: RetrainAnnotationSourceSchema,
|
|
15076
|
+
/** Which model proposed this box — or, on a `model_error`, drew the phantom. */
|
|
15077
|
+
assistModelId: string().optional(),
|
|
15078
|
+
assistScore: number().optional(),
|
|
15079
|
+
exportedInBatch: string().optional(),
|
|
15080
|
+
createdAt: number()
|
|
15081
|
+
});
|
|
15082
|
+
/** The write form — the server owns `id`, `createdAt` and the frame binding. */
|
|
15083
|
+
var RetrainAnnotationDraftSchema = RetrainAnnotationSchema.omit({
|
|
15084
|
+
id: true,
|
|
15085
|
+
trackId: true,
|
|
15086
|
+
deviceId: true,
|
|
15087
|
+
mediaKey: true,
|
|
15088
|
+
createdAt: true,
|
|
15089
|
+
exportedInBatch: true
|
|
15090
|
+
});
|
|
15091
|
+
/** A track sitting in `staging`, with everything the worklist needs to rank it. */
|
|
15092
|
+
var RetrainTrackSchema = object({
|
|
15093
|
+
trackId: string(),
|
|
15094
|
+
deviceId: number(),
|
|
15095
|
+
className: string(),
|
|
15096
|
+
label: string().optional(),
|
|
15097
|
+
firstSeen: number(),
|
|
15098
|
+
lastSeen: number(),
|
|
15099
|
+
/** How many frames the dataset already holds from this track. */
|
|
15100
|
+
frameCount: number().int(),
|
|
15101
|
+
/** How many subjects have been annotated on those frames. `0` with
|
|
15102
|
+
* `frameCount: 0` is exactly "staging, still to work". */
|
|
15103
|
+
annotationCount: number().int()
|
|
15104
|
+
});
|
|
15105
|
+
/** A frame the picker may offer — an index row, no blob was read to produce it. */
|
|
15106
|
+
var RetrainFrameCandidateSchema = object({
|
|
15107
|
+
mediaKey: string(),
|
|
15108
|
+
kind: MediaFileKindEnum,
|
|
15109
|
+
timestamp: number(),
|
|
15110
|
+
sizeBytes: number().int(),
|
|
15111
|
+
/** A copy of this original already exists — selecting it is free and cannot
|
|
15112
|
+
* fail, whatever became of the original. */
|
|
15113
|
+
copied: boolean()
|
|
15114
|
+
});
|
|
15115
|
+
/** A frame the dataset OWNS: bytes copied at selection time. */
|
|
15116
|
+
var RetrainFrameSchema = object({
|
|
15117
|
+
frameId: string(),
|
|
15118
|
+
deviceId: number(),
|
|
15119
|
+
trackId: string(),
|
|
15120
|
+
/** Provenance only. It may already point at nothing — that is expected. */
|
|
15121
|
+
sourceMediaKey: string(),
|
|
15122
|
+
sourceKind: MediaFileKindEnum,
|
|
15123
|
+
sizeBytes: number().int(),
|
|
15124
|
+
width: number().int(),
|
|
15125
|
+
height: number().int(),
|
|
15126
|
+
copiedAt: number()
|
|
15127
|
+
});
|
|
15128
|
+
/** Why a copy-on-select could not be honoured — named, never a silent skip. */
|
|
15129
|
+
var RetrainCopyRefusalSchema = _enum([
|
|
15130
|
+
"source-missing",
|
|
15131
|
+
"unreadable-image",
|
|
15132
|
+
"write-failed"
|
|
15133
|
+
]);
|
|
15134
|
+
var RetrainFrameSelectionSchema = object({
|
|
15135
|
+
copied: array(RetrainFrameSchema).readonly(),
|
|
15136
|
+
refused: array(object({
|
|
15137
|
+
sourceMediaKey: string(),
|
|
15138
|
+
reason: RetrainCopyRefusalSchema
|
|
15139
|
+
})).readonly()
|
|
15140
|
+
});
|
|
15141
|
+
var RetrainFrameListSchema = object({
|
|
15142
|
+
candidates: array(RetrainFrameCandidateSchema).readonly(),
|
|
15143
|
+
copies: array(RetrainFrameSchema).readonly(),
|
|
15144
|
+
/** What the page pre-selects — the native key frame when one survives. */
|
|
15145
|
+
autoPickMediaKey: string().optional()
|
|
15146
|
+
});
|
|
15147
|
+
/** What the operator asked the assist to look for. */
|
|
15148
|
+
var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
|
|
15149
|
+
kind: literal("package"),
|
|
15150
|
+
zone: RetrainBboxSchema.optional()
|
|
15151
|
+
}), object({
|
|
15152
|
+
kind: literal("objects"),
|
|
15153
|
+
modelId: string(),
|
|
15154
|
+
minScore: number().optional()
|
|
15155
|
+
})]);
|
|
15156
|
+
/**
|
|
15157
|
+
* The assist's answer — a discriminated union, because "the model saw nothing"
|
|
15158
|
+
* and "this node cannot run that model" lead to different next moves and a
|
|
15159
|
+
* nullable result cannot tell them apart.
|
|
15160
|
+
*/
|
|
15161
|
+
var RetrainAssistResultSchema = discriminatedUnion("kind", [object({
|
|
15162
|
+
kind: literal("proposed"),
|
|
15163
|
+
modelId: string(),
|
|
15164
|
+
stepId: string(),
|
|
15165
|
+
minScore: number(),
|
|
15166
|
+
/** Drafts, ready to edit. `source: 'assist'` until the operator touches one. */
|
|
15167
|
+
proposals: array(RetrainAnnotationDraftSchema).readonly(),
|
|
15168
|
+
/** Returned by the runner but removed by the threshold. */
|
|
15169
|
+
belowThreshold: number().int()
|
|
15170
|
+
}), object({
|
|
15171
|
+
kind: literal("refused"),
|
|
15172
|
+
/** `no-zone` is ours; the rest are the runner's own refusal vocabulary. */
|
|
15173
|
+
reason: string(),
|
|
15174
|
+
detail: string().optional()
|
|
15175
|
+
})]);
|
|
15176
|
+
/** The outcome of a lifecycle move owned by the retrain page. */
|
|
15177
|
+
var RetrainTransitionResultSchema = object({
|
|
15178
|
+
trackId: string(),
|
|
15179
|
+
/** Where the track ended up, whatever happened. */
|
|
15180
|
+
retrainStatus: RetrainStatusSchema,
|
|
15181
|
+
/** `false` ⇒ the move was refused or was a no-op; `reason` says which. */
|
|
15182
|
+
changed: boolean(),
|
|
15183
|
+
reason: _enum([
|
|
15184
|
+
"unknown-track",
|
|
15185
|
+
"no-frames-copied",
|
|
15186
|
+
"not-staging",
|
|
15187
|
+
"not-trained",
|
|
15188
|
+
"unchanged"
|
|
15189
|
+
]).optional()
|
|
15190
|
+
});
|
|
14970
15191
|
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
14971
15192
|
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
14972
15193
|
var DeviceEventQueryInput = object({
|
|
@@ -15021,7 +15242,7 @@ var KeyEventSchema = object({
|
|
|
15021
15242
|
/** Track start time (firstSeen). */
|
|
15022
15243
|
timestamp: number(),
|
|
15023
15244
|
className: string(),
|
|
15024
|
-
|
|
15245
|
+
...TieredLabelFields,
|
|
15025
15246
|
importance: number(),
|
|
15026
15247
|
/** Highest-confidence ObjectEvent id for the track (empty when none). */
|
|
15027
15248
|
bestEventId: string(),
|
|
@@ -15295,6 +15516,79 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
15295
15516
|
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
15296
15517
|
kind: "query",
|
|
15297
15518
|
auth: "admin"
|
|
15519
|
+
}), method(object({
|
|
15520
|
+
/** Empty ⇒ every camera that has staging tracks. A LIST, not a single
|
|
15521
|
+
* `deviceId`, deliberately: `deviceId` would make this device-bound and
|
|
15522
|
+
* route it at one camera's owner, and "every camera" would stop being
|
|
15523
|
+
* expressible at all. */
|
|
15524
|
+
deviceIds: array(number()).optional(),
|
|
15525
|
+
limit: number().int().min(1).max(500).optional()
|
|
15526
|
+
}), array(RetrainTrackSchema).readonly(), {
|
|
15527
|
+
kind: "query",
|
|
15528
|
+
auth: "admin"
|
|
15529
|
+
}), method(object({ trackId: string() }), RetrainFrameListSchema, {
|
|
15530
|
+
kind: "query",
|
|
15531
|
+
auth: "admin"
|
|
15532
|
+
}), method(object({
|
|
15533
|
+
deviceId: number(),
|
|
15534
|
+
trackId: string(),
|
|
15535
|
+
mediaKeys: array(string()).min(1)
|
|
15536
|
+
}), RetrainFrameSelectionSchema, {
|
|
15537
|
+
kind: "mutation",
|
|
15538
|
+
auth: "admin"
|
|
15539
|
+
}), method(object({
|
|
15540
|
+
deviceId: number(),
|
|
15541
|
+
trackId: string(),
|
|
15542
|
+
frameId: string()
|
|
15543
|
+
}), object({
|
|
15544
|
+
removed: boolean(),
|
|
15545
|
+
removedAnnotations: number().int()
|
|
15546
|
+
}), {
|
|
15547
|
+
kind: "mutation",
|
|
15548
|
+
auth: "admin"
|
|
15549
|
+
}), method(object({ frameId: string() }), object({
|
|
15550
|
+
base64: string(),
|
|
15551
|
+
width: number().int(),
|
|
15552
|
+
height: number().int()
|
|
15553
|
+
}), {
|
|
15554
|
+
kind: "query",
|
|
15555
|
+
auth: "admin"
|
|
15556
|
+
}), method(object({
|
|
15557
|
+
deviceId: number(),
|
|
15558
|
+
trackId: string(),
|
|
15559
|
+
frameId: string(),
|
|
15560
|
+
subject: RetrainAssistSubjectSchema,
|
|
15561
|
+
/** Which node runs it. Absent ⇒ wherever an unowned call lands. */
|
|
15562
|
+
nodeId: string().optional()
|
|
15563
|
+
}), RetrainAssistResultSchema, {
|
|
15564
|
+
kind: "mutation",
|
|
15565
|
+
auth: "admin"
|
|
15566
|
+
}), method(object({ trackId: string() }), array(RetrainAnnotationSchema).readonly(), {
|
|
15567
|
+
kind: "query",
|
|
15568
|
+
auth: "admin"
|
|
15569
|
+
}), method(object({
|
|
15570
|
+
deviceId: number(),
|
|
15571
|
+
trackId: string(),
|
|
15572
|
+
frameId: string(),
|
|
15573
|
+
annotations: array(RetrainAnnotationDraftSchema)
|
|
15574
|
+
}), array(RetrainAnnotationSchema).readonly(), {
|
|
15575
|
+
kind: "mutation",
|
|
15576
|
+
auth: "admin"
|
|
15577
|
+
}), method(object({
|
|
15578
|
+
deviceId: number(),
|
|
15579
|
+
trackId: string()
|
|
15580
|
+
}), RetrainTransitionResultSchema, {
|
|
15581
|
+
kind: "mutation",
|
|
15582
|
+
auth: "admin"
|
|
15583
|
+
}), method(object({
|
|
15584
|
+
deviceId: number(),
|
|
15585
|
+
trackId: string()
|
|
15586
|
+
}), RetrainTransitionResultSchema, {
|
|
15587
|
+
kind: "mutation",
|
|
15588
|
+
auth: "admin"
|
|
15589
|
+
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
15590
|
+
kind: "query",
|
|
15591
|
+
auth: "admin"
|
|
15298
15592
|
}), method(object({
|
|
15299
15593
|
eventId: string(),
|
|
15300
15594
|
kind: MediaFileKindEnum.optional()
|
|
@@ -15874,6 +16168,22 @@ var DetailResultSchema = object({
|
|
|
15874
16168
|
bbox: NativeCropBboxSchema.optional(),
|
|
15875
16169
|
embedding: string().optional(),
|
|
15876
16170
|
label: string().optional(),
|
|
16171
|
+
/**
|
|
16172
|
+
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
16173
|
+
* `StepDefinition.labelTier` (roadmap 4g). Present only when `label` is.
|
|
16174
|
+
*
|
|
16175
|
+
* It rides the wire rather than being resolved by the consumer because the
|
|
16176
|
+
* declaration lives with the step definition, which only the executing node
|
|
16177
|
+
* has: post-analysis holds no step registry, and re-deriving the tier from
|
|
16178
|
+
* `className` there would be exactly the inference this model exists to
|
|
16179
|
+
* forbid. A `label` that arrives WITHOUT this field is refused by the write
|
|
16180
|
+
* rule and logged (`label tier undeclared`) — an older runner therefore
|
|
16181
|
+
* stops enriching rather than guessing, which is why addon-pipeline is
|
|
16182
|
+
* deployed BEFORE addon-post-analysis.
|
|
16183
|
+
*/
|
|
16184
|
+
labelTier: union([literal(1), literal(2)]).optional(),
|
|
16185
|
+
/** Model that produced `label` — carried into the tier's attribution. */
|
|
16186
|
+
labelModelId: string().optional(),
|
|
15877
16187
|
alignedCropJpeg: string().optional(),
|
|
15878
16188
|
/** Face short side (px) measured on the NATIVE crop surface. The `bbox`
|
|
15879
16189
|
* above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
|
|
@@ -26191,6 +26501,12 @@ Object.freeze({
|
|
|
26191
26501
|
addonId: null,
|
|
26192
26502
|
access: "delete"
|
|
26193
26503
|
},
|
|
26504
|
+
"pipelineAnalytics.completeRetrainTrack": {
|
|
26505
|
+
capName: "pipeline-analytics",
|
|
26506
|
+
capScope: "device",
|
|
26507
|
+
addonId: null,
|
|
26508
|
+
access: "create"
|
|
26509
|
+
},
|
|
26194
26510
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26195
26511
|
capName: "pipeline-analytics",
|
|
26196
26512
|
capScope: "device",
|
|
@@ -26203,6 +26519,12 @@ Object.freeze({
|
|
|
26203
26519
|
addonId: null,
|
|
26204
26520
|
access: "delete"
|
|
26205
26521
|
},
|
|
26522
|
+
"pipelineAnalytics.deselectRetrainFrame": {
|
|
26523
|
+
capName: "pipeline-analytics",
|
|
26524
|
+
capScope: "device",
|
|
26525
|
+
addonId: null,
|
|
26526
|
+
access: "create"
|
|
26527
|
+
},
|
|
26206
26528
|
"pipelineAnalytics.getActiveTracks": {
|
|
26207
26529
|
capName: "pipeline-analytics",
|
|
26208
26530
|
capScope: "device",
|
|
@@ -26263,6 +26585,18 @@ Object.freeze({
|
|
|
26263
26585
|
addonId: null,
|
|
26264
26586
|
access: "view"
|
|
26265
26587
|
},
|
|
26588
|
+
"pipelineAnalytics.getRetrainExportUrl": {
|
|
26589
|
+
capName: "pipeline-analytics",
|
|
26590
|
+
capScope: "device",
|
|
26591
|
+
addonId: null,
|
|
26592
|
+
access: "view"
|
|
26593
|
+
},
|
|
26594
|
+
"pipelineAnalytics.getRetrainFrameImage": {
|
|
26595
|
+
capName: "pipeline-analytics",
|
|
26596
|
+
capScope: "device",
|
|
26597
|
+
addonId: null,
|
|
26598
|
+
access: "view"
|
|
26599
|
+
},
|
|
26266
26600
|
"pipelineAnalytics.getSensorEvents": {
|
|
26267
26601
|
capName: "pipeline-analytics",
|
|
26268
26602
|
capScope: "device",
|
|
@@ -26317,6 +26651,24 @@ Object.freeze({
|
|
|
26317
26651
|
addonId: null,
|
|
26318
26652
|
access: "view"
|
|
26319
26653
|
},
|
|
26654
|
+
"pipelineAnalytics.listRetrainAnnotations": {
|
|
26655
|
+
capName: "pipeline-analytics",
|
|
26656
|
+
capScope: "device",
|
|
26657
|
+
addonId: null,
|
|
26658
|
+
access: "view"
|
|
26659
|
+
},
|
|
26660
|
+
"pipelineAnalytics.listRetrainFrames": {
|
|
26661
|
+
capName: "pipeline-analytics",
|
|
26662
|
+
capScope: "device",
|
|
26663
|
+
addonId: null,
|
|
26664
|
+
access: "view"
|
|
26665
|
+
},
|
|
26666
|
+
"pipelineAnalytics.listRetrainStaging": {
|
|
26667
|
+
capName: "pipeline-analytics",
|
|
26668
|
+
capScope: "device",
|
|
26669
|
+
addonId: null,
|
|
26670
|
+
access: "view"
|
|
26671
|
+
},
|
|
26320
26672
|
"pipelineAnalytics.listTrackMedia": {
|
|
26321
26673
|
capName: "pipeline-analytics",
|
|
26322
26674
|
capScope: "device",
|
|
@@ -26329,6 +26681,12 @@ Object.freeze({
|
|
|
26329
26681
|
addonId: null,
|
|
26330
26682
|
access: "view"
|
|
26331
26683
|
},
|
|
26684
|
+
"pipelineAnalytics.proposeRetrainAnnotations": {
|
|
26685
|
+
capName: "pipeline-analytics",
|
|
26686
|
+
capScope: "device",
|
|
26687
|
+
addonId: null,
|
|
26688
|
+
access: "create"
|
|
26689
|
+
},
|
|
26332
26690
|
"pipelineAnalytics.pruneEvents": {
|
|
26333
26691
|
capName: "pipeline-analytics",
|
|
26334
26692
|
capScope: "device",
|
|
@@ -26359,12 +26717,30 @@ Object.freeze({
|
|
|
26359
26717
|
addonId: null,
|
|
26360
26718
|
access: "create"
|
|
26361
26719
|
},
|
|
26720
|
+
"pipelineAnalytics.restageRetrainTrack": {
|
|
26721
|
+
capName: "pipeline-analytics",
|
|
26722
|
+
capScope: "device",
|
|
26723
|
+
addonId: null,
|
|
26724
|
+
access: "create"
|
|
26725
|
+
},
|
|
26726
|
+
"pipelineAnalytics.saveRetrainAnnotations": {
|
|
26727
|
+
capName: "pipeline-analytics",
|
|
26728
|
+
capScope: "device",
|
|
26729
|
+
addonId: null,
|
|
26730
|
+
access: "create"
|
|
26731
|
+
},
|
|
26362
26732
|
"pipelineAnalytics.searchObjectEvents": {
|
|
26363
26733
|
capName: "pipeline-analytics",
|
|
26364
26734
|
capScope: "device",
|
|
26365
26735
|
addonId: null,
|
|
26366
26736
|
access: "view"
|
|
26367
26737
|
},
|
|
26738
|
+
"pipelineAnalytics.selectRetrainFrames": {
|
|
26739
|
+
capName: "pipeline-analytics",
|
|
26740
|
+
capScope: "device",
|
|
26741
|
+
addonId: null,
|
|
26742
|
+
access: "create"
|
|
26743
|
+
},
|
|
26368
26744
|
"pipelineAnalytics.setTrackFlags": {
|
|
26369
26745
|
capName: "pipeline-analytics",
|
|
26370
26746
|
capScope: "device",
|
|
@@ -28762,7 +29138,7 @@ var AdminUIAddon = class extends BaseAddon {
|
|
|
28762
29138
|
capability: adminUiCapability,
|
|
28763
29139
|
provider: {
|
|
28764
29140
|
getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
|
|
28765
|
-
getVersion: async () => ({ version: "1.2.
|
|
29141
|
+
getVersion: async () => ({ version: "1.2.35" })
|
|
28766
29142
|
}
|
|
28767
29143
|
}];
|
|
28768
29144
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Ct as e,Dt as t,Ja as n,Mt as r,Nt as i,Ot as a,Rr as o,St as s,Tt as c,Wr as l,Za as u,_t as d,bt as f,eo as p,g as m,gt as h,ht as g,jt as _,kt as v,m as y,mt as ee,pt as te,v as ne,vt as re,wt as b,yt as ie}from"./src-BBe6PrXe.js";import{I as x,K as S,Q as C,R as ae,S as w,W as T,b as E,o as oe,q as D,x as O,z as k}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DTufy7Ue.js";import{Q as se}from"./src-DSZBcu6j.js";import{p as ce}from"./player-overlays-CzjKRHin.js";import{t as A}from"./clock-DMJpZrGI.js";import{t as j}from"./download-c60BtWes.js";import{t as le}from"./plus-C7qYd7DF.js";import{t as M}from"./refresh-cw-D_fKxMIe.js";import{t as ue}from"./search-CY5Hv7Yv.js";import{t as N}from"./upload-AwB-upJP.js";import{C as P,G as F,L as I,N as de,R as L,Y as R,_ as fe,c as pe,h as z,i as B,m as V,q as H}from"./index-2QX2zxyn.js";import{t as U}from"./AdminPage-Dq33XE9j.js";import{t as me}from"./NodeAddonsSettingsPanel-6Dzcc5in.js";var he=F(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),W=F(`octagon-alert`,[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]]),G=F(`package`,[[`path`,{d:`M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z`,key:`1a0edw`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}],[`polyline`,{points:`3.29 7 12 12 20.71 7`,key:`ousv84`}],[`path`,{d:`m7.5 4.27 9 5.15`,key:`1c824w`}]]),K=F(`skip-forward`,[[`polygon`,{points:`5 4 15 12 5 20 5 4`,key:`16p6eg`}],[`line`,{x1:`19`,x2:`19`,y1:`5`,y2:`19`,key:`futhcm`}]]);C();var q=new Set([`completed`,`failed`,`partially-failed`,`cancelled`]),J=new Set([`done`,`failed`,`skipped`]);function Y(e){return!J.has(e.phase)&&!q.has(e.jobState)}function ge(e,t){let n=new Map,r=[...e].sort((e,t)=>e.createdAtMs-t.createdAtMs);for(let e of r){let r=q.has(e.state);for(let i of e.tasks)r&&i.finishedAtMs!==null&&t-i.finishedAtMs>6e4||n.set(i.packageName,{jobId:e.jobId,packageName:i.packageName,phase:i.phase,fromVersion:i.fromVersion,toVersion:i.toVersion,error:i.error,jobState:e.state,finishedAtMs:i.finishedAtMs})}return n}function _e(){let{data:e}=s({activeOnly:!0},{refetchOnWindowFocus:!1,refetchInterval:e=>(e.state.data?.length??0)>0?3e3:!1}),{map:t}=p(se.AddonsJobProgress,e=>e.job.jobId);return T(()=>{let n=new Map;for(let t of e??[])n.set(t.jobId,t);for(let[e,r]of t)n.set(e,r.job);return ge([...n.values()],Date.now())},[e,t])}var X={queued:{icon:A,cls:`bg-muted text-foreground-subtle`,label:`queued`},fetching:{icon:P,cls:`bg-primary/10 text-primary`,label:`fetching`,spin:!0},staged:{icon:P,cls:`bg-primary/10 text-primary`,label:`staged`,spin:!0},validating:{icon:P,cls:`bg-primary/10 text-primary`,label:`validating`,spin:!0},applying:{icon:P,cls:`bg-primary/10 text-primary`,label:`applying`,spin:!0},restarting:{icon:P,cls:`bg-amber-500/10 text-amber-600 dark:text-amber-400`,label:`restarting`,spin:!0},applied:{icon:P,cls:`bg-primary/10 text-primary`,label:`finalizing`,spin:!0},done:{icon:L,cls:`bg-success/10 text-success`,label:`updated`},failed:{icon:W,cls:`bg-danger/10 text-danger`,label:`failed`},skipped:{icon:K,cls:`bg-muted text-foreground-subtle`,label:`skipped`}};function ve({progress:e}){let t=X[e.phase],n=t.icon,r=e.error??`${e.packageName}: ${e.fromVersion??`?`} → ${e.toVersion}`;return w(`span`,{"data-testid":`addon-job-progress`,className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded shrink-0 ${t.cls}`,title:r,children:[O(n,{className:`w-2.5 h-2.5 ${t.spin?`animate-spin`:``}`}),t.label,w(`span`,{className:`font-mono`,children:[`→ `,e.toVersion]})]})}function ye({packageName:e,currentVersion:t,installSource:n,onInstall:r,onClose:i,onSelect:a,selectedVersion:o}){let s=n===`upload`||n===`local`,{data:c,isLoading:l}=re({name:e});return w(`div`,{className:`fixed z-50 w-72 rounded-lg border border-border bg-surface shadow-xl overflow-hidden`,style:{top:`auto`,bottom:`auto`},ref:e=>{if(!e)return;let t=e.parentElement?.getBoundingClientRect();if(!t)return;let n=window.innerHeight-t.bottom,r=t.top;n<280&&r>n?(e.style.bottom=`${window.innerHeight-t.top+4}px`,e.style.top=`auto`):(e.style.top=`${t.bottom+4}px`,e.style.bottom=`auto`),e.style.right=`${window.innerWidth-t.right}px`},onClick:e=>e.stopPropagation(),children:[w(`div`,{className:`flex items-center justify-between px-3 py-2 border-b border-border`,children:[O(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle font-medium`,children:`Versions`}),O(`button`,{type:`button`,onClick:i,className:`text-foreground-subtle hover:text-foreground`,children:O(B,{className:`h-3 w-3`})})]}),s&&w(`div`,{className:`flex items-start gap-2 px-3 py-2 border-b border-border bg-cyan-500/10 text-[10px]`,children:[O(N,{className:`h-3 w-3 mt-0.5 text-cyan-500 shrink-0`}),w(`div`,{className:`text-cyan-700 dark:text-cyan-200`,children:[w(`span`,{className:`font-semibold`,children:[n===`upload`?`Uploaded copy`:`Local copy`,` in place.`]}),` `,`Re-install `,O(`span`,{className:`font-mono`,children:t}),` from npm to track upstream releases again.`]})]}),l&&w(`div`,{className:`flex items-center justify-center gap-2 py-6 text-[10px] text-foreground-subtle`,children:[O(P,{className:`h-3.5 w-3.5 animate-spin`}),`Loading versions...`]}),c&&O(`div`,{className:`max-h-64 overflow-auto divide-y divide-border`,children:c.map(e=>{let n=e.version===t,i=a!==void 0&&e.version===o,c=/-(alpha|beta|rc|dev|canary|next)/i.test(e.version),l=w(E,{children:[O(`span`,{className:`font-mono flex-1 text-left ${n?`text-primary font-semibold`:c?`text-amber-400`:`text-foreground`}`,children:e.version}),n&&O(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium bg-primary/10 text-primary`,children:`current`}),e.distTags.map(e=>O(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e===`latest`?`bg-emerald-500/15 text-emerald-400`:e===`beta`?`bg-amber-500/15 text-amber-400`:`bg-gray-500/15 text-gray-400`}`,children:e},e)),e.deprecated&&O(`span`,{className:`text-[9px] text-red-400 line-through`,children:`deprecated`}),O(`span`,{className:`text-[9px] text-foreground-subtle shrink-0`,children:new Date(e.publishedAt).toLocaleDateString()})]});return a?w(`button`,{type:`button`,"aria-label":`Select ${e.version}`,onClick:()=>a(e.version),className:`w-full flex items-center gap-2 px-3 py-2 text-[11px] ${i?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[l,i?O(L,{className:`h-3 w-3 text-primary shrink-0`}):O(`span`,{className:`w-3 shrink-0`})]},e.version):w(`div`,{className:`flex items-center gap-2 px-3 py-2 text-[11px] ${n?`bg-primary/5`:`hover:bg-surface-hover`} transition-colors`,children:[l,n&&!s?O(L,{className:`h-3 w-3 text-primary shrink-0`}):O(`button`,{type:`button`,onClick:()=>r(e.version),className:`shrink-0 rounded p-0.5 hover:bg-primary/20 text-foreground-subtle hover:text-primary transition-colors`,title:n?`Re-install ${e.version} from npm`:`Install ${e.version}`,children:O(j,{className:`h-3 w-3`})})]},e.version)})}),c&&c.length===0&&O(`div`,{className:`py-4 text-center text-[10px] text-foreground-subtle`,children:`No versions found`})]})}var be={queued:{icon:A,bg:`bg-muted text-foreground-subtle`,label:`queued`},updating:{icon:P,bg:`bg-primary/10 text-primary`,label:`updating`,spin:!0},"done-pending-restart":{icon:M,bg:`bg-amber-500/10 text-amber-700`,label:`pending restart`},done:{icon:L,bg:`bg-success/10 text-success`,label:`done`},failed:{icon:W,bg:`bg-danger/10 text-danger`,label:`failed`}};function xe({item:e}){let t=be[e.status],n=t.icon;return w(`span`,{className:`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] rounded ${t.bg}`,title:e.error,children:[O(n,{className:`w-2.5 h-2.5 ${t.spin?`animate-spin`:``}`}),t.label]})}C();var Z=`device-export`;function Se(e){return e.capabilities.some(e=>(typeof e==`string`?e:e.name)===Z)}function Ce({isBundle:e,installSource:t,addonId:n,iconPath:r,color:i}){let[a,o]=D(!1),s=i?{backgroundColor:`${i.startsWith(`#`)?i:`#${i}`}26`}:void 0,c=e?`bg-indigo-500/20 text-indigo-700 dark:text-indigo-300`:`bg-purple-500/20 text-purple-700 dark:text-purple-300`,l=n&&r?`/api/addon-assets/${n}/${r}`:null,u=!!l&&!a;return w(`div`,{className:`relative flex-shrink-0`,children:[O(`div`,{className:`h-9 w-9 rounded-lg flex items-center justify-center ${s?``:c}`,style:s,children:u?O(`img`,{src:l,alt:n,className:`h-5 w-5`,onError:()=>o(!0)}):O(e?G:fe,{className:`h-4 w-4`})}),t===`local`&&O(`span`,{className:`absolute -top-1.5 -left-1.5 text-[7px] font-bold leading-none bg-orange-500 text-white px-1 py-0.5 rounded -rotate-12 shadow-sm`,children:`DEV`}),t===`npm`&&O(`span`,{className:`absolute -top-1 -left-1 w-4 h-4 rounded bg-[#cb3837] flex items-center justify-center -rotate-12 shadow-sm`,children:O(`svg`,{viewBox:`0 0 780 250`,className:`w-[11px] h-[11px]`,children:O(`path`,{fill:`#fff`,d:`M240 250h100V50h100v200h340V0H0v250z`})})}),t===`upload`&&O(`span`,{className:`absolute -top-1.5 -left-1.5 flex items-center justify-center h-4 w-4 rounded bg-cyan-500 -rotate-12 shadow-sm`,children:O(N,{className:`h-2.5 w-2.5 text-white`})})]})}function we({version:e,availableUpdate:t,selectedVersion:n,isUpdating:r,installSource:i,disabled:a,onUpdate:o,onOpenPicker:s,children:c}){if(r)return w(`span`,{className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-blue-500/30 bg-blue-500/10 text-blue-400 shrink-0`,children:[O(P,{className:`h-3 w-3 animate-spin`}),`Updating…`]});if(t){let r=n??t;return w(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[o&&w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),o()},disabled:a,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-semibold border border-blue-500/30 bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,title:`Update to ${r}`,children:[O(j,{className:`h-3 w-3`}),`Update`]}),w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),s()},disabled:a,"aria-label":`Select version to install`,title:`Installed ${e} — update available. Selected ${r}; tap to choose another version.`,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border border-amber-500/40 bg-amber-500/15 text-amber-500 hover:bg-amber-500/25 animate-pulse disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:[O(`span`,{className:`font-normal opacity-70`,children:e}),O(`span`,{className:`font-normal opacity-70`,children:`→`}),r,O(I,{className:`h-3 w-3`})]}),c]})}return w(`div`,{className:`relative inline-flex items-center gap-1 shrink-0`,children:[w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),s()},disabled:a,className:[`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border transition-colors disabled:opacity-50 disabled:cursor-not-allowed`,i===`local`?`border-orange-500/30 bg-orange-500/10 text-orange-400 hover:bg-orange-500/20`:`border-emerald-500/30 bg-emerald-500/10 text-emerald-400 hover:bg-emerald-500/20`].join(` `),title:`Version ${e} — tap to view all versions`,children:[e,O(I,{className:`h-3 w-3 opacity-50`})]}),c]})}function Te({addonId:e}){let t=oe(),{data:n=`inherit`}=g({addonId:e}),r=v({onSuccess:()=>{t.invalidateQueries({queryKey:[[`addons`,`getAddonAutoUpdate`]]})}});return O(`div`,{className:`flex rounded-lg border border-border overflow-hidden text-[10px] font-medium`,children:[`inherit`,`off`,`latest`,`beta`].map(t=>O(`button`,{type:`button`,onClick:n=>{n.stopPropagation(),r.mutate({addonId:e,channel:t})},disabled:r.isPending,className:`px-2.5 py-1 transition-colors capitalize ${n===t?t===`inherit`?`bg-gray-700/50 text-gray-700 dark:text-gray-300`:t===`off`?`bg-gray-700 text-gray-700 dark:text-gray-300`:t===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${t===`inherit`?``:`border-l border-border`}`,children:t},t))})}function Ee({addon:e,agents:i=[],clusterStatus:a,hideVersion:o,availableUpdate:s,onUpdate:l,isUpdating:u,jobProgress:d,bundle:f,bulkItem:p,disabledByBulk:h,isSystem:g}){let[_,v]=D(!1),[ee,te]=D(!1),[re,b]=D(!1),[x,S]=D(null);k(()=>{S(null)},[s]);let C=x??s,[ae,T]=D(!1),[se,A]=D(!1),[j,ue]=D(`logs`),N=oe(),P=ce(),F=H(),de=n(),{manifest:L}=e,R=e.installedOn??[],fe=!f&&!L.protected&&L.removable!==!1,U=!!f,K=f?.displayName??L.name,q=f?.packageName??L.packageName,J=f?.version??L.packageVersion??L.version,Y=f?.installSource??e.installSource,ge=f?f.bundle?.description??f.addons[0]?.manifest.description:L.description,_e=r({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`addonPages`]]}),N.invalidateQueries({queryKey:[[`capabilities`]]})}}),X=c({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]})}}),be=ie({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`addonPages`]]}),N.invalidateQueries({queryKey:[[`capabilities`]]}),N.invalidateQueries({queryKey:[[`integrations`]]})}}),Z=t({onSuccess:()=>{N.invalidateQueries({queryKey:[[`addons`]]}),N.invalidateQueries({queryKey:[[`alerts`]]})}}),Q=e.health,De=Q?.phase===`failed`&&!Q.inGracePeriod,Oe=De&&Q?.nextRetryAt&&!Q.retrying;return w(`div`,{className:`rounded-lg border bg-surface overflow-hidden ${De?`border-red-500/50`:`border-border`}`,children:[De&&Q&&w(`div`,{className:`bg-danger/10 border-b border-danger/30 px-4 py-2.5 flex items-start gap-2.5`,children:[O(W,{className:`h-4 w-4 text-danger shrink-0 mt-0.5`}),w(`div`,{className:`flex-1 min-w-0`,children:[w(`div`,{className:`text-xs font-semibold text-danger`,children:[`Failed to load (attempt #`,Q.retryCount,`)`]}),O(`div`,{className:`text-[11px] text-foreground mt-0.5 break-words font-mono`,children:Q.lastError?.message??`Unknown error`}),Oe&&Q.nextRetryAt&&w(`div`,{className:`text-[10px] text-foreground-subtle mt-1`,children:[`Auto-retry at `,new Date(Q.nextRetryAt).toLocaleTimeString()]})]}),w(`button`,{type:`button`,disabled:Z.isPending||Q.retrying,onClick:e=>{e.stopPropagation(),Z.mutate({packageName:q})},className:`inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-semibold border border-red-400/40 bg-red-400/10 text-red-700 dark:text-red-300 hover:bg-red-400/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0`,title:`Reset retry counter and force immediate reload`,children:[O(M,{className:`h-3 w-3 ${Z.isPending||Q.retrying?`animate-spin`:``}`}),`Retry now`]})]}),w(`div`,{className:`flex items-start gap-3 px-4 py-3`,children:[O(Ce,{isBundle:U||!!L.components&&L.components.length>1,installSource:Y,addonId:U?f.addons[0]?.manifest.id:L.id,iconPath:U?f.bundle?.icon??f.addons[0]?.manifest.icon:L.icon,color:U?f.addons[0]?.manifest.color:L.color}),w(`div`,{className:`flex-1 min-w-0`,children:[w(`div`,{className:`flex items-start justify-between gap-2`,children:[O(`span`,{className:`text-sm font-semibold text-foreground truncate min-w-0`,children:K}),!o&&O(we,{version:J,availableUpdate:s,...C===void 0?{}:{selectedVersion:C},isUpdating:u,installSource:Y,disabled:h,...l&&C!==void 0?{onUpdate:()=>l(C)}:{},onOpenPicker:()=>b(e=>!e),children:re&&O(ye,{packageName:q,currentVersion:J,...Y?{installSource:Y}:{},...s!==void 0&&C!==void 0?{selectedVersion:C,onSelect:e=>{S(e),b(!1)}}:{},onInstall:e=>{b(!1),be.mutate({packageName:q,version:e})},onClose:()=>b(!1)})})]}),w(`div`,{className:`flex flex-wrap items-center gap-x-1.5 gap-y-1 mt-0.5`,children:[q!==K&&O(`span`,{className:`text-[10px] text-foreground-subtle font-mono truncate max-w-full`,children:q}),U&&w(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,children:[O(G,{className:`h-3 w-3`}),f.addons.length]}),g&&w(`span`,{className:`text-[10px] rounded-full bg-amber-500/15 text-amber-700 dark:text-amber-300 px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1`,title:`System package — updating restarts the hub`,children:[O(M,{className:`h-3 w-3`}),`System`]}),p!=null&&O(xe,{item:p}),d!=null&&O(ve,{progress:d})]}),ge&&O(`p`,{className:`text-[10px] text-foreground-subtle mt-1 line-clamp-1`,children:ge}),!U&&e.process&&w(`div`,{className:`flex flex-wrap items-center gap-1.5 mt-1`,children:[O(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.mode===`forked`?`bg-blue-500/15 text-blue-400`:`bg-gray-500/15 text-gray-400`}`,children:e.process.mode===`forked`?`forked`:`in-process`}),e.process.pid!=null&&w(`span`,{className:`text-[9px] font-mono text-foreground-subtle`,children:[`PID `,e.process.pid]}),O(`span`,{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.state===`running`?`bg-emerald-500/15 text-emerald-400`:e.process.state===`crashed`||e.process.state===`failed`?`bg-red-500/15 text-red-400`:`bg-gray-500/15 text-gray-400`}`,children:e.process.state})]})]})]}),!U&&w(`div`,{className:`flex items-center gap-1 px-4 py-1.5 border-t border-border/50 bg-surface-hover/20`,children:[w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),X.mutate({addonId:L.id})},disabled:X.isPending||h,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-blue-400 hover:border-blue-500/30 hover:bg-blue-500/10 disabled:opacity-50 transition-colors`,children:[O(M,{className:`h-3 w-3 ${X.isPending?`animate-spin`:``}`}),`Restart`]}),w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),T(e=>!e)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${ae?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[O(z,{className:`h-3 w-3`}),`Logs`]}),!U&&w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),A(!0)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${se?`border-primary/30 bg-primary/10 text-primary`:`border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10`}`,children:[O(V,{className:`h-3 w-3`}),`Settings`]}),O(`div`,{className:`flex-1`}),fe&&w(`button`,{type:`button`,onClick:async e=>{e.stopPropagation(),await de({title:`Uninstall ${L.name}?`,message:`This will remove the addon package and all its data. This action cannot be undone.`,confirmLabel:`Uninstall`,variant:`danger`})&&_e.mutate({packageName:L.packageName})},disabled:_e.isPending||h,className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-red-400 hover:border-red-500/30 hover:bg-red-500/10 disabled:opacity-50 transition-colors`,children:[O(pe,{className:`h-3 w-3`}),_e.isPending?`Removing...`:`Uninstall`]})]}),a&&a.nodes.length>1&&!U&&w(`div`,{className:`border-t border-border px-4 py-2 bg-muted/10`,children:[O(`div`,{className:`text-[10px] font-medium text-foreground-subtle mb-1.5`,children:`Cluster Deployment`}),O(`div`,{className:`space-y-1`,children:a.nodes.map(e=>w(`div`,{className:`flex items-center gap-2 text-[10px]`,children:[O(`div`,{className:`h-1.5 w-1.5 rounded-full shrink-0 ${e.status===`offline`?`bg-muted-foreground/30`:e.synced?`bg-success`:`bg-amber-500`}`}),O(`span`,{className:`font-medium text-foreground min-w-[60px]`,children:e.name}),O(`span`,{className:`font-mono text-foreground-subtle`,children:e.version}),!e.synced&&e.status!==`offline`&&O(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-400 border border-amber-500/20`,children:`outdated`}),e.status===`offline`&&O(`span`,{className:`text-[9px] px-1 py-0.5 rounded bg-muted text-muted-foreground`,children:`offline`}),e.synced&&e.status!==`offline`&&O(`span`,{className:`text-[9px] text-success`,children:`synced`})]},e.nodeId))})]}),ae&&!U&&w(`div`,{className:`border-t border-border`,children:[w(`div`,{className:`flex items-center px-4 py-1 bg-surface-hover/20 border-b border-border/50`,children:[w(`div`,{className:`flex rounded border border-border overflow-hidden text-[9px]`,children:[O(`button`,{type:`button`,onClick:()=>ue(`logs`),className:`px-2 py-0.5 transition-colors ${j===`logs`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:`Logs`}),O(`button`,{type:`button`,onClick:()=>ue(`events`),className:`px-2 py-0.5 border-l border-border transition-colors ${j===`events`?`bg-primary/10 text-primary`:`text-foreground-subtle hover:bg-surface-hover`}`,children:`Events`})]}),O(`div`,{className:`flex-1`}),O(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),T(!1)},className:`text-foreground-subtle hover:text-foreground`,children:O(B,{className:`h-3.5 w-3.5`})})]}),j===`logs`&&O(m,{addonId:L.id,maxHeight:`max-h-64`,showFilters:!1}),j===`events`&&O(y,{addonId:L.id,category:`addon.*`,maxHeight:`max-h-64`})]}),U&&w(E,{children:[O(`button`,{type:`button`,onClick:()=>v(e=>!e),className:`w-full flex items-center justify-center border-t border-border py-1 hover:bg-surface-hover/50 transition-colors`,children:O(_?he:I,{className:`h-3.5 w-3.5 text-foreground-subtle`})}),_&&O(`div`,{className:`border-t border-border px-3 py-2 space-y-2`,children:f.addons.map(e=>O(Ee,{addon:e,agents:i,hideVersion:!0},e.manifest.id))})]}),se&&!U&&O(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4`,onClick:()=>A(!1),children:w(`div`,{className:`w-full max-w-lg max-h-[80vh] rounded-xl border border-border bg-surface shadow-2xl flex flex-col overflow-hidden`,onClick:e=>e.stopPropagation(),children:[w(`div`,{className:`flex items-center justify-between px-5 py-3 border-b border-border flex-shrink-0`,children:[w(`div`,{className:`flex items-center gap-2`,children:[O(V,{className:`h-4 w-4 text-primary`}),w(`h2`,{className:`text-sm font-semibold text-foreground`,children:[K,` Settings`]})]}),O(`button`,{onClick:()=>A(!1),className:`text-foreground-subtle hover:text-foreground transition-colors p-1 rounded`,children:O(B,{className:`h-4 w-4`})})]}),w(`div`,{className:`flex-1 overflow-y-auto px-5 py-4 space-y-4`,children:[O(me,{nodeId:`hub`,addonIds:[L.id],level:`global`}),Se(L)&&w(`div`,{children:[O(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Device export`}),O(ne,{addonId:L.id,trpc:P.trpcClient,onOpenDevice:e=>F(`/devices/${e}`)})]}),Y===`npm`&&w(`div`,{children:[O(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Auto-Update`}),O(Te,{addonId:L.id})]}),L.components&&L.components.length>0&&w(`div`,{children:[w(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:[`Components (`,L.components.length,`)`]}),O(`div`,{className:`flex flex-wrap gap-1`,children:L.components.map(e=>O(`span`,{className:`text-[10px] rounded bg-background border border-border px-1.5 py-0.5 text-foreground-subtle font-mono`,children:e},e))})]}),i.length>=2&&w(`div`,{children:[O(`div`,{className:`text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2`,children:`Installed on`}),w(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[R.length===0&&O(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Hub (local)`}),R.map(e=>O(`span`,{className:`rounded-full bg-surface-hover border border-border px-2 py-0.5 text-[10px] text-foreground-subtle`,children:e},e)),w(`div`,{className:`relative`,children:[w(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),te(e=>!e)},className:`inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2 py-0.5 text-[10px] text-foreground-subtle hover:text-foreground hover:border-primary transition-colors`,title:`Install on more agents`,children:[O(le,{className:`h-3 w-3`}),`Add agent`]}),ee&&w(`div`,{className:`absolute left-0 top-full mt-1 z-10 min-w-[160px] rounded-md border border-border bg-surface shadow-lg overflow-hidden`,children:[i.filter(e=>!e.isHub&&!R.includes(e.name)).map(e=>O(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),te(!1)},className:`w-full text-left px-3 py-1.5 text-[10px] text-foreground hover:bg-surface-hover transition-colors`,children:e.name},e.id)),i.filter(e=>!e.isHub&&!R.includes(e.name)).length===0&&O(`div`,{className:`px-3 py-1.5 text-[10px] text-foreground-subtle`,children:`No available agents`})]})]})]})]})]}),O(`div`,{className:`flex items-center justify-end px-5 py-3 border-t border-border flex-shrink-0`,children:O(`button`,{type:`button`,onClick:()=>A(!1),className:`rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors`,children:`Close`})})]})})]})}C();var Q=`.tgz,.tar.gz,.zip`;function De({onUploadSuccess:e}){let[t,n]=D(!1),r=S(null),i=x(async t=>{n(!0);let r=new FormData;r.append(`file`,t);let i=localStorage.getItem(`camstack_admin_token`)??``;try{(await(await fetch(`/api/addons/upload`,{method:`POST`,headers:{Authorization:`Bearer ${i}`},body:r})).json()).success&&e()}finally{n(!1)}},[e]);return w(E,{children:[O(`input`,{ref:r,type:`file`,accept:Q,onChange:x(e=>{let t=e.target.files?.[0];t&&i(t),e.target.value=``},[i]),className:`hidden`}),w(`button`,{type:`button`,onClick:()=>r.current?.click(),disabled:t,className:`flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[t?O(P,{className:`w-3.5 h-3.5 animate-spin`}):O(N,{className:`w-3.5 h-3.5`}),t?`Uploading...`:`Upload`]})]})}C();var Oe=new Set([`@camstack/system`,`@camstack/types`,`@camstack/sdk`,`@camstack/shm-ring`,`@camstack/ui-library`]);function ke(e){return e!==void 0&&Oe.has(e)}function Ae(e,t){let n=e??`hub-only`;return n===`any-node`?!0:n===`hub-only`?t:!t}function je(e){let t=e;if(!t?.manifest)return null;let n={...t.manifest,name:t.manifest.name??t.manifest.id,version:t.manifest.version??`0.0.0`,capabilities:t.manifest.capabilities??[]},r=t.process,i=r?{pid:r.pid,mode:r.mode===`forked`?`forked`:`in-process`,state:r.state??`unknown`}:void 0,a=t.health,o=t.declaration?.execution,s=t.manifest.execution,c=o?.placement??s?.placement;return{manifest:n,enabled:!0,source:t.source,installSource:t.installSource,installedOn:[],...i?{process:i}:{},hasBackup:t.hasBackup,...a?{health:a}:{},...c?{placement:c}:{}}}function Me(e){let t=new Map,n=[];for(let r of e){let e=r.manifest.packageName;if(!e){n.push(r);continue}let i=t.get(e);if(i)i.addons.push(r);else{let n=r.manifest.bundle,i={packageName:e,displayName:n?.displayName??r.manifest.packageDisplayName??r.manifest.name,version:r.manifest.packageVersion,addons:[r],...r.installSource===void 0?{}:{installSource:r.installSource},...n===void 0?{}:{bundle:n}};t.set(e,i)}}let r=[];for(let e of t.values())e.bundle!==void 0||e.addons.length>=2?r.push({bundle:e,representative:e.addons[0]}):r.push(e.addons[0]);return r.push(...n),r}function $(e){return`bundle`in e}function Ne({addons:t,clusterStatus:r,selectedNode:o,onRefresh:s,isRefreshing:c}){let l=oe(),[u,f]=D(``),p=ae(u),[m,g]=D(!1),v=S(null);k(()=>{if(!m)return;let e=e=>{v.current&&!v.current.contains(e.target)&&g(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[m]);let{data:y}=e({nodeId:o.id}),ee=T(()=>{let e=new Map;for(let t of y??[])e.set(t.name,t.latestVersion);return e},[y]),ne=T(()=>(y??[]).filter(e=>!e.isSystem).length,[y]),[re,b]=D(()=>new Set),[C,E]=D(()=>new Map),se=x(e=>{b(t=>new Set(t).add(e))},[]),ce=x(e=>{b(t=>{if(!t.has(e))return t;let n=new Set(t);return n.delete(e),n})},[]),A=x((e,t)=>{E(n=>new Map(n).set(e,t))},[]),le=x(e=>{E(t=>{if(!t.has(e))return t;let n=new Map(t);return n.delete(e),n})},[]),N=i({onMutate:e=>{se(e.name),le(e.name)},onSuccess:(e,t)=>{ce(t.name);let n=e;if(n&&n.success===!1){A(t.name,n.error??`Update failed (no error message returned by server)`);return}l.invalidateQueries({queryKey:[[`addons`]]}),l.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]})},onError:(e,t)=>{ce(t.name),A(t.name,e instanceof Error?e.message:String(e))}}),F=_e(),I=S(new Set);k(()=>{let e=new Set;for(let[t,n]of F)Y(n)&&e.add(t);let t=[...I.current].some(t=>!e.has(t));I.current=e,t&&(l.invalidateQueries({queryKey:[[`addons`]]}),l.invalidateQueries({queryKey:[[`addons`,`listUpdates`]]}))},[F,l]);let{data:fe}=h(void 0),pe=te({onSuccess:()=>{l.invalidateQueries({queryKey:[[`addons`,`getAutoUpdateSettings`]]})}}),{data:z,isFetching:B}=a({query:p||void 0},{enabled:m}),V=_(),{data:H}=d(void 0),U=H?.requestedAt,[me,he]=D(null),[W,G]=D(!1);k(()=>{if(H?.kind===`framework-bulk-update`&&H.requestedAt!==me){he(H.requestedAt),G(!0);let e=window.setTimeout(()=>G(!1),6e3);return()=>window.clearTimeout(e)}},[U,me,H]),n();let K=x(async()=>{let e=(y??[]).filter(e=>!e.isSystem);e.length!==0&&await V.mutateAsync({kind:`update`,targets:e.map(e=>({name:e.name,version:e.latestVersion})),nodeIds:[o.id]})},[y,o.id,V]),q=ie({onSuccess:()=>{l.invalidateQueries({queryKey:[[`addons`]]}),l.invalidateQueries({queryKey:[[`addonPages`]]}),l.invalidateQueries({queryKey:[[`capabilities`]]}),l.invalidateQueries({queryKey:[[`integrations`]]})}}),[J,ge]=D(`type`),[X,ve]=D(()=>typeof window>`u`?`grouped`:window.localStorage.getItem(`camstack.addons.viewMode`)===`flat`?`flat`:`grouped`),ye=e=>{ve(e),typeof window<`u`&&window.localStorage.setItem(`camstack.addons.viewMode`,e)},[be,xe]=R(),Z=be.get(`capability`),Se=T(()=>{let e=t.filter(e=>!ke(e.manifest.packageName));return o.isHub||(e=e.filter(e=>Ae(e.placement,o.isHub))),Z&&(e=e.filter(e=>(e.manifest.capabilities??[]).some(e=>(typeof e==`string`?e:e.name)===Z))),e},[t,o.isHub,Z]),Ce=()=>{let e=new URLSearchParams(be);e.delete(`capability`),xe(e,{replace:!0})},we=X===`flat`?Se:Me(Se),Te=T(()=>{let e=[...we];switch(J){case`type`:e.sort((e,t)=>{let n=+!$(e),r=+!$(t);if(n!==r)return n-r;let i=$(e)?e.bundle.displayName:e.manifest.name,a=$(t)?t.bundle.displayName:t.manifest.name;return i.localeCompare(a)});break;case`name`:e.sort((e,t)=>{let n=$(e)?e.bundle.displayName:e.manifest.name,r=$(t)?t.bundle.displayName:t.manifest.name;return n.localeCompare(r)});break;case`source`:e.sort((e,t)=>{let n=$(e)?e.bundle.installSource??``:e.installSource??``,r=$(t)?t.bundle.installSource??``:t.installSource??``;return n.localeCompare(r)});break}return e},[we,J]);return w(`div`,{className:`space-y-4`,children:[[...C.entries()].map(([e,t])=>O(`div`,{className:`rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-[11px]`,children:w(`div`,{className:`flex items-start justify-between gap-3`,children:[w(`div`,{className:`space-y-0.5`,children:[w(`div`,{className:`font-medium text-danger`,children:[`Failed to update `,e]}),O(`div`,{className:`text-foreground-subtle font-mono`,children:t})]}),O(`button`,{type:`button`,onClick:()=>le(e),className:`text-foreground-subtle hover:text-foreground text-[10px]`,children:`dismiss`})]})},e)),w(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[w(`div`,{className:`flex items-center gap-1.5`,children:[O(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Sort:`}),w(`select`,{value:J,onChange:e=>ge(e.target.value),className:`rounded-md border border-border bg-surface px-2 py-1.5 text-[11px] text-foreground focus:outline-none focus:border-primary/50`,children:[O(`option`,{value:`type`,children:`Bundles first`}),O(`option`,{value:`name`,children:`Name`}),O(`option`,{value:`source`,children:`Install source`})]})]}),w(`div`,{className:`flex items-center gap-1.5`,children:[O(`span`,{className:`text-[10px] text-foreground-subtle`,children:`View:`}),O(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`grouped`,`flat`].map(e=>O(`button`,{type:`button`,onClick:()=>ye(e),className:`px-2.5 py-1.5 transition-colors capitalize ${X===e?`bg-primary/10 text-primary`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`}`,title:e===`grouped`?`Group multi-addon packages into a bundle card`:`Show every addon as its own card`,children:e},e))})]}),o.isHub&&w(`div`,{className:`flex items-center gap-1.5`,children:[O(M,{className:`h-3 w-3 text-foreground-subtle`}),O(`span`,{className:`text-[10px] text-foreground-subtle`,children:`Auto-Update:`}),O(`div`,{className:`flex rounded-md border border-border overflow-hidden text-[10px] font-medium`,children:[`off`,`latest`,`beta`].map(e=>O(`button`,{type:`button`,onClick:()=>pe.mutate({channel:e}),disabled:pe.isPending,className:`px-2.5 py-1.5 transition-colors capitalize ${fe?.channel===e?e===`off`?`bg-gray-700 text-gray-200`:e===`latest`?`bg-blue-500/20 text-blue-400`:`bg-amber-500/20 text-amber-400`:`bg-transparent text-foreground-subtle hover:bg-surface-hover`} ${e===`off`?``:`border-l border-border`}`,children:e},e))})]}),ne>0&&w(`button`,{type:`button`,onClick:()=>void K(),disabled:V.isPending,className:`flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 border border-blue-500/30 disabled:opacity-50 transition-colors font-medium`,children:[V.isPending?O(P,{className:`w-3 h-3 animate-spin`}):O(j,{className:`w-3 h-3`}),V.isPending?`Updating…`:`Update All (${ne})`]}),w(`button`,{type:`button`,onClick:s,disabled:c||V.isPending,className:`flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,children:[O(M,{className:`w-3 h-3 ${c?`animate-spin`:``}`}),`Refresh`]})]}),w(`div`,{className:`flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3`,children:[w(`div`,{className:`relative flex-1 min-w-0 sm:min-w-[200px]`,ref:v,children:[O(ue,{className:`absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-foreground-subtle`}),O(`input`,{type:`text`,value:u,onChange:e=>{f(e.target.value),g(!0)},onFocus:()=>g(!0),placeholder:`Search addons on npm...`,disabled:V.isPending,className:`w-full rounded-lg border border-border bg-background pl-9 pr-3 py-2 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed`}),B&&O(P,{className:`absolute right-2.5 top-1/2 -translate-y-1/2 h-3 w-3 text-foreground-subtle animate-spin`}),m&&z&&z.length>0&&w(`div`,{className:`absolute left-0 right-0 top-full mt-1 z-40 rounded-lg border border-border bg-surface shadow-xl overflow-hidden`,children:[z.length>0&&w(`div`,{className:`px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border`,children:[`npm results (`,z.length,`)`]}),z&&z.length>0&&O(`div`,{className:`max-h-72 overflow-auto divide-y divide-border`,children:z.map(e=>w(`div`,{className:`flex items-center gap-3 px-3 py-2 hover:bg-surface-hover transition-colors`,children:[O(`div`,{className:`w-6 h-6 rounded-md bg-primary/10 flex items-center justify-center text-primary text-[9px] font-bold shrink-0`,children:e.name.replace(`@camstack/addon-`,``).charAt(0).toUpperCase()}),w(`div`,{className:`flex-1 min-w-0`,children:[w(`div`,{className:`flex items-baseline gap-2 min-w-0`,children:[O(`span`,{className:`text-[11px] font-semibold break-words`,children:e.name.replace(/^@camstack\/(addon-)?/,``)}),w(`span`,{className:`text-[10px] text-foreground-subtle shrink-0`,children:[`v`,e.version]})]}),O(`div`,{className:`font-mono text-[9px] text-foreground-subtle/80 truncate`,children:e.name}),e.description&&O(`div`,{className:`text-[10px] text-foreground-subtle truncate`,children:e.description})]}),e.installed?w(`span`,{className:`inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md border border-emerald-500/30 bg-emerald-500/10 text-emerald-400 shrink-0`,children:[O(L,{className:`h-3 w-3`}),e.installedVersion??`Installed`]}):w(`button`,{type:`button`,onClick:()=>q.mutate({packageName:e.name}),disabled:q.isPending,className:`inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors shrink-0`,children:[q.isPending?O(P,{className:`h-3 w-3 animate-spin`}):O(j,{className:`h-3 w-3`}),`Install`]})]},e.name))})]})]}),O(De,{onUploadSuccess:()=>{l.invalidateQueries({queryKey:[[`addons`]]}),s()}})]}),Z&&w(`div`,{className:`flex items-center gap-2 px-3 py-2 rounded-lg bg-primary/10 border border-primary/30 text-sm`,children:[O(`span`,{className:`text-foreground-subtle`,children:`Filtering by capability:`}),O(`span`,{className:`font-mono text-primary font-semibold`,children:Z}),O(`button`,{type:`button`,onClick:Ce,className:`ml-auto text-xs text-foreground-subtle hover:text-foreground underline`,children:`Clear`})]}),W&&w(`div`,{className:`fixed top-4 right-4 z-50 flex items-start gap-2 px-3 py-2.5 rounded-md border border-green-500/30 bg-green-500/10 shadow-lg backdrop-blur-sm max-w-sm pointer-events-auto`,children:[O(de,{className:`w-4 h-4 shrink-0 mt-0.5 text-green-400`}),w(`div`,{children:[O(`div`,{className:`text-[11px] font-semibold text-foreground`,children:`Bulk update completed`}),O(`div`,{className:`text-[10px] text-foreground-subtle mt-0.5`,children:`System packages updated — hub restarted successfully.`})]})]}),Se.length===0&&O(`div`,{className:`text-xs text-foreground-subtle`,children:t.length===0?`No addons installed`:Z?`No installed addons declare the "${Z}" capability. Browse the npm catalog above to find a compatible addon.`:`No addons compatible with ${o.name} (placement filter active)`}),O(`div`,{className:`space-y-2`,children:Te.map(e=>{let t=$(e)?e.bundle.packageName:e.manifest.packageName,n=ee.get(t),i=$(e)?e.representative:e,a=n?e=>N.mutate({name:t,version:e,nodeId:o.id}):void 0,s=F.get(t)??null,c=s!==null&&Y(s);return O(Ee,{addon:i,clusterStatus:r?.[i.manifest.id],bundle:$(e)?e.bundle:void 0,availableUpdate:n,isUpdating:re.has(t)||c,jobProgress:s,onUpdate:a,disabledByBulk:V.isPending},$(e)?t:e.manifest.id)})})]})}function Pe(){let e=oe(),{data:t,isLoading:n,isError:r}=f(),{data:i}=o(void 0),{data:a}=l(void 0,{refetchInterval:1e4}),s=T(()=>{let e=new Map;e.set(`hub`,{id:`hub`,name:`Hub`,isHub:!0});for(let t of a??[]){let n=String(t.id??``);n&&e.set(n,{id:n,name:String(t.name??n),isHub:!!t.isHub})}return[...e.values()]},[a]),[c,d]=D(`hub`),p=s.find(e=>e.id===c)??s[0],m=ee(),h=b(),g=m.isPending||h.isPending,_=async()=>{await m.mutateAsync({nodeId:c}),await h.mutateAsync(),e.invalidateQueries({queryKey:[[`addons`]]})},v=S(m);v.current=m,k(()=>{v.current.mutate({nodeId:`hub`})},[]);let y=(t??[]).map(je).filter(e=>e!==null);return w(U,{children:[w(`div`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[O(u,{selectedNodeId:c,onSelect:d}),w(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[!n&&!r&&w(`span`,{className:`text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium`,children:[y.length,` installed`]}),w(`button`,{type:`button`,onClick:()=>void _(),disabled:g,className:`inline-flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors`,title:`Re-fetch addons + check npm for new versions`,children:[O(M,{className:`w-3 h-3 ${g?`animate-spin`:``}`}),`Check for updates`]})]})]}),!p.isHub&&w(`div`,{className:`rounded-md border border-warning/30 bg-warning/5 px-3 py-2 text-[11px] text-foreground-subtle`,children:[`Showing only addons compatible with`,` `,O(`span`,{className:`font-medium text-foreground`,children:p.name}),` — agents only run`,` `,O(`code`,{className:`font-mono`,children:`agent-only`}),` and`,` `,O(`code`,{className:`font-mono`,children:`any-node`}),` addons. Install / uninstall is hub-driven; agents auto-sync from the hub.`]}),n&&O(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Loading…`}),r&&O(`div`,{className:`text-xs text-danger`,children:`Failed to load addons`}),!n&&!r&&O(Ne,{addons:y,clusterStatus:i,selectedNode:p,onRefresh:()=>void _(),isRefreshing:g})]})}export{Pe as AddonsPage};
|