@knkcs/contenthub-ui 0.2.0 → 0.3.1

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ProtoChangeSetState","ProtoBranchKind","ProtoReleaseKind","ProtoCheckOutcome","ProtoCheckScope","ProtoCollectionAccessLevel","ProtoRevisionCause","ProtoEdgeKind","ProtoFieldChangeKind","ProtoPendingMergeReason","ProtoMergeSide","BranchContentFields","periodText","periodText","ICONS","targetOf","Section","ConnectCode","RefusalAlert","_Fragment","_Fragment","periodText","_Fragment","periodText","EMPTY","FORM_ID","TABS","sameIds","ConnectCode","FORM_ID","RouterLink","FORM_ID","EMPTY","FORM_ID","EMPTY","FORM_ID","TABS","ConnectCode","EMPTY","StaleStatusError","NameTakenError","SOURCE_REFERENCE_MAX","RestrictionUnavailableError","WithheldWorkError","ServiceUnavailableError","InvalidInputError","REQUIRED_CHECK_NAME_MAX","ContentArchivedError","localToday","CoversReleaseError","BLOCK_REASON_NAME_MAX","CHANGE_SET_NAME_MAX","CHECK_NOTE_MAX","CheckResultDeniedError","inForceOnOrAfter","StatusTransitionRefusedError","StaleHeadError","BLUEPRINT_ACCESSOR_MAX","CONTENT_SEARCH_MAX","releaseInForceOn","COLLECTION_NAME_MAX","DAY","AccessDeniedError","headsOf","BlockReasonNameTakenError","ContentBlockedError","PublishRefusedError","GuardianModeRequiredError","ContentRefusedError","NEW_CHANGE_SET","collectionPath","CONTENTHUB_UI_NS","contenthubTranslations","ChangeSetChoiceFields","useOpenChangeSets","contenthubKeys","ContentLibrary","changeSetChoiceIssue","i18nResources","contentLabel","CreateChangeSetModal","COLLECTION_PARAM","useBlueprintSource","usePageRail$1","Link$1","file_contenthub_v1_workspace_config","file_google_protobuf_struct","file_google_protobuf_timestamp","GuardianModeRequiredSchema","RefusalSchema","CheckScope","\"UNSPECIFIED\"","\"BRANCH\"","\"CHANGE_SET\"","WorkspaceConfigService","BlueprintCatalogService","fileDesc","file_contenthub_v1_content_graph","EdgeKind","\"REFERENCE\"","\"TOC\"","\"INCLUDE\"","\"EXCLUDE\"","\"REPLACE\"","\"ANNOTATE\"","\"LINK\"","\"FOOTNOTE\"","\"ANCHOR\"","\"MEDIA\"","\"BLUEPRINT\"","file_contenthub_v1_release","PublishBlockerSchema","ReleaseKind","\"REVISION\"","\"DATE_ONLY\"","\"REPEAL\"","\"WITHDRAWAL\"","file_contenthub_v1_release_read","ReleaseService","file_contenthub_v1_graph_warnings","file_contenthub_v1_merge","PendingMergeReason","\"CONFLICT\"","\"INVALID\"","MergeSide","\"OURS\"","\"THEIRS\"","file_contenthub_v1_planning","CoversReleaseSchema","file_contenthub_v1_change_set","StaleHeadSchema","ChangeSetClosedSchema","WithheldWorkSchema","StaleStatusSchema","StatusTransitionRefusedSchema","ViolationSchema","ChangeSetState","\"OPEN\"","\"PUBLISHED\"","\"DISCARDED\"","BranchKind","\"EDITORIAL\"","\"CARRY_FORWARD\"","CheckOutcome","\"PASSED\"","\"FAILED\"","\"WAIVED\"","ChangeSetService","file_contenthub_v1_collection","CollectionAccessLevel","\"VIEWER\"","\"EDITOR\"","\"OWNER\"","CollectionService","file_contenthub_v1_revision","RevisionCause","\"CREATE\"","\"SAVE\"","\"MERGE\"","\"RESOLVE\"","\"UPGRADE\"","FieldChangeKind","\"ADDED\"","\"REMOVED\"","\"CHANGED\"","file_contenthub_v1_content","ContentBlockedSchema","ContentArchivedSchema","ContentService","iso","ts","timestampDate","catalogReleaseFromProto","r","v","catalogRead","call","err","ce","ConnectError","Code","blockReasonFromProto","STATE_FROM_PROTO","STATE_TO_PROTO","stateFromProto","state","changeSetFromProto","cs","chain","b","plannedReleaseFromProto","KIND_FROM_PROTO","periodFromProto","p","pr","releaseFromProto","blockerFromProto","pendingFromProto","jsonOf","toJson","ValueSchema","mergeFieldFromProto","f","planRefusal","covers","saveRefusal","changeSetId","struct","values","OUTCOME_FROM_PROTO","OUTCOME_TO_PROTO","checkResultFromProto","requiredCheckFromProto","c","collectionFromProto","SCOPE_TO_PROTO","LEVEL_FROM_PROTO","COLLECTION_RESTRICTION","settingsRefusal","name","guardianMode","recorderToProto","settingsWrite","contentFromProto","attributesFromProto","a","resolvedReleaseFromBytes","bytes","doc","fields","parts","timelineEntryFromProto","requiredPlannedRelease","CAUSES","revisionFromProto","EDGE_KINDS","edgeFromProto","plannedEndFromProto","res","g","editRefusal","blocked","archived","changeSetRefusal","attributeWrite","contentRefusal","reasons","refused","stale","closed","id","ChangeSetClosedError","blockers","moved","changeSetWrite","nameRefusal","createConnectContenthubClient","transport","options","createConnectTransport","config","createClient","changeSets","contents","collections","releases","catalog","input","updateMask","idempotencyKey","dependsOnId","chainId","st","outcome","recorder","level","view","copyFrom","data","fieldMask","target","pageSize","pageToken","base","kinds","revisionId","includeOpenChangeSets","effectiveOn","changeSetName","releaseSpec","supersedesReleaseIds","resolutions","fromJson","row","contentId","validOn","STANDALONE_CONTENTHUB_PATHS","contenthubSettingsPath","tab","paths","PathsContext","createContext","ContenthubPathsProvider","useContenthubPaths","useContext","BlockReasonNameModal","useTranslation","formId","mode","schema","useMemo","z","t","methods","useForm","zodResolver","initialName","failed","setFailed","useState","submitting","open","submit","onSubmit","Modal","HStack","Button","onClose","FormProvider","Stack","InputField","Alert","RemoveBlockReasonModal","reason","shown","setShown","removing","setRemoving","confirm","onConfirm","Text","useBlockReasons","useQuery","client","CreateBlockReasonButton","Plus","label","BlockReasonsBody","queryClient","useQueryClient","renaming","setRenaming","query","refresh","columns","TruncatedTextCell","DateCell","MenuCell","Pencil","Trash2","toolbar","DataTable","EmptyState","Lock","onCreatingChange","creating","BlockReasonsCount","count","Toolbar","BlockReasonsTab","setCreating","BlockReasonsSettings","IndexPageTemplate","isAnswer","newIdempotencyKey","what","useAttemptKey","attempt","useRef","useCallback","json","asked","ContentDataFields","lazy","valueText","value","plainRows","declared","known","rest","k","ContentDataTab","detail","labels","Box","content","blueprintRelease","Suspense","Spinner","Card","DescriptionList","BranchCompareTab","born","against","compareBase","comparison","headRevisionId","SlugCell","onCompareBase","BranchContentFields$1","BranchContentTab","release","record","BranchContentFields","periodText$2","planIssues","dated","issues","BranchReleaseTab","ctx","planning","useWatch","firstDay","lastDay","published","timeline","releaseOptions","canPreview","preview","proposals","changeSet","readOnly","BaseSelectField","Heading","branchId","CalendarPlus","contentRefusalText","BranchUpdateModal","setOutcome","failure","setFailure","running","setRunning","settle","run","keyFor","stopped","merged","onResolve","ResolveMergeModal","resolveKey","abortKey","pending","busy","setBusy","pm","nameOf","accessor","path","resolve","undecided","choices","i","request","onDone","abort","RadioGroupField","PreviewModal","defaultDay","day","valid","AppendBranchModal","after","ICONS$1","GitMerge","Wrench","GitCompare","Eye","GitPullRequestArrow","BranchRail","ContextRail","actions","Zap","Icon","action","onAction","Info","about","targetOf$1","edge","Section$1","title","children","BranchReferencesTab","outgoing","pins","outgoingColumns","pinColumns","index","ConfirmModal","message","confirmLabel","danger","failedMessage","refusal","setRefusal","withoutRequired","clear","out","key","CONTENT","RELEASE","COMPARE","BRANCH_EDITOR_TABS","BranchEditor","BranchEditorFrame","props","TabDirtyProvider","BranchScreen","kitLoad","loadKit","m","useFormKit","kit","setKit","useEffect","live","loaded","sameJSON","canonical","x","y","changedFields","baseline","draft","formPath","part","planValuesOf","planned","branch","settleForm","form","sent","useTabDirty","searchParams","setSearchParams","useSearchParams","tabParam","tabs","each","readKey","changeSetKey","setRecord","head","contentKey","releaseKey","resolverRef","context","seeded","setSeeded","planForm","specResolverRef","specForm","setPlanned","releaseSeeded","setReleaseSeeded","seed","defaults","specFields","plan","contentDirty","setTabDirty","releaseDirty","saving","setSaving","saved","setSaved","changed","dirtyTabs","setCompareBase","dialog","setDialog","closeDialog","dropKey","selectTab","params","current","next","saveContent","mask","snapshot","parsed","saveRelease","validityPeriod","sentPlan","spec","result","save","doContent","doRelease","planSnapshot","issue","contentSaved","reload","fresh","headMoved","pendingMerge","railActions","offered","onRailAction","notFound","DetailPageTemplate","otherBranch","active","lastEditorial","TypeBadge","Save","Tabs","RefusalAlert$1","ids","UnsavedChangesGuard","appended","onOpenBranch","onDeleted","savedFirst","reloading","onReload","RotateCcw","onSupersede","NO_STATUSES","useChangeSetStatuses","statuses","source","labelOf","slug","s","available","failureOf","UpdateFromMainModal","Fragment","DiscardChangeSetModal","subjectText","standingKey","ChangeSetChecksTab","useHostIdentity","standingLabel","latest","members","StatusBadgeCell","canRecord","ActionCell","ClipboardCheck","onRecord","loading","standings","ListChecks","branchToOpen","ChangeSetContentsTab","CountCell","BooleanCell","FileText","generalValuesOf","DEPENDENCY_CANDIDATES","ChangeSetGeneralTab","statusOptions","o","assigneeOptions","unknown","searchDependencies","q","resolveDependencies","createdBy","status","LookupSelectField","periodText$1","period","coveredRows","rows","ChangeSetReleasesTab","originText","covered","coveredColumns","CalendarRange","KNOWN","blockerMessage","checkName","FIXED_IN_EDITOR","PublishBlockerList","onOpenContent","PublishReviewModal","reviewed","setReviewed","stage","setStage","publishing","setPublishing","session","review","heads","answer","onReviewed","publish","previous","contentOf","ready","Send","refusalKey","EMPTY$4","FORM_ID$5","OUTCOMES","RecordCheckResultModal","standing","TextareaField","TABS$2","GENERAL","NO_VALUES","ChangeSetPage","ChangeSetEditor","sameIds$1","trimmed","updateMaskOf","was","statusSource","setBaseline","generalDirty","updateKeyFor","settleUpdateKey","saveAll","wanted","isOpen","freshHeads","readiness","checkNames","names","recording","setRecording","refreshReview","adopt","kept","onPublished","updateFromMain","discard","onDiscarded","openRecord","blockerCount","railStatus","openContent","StatusBadge","RefusalAlert","STATES","ME","PAGE_SIZE","ChangeSetsIndex","setState","assignee","setAssignee","filter","userId","useInfiniteQuery","pageParam","last","keepPreviousData","page","createButton","NativeSelect","onOpenChangeSet","FolderGit2","created","ArchiveContentModal","FORM_ID$4","BlockContentModal","empty","reasonOptions","userOptions","noReasons","Link","REVISIONS_PAGE","useContentChangeSets","ContentRevisionsTab","revisions","selected","setSelected","changeSetOf","History","RevisionComparison","revision","ContentChangeSetsTab","GitBranch","filingValuesOf","pathOf","seen","parent","all","ContentFilingTab","collectionOptions","attributes","ICONS","PencilLine","Copy","FileX","Ban","LockOpen","Archive","ArchiveRestore","ContentRail","REFERRERS_PAGE","targetOf","Section","ContentReferencesTab","referrerPages","referrers","pinSource","kindColumn","pathColumn","referrerColumns","openTarget","periodText","useContentTimeline","ContentReleasesTab","openChangeSets","inForce","entryColumns","NumberCell","plannedColumns","CalendarClock","FORM_ID$3","EMPTY$3","DuplicateContentModal","copy","onCreated","FORM_ID$2","EMPTY$2","EndForceModal","kind","FORM_ID$1","StartEditingModal","isNew","started","onStarted","TABS$1","NO_FILING","ContentPage","ContentScreen","sameIds","blueprintSource","blueprintName","blockReasons","filingDirty","applyAttributes","old","writeNow","write","entries","today","publishedKnown","list","blockReason","blockedBy","railLabels","rail","EMPTY$1","LEVEL_KEYS","CollectionAccessModal","me","collection","grants","picked","unavailable","onRestrictionUnavailable","roster","owner","granted","candidates","levels","grant","revoke","loadError","ROOT","placeOptions","rootLabel","except","isWithin","CollectionFormModal","initial","parents","canRestrict","SwitchField","MoveCollectionModal","places","treeOrder","walk","CollectionsTab","moving","setMoving","confirming","setConfirming","managing","setManaging","restrictionUnavailable","setRestrictionUnavailable","markUnavailable","learning","above","FolderInput","Users","confirmText","FolderTree","FORM_ID","SCOPE_LABELS","valuesOf","check","accessorsOf","text","RequiredCheckModal","everyBlueprint","scopeOptions","fail","field","accessors","EMPTY","retryRecorders","failures","RequiredCheckRecordersModal","recorders","onGuardianModeRequired","everyMember","named","change","add","RecordersCell","checkId","workspaceMode","u","RequiredChecksTab","editing","setEditing","narrowing","setNarrowing","setWorkspaceMode","markWorkspaceMode","checks","UserCheck","TABS","TAB_LABELS","ContenthubSettings","select","SettingsPageTemplate"],"sources":["../../../gen/ts/contenthub/v1/workspace_config_pb.ts","../../../gen/ts/contenthub/v1/blueprint_catalog_pb.ts","../../../gen/ts/contenthub/v1/content_graph_pb.ts","../../../gen/ts/contenthub/v1/release_pb.ts","../../../gen/ts/contenthub/v1/release_read_pb.ts","../../../gen/ts/contenthub/v1/graph_warnings_pb.ts","../../../gen/ts/contenthub/v1/merge_pb.ts","../../../gen/ts/contenthub/v1/planning_pb.ts","../../../gen/ts/contenthub/v1/change_set_pb.ts","../../../gen/ts/contenthub/v1/collection_pb.ts","../../../gen/ts/contenthub/v1/revision_pb.ts","../../../gen/ts/contenthub/v1/content_pb.ts","../src/client/connect-contenthub-client.ts","../src/common/paths.tsx","../src/screens/block-reason-name-modal.tsx","../src/screens/remove-block-reason-modal.tsx","../src/screens/block-reasons-settings.tsx","../src/common/idempotency.ts","../src/screens/content-data-tab.tsx","../src/screens/branch-compare-tab.tsx","../src/screens/branch-content-tab.tsx","../src/screens/branch-release-tab.tsx","../src/screens/content-refusal.ts","../src/screens/branch-dialogs.tsx","../src/screens/branch-rail.tsx","../src/screens/branch-references-tab.tsx","../src/screens/confirm-modal.tsx","../src/screens/required-fields.ts","../src/screens/branch-editor.tsx","../src/common/use-change-set-statuses.ts","../src/screens/change-set-action-modals.tsx","../src/screens/change-set-checks-tab.tsx","../src/screens/change-set-contents-tab.tsx","../src/screens/change-set-general-tab.tsx","../src/screens/change-set-releases-tab.tsx","../src/screens/publish-blockers.tsx","../src/screens/publish-review-modal.tsx","../src/screens/record-check-result-modal.tsx","../src/screens/change-set-page.tsx","../src/screens/change-sets-index.tsx","../src/screens/archive-content-modal.tsx","../src/screens/block-content-modal.tsx","../src/screens/content-revisions-tab.tsx","../src/screens/content-change-sets-tab.tsx","../src/screens/content-filing-tab.tsx","../src/screens/content-rail.tsx","../src/screens/content-references-tab.tsx","../src/screens/content-releases-tab.tsx","../src/screens/duplicate-content-modal.tsx","../src/screens/end-force-modal.tsx","../src/screens/start-editing-modal.tsx","../src/screens/content-page.tsx","../src/screens/collection-access-modal.tsx","../src/screens/collection-modals.tsx","../src/screens/collections-tab.tsx","../src/screens/required-check-modal.tsx","../src/screens/required-check-recorders-modal.tsx","../src/screens/required-checks-tab.tsx","../src/screens/contenthub-settings.tsx"],"sourcesContent":["// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/workspace_config.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/workspace_config.proto.\n */\nexport const file_contenthub_v1_workspace_config: GenFile = /*@__PURE__*/\n fileDesc(\"CiRjb250ZW50aHViL3YxL3dvcmtzcGFjZV9jb25maWcucHJvdG8SDWNvbnRlbnRodWIudjEiiQEKC0Jsb2NrUmVhc29uEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSLwoLY3JlYXRlX3RpbWUYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC3VwZGF0ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIoChhDcmVhdGVCbG9ja1JlYXNvblJlcXVlc3QSDAoEbmFtZRgBIAEoCSJNChlDcmVhdGVCbG9ja1JlYXNvblJlc3BvbnNlEjAKDGJsb2NrX3JlYXNvbhgBIAEoCzIaLmNvbnRlbnRodWIudjEuQmxvY2tSZWFzb24iGQoXTGlzdEJsb2NrUmVhc29uc1JlcXVlc3QiTQoYTGlzdEJsb2NrUmVhc29uc1Jlc3BvbnNlEjEKDWJsb2NrX3JlYXNvbnMYASADKAsyGi5jb250ZW50aHViLnYxLkJsb2NrUmVhc29uIjQKGFJlbmFtZUJsb2NrUmVhc29uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJIk0KGVJlbmFtZUJsb2NrUmVhc29uUmVzcG9uc2USMAoMYmxvY2tfcmVhc29uGAEgASgLMhouY29udGVudGh1Yi52MS5CbG9ja1JlYXNvbiImChhEZWxldGVCbG9ja1JlYXNvblJlcXVlc3QSCgoCaWQYASABKAkiGwoZRGVsZXRlQmxvY2tSZWFzb25SZXNwb25zZSLnAQoNUmVxdWlyZWRDaGVjaxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEigKBXNjb3BlGAMgASgOMhkuY29udGVudGh1Yi52MS5DaGVja1Njb3BlEhsKE2JsdWVwcmludF9hY2Nlc3NvcnMYBCADKAkSEwoLaW5kZXBlbmRlbnQYBSABKAgSLwoLY3JlYXRlX3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC3VwZGF0ZV90aW1lGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKGAQoaQ3JlYXRlUmVxdWlyZWRDaGVja1JlcXVlc3QSDAoEbmFtZRgBIAEoCRIoCgVzY29wZRgCIAEoDjIZLmNvbnRlbnRodWIudjEuQ2hlY2tTY29wZRIbChNibHVlcHJpbnRfYWNjZXNzb3JzGAMgAygJEhMKC2luZGVwZW5kZW50GAQgASgIIlMKG0NyZWF0ZVJlcXVpcmVkQ2hlY2tSZXNwb25zZRI0Cg5yZXF1aXJlZF9jaGVjaxgBIAEoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayIbChlMaXN0UmVxdWlyZWRDaGVja3NSZXF1ZXN0IlMKGkxpc3RSZXF1aXJlZENoZWNrc1Jlc3BvbnNlEjUKD3JlcXVpcmVkX2NoZWNrcxgBIAMoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayKSAQoaVXBkYXRlUmVxdWlyZWRDaGVja1JlcXVlc3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIoCgVzY29wZRgDIAEoDjIZLmNvbnRlbnRodWIudjEuQ2hlY2tTY29wZRIbChNibHVlcHJpbnRfYWNjZXNzb3JzGAQgAygJEhMKC2luZGVwZW5kZW50GAUgASgIIlMKG1VwZGF0ZVJlcXVpcmVkQ2hlY2tSZXNwb25zZRI0Cg5yZXF1aXJlZF9jaGVjaxgBIAEoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayIoChpEZWxldGVSZXF1aXJlZENoZWNrUmVxdWVzdBIKCgJpZBgBIAEoCSIdChtEZWxldGVSZXF1aXJlZENoZWNrUmVzcG9uc2UiQQoIUmVjb3JkZXISEQoHdXNlcl9pZBgBIAEoCUgAEhYKDGV2ZXJ5X21lbWJlchgCIAEoCEgAQgoKCHJlY29yZGVyIj4KIUxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzUmVxdWVzdBIZChFyZXF1aXJlZF9jaGVja19pZBgBIAEoCSJMCiJMaXN0UmVxdWlyZWRDaGVja1JlY29yZGVyc1Jlc3BvbnNlEhQKDGV2ZXJ5X21lbWJlchgBIAEoCBIQCgh1c2VyX2lkcxgCIAMoCSJpCiFHcmFudFJlcXVpcmVkQ2hlY2tSZWNvcmRlclJlcXVlc3QSGQoRcmVxdWlyZWRfY2hlY2tfaWQYASABKAkSKQoIcmVjb3JkZXIYAiABKAsyFy5jb250ZW50aHViLnYxLlJlY29yZGVyIiQKIkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UiagoiUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVxdWVzdBIZChFyZXF1aXJlZF9jaGVja19pZBgBIAEoCRIpCghyZWNvcmRlchgCIAEoCzIXLmNvbnRlbnRodWIudjEuUmVjb3JkZXIiJQojUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UiJwoUR3VhcmRpYW5Nb2RlUmVxdWlyZWQSDwoHZmVhdHVyZRgBIAEoCSI4ChxDaGVja0JsdWVwcmludFJlbGVhc2VSZXF1ZXN0EhgKEHJlc29sdmVkX3JlbGVhc2UYASABKAwiSQodQ2hlY2tCbHVlcHJpbnRSZWxlYXNlUmVzcG9uc2USKAoIcmVmdXNhbHMYASADKAsyFi5jb250ZW50aHViLnYxLlJlZnVzYWwiXgoHUmVmdXNhbBIOCgZzb3VyY2UYASABKAkSDAoEY29kZRgCIAEoCRIMCgRwYXRoGAMgASgJEicKBnBhcmFtcxgEIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QqXQoKQ2hlY2tTY29wZRIbChdDSEVDS19TQ09QRV9VTlNQRUNJRklFRBAAEhYKEkNIRUNLX1NDT1BFX0JSQU5DSBABEhoKFkNIRUNLX1NDT1BFX0NIQU5HRV9TRVQQAjLtCgoWV29ya3NwYWNlQ29uZmlnU2VydmljZRJmChFDcmVhdGVCbG9ja1JlYXNvbhInLmNvbnRlbnRodWIudjEuQ3JlYXRlQmxvY2tSZWFzb25SZXF1ZXN0GiguY29udGVudGh1Yi52MS5DcmVhdGVCbG9ja1JlYXNvblJlc3BvbnNlEmMKEExpc3RCbG9ja1JlYXNvbnMSJi5jb250ZW50aHViLnYxLkxpc3RCbG9ja1JlYXNvbnNSZXF1ZXN0GicuY29udGVudGh1Yi52MS5MaXN0QmxvY2tSZWFzb25zUmVzcG9uc2USZgoRUmVuYW1lQmxvY2tSZWFzb24SJy5jb250ZW50aHViLnYxLlJlbmFtZUJsb2NrUmVhc29uUmVxdWVzdBooLmNvbnRlbnRodWIudjEuUmVuYW1lQmxvY2tSZWFzb25SZXNwb25zZRJmChFEZWxldGVCbG9ja1JlYXNvbhInLmNvbnRlbnRodWIudjEuRGVsZXRlQmxvY2tSZWFzb25SZXF1ZXN0GiguY29udGVudGh1Yi52MS5EZWxldGVCbG9ja1JlYXNvblJlc3BvbnNlEmwKE0NyZWF0ZVJlcXVpcmVkQ2hlY2sSKS5jb250ZW50aHViLnYxLkNyZWF0ZVJlcXVpcmVkQ2hlY2tSZXF1ZXN0GiouY29udGVudGh1Yi52MS5DcmVhdGVSZXF1aXJlZENoZWNrUmVzcG9uc2USaQoSTGlzdFJlcXVpcmVkQ2hlY2tzEiguY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja3NSZXF1ZXN0GikuY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja3NSZXNwb25zZRJsChNVcGRhdGVSZXF1aXJlZENoZWNrEikuY29udGVudGh1Yi52MS5VcGRhdGVSZXF1aXJlZENoZWNrUmVxdWVzdBoqLmNvbnRlbnRodWIudjEuVXBkYXRlUmVxdWlyZWRDaGVja1Jlc3BvbnNlEmwKE0RlbGV0ZVJlcXVpcmVkQ2hlY2sSKS5jb250ZW50aHViLnYxLkRlbGV0ZVJlcXVpcmVkQ2hlY2tSZXF1ZXN0GiouY29udGVudGh1Yi52MS5EZWxldGVSZXF1aXJlZENoZWNrUmVzcG9uc2USgQEKGkxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzEjAuY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja1JlY29yZGVyc1JlcXVlc3QaMS5jb250ZW50aHViLnYxLkxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzUmVzcG9uc2USgQEKGkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyEjAuY29udGVudGh1Yi52MS5HcmFudFJlcXVpcmVkQ2hlY2tSZWNvcmRlclJlcXVlc3QaMS5jb250ZW50aHViLnYxLkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UShAEKG1Jldm9rZVJlcXVpcmVkQ2hlY2tSZWNvcmRlchIxLmNvbnRlbnRodWIudjEuUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVxdWVzdBoyLmNvbnRlbnRodWIudjEuUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UScgoVQ2hlY2tCbHVlcHJpbnRSZWxlYXNlEisuY29udGVudGh1Yi52MS5DaGVja0JsdWVwcmludFJlbGVhc2VSZXF1ZXN0GiwuY29udGVudGh1Yi52MS5DaGVja0JsdWVwcmludFJlbGVhc2VSZXNwb25zZUI8WjpnaXRodWIuY29tL2tua2NzL2NvbnRlbnRodWIvZ2VuL2NvbnRlbnRodWIvdjE7Y29udGVudGh1YnYxYgZwcm90bzM\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * BlockReason is one of a workspace's own reasons a Content may be blocked,\n * such as \"being revised by the author\" (CONTEXT.md). It is configuration, not\n * versioned.\n *\n * @generated from message contenthub.v1.BlockReason\n */\nexport type BlockReason = Message<\"contenthub.v1.BlockReason\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 3;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 4;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.BlockReason.\n * Use `create(BlockReasonSchema)` to create a new message.\n */\nexport const BlockReasonSchema: GenMessage<BlockReason> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 0);\n\n/**\n * @generated from message contenthub.v1.CreateBlockReasonRequest\n */\nexport type CreateBlockReasonRequest = Message<\"contenthub.v1.CreateBlockReasonRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, and no other Block Reason\n * of the workspace may have it. Surrounding whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateBlockReasonRequest.\n * Use `create(CreateBlockReasonRequestSchema)` to create a new message.\n */\nexport const CreateBlockReasonRequestSchema: GenMessage<CreateBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 1);\n\n/**\n * @generated from message contenthub.v1.CreateBlockReasonResponse\n */\nexport type CreateBlockReasonResponse = Message<\"contenthub.v1.CreateBlockReasonResponse\"> & {\n /**\n * @generated from field: contenthub.v1.BlockReason block_reason = 1;\n */\n blockReason?: BlockReason | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateBlockReasonResponse.\n * Use `create(CreateBlockReasonResponseSchema)` to create a new message.\n */\nexport const CreateBlockReasonResponseSchema: GenMessage<CreateBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 2);\n\n/**\n * @generated from message contenthub.v1.ListBlockReasonsRequest\n */\nexport type ListBlockReasonsRequest = Message<\"contenthub.v1.ListBlockReasonsRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListBlockReasonsRequest.\n * Use `create(ListBlockReasonsRequestSchema)` to create a new message.\n */\nexport const ListBlockReasonsRequestSchema: GenMessage<ListBlockReasonsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 3);\n\n/**\n * @generated from message contenthub.v1.ListBlockReasonsResponse\n */\nexport type ListBlockReasonsResponse = Message<\"contenthub.v1.ListBlockReasonsResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.BlockReason block_reasons = 1;\n */\n blockReasons: BlockReason[];\n};\n\n/**\n * Describes the message contenthub.v1.ListBlockReasonsResponse.\n * Use `create(ListBlockReasonsResponseSchema)` to create a new message.\n */\nexport const ListBlockReasonsResponseSchema: GenMessage<ListBlockReasonsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 4);\n\n/**\n * @generated from message contenthub.v1.RenameBlockReasonRequest\n */\nexport type RenameBlockReasonRequest = Message<\"contenthub.v1.RenameBlockReasonRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The new name, under the rules of CreateBlockReasonRequest.name.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.RenameBlockReasonRequest.\n * Use `create(RenameBlockReasonRequestSchema)` to create a new message.\n */\nexport const RenameBlockReasonRequestSchema: GenMessage<RenameBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 5);\n\n/**\n * @generated from message contenthub.v1.RenameBlockReasonResponse\n */\nexport type RenameBlockReasonResponse = Message<\"contenthub.v1.RenameBlockReasonResponse\"> & {\n /**\n * @generated from field: contenthub.v1.BlockReason block_reason = 1;\n */\n blockReason?: BlockReason | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RenameBlockReasonResponse.\n * Use `create(RenameBlockReasonResponseSchema)` to create a new message.\n */\nexport const RenameBlockReasonResponseSchema: GenMessage<RenameBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 6);\n\n/**\n * @generated from message contenthub.v1.DeleteBlockReasonRequest\n */\nexport type DeleteBlockReasonRequest = Message<\"contenthub.v1.DeleteBlockReasonRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.DeleteBlockReasonRequest.\n * Use `create(DeleteBlockReasonRequestSchema)` to create a new message.\n */\nexport const DeleteBlockReasonRequestSchema: GenMessage<DeleteBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 7);\n\n/**\n * @generated from message contenthub.v1.DeleteBlockReasonResponse\n */\nexport type DeleteBlockReasonResponse = Message<\"contenthub.v1.DeleteBlockReasonResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.DeleteBlockReasonResponse.\n * Use `create(DeleteBlockReasonResponseSchema)` to create a new message.\n */\nexport const DeleteBlockReasonResponseSchema: GenMessage<DeleteBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 8);\n\n/**\n * RequiredCheck is a condition the workspace requires to have passed before\n * Publish, such as a lawyer's approval or a print round trip (CONTEXT.md).\n * It is configuration, never released and not versioned.\n *\n * @generated from message contenthub.v1.RequiredCheck\n */\nexport type RequiredCheck = Message<\"contenthub.v1.RequiredCheck\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: contenthub.v1.CheckScope scope = 3;\n */\n scope: CheckScope;\n\n /**\n * The accessors of the Blueprints whose Content it applies to, sorted;\n * empty means every Blueprint.\n *\n * @generated from field: repeated string blueprint_accessors = 4;\n */\n blueprintAccessors: string[];\n\n /**\n * When set, passed and waived are refused from anyone who authored a\n * Revision on the Branches the result covers; failed is accepted from\n * anyone.\n *\n * @generated from field: bool independent = 5;\n */\n independent: boolean;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 7;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RequiredCheck.\n * Use `create(RequiredCheckSchema)` to create a new message.\n */\nexport const RequiredCheckSchema: GenMessage<RequiredCheck> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 9);\n\n/**\n * @generated from message contenthub.v1.CreateRequiredCheckRequest\n */\nexport type CreateRequiredCheckRequest = Message<\"contenthub.v1.CreateRequiredCheckRequest\"> & {\n /**\n * Required: not blank, one line, at most 200 characters, and no other\n * Required Check of the workspace may have it. Surrounding whitespace is\n * trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.CheckScope scope = 2;\n */\n scope: CheckScope;\n\n /**\n * Blueprint accessors; empty means every Blueprint. Duplicates are\n * dropped.\n *\n * @generated from field: repeated string blueprint_accessors = 3;\n */\n blueprintAccessors: string[];\n\n /**\n * @generated from field: bool independent = 4;\n */\n independent: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CreateRequiredCheckRequest.\n * Use `create(CreateRequiredCheckRequestSchema)` to create a new message.\n */\nexport const CreateRequiredCheckRequestSchema: GenMessage<CreateRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 10);\n\n/**\n * @generated from message contenthub.v1.CreateRequiredCheckResponse\n */\nexport type CreateRequiredCheckResponse = Message<\"contenthub.v1.CreateRequiredCheckResponse\"> & {\n /**\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateRequiredCheckResponse.\n * Use `create(CreateRequiredCheckResponseSchema)` to create a new message.\n */\nexport const CreateRequiredCheckResponseSchema: GenMessage<CreateRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 11);\n\n/**\n * @generated from message contenthub.v1.ListRequiredChecksRequest\n */\nexport type ListRequiredChecksRequest = Message<\"contenthub.v1.ListRequiredChecksRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredChecksRequest.\n * Use `create(ListRequiredChecksRequestSchema)` to create a new message.\n */\nexport const ListRequiredChecksRequestSchema: GenMessage<ListRequiredChecksRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 12);\n\n/**\n * @generated from message contenthub.v1.ListRequiredChecksResponse\n */\nexport type ListRequiredChecksResponse = Message<\"contenthub.v1.ListRequiredChecksResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.RequiredCheck required_checks = 1;\n */\n requiredChecks: RequiredCheck[];\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredChecksResponse.\n * Use `create(ListRequiredChecksResponseSchema)` to create a new message.\n */\nexport const ListRequiredChecksResponseSchema: GenMessage<ListRequiredChecksResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 13);\n\n/**\n * @generated from message contenthub.v1.UpdateRequiredCheckRequest\n */\nexport type UpdateRequiredCheckRequest = Message<\"contenthub.v1.UpdateRequiredCheckRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Every field is replaced, under the rules of CreateRequiredCheckRequest.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: contenthub.v1.CheckScope scope = 3;\n */\n scope: CheckScope;\n\n /**\n * @generated from field: repeated string blueprint_accessors = 4;\n */\n blueprintAccessors: string[];\n\n /**\n * @generated from field: bool independent = 5;\n */\n independent: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateRequiredCheckRequest.\n * Use `create(UpdateRequiredCheckRequestSchema)` to create a new message.\n */\nexport const UpdateRequiredCheckRequestSchema: GenMessage<UpdateRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 14);\n\n/**\n * @generated from message contenthub.v1.UpdateRequiredCheckResponse\n */\nexport type UpdateRequiredCheckResponse = Message<\"contenthub.v1.UpdateRequiredCheckResponse\"> & {\n /**\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateRequiredCheckResponse.\n * Use `create(UpdateRequiredCheckResponseSchema)` to create a new message.\n */\nexport const UpdateRequiredCheckResponseSchema: GenMessage<UpdateRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 15);\n\n/**\n * @generated from message contenthub.v1.DeleteRequiredCheckRequest\n */\nexport type DeleteRequiredCheckRequest = Message<\"contenthub.v1.DeleteRequiredCheckRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.DeleteRequiredCheckRequest.\n * Use `create(DeleteRequiredCheckRequestSchema)` to create a new message.\n */\nexport const DeleteRequiredCheckRequestSchema: GenMessage<DeleteRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 16);\n\n/**\n * @generated from message contenthub.v1.DeleteRequiredCheckResponse\n */\nexport type DeleteRequiredCheckResponse = Message<\"contenthub.v1.DeleteRequiredCheckResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.DeleteRequiredCheckResponse.\n * Use `create(DeleteRequiredCheckResponseSchema)` to create a new message.\n */\nexport const DeleteRequiredCheckResponseSchema: GenMessage<DeleteRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 17);\n\n/**\n * Recorder is who a recorder grant names: one user, or every member of the\n * workspace (`core/workspace:<W>#member`).\n *\n * @generated from message contenthub.v1.Recorder\n */\nexport type Recorder = Message<\"contenthub.v1.Recorder\"> & {\n /**\n * @generated from oneof contenthub.v1.Recorder.recorder\n */\n recorder: {\n /**\n * An odon user id, a member of the workspace.\n *\n * @generated from field: string user_id = 1;\n */\n value: string;\n case: \"userId\";\n } | {\n /**\n * Every member of the workspace, now and later; only true is meaningful.\n *\n * @generated from field: bool every_member = 2;\n */\n value: boolean;\n case: \"everyMember\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.Recorder.\n * Use `create(RecorderSchema)` to create a new message.\n */\nexport const RecorderSchema: GenMessage<Recorder> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 18);\n\n/**\n * @generated from message contenthub.v1.ListRequiredCheckRecordersRequest\n */\nexport type ListRequiredCheckRecordersRequest = Message<\"contenthub.v1.ListRequiredCheckRecordersRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredCheckRecordersRequest.\n * Use `create(ListRequiredCheckRecordersRequestSchema)` to create a new message.\n */\nexport const ListRequiredCheckRecordersRequestSchema: GenMessage<ListRequiredCheckRecordersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 19);\n\n/**\n * @generated from message contenthub.v1.ListRequiredCheckRecordersResponse\n */\nexport type ListRequiredCheckRecordersResponse = Message<\"contenthub.v1.ListRequiredCheckRecordersResponse\"> & {\n /**\n * Whether every member of the workspace records the check.\n *\n * @generated from field: bool every_member = 1;\n */\n everyMember: boolean;\n\n /**\n * The users granted by name, sorted. Unpaginated: bounded by the\n * workspace's members.\n *\n * @generated from field: repeated string user_ids = 2;\n */\n userIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredCheckRecordersResponse.\n * Use `create(ListRequiredCheckRecordersResponseSchema)` to create a new message.\n */\nexport const ListRequiredCheckRecordersResponseSchema: GenMessage<ListRequiredCheckRecordersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 20);\n\n/**\n * @generated from message contenthub.v1.GrantRequiredCheckRecorderRequest\n */\nexport type GrantRequiredCheckRecorderRequest = Message<\"contenthub.v1.GrantRequiredCheckRecorderRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.Recorder recorder = 2;\n */\n recorder?: Recorder | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GrantRequiredCheckRecorderRequest.\n * Use `create(GrantRequiredCheckRecorderRequestSchema)` to create a new message.\n */\nexport const GrantRequiredCheckRecorderRequestSchema: GenMessage<GrantRequiredCheckRecorderRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 21);\n\n/**\n * @generated from message contenthub.v1.GrantRequiredCheckRecorderResponse\n */\nexport type GrantRequiredCheckRecorderResponse = Message<\"contenthub.v1.GrantRequiredCheckRecorderResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.GrantRequiredCheckRecorderResponse.\n * Use `create(GrantRequiredCheckRecorderResponseSchema)` to create a new message.\n */\nexport const GrantRequiredCheckRecorderResponseSchema: GenMessage<GrantRequiredCheckRecorderResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 22);\n\n/**\n * @generated from message contenthub.v1.RevokeRequiredCheckRecorderRequest\n */\nexport type RevokeRequiredCheckRecorderRequest = Message<\"contenthub.v1.RevokeRequiredCheckRecorderRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.Recorder recorder = 2;\n */\n recorder?: Recorder | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RevokeRequiredCheckRecorderRequest.\n * Use `create(RevokeRequiredCheckRecorderRequestSchema)` to create a new message.\n */\nexport const RevokeRequiredCheckRecorderRequestSchema: GenMessage<RevokeRequiredCheckRecorderRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 23);\n\n/**\n * @generated from message contenthub.v1.RevokeRequiredCheckRecorderResponse\n */\nexport type RevokeRequiredCheckRecorderResponse = Message<\"contenthub.v1.RevokeRequiredCheckRecorderResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.RevokeRequiredCheckRecorderResponse.\n * Use `create(RevokeRequiredCheckRecorderResponseSchema)` to create a new message.\n */\nexport const RevokeRequiredCheckRecorderResponseSchema: GenMessage<RevokeRequiredCheckRecorderResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 24);\n\n/**\n * GuardianModeRequired is the detail of a FailedPrecondition refusal of what\n * only `authz.mode: guardian` can hold (ADR 0017): in workspace mode every\n * member records any Required Check, so who records one can't be narrowed,\n * and no Collection can be restricted, since nothing could enforce it.\n * A client reads it as \"this workspace runs in workspace mode\" and stops\n * offering the feature.\n *\n * @generated from message contenthub.v1.GuardianModeRequired\n */\nexport type GuardianModeRequired = Message<\"contenthub.v1.GuardianModeRequired\"> & {\n /**\n * What was refused: \"required_check_recorders\" (who records a Required\n * Check) or \"collection_restriction\" (restricting a Collection and its\n * grants).\n *\n * @generated from field: string feature = 1;\n */\n feature: string;\n};\n\n/**\n * Describes the message contenthub.v1.GuardianModeRequired.\n * Use `create(GuardianModeRequiredSchema)` to create a new message.\n */\nexport const GuardianModeRequiredSchema: GenMessage<GuardianModeRequired> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 25);\n\n/**\n * @generated from message contenthub.v1.CheckBlueprintReleaseRequest\n */\nexport type CheckBlueprintReleaseRequest = Message<\"contenthub.v1.CheckBlueprintReleaseRequest\"> & {\n /**\n * The Resolved Release document, byte for byte as blueprinthub stores and\n * serves it. The workspace comes from the token.\n *\n * @generated from field: bytes resolved_release = 1;\n */\n resolvedRelease: Uint8Array;\n};\n\n/**\n * Describes the message contenthub.v1.CheckBlueprintReleaseRequest.\n * Use `create(CheckBlueprintReleaseRequestSchema)` to create a new message.\n */\nexport const CheckBlueprintReleaseRequestSchema: GenMessage<CheckBlueprintReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 26);\n\n/**\n * @generated from message contenthub.v1.CheckBlueprintReleaseResponse\n */\nexport type CheckBlueprintReleaseResponse = Message<\"contenthub.v1.CheckBlueprintReleaseResponse\"> & {\n /**\n * Every reason contenthub refuses the Release; empty means accepted.\n *\n * @generated from field: repeated contenthub.v1.Refusal refusals = 1;\n */\n refusals: Refusal[];\n};\n\n/**\n * Describes the message contenthub.v1.CheckBlueprintReleaseResponse.\n * Use `create(CheckBlueprintReleaseResponseSchema)` to create a new message.\n */\nexport const CheckBlueprintReleaseResponseSchema: GenMessage<CheckBlueprintReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 27);\n\n/**\n * Refusal is one reason contenthub can't load a Resolved Release.\n *\n * @generated from message contenthub.v1.Refusal\n */\nexport type Refusal = Message<\"contenthub.v1.Refusal\"> & {\n /**\n * Whose rule refused it: \"format\" (the envelope), \"fieldkit\", \"knkeditor\"\n * or \"contenthub\" (contenthub's own policy).\n *\n * @generated from field: string source = 1;\n */\n source: string;\n\n /**\n * The refusing module's own data-contract code, unchanged: format's\n * \"format_too_new\", fieldkit's \"unknown_field_type\", knkeditor's\n * \"unknown-node\", contenthub's \"localizable_unsupported\".\n *\n * @generated from field: string code = 2;\n */\n code: string;\n\n /**\n * A /-separated location in the Resolved Release document, such as\n * \"/spec/fields/title/settings/max\" or \"/spec/parts/text_type/<id>/nodes/x\".\n * Below spec.fields, segments are Field accessors as fieldkit names them,\n * not list indexes. \"\" is the document itself.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * Detail a message may interpolate, as the module gave it; empty when the\n * code says everything.\n *\n * @generated from field: google.protobuf.Struct params = 4;\n */\n params?: JsonObject | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Refusal.\n * Use `create(RefusalSchema)` to create a new message.\n */\nexport const RefusalSchema: GenMessage<Refusal> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 28);\n\n/**\n * CheckScope is what one Check Result of a Required Check is about (ADR\n * 0014).\n *\n * @generated from enum contenthub.v1.CheckScope\n */\nexport enum CheckScope {\n /**\n * @generated from enum value: CHECK_SCOPE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Each Branch of covered Content in a Change Set, and each of its Planned\n * Releases that has no Branch (date-only, Repeal, Withdrawal), needs a\n * result of its own, against its head.\n *\n * @generated from enum value: CHECK_SCOPE_BRANCH = 1;\n */\n BRANCH = 1,\n\n /**\n * A Change Set containing any covered Content needs one result, against\n * every head in it: each Branch's, and the Revision each Branch-less\n * Planned Release re-pins.\n *\n * @generated from enum value: CHECK_SCOPE_CHANGE_SET = 2;\n */\n CHANGE_SET = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.CheckScope.\n */\nexport const CheckScopeSchema: GenEnum<CheckScope> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_workspace_config, 0);\n\n/**\n * WorkspaceConfigService holds contenthub's own per-workspace configuration\n * (ADR 0015): its Block Reasons and its Required Checks, and\n * CheckBlueprintRelease, blueprinthub's question before it cuts a Release.\n * The workspace's time zone is not here: it is the workspace's in odon\n * (ADR 0021), and contenthub only keeps a copy.\n *\n * Every RPC acts on the caller's workspace, which comes from the token's\n * active workspace and never from a request field: no message here names a\n * workspace. Reads need `viewer`, writes `admin` (ADR 0017).\n *\n * @generated from service contenthub.v1.WorkspaceConfigService\n */\nexport const WorkspaceConfigService: GenService<{\n /**\n * CreateBlockReason adds a Block Reason. Names are unique in a workspace.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CreateBlockReason\n */\n createBlockReason: {\n methodKind: \"unary\";\n input: typeof CreateBlockReasonRequestSchema;\n output: typeof CreateBlockReasonResponseSchema;\n },\n /**\n * ListBlockReasons returns every Block Reason of the workspace, by name. A\n * workspace keeps a handful, so the list is not paged.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListBlockReasons\n */\n listBlockReasons: {\n methodKind: \"unary\";\n input: typeof ListBlockReasonsRequestSchema;\n output: typeof ListBlockReasonsResponseSchema;\n },\n /**\n * RenameBlockReason changes a Block Reason's name; its id stays.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.RenameBlockReason\n */\n renameBlockReason: {\n methodKind: \"unary\";\n input: typeof RenameBlockReasonRequestSchema;\n output: typeof RenameBlockReasonResponseSchema;\n },\n /**\n * DeleteBlockReason removes a Block Reason.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.DeleteBlockReason\n */\n deleteBlockReason: {\n methodKind: \"unary\";\n input: typeof DeleteBlockReasonRequestSchema;\n output: typeof DeleteBlockReasonResponseSchema;\n },\n /**\n * CreateRequiredCheck declares a Required Check (ADR 0014). Names are\n * unique in a workspace. It gates every open Change Set at once: Publish\n * reads the checks as declared at that moment.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CreateRequiredCheck\n */\n createRequiredCheck: {\n methodKind: \"unary\";\n input: typeof CreateRequiredCheckRequestSchema;\n output: typeof CreateRequiredCheckResponseSchema;\n },\n /**\n * ListRequiredChecks returns every Required Check of the workspace, by\n * name. A workspace keeps a handful, so the list is not paged.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListRequiredChecks\n */\n listRequiredChecks: {\n methodKind: \"unary\";\n input: typeof ListRequiredChecksRequestSchema;\n output: typeof ListRequiredChecksResponseSchema;\n },\n /**\n * UpdateRequiredCheck replaces a Required Check's name, scope, Blueprints\n * and independent flag; its id stays. Results recorded under another scope\n * stop counting.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.UpdateRequiredCheck\n */\n updateRequiredCheck: {\n methodKind: \"unary\";\n input: typeof UpdateRequiredCheckRequestSchema;\n output: typeof UpdateRequiredCheckResponseSchema;\n },\n /**\n * DeleteRequiredCheck removes a Required Check: it stops gating every open\n * Change Set. Its results are kept, and count for nothing.\n * Its recorders' grants go with it.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.DeleteRequiredCheck\n */\n deleteRequiredCheck: {\n methodKind: \"unary\";\n input: typeof DeleteRequiredCheckRequestSchema;\n output: typeof DeleteRequiredCheckResponseSchema;\n },\n /**\n * ListRequiredCheckRecorders reads who records a Required Check's results\n * (ADR 0017's 2026-10-03 amendment): every member of the workspace, named\n * people, or both while an admin narrows it. A new check starts with every\n * member. Only `admin` reads it, as only `admin` changes it.\n *\n * In `authz.mode: workspace` any member records any check, so there is\n * nothing to read or narrow: all three recorder RPCs are FailedPrecondition\n * with a GuardianModeRequired detail.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListRequiredCheckRecorders\n */\n listRequiredCheckRecorders: {\n methodKind: \"unary\";\n input: typeof ListRequiredCheckRecordersRequestSchema;\n output: typeof ListRequiredCheckRecordersResponseSchema;\n },\n /**\n * GrantRequiredCheckRecorder makes a member of the workspace, or every\n * member, a recorder of a Required Check; `admin` only. A grantee who is\n * not a member is InvalidArgument. An admin records only what they are\n * granted, so granting oneself is their break-glass, announced like any\n * grant. Granting what is granted already succeeds. It publishes\n * contenthub.required_check.recorder_granted.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.GrantRequiredCheckRecorder\n */\n grantRequiredCheckRecorder: {\n methodKind: \"unary\";\n input: typeof GrantRequiredCheckRecorderRequestSchema;\n output: typeof GrantRequiredCheckRecorderResponseSchema;\n },\n /**\n * RevokeRequiredCheckRecorder takes recorder from a user, or from every\n * member (narrowing the check to the people granted by name); `admin`\n * only. Revoking what isn't granted succeeds. Revoking the last recorder is\n * allowed: Publish then waits on the check until someone is granted. It\n * publishes contenthub.required_check.recorder_revoked.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.RevokeRequiredCheckRecorder\n */\n revokeRequiredCheckRecorder: {\n methodKind: \"unary\";\n input: typeof RevokeRequiredCheckRecorderRequestSchema;\n output: typeof RevokeRequiredCheckRecorderResponseSchema;\n },\n /**\n * CheckBlueprintRelease says whether contenthub can load a Resolved Release\n * (blueprinthub ADR 0004, contenthub#51). blueprinthub's CutRelease asks it\n * before it commits, forwarding its caller's token, and cuts nothing that\n * is refused.\n *\n * The check validates fully, with contenthub's own modules, and compares\n * no versions: (1) the envelope decodes strictly, in a format contenthub\n * knows; (2) spec.fields and release_spec pass fieldkit's publishing\n * catalogue with contenthub's policy, a release_spec refusal's path under\n * /release_spec; (3) every Text Type part passes knkeditor's resolved check\n * and needs no newer vocabulary; (4) every TI Set part has fieldkit's\n * minimum shape and no code twice (duplicate_code, naming the Set and the\n * code). A catalogue or vocabulary stated newer than contenthub's is\n * information, not a refusal: only what the Release uses counts.\n *\n * Refusals are a successful response. An error means contenthub gave no\n * answer, and is what blueprinthub retries. It has no side effects, so\n * `viewer` is enough, and it answers well inside blueprinthub's 10-second\n * deadline. Loading a Blueprint Release, and pinning one, run the same\n * check.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CheckBlueprintRelease\n */\n checkBlueprintRelease: {\n methodKind: \"unary\";\n input: typeof CheckBlueprintReleaseRequestSchema;\n output: typeof CheckBlueprintReleaseResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_workspace_config, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/blueprint_catalog.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Refusal } from \"./workspace_config_pb\";\nimport { file_contenthub_v1_workspace_config } from \"./workspace_config_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/blueprint_catalog.proto.\n */\nexport const file_contenthub_v1_blueprint_catalog: GenFile = /*@__PURE__*/\n fileDesc(\"CiVjb250ZW50aHViL3YxL2JsdWVwcmludF9jYXRhbG9nLnByb3RvEg1jb250ZW50aHViLnYxIj4KEENhdGFsb2dCbHVlcHJpbnQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIQCghhY2Nlc3NvchgDIAEoCSJPChdTZWFyY2hCbHVlcHJpbnRzUmVxdWVzdBINCgVxdWVyeRgBIAEoCRIRCglwYWdlX3NpemUYAiABKAUSEgoKcGFnZV90b2tlbhgDIAEoCSJoChhTZWFyY2hCbHVlcHJpbnRzUmVzcG9uc2USMwoKYmx1ZXByaW50cxgBIAMoCzIfLmNvbnRlbnRodWIudjEuQ2F0YWxvZ0JsdWVwcmludBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkirgEKDkNhdGFsb2dSZWxlYXNlEgoKAmlkGAEgASgJEhQKDGJsdWVwcmludF9pZBgCIAEoCRIMCgRuYW1lGAMgASgJEjAKDHJlbGVhc2VfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASEAoIYWNjZXB0ZWQYBSABKAgSKAoIcmVmdXNhbHMYBiADKAsyFi5jb250ZW50aHViLnYxLlJlZnVzYWwiNAocTGlzdEJsdWVwcmludFJlbGVhc2VzUmVxdWVzdBIUCgxibHVlcHJpbnRfaWQYASABKAkiUAodTGlzdEJsdWVwcmludFJlbGVhc2VzUmVzcG9uc2USLwoIcmVsZWFzZXMYASADKAsyHS5jb250ZW50aHViLnYxLkNhdGFsb2dSZWxlYXNlMvIBChdCbHVlcHJpbnRDYXRhbG9nU2VydmljZRJjChBTZWFyY2hCbHVlcHJpbnRzEiYuY29udGVudGh1Yi52MS5TZWFyY2hCbHVlcHJpbnRzUmVxdWVzdBonLmNvbnRlbnRodWIudjEuU2VhcmNoQmx1ZXByaW50c1Jlc3BvbnNlEnIKFUxpc3RCbHVlcHJpbnRSZWxlYXNlcxIrLmNvbnRlbnRodWIudjEuTGlzdEJsdWVwcmludFJlbGVhc2VzUmVxdWVzdBosLmNvbnRlbnRodWIudjEuTGlzdEJsdWVwcmludFJlbGVhc2VzUmVzcG9uc2VCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_contenthub_v1_workspace_config, file_google_protobuf_timestamp]);\n\n/**\n * CatalogBlueprint is a Blueprint as New Content offers it.\n *\n * @generated from message contenthub.v1.CatalogBlueprint\n */\nexport type CatalogBlueprint = Message<\"contenthub.v1.CatalogBlueprint\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * What editors call it: the head Revision's name, or the accessor when it\n * has none.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The accessor, unique in the workspace for good.\n *\n * @generated from field: string accessor = 3;\n */\n accessor: string;\n};\n\n/**\n * Describes the message contenthub.v1.CatalogBlueprint.\n * Use `create(CatalogBlueprintSchema)` to create a new message.\n */\nexport const CatalogBlueprintSchema: GenMessage<CatalogBlueprint> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 0);\n\n/**\n * @generated from message contenthub.v1.SearchBlueprintsRequest\n */\nexport type SearchBlueprintsRequest = Message<\"contenthub.v1.SearchBlueprintsRequest\"> & {\n /**\n * Only Blueprints whose accessor or name contains this text, ignoring\n * case. Empty means every one.\n *\n * @generated from field: string query = 1;\n */\n query: string;\n\n /**\n * At most this many Blueprints; 0 is blueprinthub's default. A page can\n * hold fewer and still not be the last.\n *\n * @generated from field: int32 page_size = 2;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 3;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.SearchBlueprintsRequest.\n * Use `create(SearchBlueprintsRequestSchema)` to create a new message.\n */\nexport const SearchBlueprintsRequestSchema: GenMessage<SearchBlueprintsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 1);\n\n/**\n * @generated from message contenthub.v1.SearchBlueprintsResponse\n */\nexport type SearchBlueprintsResponse = Message<\"contenthub.v1.SearchBlueprintsResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.CatalogBlueprint blueprints = 1;\n */\n blueprints: CatalogBlueprint[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.SearchBlueprintsResponse.\n * Use `create(SearchBlueprintsResponseSchema)` to create a new message.\n */\nexport const SearchBlueprintsResponseSchema: GenMessage<SearchBlueprintsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 2);\n\n/**\n * CatalogRelease is a Blueprint Release and whether Content can pin it.\n *\n * @generated from message contenthub.v1.CatalogRelease\n */\nexport type CatalogRelease = Message<\"contenthub.v1.CatalogRelease\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string blueprint_id = 2;\n */\n blueprintId: string;\n\n /**\n * The name given when it was cut, such as \"2026-10\".\n *\n * @generated from field: string name = 3;\n */\n name: string;\n\n /**\n * When it was cut.\n *\n * @generated from field: google.protobuf.Timestamp release_time = 4;\n */\n releaseTime?: Timestamp | undefined;\n\n /**\n * Whether contenthub loads it. A refused Release can't be pinned.\n *\n * @generated from field: bool accepted = 5;\n */\n accepted: boolean;\n\n /**\n * Why it is refused, as CheckBlueprintRelease would answer for it; empty\n * when accepted.\n *\n * @generated from field: repeated contenthub.v1.Refusal refusals = 6;\n */\n refusals: Refusal[];\n};\n\n/**\n * Describes the message contenthub.v1.CatalogRelease.\n * Use `create(CatalogReleaseSchema)` to create a new message.\n */\nexport const CatalogReleaseSchema: GenMessage<CatalogRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 3);\n\n/**\n * @generated from message contenthub.v1.ListBlueprintReleasesRequest\n */\nexport type ListBlueprintReleasesRequest = Message<\"contenthub.v1.ListBlueprintReleasesRequest\"> & {\n /**\n * @generated from field: string blueprint_id = 1;\n */\n blueprintId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListBlueprintReleasesRequest.\n * Use `create(ListBlueprintReleasesRequestSchema)` to create a new message.\n */\nexport const ListBlueprintReleasesRequestSchema: GenMessage<ListBlueprintReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 4);\n\n/**\n * @generated from message contenthub.v1.ListBlueprintReleasesResponse\n */\nexport type ListBlueprintReleasesResponse = Message<\"contenthub.v1.ListBlueprintReleasesResponse\"> & {\n /**\n * Newest first. Empty while none has been cut, or for a Blueprint the\n * caller's workspace doesn't have.\n *\n * @generated from field: repeated contenthub.v1.CatalogRelease releases = 1;\n */\n releases: CatalogRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.ListBlueprintReleasesResponse.\n * Use `create(ListBlueprintReleasesResponseSchema)` to create a new message.\n */\nexport const ListBlueprintReleasesResponseSchema: GenMessage<ListBlueprintReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 5);\n\n/**\n * BlueprintCatalogService answers which Blueprints and Blueprint Releases\n * Content can be made from (#238, ADR 0020 as amended). blueprinthub is\n * contenthub's direct dependency, not a port a host fills: contenthub reads\n * the workspace's Blueprints from it with the caller's token (ADR 0017) and\n * says of each Release whether it loads, with the same check that runs when\n * Content pins it. A host mounting contenthub's screens therefore needs no\n * connection to blueprinthub of its own.\n *\n * The workspace comes from the token's active workspace, never a request\n * field. Both RPCs are reads and need `viewer`. blueprinthub giving no answer\n * is Unavailable (or the code it failed with); a Release contenthub refuses\n * is data, not an error.\n *\n * @generated from service contenthub.v1.BlueprintCatalogService\n */\nexport const BlueprintCatalogService: GenService<{\n /**\n * SearchBlueprints returns a page of the workspace's content Blueprints\n * that Content can be made from: of kind content, not archived, with at\n * least one Release. Ordered and paged as blueprinthub lists them, by\n * accessor.\n *\n * @generated from rpc contenthub.v1.BlueprintCatalogService.SearchBlueprints\n */\n searchBlueprints: {\n methodKind: \"unary\";\n input: typeof SearchBlueprintsRequestSchema;\n output: typeof SearchBlueprintsResponseSchema;\n },\n /**\n * ListBlueprintReleases returns every Release of a Blueprint, newest\n * first, each saying whether contenthub accepts it. Each answer is the\n * Blueprint Release cache's: an accepted Release is loaded into the cache\n * as a pin would load it, so a later pin costs no fetch.\n *\n * @generated from rpc contenthub.v1.BlueprintCatalogService.ListBlueprintReleases\n */\n listBlueprintReleases: {\n methodKind: \"unary\";\n input: typeof ListBlueprintReleasesRequestSchema;\n output: typeof ListBlueprintReleasesResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_blueprint_catalog, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/content_graph.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/content_graph.proto.\n */\nexport const file_contenthub_v1_content_graph: GenFile = /*@__PURE__*/\n fileDesc(\"CiFjb250ZW50aHViL3YxL2NvbnRlbnRfZ3JhcGgucHJvdG8SDWNvbnRlbnRodWIudjEitwIKBEVkZ2USGQoRc291cmNlX2NvbnRlbnRfaWQYASABKAkSGgoSc291cmNlX3JldmlzaW9uX2lkGAIgASgJEgwKBHBhdGgYAyABKAkSJQoEa2luZBgEIAEoDjIXLmNvbnRlbnRodWIudjEuRWRnZUtpbmQSGQoRdGFyZ2V0X2NvbnRlbnRfaWQYBSABKAkSFQoNdGFyZ2V0X2FuY2hvchgGIAEoCRIXCg90YXJnZXRfYXNzZXRfaWQYByABKAkSIwobdGFyZ2V0X2JsdWVwcmludF9yZWxlYXNlX2lkGAggASgJEhYKDnBpbl9yZWxlYXNlX2lkGAkgASgJEhMKC3BhcmVudF9wYXRoGAogASgJEhQKDGhhc19wb3NpdGlvbhgLIAEoCBIQCghwb3NpdGlvbhgMIAEoBSJLCglJbkZvcmNlQXQSEAoIdmFsaWRfb24YASABKAkSLAoIa25vd25fYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIsYBChVMaXN0UmVmZXJlbmNlc1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIVCgtyZXZpc2lvbl9pZBgCIAEoCUgAEhQKCnJlbGVhc2VfaWQYAyABKAlIABIvCgtpbl9mb3JjZV9hdBgEIAEoCzIYLmNvbnRlbnRodWIudjEuSW5Gb3JjZUF0SAASJgoFa2luZHMYBSADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kEg0KBWRlcHRoGAYgASgFQgQKAmF0IkYKFkxpc3RSZWZlcmVuY2VzUmVzcG9uc2USLAoKcmVmZXJlbmNlcxgBIAMoCzIYLmNvbnRlbnRodWIudjEuUmVmZXJlbmNlIlgKCVJlZmVyZW5jZRIhCgRlZGdlGAEgASgLMhMuY29udGVudGh1Yi52MS5FZGdlEg0KBWRlcHRoGAIgASgFEhkKEXNvdXJjZV9yZWxlYXNlX2lkGAMgASgJItEBChRMaXN0UmVmZXJyZXJzUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEg4KBmFuY2hvchgCIAEoCRImCgVraW5kcxgDIAMoDjIXLmNvbnRlbnRodWIudjEuRWRnZUtpbmQSJAoCYXQYBCABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIgChhpbmNsdWRlX29wZW5fY2hhbmdlX3NldHMYBSABKAgSEQoJcGFnZV9zaXplGAYgASgFEhIKCnBhZ2VfdG9rZW4YByABKAkiXAoVTGlzdFJlZmVycmVyc1Jlc3BvbnNlEioKCXJlZmVycmVycxgBIAMoCzIXLmNvbnRlbnRodWIudjEuUmVmZXJyZXISFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJImsKCFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCRIVCg1jaGFuZ2Vfc2V0X2lkGAMgASgJEhEKCWJyYW5jaF9pZBgEIAEoCSqeAgoIRWRnZUtpbmQSGQoVRURHRV9LSU5EX1VOU1BFQ0lGSUVEEAASFwoTRURHRV9LSU5EX1JFRkVSRU5DRRABEhEKDUVER0VfS0lORF9UT0MQAhIVChFFREdFX0tJTkRfSU5DTFVERRADEhUKEUVER0VfS0lORF9FWENMVURFEAQSFQoRRURHRV9LSU5EX1JFUExBQ0UQBRIWChJFREdFX0tJTkRfQU5OT1RBVEUQBhISCg5FREdFX0tJTkRfTElOSxAHEhYKEkVER0VfS0lORF9GT09UTk9URRAIEhQKEEVER0VfS0lORF9BTkNIT1IQCRITCg9FREdFX0tJTkRfTUVESUEQChIXChNFREdFX0tJTkRfQkxVRVBSSU5UEAtCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_timestamp]);\n\n/**\n * Edge is one edge of one Revision.\n *\n * @generated from message contenthub.v1.Edge\n */\nexport type Edge = Message<\"contenthub.v1.Edge\"> & {\n /**\n * The Content and Revision holding the edge.\n *\n * @generated from field: string source_content_id = 1;\n */\n sourceContentId: string;\n\n /**\n * @generated from field: string source_revision_id = 2;\n */\n sourceRevisionId: string;\n\n /**\n * fieldkit's Path of the value the edge comes from, each row as its _id\n * (\"/sections/r1/image\"); empty for the blueprint edge.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * @generated from field: contenthub.v1.EdgeKind kind = 4;\n */\n kind: EdgeKind;\n\n /**\n * What it points at: exactly one of target_content_id, target_asset_id and\n * target_blueprint_release_id is set.\n *\n * @generated from field: string target_content_id = 5;\n */\n targetContentId: string;\n\n /**\n * The Anchor (a node id) a link names inside target_content_id.\n *\n * @generated from field: string target_anchor = 6;\n */\n targetAnchor: string;\n\n /**\n * @generated from field: string target_asset_id = 7;\n */\n targetAssetId: string;\n\n /**\n * @generated from field: string target_blueprint_release_id = 8;\n */\n targetBlueprintReleaseId: string;\n\n /**\n * The Release of target_content_id the edge is pinned to; empty when it\n * follows the Release In Force.\n *\n * @generated from field: string pin_release_id = 9;\n */\n pinReleaseId: string;\n\n /**\n * For a node of a reference tree (the TOC Field's above all): the Path of\n * its parent node, empty at the top of the tree, and its index among its\n * siblings. has_position is false for an edge that is no tree node.\n *\n * @generated from field: string parent_path = 10;\n */\n parentPath: string;\n\n /**\n * @generated from field: bool has_position = 11;\n */\n hasPosition: boolean;\n\n /**\n * @generated from field: int32 position = 12;\n */\n position: number;\n};\n\n/**\n * Describes the message contenthub.v1.Edge.\n * Use `create(EdgeSchema)` to create a new message.\n */\nexport const EdgeSchema: GenMessage<Edge> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 0);\n\n/**\n * InForceAt is a date and a moment to read In Force at (CONTEXT.md).\n *\n * @generated from message contenthub.v1.InForceAt\n */\nexport type InForceAt = Message<\"contenthub.v1.InForceAt\"> & {\n /**\n * The day, as YYYY-MM-DD in the workspace's time zone; empty for today.\n *\n * @generated from field: string valid_on = 1;\n */\n validOn: string;\n\n /**\n * The moment the state was known at; unset for now.\n *\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.InForceAt.\n * Use `create(InForceAtSchema)` to create a new message.\n */\nexport const InForceAtSchema: GenMessage<InForceAt> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 1);\n\n/**\n * @generated from message contenthub.v1.ListReferencesRequest\n */\nexport type ListReferencesRequest = Message<\"contenthub.v1.ListReferencesRequest\"> & {\n /**\n * The Content whose outgoing edges to read.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Which of its Revisions: one by id, the one a Release pins, or the one\n * its Release In Force pins. Exactly one is required.\n *\n * @generated from oneof contenthub.v1.ListReferencesRequest.at\n */\n at: {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | {\n /**\n * @generated from field: string release_id = 3;\n */\n value: string;\n case: \"releaseId\";\n } | {\n /**\n * @generated from field: contenthub.v1.InForceAt in_force_at = 4;\n */\n value: InForceAt;\n case: \"inForceAt\";\n } | { case: undefined; value?: undefined };\n\n /**\n * Only edges of these kinds, at every depth; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 5;\n */\n kinds: EdgeKind[];\n\n /**\n * How far to follow edges into the Content they point at: 1 (0 means 1)\n * reads the Revision's own edges, 2 also those of each target, and so on,\n * at most 8. With kinds [TOC] it reads a TOC subtree.\n *\n * A target is read at the Release an edge pins, or else at its Release In\n * Force: at in_force_at; for release_id, on the first day of that\n * Release's Validity Period (for undated Content, the day of its Publish\n * Time) as known now; for revision_id, today as known now. A target\n * already on the way there is not entered again. A footnote edge is\n * listed but not followed: a Footnote Body is read at its citer's Release\n * coordinates, never at these (ADR 0009 as amended).\n *\n * @generated from field: int32 depth = 6;\n */\n depth: number;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferencesRequest.\n * Use `create(ListReferencesRequestSchema)` to create a new message.\n */\nexport const ListReferencesRequestSchema: GenMessage<ListReferencesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 2);\n\n/**\n * @generated from message contenthub.v1.ListReferencesResponse\n */\nexport type ListReferencesResponse = Message<\"contenthub.v1.ListReferencesResponse\"> & {\n /**\n * In walk order: the Revision's own edges in their order, each followed by\n * the edges of its target.\n *\n * @generated from field: repeated contenthub.v1.Reference references = 1;\n */\n references: Reference[];\n};\n\n/**\n * Describes the message contenthub.v1.ListReferencesResponse.\n * Use `create(ListReferencesResponseSchema)` to create a new message.\n */\nexport const ListReferencesResponseSchema: GenMessage<ListReferencesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 3);\n\n/**\n * Reference is one edge ListReferences reached.\n *\n * @generated from message contenthub.v1.Reference\n */\nexport type Reference = Message<\"contenthub.v1.Reference\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * 1 for the Revision's own edges, 2 for its targets' edges, and so on.\n *\n * @generated from field: int32 depth = 2;\n */\n depth: number;\n\n /**\n * The Release of edge.source_content_id it was read at: the Release\n * named, or In Force, or that an edge pinned; empty for the edges of a\n * Revision read by its id.\n *\n * @generated from field: string source_release_id = 3;\n */\n sourceReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Reference.\n * Use `create(ReferenceSchema)` to create a new message.\n */\nexport const ReferenceSchema: GenMessage<Reference> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 4);\n\n/**\n * @generated from message contenthub.v1.ListReferrersRequest\n */\nexport type ListReferrersRequest = Message<\"contenthub.v1.ListReferrersRequest\"> & {\n /**\n * The Content pointed at.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only edges naming this Anchor inside it; empty for every edge to the\n * Content, Anchor or not.\n *\n * @generated from field: string anchor = 2;\n */\n anchor: string;\n\n /**\n * Only edges of these kinds; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 3;\n */\n kinds: EdgeKind[];\n\n /**\n * Releases In Force at this date and moment are searched; unset is today,\n * as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 4;\n */\n at?: InForceAt | undefined;\n\n /**\n * Also search the head of every Branch of every open Change Set.\n *\n * @generated from field: bool include_open_change_sets = 5;\n */\n includeOpenChangeSets: boolean;\n\n /**\n * 0 means 100; above 1000 reads as 1000.\n *\n * @generated from field: int32 page_size = 6;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page, asked with the same other\n * fields; empty for the first.\n *\n * @generated from field: string page_token = 7;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferrersRequest.\n * Use `create(ListReferrersRequestSchema)` to create a new message.\n */\nexport const ListReferrersRequestSchema: GenMessage<ListReferrersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 5);\n\n/**\n * @generated from message contenthub.v1.ListReferrersResponse\n */\nexport type ListReferrersResponse = Message<\"contenthub.v1.ListReferrersResponse\"> & {\n /**\n * Those found in Releases first, then those in open Change Sets, each\n * ordered by the referring Content (in a Change Set, then by Change Set\n * and Branch) and its edge order. A page leaves out the referrers the\n * caller may not see without coming up short for them.\n *\n * @generated from field: repeated contenthub.v1.Referrer referrers = 1;\n */\n referrers: Referrer[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferrersResponse.\n * Use `create(ListReferrersResponseSchema)` to create a new message.\n */\nexport const ListReferrersResponseSchema: GenMessage<ListReferrersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 6);\n\n/**\n * Referrer is one incoming edge, and where it was found.\n *\n * @generated from message contenthub.v1.Referrer\n */\nexport type Referrer = Message<\"contenthub.v1.Referrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release In Force that pins edge.source_revision_id; empty when\n * found in a Change Set.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * The open Change Set and Branch whose head is edge.source_revision_id;\n * empty when found in a Release.\n *\n * @generated from field: string change_set_id = 3;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Referrer.\n * Use `create(ReferrerSchema)` to create a new message.\n */\nexport const ReferrerSchema: GenMessage<Referrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 7);\n\n/**\n * EdgeKind is what an edge is, and which kind of value it comes from.\n *\n * @generated from enum contenthub.v1.EdgeKind\n */\nexport enum EdgeKind {\n /**\n * @generated from enum value: EDGE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * From a reference field.\n *\n * @generated from enum value: EDGE_KIND_REFERENCE = 1;\n */\n REFERENCE = 1,\n\n /**\n * From the Blueprint's TOC Field: the Content's children.\n *\n * @generated from enum value: EDGE_KIND_TOC = 2;\n */\n TOC = 2,\n\n /**\n * From a Title's manipulation tree (and EXCLUDE also from a\n * reference_filter).\n *\n * @generated from enum value: EDGE_KIND_INCLUDE = 3;\n */\n INCLUDE = 3,\n\n /**\n * @generated from enum value: EDGE_KIND_EXCLUDE = 4;\n */\n EXCLUDE = 4,\n\n /**\n * @generated from enum value: EDGE_KIND_REPLACE = 5;\n */\n REPLACE = 5,\n\n /**\n * @generated from enum value: EDGE_KIND_ANNOTATE = 6;\n */\n ANNOTATE = 6,\n\n /**\n * From a content link in rich text, with an optional Anchor. An internal\n * link names a node in the same document and is no edge.\n *\n * @generated from enum value: EDGE_KIND_LINK = 7;\n */\n LINK = 7,\n\n /**\n * From a footnote in rich text, to the Content holding its body.\n *\n * @generated from enum value: EDGE_KIND_FOOTNOTE = 8;\n */\n FOOTNOTE = 8,\n\n /**\n * From a typesetting instruction, to the node it is anchored at.\n *\n * @generated from enum value: EDGE_KIND_ANCHOR = 9;\n */\n ANCHOR = 9,\n\n /**\n * From a media field or an image in rich text, to a mediahub Asset.\n *\n * @generated from enum value: EDGE_KIND_MEDIA = 10;\n */\n MEDIA = 10,\n\n /**\n * To the Blueprint Release the Revision pins.\n *\n * @generated from enum value: EDGE_KIND_BLUEPRINT = 11;\n */\n BLUEPRINT = 11,\n}\n\n/**\n * Describes the enum contenthub.v1.EdgeKind.\n */\nexport const EdgeKindSchema: GenEnum<EdgeKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_content_graph, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/release.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/release.proto.\n */\nexport const file_contenthub_v1_release: GenFile = /*@__PURE__*/\n fileDesc(\"Chtjb250ZW50aHViL3YxL3JlbGVhc2UucHJvdG8SDWNvbnRlbnRodWIudjEiNQoOVmFsaWRpdHlQZXJpb2QSEQoJZmlyc3RfZGF5GAEgASgJEhAKCGxhc3RfZGF5GAIgASgJIu0CCg5QbGFubmVkUmVsZWFzZRIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEigKBGtpbmQYAyABKA4yGi5jb250ZW50aHViLnYxLlJlbGVhc2VLaW5kEhEKCWJyYW5jaF9pZBgEIAEoCRITCgtyZXZpc2lvbl9pZBgFIAEoCRI2Cg92YWxpZGl0eV9wZXJpb2QYBiABKAsyHS5jb250ZW50aHViLnYxLlZhbGlkaXR5UGVyaW9kEi0KDHJlbGVhc2Vfc3BlYxgHIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSHgoWc3VwZXJzZWRlc19yZWxlYXNlX2lkcxgIIAMoCRIQCghwcm9wb3NlZBgJIAEoCBIfChdwcm9wb3NlZF9mb3JfcmVsZWFzZV9pZBgKIAEoCRIdChVzcGxpdF9mcm9tX3JlbGVhc2VfaWQYCyABKAkSEAoId2l0aGhlbGQYDCABKAgiJAoNUmVsZWFzZUlkTGlzdBITCgtyZWxlYXNlX2lkcxgBIAMoCSLhAgoHUmVsZWFzZRIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEigKBGtpbmQYAyABKA4yGi5jb250ZW50aHViLnYxLlJlbGVhc2VLaW5kEhEKCWJyYW5jaF9pZBgEIAEoCRITCgtyZXZpc2lvbl9pZBgFIAEoCRIcChRibHVlcHJpbnRfcmVsZWFzZV9pZBgGIAEoCRINCgVmaXJzdBgHIAEoCBIeChZzdXBlcnNlZGVzX3JlbGVhc2VfaWRzGAggAygJEjYKD3ZhbGlkaXR5X3BlcmlvZBgJIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSLQoMcmVsZWFzZV9zcGVjGAogASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIwCgxwdWJsaXNoX3RpbWUYCyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIu4CCg5QdWJsaXNoQmxvY2tlchIMCgRjb2RlGAEgASgJEhIKCmNvbnRlbnRfaWQYAiABKAkSEQoJYnJhbmNoX2lkGAMgASgJEhgKEGV4cGVjdGVkX2hlYWRfaWQYBCABKAkSFwoPY3VycmVudF9oZWFkX2lkGAUgASgJEhIKCnJlbGVhc2VfaWQYBiABKAkSGwoTb3ZlcmxhcHNfcmVsZWFzZV9pZBgHIAEoCRIgChhkZXBlbmRlbmN5X2NoYW5nZV9zZXRfaWQYCCABKAkSDAoEcGF0aBgJIAEoCRIZChF0YXJnZXRfY29udGVudF9pZBgKIAEoCRIQCghhc3NldF9pZBgLIAEoCRIaChJwYXJlbnRfY29udGVudF9pZHMYDCADKAkSGQoRcmVxdWlyZWRfY2hlY2tfaWQYDSABKAkSGgoSY292ZXJlZF9yZWxlYXNlX2lkGA4gASgJEhMKC3JldmlzaW9uX2lkGA8gASgJKpgBCgtSZWxlYXNlS2luZBIcChhSRUxFQVNFX0tJTkRfVU5TUEVDSUZJRUQQABIZChVSRUxFQVNFX0tJTkRfUkVWSVNJT04QARIaChZSRUxFQVNFX0tJTkRfREFURV9PTkxZEAISFwoTUkVMRUFTRV9LSU5EX1JFUEVBTBADEhsKF1JFTEVBU0VfS0lORF9XSVRIRFJBV0FMEARCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * ValidityPeriod is the span of calendar days a Release of Dated Content is\n * In Force (CONTEXT.md): a first day, and a last day if one is known, both\n * included, as days of the workspace's time zone. Releases of undated Content\n * carry none.\n *\n * @generated from message contenthub.v1.ValidityPeriod\n */\nexport type ValidityPeriod = Message<\"contenthub.v1.ValidityPeriod\"> & {\n /**\n * The first day, as YYYY-MM-DD.\n *\n * @generated from field: string first_day = 1;\n */\n firstDay: string;\n\n /**\n * The last day, as YYYY-MM-DD; empty for an open end. A planned open end\n * stays open until Publish, which ends it the day before the next later\n * Release In Force then starts.\n *\n * @generated from field: string last_day = 2;\n */\n lastDay: string;\n};\n\n/**\n * Describes the message contenthub.v1.ValidityPeriod.\n * Use `create(ValidityPeriodSchema)` to create a new message.\n */\nexport const ValidityPeriodSchema: GenMessage<ValidityPeriod> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 0);\n\n/**\n * PlannedRelease is a Release a Change Set will cut when it is published,\n * with its Validity Period and Release Spec values set and reviewable\n * beforehand (CONTEXT.md). Its id is the Release's id from the moment it is\n * planned.\n *\n * @generated from message contenthub.v1.PlannedRelease\n */\nexport type PlannedRelease = Message<\"contenthub.v1.PlannedRelease\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The editorial Branch whose head at Publish it pins; empty for a\n * Branch-less kind.\n *\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n\n /**\n * The Revision a Branch-less kind re-pins; empty for a Branch's Release.\n *\n * @generated from field: string revision_id = 5;\n */\n revisionId: string;\n\n /**\n * Absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 6;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Its Release Spec values, keyed by the Release Spec Field's accessor.\n *\n * @generated from field: google.protobuf.Struct release_spec = 7;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Releases it will Supersede.\n *\n * @generated from field: repeated string supersedes_release_ids = 8;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Whether the Change Set proposed it, to end proposed_for_release_id, a\n * Release a planned Validity Period cuts into.\n *\n * @generated from field: bool proposed = 9;\n */\n proposed: boolean;\n\n /**\n * @generated from field: string proposed_for_release_id = 10;\n */\n proposedForReleaseId: string;\n\n /**\n * For a proposed tail, the Release it was split from: a Validity Period\n * planned strictly inside that Release proposes a cut ending it the day\n * before and this tail, which resumes its wording the day after that\n * Validity Period and supersedes nothing.\n *\n * @generated from field: string split_from_release_id = 11;\n */\n splitFromReleaseId: string;\n\n /**\n * For the proposal of a Carry-forward link, whether a plan of the Change\n * Set supersedes the Release it carries (a Repeal reaching it, say), so\n * that Publish doesn't cut it.\n *\n * @generated from field: bool withheld = 12;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.PlannedRelease.\n * Use `create(PlannedReleaseSchema)` to create a new message.\n */\nexport const PlannedReleaseSchema: GenMessage<PlannedRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 1);\n\n/**\n * ReleaseIdList is a list of Release ids that can be told apart from none\n * given.\n *\n * @generated from message contenthub.v1.ReleaseIdList\n */\nexport type ReleaseIdList = Message<\"contenthub.v1.ReleaseIdList\"> & {\n /**\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseIdList.\n * Use `create(ReleaseIdListSchema)` to create a new message.\n */\nexport const ReleaseIdListSchema: GenMessage<ReleaseIdList> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 2);\n\n/**\n * Release is one Release a Publish cut: immutable, pinning one Revision.\n *\n * @generated from message contenthub.v1.Release\n */\nexport type Release = Message<\"contenthub.v1.Release\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The editorial Branch whose head it pins; empty for a Withdrawal.\n *\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n\n /**\n * The Revision it pins, and the Blueprint Release that Revision pins.\n *\n * @generated from field: string revision_id = 5;\n */\n revisionId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 6;\n */\n blueprintReleaseId: string;\n\n /**\n * Whether it is the Content's first Release: the moment the Content\n * exists outside its Change Set.\n *\n * @generated from field: bool first = 7;\n */\n first: boolean;\n\n /**\n * The Releases it Supersedes from its Publish Time on.\n *\n * @generated from field: repeated string supersedes_release_ids = 8;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Its Validity Period, an open end resolved as Publish resolved it;\n * absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 9;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 10;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Its Publish Time; absent in ValidatePublish's would-be outcome, since a\n * Publish Time is stamped only when the Publish writes.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 11;\n */\n publishTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Release.\n * Use `create(ReleaseSchema)` to create a new message.\n */\nexport const ReleaseSchema: GenMessage<Release> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 3);\n\n/**\n * PublishBlocker is one reason a Publish is refused, or would be. Publish\n * lists every one at once, as FailedPrecondition details, and\n * ValidatePublish returns them, so the editor fixes everything in one pass\n * (ADR 0015). Which ids are set depends on the code.\n *\n * @generated from message contenthub.v1.PublishBlocker\n */\nexport type PublishBlocker = Message<\"contenthub.v1.PublishBlocker\"> & {\n /**\n * The reason. versionkit's, as it names them: moved_head,\n * unplanned_branch, several_branches, behind_base, superseded_release,\n * overlapping_periods, covers_release, pending_merge, nothing_in_force,\n * withdrawal_with_chain, dated_changed, unpublished_dependency or\n * discarded_dependency. contenthub's Content Graph's (ADR 0009):\n * dangling_pin (a pin naming a Release that won't exist),\n * second_toc_parent (a Content in the TOC of two Contents on the\n * resulting Main heads), missing_asset (a media edge to an Asset\n * mediahub says doesn't exist) and media_unavailable (mediahub refused\n * the caller's token, as for an org that doesn't license it, so no Asset\n * could be checked; once per Publish, naming nothing, and never beside a\n * missing_asset). contenthub's Required Checks' (ADR\n * 0014): outstanding_check (a check that applies lacks a latest passed\n * or waived result on the reviewed heads; for a Branch-scope check, on\n * branch_id's head or on the Revision Planned Release release_id\n * re-pins). contenthub's unversioned attributes' (ADR 0015):\n * blocked_content (a Content the Publish changes is blocked, and its\n * Block doesn't allow the caller) and archived_content (a Content the\n * Publish changes is Archived). contenthub's Footnote Bodies' (ADR 0009\n * as amended), each\n * against the resulting Main heads: footnote_body_citers (Footnote Body\n * content_id cited by more than one Content), footnote_body_edge (an\n * edge of another kind than footnote, a link with an Anchor say, from\n * content_id into Footnote Body target_content_id), footnote_body_alone\n * (Footnote Body content_id released without any of its citers),\n * footnote_body_born_elsewhere (a footnote of content_id into\n * target_content_id, which wasn't born in this Change Set) and\n * footnote_body_not_ended (Footnote Body content_id, which its citer\n * leaves, or ends, and which can't be Repealed or withdrawn with it).\n * contenthub's check of the released values (decision D1 of #176):\n * missing_required_field (a required Field left empty, at path, in\n * revision_id, a Revision of content_id the Publish releases; a save\n * allows it, Publish doesn't).\n *\n * @generated from field: string code = 1;\n */\n code: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 3;\n */\n branchId: string;\n\n /**\n * For moved_head, the head the caller reviewed (empty for a Branch the\n * reviewed heads left out) and the head now (empty for a reviewed Branch\n * that isn't the Change Set's). For behind_base, the upstream Revision\n * the Branch last took in and the upstream's head now.\n *\n * @generated from field: string expected_head_id = 4;\n */\n expectedHeadId: string;\n\n /**\n * @generated from field: string current_head_id = 5;\n */\n currentHeadId: string;\n\n /**\n * For superseded_release, the Release superseded already; for\n * overlapping_periods, the Release to cut and the one it overlaps; for\n * covers_release, the Planned Release whose Validity Period covers\n * covered_release_id; for dangling_pin, the Release the pin names.\n *\n * @generated from field: string release_id = 6;\n */\n releaseId: string;\n\n /**\n * @generated from field: string overlaps_release_id = 7;\n */\n overlapsReleaseId: string;\n\n /**\n * For unpublished_dependency and discarded_dependency, the Change Set\n * depended on.\n *\n * @generated from field: string dependency_change_set_id = 8;\n */\n dependencyChangeSetId: string;\n\n /**\n * For dangling_pin, missing_asset, footnote_body_edge and\n * footnote_body_born_elsewhere, fieldkit's Path of the value in\n * content_id's head the edge comes from. For missing_required_field,\n * fieldkit's Path of the empty Field.\n *\n * @generated from field: string path = 9;\n */\n path: string;\n\n /**\n * For dangling_pin, the Content the pin points at; release_id is the\n * Release it names. For footnote_body_edge and\n * footnote_body_born_elsewhere, the Footnote Body.\n *\n * @generated from field: string target_content_id = 10;\n */\n targetContentId: string;\n\n /**\n * For missing_asset, the Asset.\n *\n * @generated from field: string asset_id = 11;\n */\n assetId: string;\n\n /**\n * For second_toc_parent, every Content whose TOC holds content_id on\n * the resulting Main heads, ordered by id. For footnote_body_citers and\n * footnote_body_alone, every Content citing Footnote Body content_id,\n * ordered by id; for footnote_body_not_ended, the citer that left or\n * ended it.\n *\n * @generated from field: repeated string parent_content_ids = 12;\n */\n parentContentIds: string[];\n\n /**\n * For outstanding_check, the Required Check.\n *\n * @generated from field: string required_check_id = 13;\n */\n requiredCheckId: string;\n\n /**\n * For covers_release, the published Release whose Validity Period\n * release_id's covers entirely: one another Change Set published after\n * this one was planned, or one a Repeal reaches. Publish never re-plans;\n * a replan in the Change Set supersedes it, or changes the dates.\n *\n * @generated from field: string covered_release_id = 14;\n */\n coveredReleaseId: string;\n\n /**\n * For missing_required_field, the Revision that leaves the Field empty:\n * a head the Publish releases.\n *\n * @generated from field: string revision_id = 15;\n */\n revisionId: string;\n};\n\n/**\n * Describes the message contenthub.v1.PublishBlocker.\n * Use `create(PublishBlockerSchema)` to create a new message.\n */\nexport const PublishBlockerSchema: GenMessage<PublishBlocker> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 4);\n\n/**\n * ReleaseKind says how a Release came to be (ADR 0016).\n *\n * @generated from enum contenthub.v1.ReleaseKind\n */\nexport enum ReleaseKind {\n /**\n * @generated from enum value: RELEASE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Cut of an editorial Branch's head.\n *\n * @generated from enum value: RELEASE_KIND_REVISION = 1;\n */\n REVISION = 1,\n\n /**\n * Re-pins an existing Release's Revision with a corrected Validity Period.\n *\n * @generated from enum value: RELEASE_KIND_DATE_ONLY = 2;\n */\n DATE_ONLY = 2,\n\n /**\n * Ends a Dated Content's force, leaving a gap.\n *\n * @generated from enum value: RELEASE_KIND_REPEAL = 3;\n */\n REPEAL = 3,\n\n /**\n * Ends an undated Content's force.\n *\n * @generated from enum value: RELEASE_KIND_WITHDRAWAL = 4;\n */\n WITHDRAWAL = 4,\n}\n\n/**\n * Describes the enum contenthub.v1.ReleaseKind.\n */\nexport const ReleaseKindSchema: GenEnum<ReleaseKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_release, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/release_read.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Edge, EdgeKind, InForceAt } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { PlannedRelease, ReleaseKind, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/release_read.proto.\n */\nexport const file_contenthub_v1_release_read: GenFile = /*@__PURE__*/\n fileDesc(\"CiBjb250ZW50aHViL3YxL3JlbGVhc2VfcmVhZC5wcm90bxINY29udGVudGh1Yi52MSKqBAoPUmVsZWFzZWRDb250ZW50EhIKCnJlbGVhc2VfaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIoCgRraW5kGAMgASgOMhouY29udGVudGh1Yi52MS5SZWxlYXNlS2luZBITCgtyZXZpc2lvbl9pZBgEIAEoCRIUCgxibHVlcHJpbnRfaWQYBSABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYBiABKAkSDQoFZmlyc3QYByABKAgSNgoPdmFsaWRpdHlfcGVyaW9kGAggASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYCSABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKDHB1Ymxpc2hfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASIAoYc3VwZXJzZWRlZF9ieV9yZWxlYXNlX2lkGAsgASgJEjIKDnN1cGVyc2VkZV90aW1lGAwgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIPCgdwbGFubmVkGA0gASgIEiUKBGRhdGEYDiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjQKCnJlZmVyZW5jZXMYDyADKAsyIC5jb250ZW50aHViLnYxLlJlc29sdmVkUmVmZXJlbmNlEhAKCHdpdGhoZWxkGBAgASgIIoYBChFSZXNvbHZlZFJlZmVyZW5jZRIhCgRlZGdlGAEgASgLMhMuY29udGVudGh1Yi52MS5FZGdlEg0KBWRlcHRoGAIgASgFEhkKEXNvdXJjZV9yZWxlYXNlX2lkGAMgASgJEhIKCnJlbGVhc2VfaWQYBCABKAkSEAoId2l0aGhlbGQYBSABKAgiRAoLUmVsZWFzZVJlYWQSDQoFZGVwdGgYASABKAUSJgoFa2luZHMYAiADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kIqoBChJMaXN0SW5Gb3JjZVJlcXVlc3QSJAoCYXQYASABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIdChVwcmV2aWV3X2NoYW5nZV9zZXRfaWQYAiABKAkSKAoEcmVhZBgDIAEoCzIaLmNvbnRlbnRodWIudjEuUmVsZWFzZVJlYWQSEQoJcGFnZV9zaXplGAQgASgFEhIKCnBhZ2VfdG9rZW4YBSABKAkilAEKE0xpc3RJbkZvcmNlUmVzcG9uc2USMAoIY29udGVudHMYASADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudBIyCgpyZWZlcmVuY2VkGAIgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQSFwoPbmV4dF9wYWdlX3Rva2VuGAMgASgJIpcBChFHZXRJbkZvcmNlUmVxdWVzdBITCgtjb250ZW50X2lkcxgBIAMoCRIkCgJhdBgCIAEoCzIYLmNvbnRlbnRodWIudjEuSW5Gb3JjZUF0Eh0KFXByZXZpZXdfY2hhbmdlX3NldF9pZBgDIAEoCRIoCgRyZWFkGAQgASgLMhouY29udGVudGh1Yi52MS5SZWxlYXNlUmVhZCJ6ChJHZXRJbkZvcmNlUmVzcG9uc2USMAoIY29udGVudHMYASADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudBIyCgpyZWZlcmVuY2VkGAIgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQihwEKIFJlbGVhc2VTZXJ2aWNlR2V0UmVsZWFzZXNSZXF1ZXN0EhMKC3JlbGVhc2VfaWRzGAEgAygJEiQKAmF0GAIgASgLMhguY29udGVudGh1Yi52MS5JbkZvcmNlQXQSKAoEcmVhZBgDIAEoCzIaLmNvbnRlbnRodWIudjEuUmVsZWFzZVJlYWQiiQEKIVJlbGVhc2VTZXJ2aWNlR2V0UmVsZWFzZXNSZXNwb25zZRIwCghyZWxlYXNlcxgBIAMoCzIeLmNvbnRlbnRodWIudjEuUmVsZWFzZWRDb250ZW50EjIKCnJlZmVyZW5jZWQYAiADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudCJkCiBSZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEiwKCGtub3duX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJSCiFSZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVzcG9uc2USLQoHZW50cmllcxgBIAMoCzIcLmNvbnRlbnRodWIudjEuVGltZWxpbmVFbnRyeSK5AgoNVGltZWxpbmVFbnRyeRIPCgdvcmRpbmFsGAEgASgFEhIKCnJlbGVhc2VfaWQYAiABKAkSKAoEa2luZBgDIAEoDjIaLmNvbnRlbnRodWIudjEuUmVsZWFzZUtpbmQSEwoLcmV2aXNpb25faWQYBCABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYBSABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAYgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYByABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKDHB1Ymxpc2hfdGltZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDQoFZmlyc3QYCSABKAgivQEKIlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIOCgZhbmNob3IYAiABKAkSJgoFa2luZHMYAyADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kEiQKAmF0GAQgASgLMhguY29udGVudGh1Yi52MS5JbkZvcmNlQXQSEQoJcGFnZV9zaXplGAUgASgFEhIKCnBhZ2VfdG9rZW4YBiABKAkicgojUmVsZWFzZVNlcnZpY2VMaXN0UmVmZXJyZXJzUmVzcG9uc2USMgoJcmVmZXJyZXJzGAEgAygLMh8uY29udGVudGh1Yi52MS5SZWxlYXNlZFJlZmVycmVyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSJJChBSZWxlYXNlZFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCSJ5ChJHZXRSZWxlYXNlc1JlcXVlc3QSEwoLcmVsZWFzZV9pZHMYASADKAkSJAoCYXQYAiABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIoCgRyZWFkGAMgASgLMhouY29udGVudGh1Yi52MS5SZWxlYXNlUmVhZCJ7ChNHZXRSZWxlYXNlc1Jlc3BvbnNlEjAKCHJlbGVhc2VzGAEgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQSMgoKcmVmZXJlbmNlZBgCIAMoCzIeLmNvbnRlbnRodWIudjEuUmVsZWFzZWRDb250ZW50IlYKEkdldFRpbWVsaW5lUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEiwKCGtub3duX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKGAQoTR2V0VGltZWxpbmVSZXNwb25zZRItCgdlbnRyaWVzGAEgAygLMhwuY29udGVudGh1Yi52MS5UaW1lbGluZUVudHJ5EkAKEHBsYW5uZWRfcmVsZWFzZXMYAiADKAsyJi5jb250ZW50aHViLnYxLkNoYW5nZVNldFBsYW5uZWRSZWxlYXNlImgKF0NoYW5nZVNldFBsYW5uZWRSZWxlYXNlEhUKDWNoYW5nZV9zZXRfaWQYASABKAkSNgoPcGxhbm5lZF9yZWxlYXNlGAIgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZTKVBAoOUmVsZWFzZVNlcnZpY2USVAoLTGlzdEluRm9yY2USIS5jb250ZW50aHViLnYxLkxpc3RJbkZvcmNlUmVxdWVzdBoiLmNvbnRlbnRodWIudjEuTGlzdEluRm9yY2VSZXNwb25zZRJRCgpHZXRJbkZvcmNlEiAuY29udGVudGh1Yi52MS5HZXRJbkZvcmNlUmVxdWVzdBohLmNvbnRlbnRodWIudjEuR2V0SW5Gb3JjZVJlc3BvbnNlEnAKC0dldFJlbGVhc2VzEi8uY29udGVudGh1Yi52MS5SZWxlYXNlU2VydmljZUdldFJlbGVhc2VzUmVxdWVzdBowLmNvbnRlbnRodWIudjEuUmVsZWFzZVNlcnZpY2VHZXRSZWxlYXNlc1Jlc3BvbnNlEnAKC0dldFRpbWVsaW5lEi8uY29udGVudGh1Yi52MS5SZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVxdWVzdBowLmNvbnRlbnRodWIudjEuUmVsZWFzZVNlcnZpY2VHZXRUaW1lbGluZVJlc3BvbnNlEnYKDUxpc3RSZWZlcnJlcnMSMS5jb250ZW50aHViLnYxLlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1JlcXVlc3QaMi5jb250ZW50aHViLnYxLlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1Jlc3BvbnNlQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_contenthub_v1_content_graph, file_contenthub_v1_release, file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * ReleasedContent is one Release, with the data of the Revision it pins.\n *\n * @generated from message contenthub.v1.ReleasedContent\n */\nexport type ReleasedContent = Message<\"contenthub.v1.ReleasedContent\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The Revision the Release pins; in a Preview's planned row, the Branch\n * head it would pin if published now.\n *\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * The Blueprint, and the Blueprint Release the Revision pins.\n *\n * @generated from field: string blueprint_id = 5;\n */\n blueprintId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 6;\n */\n blueprintReleaseId: string;\n\n /**\n * Whether it is the Content's first Release.\n *\n * @generated from field: bool first = 7;\n */\n first: boolean;\n\n /**\n * Absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 8;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 9;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Its Publish Time; for a planned row, the earliest the next Publish\n * could get.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 10;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * The Release that supersedes it, and that one's Publish Time, as known at\n * the read's known_at; empty while it isn't superseded then.\n *\n * @generated from field: string superseded_by_release_id = 11;\n */\n supersededByReleaseId: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp supersede_time = 12;\n */\n supersedeTime?: Timestamp | undefined;\n\n /**\n * Whether it is a Preview's Planned Release, read as if published now.\n *\n * @generated from field: bool planned = 13;\n */\n planned: boolean;\n\n /**\n * The Revision's data, a JSON object keyed by field accessor.\n *\n * @generated from field: google.protobuf.Struct data = 14;\n */\n data?: JsonObject | undefined;\n\n /**\n * Its References, resolved to the depth asked for, in walk order: each\n * edge followed by the edges of the Release it resolved to.\n *\n * @generated from field: repeated contenthub.v1.ResolvedReference references = 15;\n */\n references: ResolvedReference[];\n\n /**\n * In a Preview, whether this Content is Restricted (ADR 0017) and the\n * caller is not granted on it: the row is then its Release In Force\n * without the Preview, and what the Change Set does to it is withheld.\n *\n * @generated from field: bool withheld = 16;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.ReleasedContent.\n * Use `create(ReleasedContentSchema)` to create a new message.\n */\nexport const ReleasedContentSchema: GenMessage<ReleasedContent> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 0);\n\n/**\n * ResolvedReference is one edge from a Release's Revision to another Content,\n * and the Release of that Content it resolves to at the read's coordinates.\n *\n * @generated from message contenthub.v1.ResolvedReference\n */\nexport type ResolvedReference = Message<\"contenthub.v1.ResolvedReference\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * 1 for the Release's own edges, 2 for those of the Release an edge\n * resolved to, and so on.\n *\n * @generated from field: int32 depth = 2;\n */\n depth: number;\n\n /**\n * The Release whose Revision holds the edge.\n *\n * @generated from field: string source_release_id = 3;\n */\n sourceReleaseId: string;\n\n /**\n * The Release of edge.target_content_id it resolves to: the one the edge\n * pins, or else the one In Force at the read's coordinates. Empty when\n * none is In Force then, and for a footnote, whose Footnote Body is read\n * at its citer's Release coordinates (ADR 0009 as amended).\n *\n * @generated from field: string release_id = 4;\n */\n releaseId: string;\n\n /**\n * In a Preview, whether the target is Restricted Content the Preview\n * changes and the caller is not granted on (ADR 0017): it resolves to\n * edge.target_content_id and nothing more, release_id is empty, and the\n * walk does not go through it.\n *\n * @generated from field: bool withheld = 5;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.ResolvedReference.\n * Use `create(ResolvedReferenceSchema)` to create a new message.\n */\nexport const ResolvedReferenceSchema: GenMessage<ResolvedReference> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 1);\n\n/**\n * ReleaseRead is how deep a read resolves References, and which.\n *\n * @generated from message contenthub.v1.ReleaseRead\n */\nexport type ReleaseRead = Message<\"contenthub.v1.ReleaseRead\"> & {\n /**\n * 0 resolves none; 1 resolves each Release's own References; 2 also those\n * of the Releases they resolve to; and so on, at most 8. A Content\n * already on the way is not entered again.\n *\n * @generated from field: int32 depth = 1;\n */\n depth: number;\n\n /**\n * Only References of these kinds, at every depth; empty for every kind\n * that points at Content.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 2;\n */\n kinds: EdgeKind[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseRead.\n * Use `create(ReleaseReadSchema)` to create a new message.\n */\nexport const ReleaseReadSchema: GenMessage<ReleaseRead> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 2);\n\n/**\n * @generated from message contenthub.v1.ListInForceRequest\n */\nexport type ListInForceRequest = Message<\"contenthub.v1.ListInForceRequest\"> & {\n /**\n * The date and moment to read at; unset is today, as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 1;\n */\n at?: InForceAt | undefined;\n\n /**\n * An open Change Set to Preview: it, and the open Change Sets it depends\n * on, read as if published now. User tokens only; an API key is\n * PermissionDenied.\n *\n * @generated from field: string preview_change_set_id = 2;\n */\n previewChangeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 4;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 5;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListInForceRequest.\n * Use `create(ListInForceRequestSchema)` to create a new message.\n */\nexport const ListInForceRequestSchema: GenMessage<ListInForceRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 3);\n\n/**\n * @generated from message contenthub.v1.ListInForceResponse\n */\nexport type ListInForceResponse = Message<\"contenthub.v1.ListInForceResponse\"> & {\n /**\n * By Content id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent contents = 1;\n */\n contents: ReleasedContent[];\n\n /**\n * The Releases References resolved to that aren't in contents, each once,\n * by Release id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 3;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListInForceResponse.\n * Use `create(ListInForceResponseSchema)` to create a new message.\n */\nexport const ListInForceResponseSchema: GenMessage<ListInForceResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 4);\n\n/**\n * @generated from message contenthub.v1.GetInForceRequest\n */\nexport type GetInForceRequest = Message<\"contenthub.v1.GetInForceRequest\"> & {\n /**\n * At most 200.\n *\n * @generated from field: repeated string content_ids = 1;\n */\n contentIds: string[];\n\n /**\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * As ListInForceRequest.preview_change_set_id.\n *\n * @generated from field: string preview_change_set_id = 3;\n */\n previewChangeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 4;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetInForceRequest.\n * Use `create(GetInForceRequestSchema)` to create a new message.\n */\nexport const GetInForceRequestSchema: GenMessage<GetInForceRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 5);\n\n/**\n * @generated from message contenthub.v1.GetInForceResponse\n */\nexport type GetInForceResponse = Message<\"contenthub.v1.GetInForceResponse\"> & {\n /**\n * By Content id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent contents = 1;\n */\n contents: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.GetInForceResponse.\n * Use `create(GetInForceResponseSchema)` to create a new message.\n */\nexport const GetInForceResponseSchema: GenMessage<GetInForceResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 6);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetReleasesRequest\n */\nexport type ReleaseServiceGetReleasesRequest = Message<\"contenthub.v1.ReleaseServiceGetReleasesRequest\"> & {\n /**\n * At most 200. An id that isn't a Release of the workspace is NotFound.\n *\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n\n /**\n * Where unpinned References resolve and supersede marks are read. Unset,\n * each Release's References resolve on the first day of its Validity\n * Period (for undated Content, the day of its Publish Time), as known now\n * (ADR 0009); a known_at alone keeps those days.\n *\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetReleasesRequest.\n * Use `create(ReleaseServiceGetReleasesRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceGetReleasesRequestSchema: GenMessage<ReleaseServiceGetReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 7);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetReleasesResponse\n */\nexport type ReleaseServiceGetReleasesResponse = Message<\"contenthub.v1.ReleaseServiceGetReleasesResponse\"> & {\n /**\n * In the order asked.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent releases = 1;\n */\n releases: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetReleasesResponse.\n * Use `create(ReleaseServiceGetReleasesResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceGetReleasesResponseSchema: GenMessage<ReleaseServiceGetReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 8);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetTimelineRequest\n */\nexport type ReleaseServiceGetTimelineRequest = Message<\"contenthub.v1.ReleaseServiceGetTimelineRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The moment to read it as known at; unset for now.\n *\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetTimelineRequest.\n * Use `create(ReleaseServiceGetTimelineRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceGetTimelineRequestSchema: GenMessage<ReleaseServiceGetTimelineRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 9);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetTimelineResponse\n */\nexport type ReleaseServiceGetTimelineResponse = Message<\"contenthub.v1.ReleaseServiceGetTimelineResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.TimelineEntry entries = 1;\n */\n entries: TimelineEntry[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetTimelineResponse.\n * Use `create(ReleaseServiceGetTimelineResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceGetTimelineResponseSchema: GenMessage<ReleaseServiceGetTimelineResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 10);\n\n/**\n * TimelineEntry is one Release of a Timeline, without its data.\n *\n * @generated from message contenthub.v1.TimelineEntry\n */\nexport type TimelineEntry = Message<\"contenthub.v1.TimelineEntry\"> & {\n /**\n * Its place in the Timeline, from 1.\n *\n * @generated from field: int32 ordinal = 1;\n */\n ordinal: number;\n\n /**\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 5;\n */\n blueprintReleaseId: string;\n\n /**\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 6;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 7;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp publish_time = 8;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * @generated from field: bool first = 9;\n */\n first: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.TimelineEntry.\n * Use `create(TimelineEntrySchema)` to create a new message.\n */\nexport const TimelineEntrySchema: GenMessage<TimelineEntry> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 11);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceListReferrersRequest\n */\nexport type ReleaseServiceListReferrersRequest = Message<\"contenthub.v1.ReleaseServiceListReferrersRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only edges naming this Anchor; empty for every edge to the Content.\n *\n * @generated from field: string anchor = 2;\n */\n anchor: string;\n\n /**\n * Only edges of these kinds; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 3;\n */\n kinds: EdgeKind[];\n\n /**\n * Unset is today, as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 4;\n */\n at?: InForceAt | undefined;\n\n /**\n * As ListReferrersRequest.page_size: 0 means 100; above 1000 reads as\n * 1000.\n *\n * @generated from field: int32 page_size = 5;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page, asked with the same other\n * fields; empty for the first.\n *\n * @generated from field: string page_token = 6;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceListReferrersRequest.\n * Use `create(ReleaseServiceListReferrersRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceListReferrersRequestSchema: GenMessage<ReleaseServiceListReferrersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 12);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceListReferrersResponse\n */\nexport type ReleaseServiceListReferrersResponse = Message<\"contenthub.v1.ReleaseServiceListReferrersResponse\"> & {\n /**\n * Ordered by the referring Content and its edge order.\n *\n * @generated from field: repeated contenthub.v1.ReleasedReferrer referrers = 1;\n */\n referrers: ReleasedReferrer[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceListReferrersResponse.\n * Use `create(ReleaseServiceListReferrersResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceListReferrersResponseSchema: GenMessage<ReleaseServiceListReferrersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 13);\n\n/**\n * ReleasedReferrer is one incoming edge, and the Release In Force whose\n * Revision holds it.\n *\n * @generated from message contenthub.v1.ReleasedReferrer\n */\nexport type ReleasedReferrer = Message<\"contenthub.v1.ReleasedReferrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleasedReferrer.\n * Use `create(ReleasedReferrerSchema)` to create a new message.\n */\nexport const ReleasedReferrerSchema: GenMessage<ReleasedReferrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 14);\n\n/**\n * @generated from message contenthub.v1.GetReleasesRequest\n */\nexport type GetReleasesRequest = Message<\"contenthub.v1.GetReleasesRequest\"> & {\n /**\n * As ReleaseServiceGetReleasesRequest.\n *\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n\n /**\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetReleasesRequest.\n * Use `create(GetReleasesRequestSchema)` to create a new message.\n */\nexport const GetReleasesRequestSchema: GenMessage<GetReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 15);\n\n/**\n * @generated from message contenthub.v1.GetReleasesResponse\n */\nexport type GetReleasesResponse = Message<\"contenthub.v1.GetReleasesResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent releases = 1;\n */\n releases: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.GetReleasesResponse.\n * Use `create(GetReleasesResponseSchema)` to create a new message.\n */\nexport const GetReleasesResponseSchema: GenMessage<GetReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 16);\n\n/**\n * @generated from message contenthub.v1.GetTimelineRequest\n */\nexport type GetTimelineRequest = Message<\"contenthub.v1.GetTimelineRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetTimelineRequest.\n * Use `create(GetTimelineRequestSchema)` to create a new message.\n */\nexport const GetTimelineRequestSchema: GenMessage<GetTimelineRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 17);\n\n/**\n * @generated from message contenthub.v1.GetTimelineResponse\n */\nexport type GetTimelineResponse = Message<\"contenthub.v1.GetTimelineResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.TimelineEntry entries = 1;\n */\n entries: TimelineEntry[];\n\n /**\n * The Planned Releases of the Content in open Change Sets, by Change Set\n * and in the order they were planned: what may join the Timeline.\n *\n * @generated from field: repeated contenthub.v1.ChangeSetPlannedRelease planned_releases = 2;\n */\n plannedReleases: ChangeSetPlannedRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.GetTimelineResponse.\n * Use `create(GetTimelineResponseSchema)` to create a new message.\n */\nexport const GetTimelineResponseSchema: GenMessage<GetTimelineResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 18);\n\n/**\n * ChangeSetPlannedRelease is a Planned Release and the open Change Set whose\n * Publish would cut it.\n *\n * @generated from message contenthub.v1.ChangeSetPlannedRelease\n */\nexport type ChangeSetPlannedRelease = Message<\"contenthub.v1.ChangeSetPlannedRelease\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 2;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSetPlannedRelease.\n * Use `create(ChangeSetPlannedReleaseSchema)` to create a new message.\n */\nexport const ChangeSetPlannedReleaseSchema: GenMessage<ChangeSetPlannedRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 19);\n\n/**\n * ReleaseService is the read path for template, export, flows and API keys\n * (ADR 0015): released data at (valid_on, known_at), with References resolved\n * at the same coordinates. Its responses never contain a Branch, or a\n * Revision that no Release pins, apart from a Preview's rows, which are\n * marked planned.\n *\n * Every RPC acts in the caller's workspace, from the token, and needs\n * `viewer` (ADR 0017). preview_change_set is accepted from user tokens only:\n * an API key never Previews (ADR 0006).\n *\n * @generated from service contenthub.v1.ReleaseService\n */\nexport const ReleaseService: GenService<{\n /**\n * ListInForce lists the Release In Force of every Content, one page at a\n * time, by Content id.\n *\n * @generated from rpc contenthub.v1.ReleaseService.ListInForce\n */\n listInForce: {\n methodKind: \"unary\";\n input: typeof ListInForceRequestSchema;\n output: typeof ListInForceResponseSchema;\n },\n /**\n * GetInForce reads the Release In Force of each Content named. A Content\n * with none In Force then (a gap, before its first Release, or unknown) is\n * left out.\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetInForce\n */\n getInForce: {\n methodKind: \"unary\";\n input: typeof GetInForceRequestSchema;\n output: typeof GetInForceResponseSchema;\n },\n /**\n * GetReleases reads Releases by id, superseded ones included and marked.\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetReleases\n */\n getReleases: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceGetReleasesRequestSchema;\n output: typeof ReleaseServiceGetReleasesResponseSchema;\n },\n /**\n * GetTimeline reads a Content's Timeline (CONTEXT.md).\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetTimeline\n */\n getTimeline: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceGetTimelineRequestSchema;\n output: typeof ReleaseServiceGetTimelineResponseSchema;\n },\n /**\n * ListReferrers reads the edges pointing at a Content, or at an Anchor in\n * it, from the Releases In Force at a date and moment.\n *\n * @generated from rpc contenthub.v1.ReleaseService.ListReferrers\n */\n listReferrers: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceListReferrersRequestSchema;\n output: typeof ReleaseServiceListReferrersResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_release_read, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/graph_warnings.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Edge } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { TimelineEntry } from \"./release_read_pb\";\nimport { file_contenthub_v1_release_read } from \"./release_read_pb\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/graph_warnings.proto.\n */\nexport const file_contenthub_v1_graph_warnings: GenFile = /*@__PURE__*/\n fileDesc(\"CiJjb250ZW50aHViL3YxL2dyYXBoX3dhcm5pbmdzLnByb3RvEg1jb250ZW50aHViLnYxImEKF0xpc3RPdXRkYXRlZFBpbnNSZXF1ZXN0EhMKCWJyYW5jaF9pZBgBIAEoCUgAEhUKC3JldmlzaW9uX2lkGAIgASgJSAASEAoIdmFsaWRfb24YAyABKAlCCAoGc291cmNlIkQKGExpc3RPdXRkYXRlZFBpbnNSZXNwb25zZRIoCgRwaW5zGAEgAygLMhouY29udGVudGh1Yi52MS5PdXRkYXRlZFBpbiKhAQoLT3V0ZGF0ZWRQaW4SIQoEZWRnZRgBIAEoCzITLmNvbnRlbnRodWIudjEuRWRnZRIgChhzdXBlcnNlZGVkX2J5X3JlbGVhc2VfaWQYAiABKAkSGwoTaW5fZm9yY2VfcmVsZWFzZV9pZBgDIAEoCRIwCgpjYW5kaWRhdGVzGAQgAygLMhwuY29udGVudGh1Yi52MS5UaW1lbGluZUVudHJ5IkQKC0dhcFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCSJ0Cg5QdWJsaXNoV2FybmluZxIMCgRjb2RlGAEgASgJEhIKCmNvbnRlbnRfaWQYAiABKAkSEgoKcmVsZWFzZV9pZBgDIAEoCRIsCghyZWZlcnJlchgEIAEoCzIaLmNvbnRlbnRodWIudjEuR2FwUmVmZXJyZXJCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_contenthub_v1_content_graph, file_contenthub_v1_release_read]);\n\n/**\n * @generated from message contenthub.v1.ListOutdatedPinsRequest\n */\nexport type ListOutdatedPinsRequest = Message<\"contenthub.v1.ListOutdatedPinsRequest\"> & {\n /**\n * Whose pins: the head of a Branch, or one Revision. Exactly one is\n * required.\n *\n * @generated from oneof contenthub.v1.ListOutdatedPinsRequest.source\n */\n source: {\n /**\n * @generated from field: string branch_id = 1;\n */\n value: string;\n case: \"branchId\";\n } | {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | { case: undefined; value?: undefined };\n\n /**\n * The day each pin is compared with its target's Release In Force, as\n * YYYY-MM-DD in the workspace's time zone; empty for today. In Force is\n * read as known now.\n *\n * @generated from field: string valid_on = 3;\n */\n validOn: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListOutdatedPinsRequest.\n * Use `create(ListOutdatedPinsRequestSchema)` to create a new message.\n */\nexport const ListOutdatedPinsRequestSchema: GenMessage<ListOutdatedPinsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 0);\n\n/**\n * @generated from message contenthub.v1.ListOutdatedPinsResponse\n */\nexport type ListOutdatedPinsResponse = Message<\"contenthub.v1.ListOutdatedPinsResponse\"> & {\n /**\n * In the Revision's edge order.\n *\n * @generated from field: repeated contenthub.v1.OutdatedPin pins = 1;\n */\n pins: OutdatedPin[];\n};\n\n/**\n * Describes the message contenthub.v1.ListOutdatedPinsResponse.\n * Use `create(ListOutdatedPinsResponseSchema)` to create a new message.\n */\nexport const ListOutdatedPinsResponseSchema: GenMessage<ListOutdatedPinsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 1);\n\n/**\n * OutdatedPin is a pinned edge whose Release is superseded, or is not the\n * one In Force on valid_on. A pin to a Planned Release is never outdated: it\n * names the newest wording there is.\n *\n * @generated from message contenthub.v1.OutdatedPin\n */\nexport type OutdatedPin = Message<\"contenthub.v1.OutdatedPin\"> & {\n /**\n * The edge; pin_release_id is the Release it pins.\n *\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release that supersedes the pinned one, as known now; empty if\n * none.\n *\n * @generated from field: string superseded_by_release_id = 2;\n */\n supersededByReleaseId: string;\n\n /**\n * The target's Release In Force on valid_on; empty in a gap.\n *\n * @generated from field: string in_force_release_id = 3;\n */\n inForceReleaseId: string;\n\n /**\n * The target's Timeline as known now: the Releases to re-pin to, in\n * order, as GetTimeline lists them: superseded Releases are never among\n * them, while a Repeal or Withdrawal is, so that the gap it leaves shows.\n *\n * @generated from field: repeated contenthub.v1.TimelineEntry candidates = 4;\n */\n candidates: TimelineEntry[];\n};\n\n/**\n * Describes the message contenthub.v1.OutdatedPin.\n * Use `create(OutdatedPinSchema)` to create a new message.\n */\nexport const OutdatedPinSchema: GenMessage<OutdatedPin> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 2);\n\n/**\n * GapReferrer is an unpinned edge that a Repeal or Withdrawal will leave\n * pointing at a gap: it is held by a Release In Force, with the Change Set\n * published, on the first day without the Content (the day after a Repeal's\n * last day, today for a Withdrawal) or on today if that is later, each day\n * counting only while the Content has nothing In Force on it. A pinned edge\n * keeps resolving, and a footnote resolves at its citer's coordinates, so\n * neither is ever one. Branch heads of other open Change Sets are not read.\n *\n * @generated from message contenthub.v1.GapReferrer\n */\nexport type GapReferrer = Message<\"contenthub.v1.GapReferrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release of edge.source_content_id holding the edge: a Planned\n * Release of the Change Set where it is one.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GapReferrer.\n * Use `create(GapReferrerSchema)` to create a new message.\n */\nexport const GapReferrerSchema: GenMessage<GapReferrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 3);\n\n/**\n * PublishWarning is advice ValidatePublish gives: it never blocks Publish.\n *\n * @generated from message contenthub.v1.PublishWarning\n */\nexport type PublishWarning = Message<\"contenthub.v1.PublishWarning\"> & {\n /**\n * \"gap_referrer\": referrer is left with a gap by the Repeal or Withdrawal\n * release_id of content_id.\n *\n * @generated from field: string code = 1;\n */\n code: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string release_id = 3;\n */\n releaseId: string;\n\n /**\n * @generated from field: contenthub.v1.GapReferrer referrer = 4;\n */\n referrer?: GapReferrer | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PublishWarning.\n * Use `create(PublishWarningSchema)` to create a new message.\n */\nexport const PublishWarningSchema: GenMessage<PublishWarning> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 4);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/merge.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp, Value } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/merge.proto.\n */\nexport const file_contenthub_v1_merge: GenFile = /*@__PURE__*/\n fileDesc(\"Chljb250ZW50aHViL3YxL21lcmdlLnByb3RvEg1jb250ZW50aHViLnYxIrICCgxQZW5kaW5nTWVyZ2USEQoJYnJhbmNoX2lkGAEgASgJEhAKCGNoYWluX2lkGAIgASgJEhIKCmNvbnRlbnRfaWQYAyABKAkSFQoNY2hhbmdlX3NldF9pZBgEIAEoCRIYChBiYXNlX3JldmlzaW9uX2lkGAUgASgJEhgKEG91cnNfcmV2aXNpb25faWQYBiABKAkSGgoSdGhlaXJzX3JldmlzaW9uX2lkGAcgASgJEjEKBnJlYXNvbhgIIAEoDjIhLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlUmVhc29uEg0KBXBhdGhzGAkgAygJEg8KB2NhcnJpZWQYCiABKAgSLwoLY3JlYXRlX3RpbWUYCyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIqYBCgpNZXJnZUZpZWxkEgwKBHBhdGgYASABKAkSFgoOY29uZmxpY3RfcGF0aHMYAiADKAkSJAoEYmFzZRgDIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRIkCgRvdXJzGAQgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEiYKBnRoZWlycxgFIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSJ8Cg9GaWVsZFJlc29sdXRpb24SDAoEcGF0aBgBIAEoCRIoCgRzaWRlGAIgASgOMhguY29udGVudGh1Yi52MS5NZXJnZVNpZGVIABInCgV2YWx1ZRgDIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZUgAQggKBmNob2ljZSp/ChJQZW5kaW5nTWVyZ2VSZWFzb24SJAogUEVORElOR19NRVJHRV9SRUFTT05fVU5TUEVDSUZJRUQQABIhCh1QRU5ESU5HX01FUkdFX1JFQVNPTl9DT05GTElDVBABEiAKHFBFTkRJTkdfTUVSR0VfUkVBU09OX0lOVkFMSUQQAipTCglNZXJnZVNpZGUSGgoWTUVSR0VfU0lERV9VTlNQRUNJRklFRBAAEhMKD01FUkdFX1NJREVfT1VSUxABEhUKEU1FUkdFX1NJREVfVEhFSVJTEAJCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * PendingMerge is a merge on a Branch that stopped (CONTEXT.md, Conflict):\n * Update from Main stores one on a Branch whose merge has Conflicts, or is\n * clean but fails the Blueprint Release it would pin. It stays until it is\n * resolved (ResolveMerge) or aborted (AbortMerge); until then saves on the\n * Branch and Publish are refused, and later updates leave the Branch alone.\n *\n * @generated from message contenthub.v1.PendingMerge\n */\nexport type PendingMerge = Message<\"contenthub.v1.PendingMerge\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * @generated from field: string content_id = 3;\n */\n contentId: string;\n\n /**\n * @generated from field: string change_set_id = 4;\n */\n changeSetId: string;\n\n /**\n * The merge's three Revisions: what the Branch last took in (base), its\n * head (ours, still its head while the merge is pending) and what it was\n * merging (theirs: Main's head, a dependency's Branch head, the link before\n * it, or the Release a link carries).\n *\n * @generated from field: string base_revision_id = 5;\n */\n baseRevisionId: string;\n\n /**\n * @generated from field: string ours_revision_id = 6;\n */\n oursRevisionId: string;\n\n /**\n * @generated from field: string theirs_revision_id = 7;\n */\n theirsRevisionId: string;\n\n /**\n * @generated from field: contenthub.v1.PendingMergeReason reason = 8;\n */\n reason: PendingMergeReason;\n\n /**\n * Where it stopped: the conflicting field paths (an accessor, or an\n * accessor and a path within the field such as \"rows/r1\") for a conflict;\n * the paths the Blueprint Release refuses (\"/\" and an accessor, and\n * deeper) for invalid data. Never empty.\n *\n * @generated from field: repeated string paths = 9;\n */\n paths: string[];\n\n /**\n * Whether theirs is what a Chain link on Dated Content carries, rather\n * than its upstream Branch's head.\n *\n * @generated from field: bool carried = 10;\n */\n carried: boolean;\n\n /**\n * When Update from Main stored it.\n *\n * @generated from field: google.protobuf.Timestamp create_time = 11;\n */\n createTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PendingMerge.\n * Use `create(PendingMergeSchema)` to create a new message.\n */\nexport const PendingMergeSchema: GenMessage<PendingMerge> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 0);\n\n/**\n * MergeField is one field a resolution must decide: a field both sides\n * changed in ways that don't merge, or one whose merged value the Blueprint\n * Release refuses.\n *\n * @generated from message contenthub.v1.MergeField\n */\nexport type MergeField = Message<\"contenthub.v1.MergeField\"> & {\n /**\n * \"/\" and the field's accessor, as a Violation spells it.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * The Pending Merge's paths within this field.\n *\n * @generated from field: repeated string conflict_paths = 2;\n */\n conflictPaths: string[];\n\n /**\n * The field's value in base, ours and theirs; unset on a side that doesn't\n * hold the field.\n *\n * @generated from field: google.protobuf.Value base = 3;\n */\n base?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value ours = 4;\n */\n ours?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value theirs = 5;\n */\n theirs?: Value | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.MergeField.\n * Use `create(MergeFieldSchema)` to create a new message.\n */\nexport const MergeFieldSchema: GenMessage<MergeField> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 1);\n\n/**\n * FieldResolution decides one MergeField: one side's value (its absence\n * included, when that side doesn't hold the field), or a value the editor\n * wrote.\n *\n * @generated from message contenthub.v1.FieldResolution\n */\nexport type FieldResolution = Message<\"contenthub.v1.FieldResolution\"> & {\n /**\n * The MergeField's path.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from oneof contenthub.v1.FieldResolution.choice\n */\n choice: {\n /**\n * @generated from field: contenthub.v1.MergeSide side = 2;\n */\n value: MergeSide;\n case: \"side\";\n } | {\n /**\n * @generated from field: google.protobuf.Value value = 3;\n */\n value: Value;\n case: \"value\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.FieldResolution.\n * Use `create(FieldResolutionSchema)` to create a new message.\n */\nexport const FieldResolutionSchema: GenMessage<FieldResolution> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 2);\n\n/**\n * PendingMergeReason is why Update from Main stored a Pending Merge.\n *\n * @generated from enum contenthub.v1.PendingMergeReason\n */\nexport enum PendingMergeReason {\n /**\n * @generated from enum value: PENDING_MERGE_REASON_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Both sides changed fields in ways that don't merge.\n *\n * @generated from enum value: PENDING_MERGE_REASON_CONFLICT = 1;\n */\n CONFLICT = 1,\n\n /**\n * The merge was clean, but its data fails the Blueprint Release it would\n * pin.\n *\n * @generated from enum value: PENDING_MERGE_REASON_INVALID = 2;\n */\n INVALID = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.PendingMergeReason.\n */\nexport const PendingMergeReasonSchema: GenEnum<PendingMergeReason> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_merge, 0);\n\n/**\n * MergeSide is a side of a Pending Merge whose value a resolution takes.\n *\n * @generated from enum contenthub.v1.MergeSide\n */\nexport enum MergeSide {\n /**\n * @generated from enum value: MERGE_SIDE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * The Branch's head.\n *\n * @generated from enum value: MERGE_SIDE_OURS = 1;\n */\n OURS = 1,\n\n /**\n * What the Branch was merging.\n *\n * @generated from enum value: MERGE_SIDE_THEIRS = 2;\n */\n THEIRS = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.MergeSide.\n */\nexport const MergeSideSchema: GenEnum<MergeSide> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_merge, 1);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/planning.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { GapReferrer } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { PlannedRelease, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/planning.proto.\n */\nexport const file_contenthub_v1_planning: GenFile = /*@__PURE__*/\n fileDesc(\"Chxjb250ZW50aHViL3YxL3BsYW5uaW5nLnByb3RvEg1jb250ZW50aHViLnYxIpgBChpQbGFuRGF0ZU9ubHlSZWxlYXNlUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhIKCnJlbGVhc2VfaWQYAiABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAMgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiVQobUGxhbkRhdGVPbmx5UmVsZWFzZVJlc3BvbnNlEjYKD3BsYW5uZWRfcmVsZWFzZRgBIAEoCzIdLmNvbnRlbnRodWIudjEuUGxhbm5lZFJlbGVhc2UiaQoRUGxhblJlcGVhbFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhAKCGxhc3RfZGF5GAMgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgEIAEoCSJ/ChJQbGFuUmVwZWFsUmVzcG9uc2USNgoPcGxhbm5lZF9yZWxlYXNlGAEgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZRIxCg1nYXBfcmVmZXJyZXJzGAIgAygLMhouY29udGVudGh1Yi52MS5HYXBSZWZlcnJlciJbChVQbGFuV2l0aGRyYXdhbFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSKDAQoWUGxhbldpdGhkcmF3YWxSZXNwb25zZRI2Cg9wbGFubmVkX3JlbGVhc2UYASABKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlEjEKDWdhcF9yZWZlcnJlcnMYAiADKAsyGi5jb250ZW50aHViLnYxLkdhcFJlZmVycmVyImcKGURyb3BQbGFubmVkUmVsZWFzZVJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIaChJwbGFubmVkX3JlbGVhc2VfaWQYAiABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIlUKGkRyb3BQbGFubmVkUmVsZWFzZVJlc3BvbnNlEjcKEHBsYW5uZWRfcmVsZWFzZXMYASADKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlIkAKDUNvdmVyc1JlbGVhc2USEgoKY29udGVudF9pZBgBIAEoCRIbChNjb3ZlcmVkX3JlbGVhc2VfaWRzGAIgAygJQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_contenthub_v1_graph_warnings, file_contenthub_v1_release]);\n\n/**\n * @generated from message contenthub.v1.PlanDateOnlyReleaseRequest\n */\nexport type PlanDateOnlyReleaseRequest = Message<\"contenthub.v1.PlanDateOnlyReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Release of Dated Content to re-pin and supersede.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * Required: the corrected Validity Period.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanDateOnlyReleaseRequest.\n * Use `create(PlanDateOnlyReleaseRequestSchema)` to create a new message.\n */\nexport const PlanDateOnlyReleaseRequestSchema: GenMessage<PlanDateOnlyReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 0);\n\n/**\n * @generated from message contenthub.v1.PlanDateOnlyReleaseResponse\n */\nexport type PlanDateOnlyReleaseResponse = Message<\"contenthub.v1.PlanDateOnlyReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PlanDateOnlyReleaseResponse.\n * Use `create(PlanDateOnlyReleaseResponseSchema)` to create a new message.\n */\nexport const PlanDateOnlyReleaseResponseSchema: GenMessage<PlanDateOnlyReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 1);\n\n/**\n * @generated from message contenthub.v1.PlanRepealRequest\n */\nexport type PlanRepealRequest = Message<\"contenthub.v1.PlanRepealRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Dated Content to repeal.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Required: the last day it is In Force, as YYYY-MM-DD.\n *\n * @generated from field: string last_day = 3;\n */\n lastDay: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanRepealRequest.\n * Use `create(PlanRepealRequestSchema)` to create a new message.\n */\nexport const PlanRepealRequestSchema: GenMessage<PlanRepealRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 2);\n\n/**\n * @generated from message contenthub.v1.PlanRepealResponse\n */\nexport type PlanRepealResponse = Message<\"contenthub.v1.PlanRepealResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n\n /**\n * A warning, never a refusal: the referrers it will leave with a gap\n * once the Change Set is published (ADR 0009).\n *\n * @generated from field: repeated contenthub.v1.GapReferrer gap_referrers = 2;\n */\n gapReferrers: GapReferrer[];\n};\n\n/**\n * Describes the message contenthub.v1.PlanRepealResponse.\n * Use `create(PlanRepealResponseSchema)` to create a new message.\n */\nexport const PlanRepealResponseSchema: GenMessage<PlanRepealResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 3);\n\n/**\n * @generated from message contenthub.v1.PlanWithdrawalRequest\n */\nexport type PlanWithdrawalRequest = Message<\"contenthub.v1.PlanWithdrawalRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The undated Content to withdraw.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanWithdrawalRequest.\n * Use `create(PlanWithdrawalRequestSchema)` to create a new message.\n */\nexport const PlanWithdrawalRequestSchema: GenMessage<PlanWithdrawalRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 4);\n\n/**\n * @generated from message contenthub.v1.PlanWithdrawalResponse\n */\nexport type PlanWithdrawalResponse = Message<\"contenthub.v1.PlanWithdrawalResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n\n /**\n * A warning, never a refusal: the referrers it will leave with a gap\n * once the Change Set is published (ADR 0009).\n *\n * @generated from field: repeated contenthub.v1.GapReferrer gap_referrers = 2;\n */\n gapReferrers: GapReferrer[];\n};\n\n/**\n * Describes the message contenthub.v1.PlanWithdrawalResponse.\n * Use `create(PlanWithdrawalResponseSchema)` to create a new message.\n */\nexport const PlanWithdrawalResponseSchema: GenMessage<PlanWithdrawalResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 5);\n\n/**\n * @generated from message contenthub.v1.DropPlannedReleaseRequest\n */\nexport type DropPlannedReleaseRequest = Message<\"contenthub.v1.DropPlannedReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string planned_release_id = 2;\n */\n plannedReleaseId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DropPlannedReleaseRequest.\n * Use `create(DropPlannedReleaseRequestSchema)` to create a new message.\n */\nexport const DropPlannedReleaseRequestSchema: GenMessage<DropPlannedReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 6);\n\n/**\n * @generated from message contenthub.v1.DropPlannedReleaseResponse\n */\nexport type DropPlannedReleaseResponse = Message<\"contenthub.v1.DropPlannedReleaseResponse\"> & {\n /**\n * The Change Set's Planned Releases left, proposals recomputed.\n *\n * @generated from field: repeated contenthub.v1.PlannedRelease planned_releases = 1;\n */\n plannedReleases: PlannedRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.DropPlannedReleaseResponse.\n * Use `create(DropPlannedReleaseResponseSchema)` to create a new message.\n */\nexport const DropPlannedReleaseResponseSchema: GenMessage<DropPlannedReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 7);\n\n/**\n * CoversRelease is the detail of a FailedPrecondition plan whose Validity\n * Period would cover other Releases of the Content entirely: nothing is\n * planned. Supersede them (drop them, if they are planned) or change the\n * dates.\n *\n * @generated from message contenthub.v1.CoversRelease\n */\nexport type CoversRelease = Message<\"contenthub.v1.CoversRelease\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The Releases covered, by first day.\n *\n * @generated from field: repeated string covered_release_ids = 2;\n */\n coveredReleaseIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.CoversRelease.\n * Use `create(CoversReleaseSchema)` to create a new message.\n */\nexport const CoversReleaseSchema: GenMessage<CoversRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 8);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/change_set.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { PublishWarning } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { FieldResolution, MergeField, PendingMerge } from \"./merge_pb\";\nimport { file_contenthub_v1_merge } from \"./merge_pb\";\nimport type { DropPlannedReleaseRequestSchema, DropPlannedReleaseResponseSchema, PlanDateOnlyReleaseRequestSchema, PlanDateOnlyReleaseResponseSchema, PlanRepealRequestSchema, PlanRepealResponseSchema, PlanWithdrawalRequestSchema, PlanWithdrawalResponseSchema } from \"./planning_pb\";\nimport { file_contenthub_v1_planning } from \"./planning_pb\";\nimport type { PlannedRelease, PublishBlocker, Release, ReleaseIdList, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { RequiredCheck } from \"./workspace_config_pb\";\nimport { file_contenthub_v1_workspace_config } from \"./workspace_config_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/change_set.proto.\n */\nexport const file_contenthub_v1_change_set: GenFile = /*@__PURE__*/\n fileDesc(\"Ch5jb250ZW50aHViL3YxL2NoYW5nZV9zZXQucHJvdG8SDWNvbnRlbnRodWIudjEiKQoGU291cmNlEgwKBGRhdGUYASABKAkSEQoJcmVmZXJlbmNlGAIgASgJIpcDCglDaGFuZ2VTZXQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIlCgZzb3VyY2UYAyABKAsyFS5jb250ZW50aHViLnYxLlNvdXJjZRIsCgVzdGF0ZRgEIAEoDjIdLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0U3RhdGUSEgoKY3JlYXRlZF9ieRgFIAEoCRIvCgtjcmVhdGVfdGltZRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKY2xvc2VfdGltZRgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJAoGY2hhaW5zGAggAygLMhQuY29udGVudGh1Yi52MS5DaGFpbhIhChlkZXBlbmRzX29uX2NoYW5nZV9zZXRfaWRzGAkgAygJEjcKEHBsYW5uZWRfcmVsZWFzZXMYCiADKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlEg4KBnN0YXR1cxgLIAEoCRIUCgxhc3NpZ25lZV9pZHMYDCADKAkiXgoFQ2hhaW4SCgoCaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIMCgRib3JuGAMgASgIEicKCGJyYW5jaGVzGAQgAygLMhUuY29udGVudGh1Yi52MS5CcmFuY2gitgEKBkJyYW5jaBIKCgJpZBgBIAEoCRIQCghwb3NpdGlvbhgCIAEoBRInCgRraW5kGAMgASgOMhkuY29udGVudGh1Yi52MS5CcmFuY2hLaW5kEhgKEGhlYWRfcmV2aXNpb25faWQYBCABKAkSFAoMZWZmZWN0aXZlX29uGAUgASgJEhoKEmNhcnJpZWRfcmVsZWFzZV9pZBgGIAEoCRIZChFoYXNfcGVuZGluZ19tZXJnZRgHIAEoCCJmChZDcmVhdGVDaGFuZ2VTZXRSZXF1ZXN0EgwKBG5hbWUYASABKAkSJQoGc291cmNlGAIgASgLMhUuY29udGVudGh1Yi52MS5Tb3VyY2USFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIkcKF0NyZWF0ZUNoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCIhChNHZXRDaGFuZ2VTZXRSZXF1ZXN0EgoKAmlkGAEgASgJIkQKFEdldENoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCKhAQoWVXBkYXRlQ2hhbmdlU2V0UmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEiUKBnNvdXJjZRgDIAEoCzIVLmNvbnRlbnRodWIudjEuU291cmNlEi0KC3VwZGF0ZV9tYXNrGAQgASgLMhguY29udGVudGh1Yi52MS5GaWVsZE1hc2sSFwoPaWRlbXBvdGVuY3lfa2V5GAUgASgJIkcKF1VwZGF0ZUNoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCI+ChdEaXNjYXJkQ2hhbmdlU2V0UmVxdWVzdBIKCgJpZBgBIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAiABKAkiSAoYRGlzY2FyZENoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCJ0ChlTZXRDaGFuZ2VTZXRTdGF0dXNSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSFwoPZXhwZWN0ZWRfc3RhdHVzGAIgASgJEg4KBnN0YXR1cxgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiSgoaU2V0Q2hhbmdlU2V0U3RhdHVzUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0ImQKHFNldENoYW5nZVNldEFzc2lnbmVlc1JlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIUCgxhc3NpZ25lZV9pZHMYAiADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIk0KHVNldENoYW5nZVNldEFzc2lnbmVlc1Jlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCJBCghDb3B5RnJvbRIUCgpyZWxlYXNlX2lkGAEgASgJSAASFQoLcmV2aXNpb25faWQYAiABKAlIAEIICgZzb3VyY2Ui4wEKFENyZWF0ZUNvbnRlbnRSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIcChRibHVlcHJpbnRfcmVsZWFzZV9pZBgDIAEoCRIlCgRkYXRhGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIqCgljb3B5X2Zyb20YBSABKAsyFy5jb250ZW50aHViLnYxLkNvcHlGcm9tEhYKDmNvbGxlY3Rpb25faWRzGAYgAygJEhcKD2lkZW1wb3RlbmN5X2tleRgHIAEoCSJAChVDcmVhdGVDb250ZW50UmVzcG9uc2USJwoHY29udGVudBgBIAEoCzIWLmNvbnRlbnRodWIudjEuQ29udGVudCIbCglGaWVsZE1hc2sSDgoGZmllbGRzGAEgAygJIrABChNTYXZlUmV2aXNpb25SZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAIgASgJEiUKBGRhdGEYAyABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EiwKCmZpZWxkX21hc2sYBCABKAsyGC5jb250ZW50aHViLnYxLkZpZWxkTWFzaxIXCg9pZGVtcG90ZW5jeV9rZXkYBSABKAkiPwoUU2F2ZVJldmlzaW9uUmVzcG9uc2USJwoHY29udGVudBgBIAEoCzIWLmNvbnRlbnRodWIudjEuQ29udGVudCL9AQoHQ29udGVudBIKCgJpZBgBIAEoCRIUCgxibHVlcHJpbnRfaWQYAiABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYAyABKAkSEwoLcmV2aXNpb25faWQYBCABKAkSJQoEZGF0YRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSFQoNY2hhbmdlX3NldF9pZBgGIAEoCRIRCglicmFuY2hfaWQYByABKAkSOAoUcmV2aXNpb25fY3JlYXRlX3RpbWUYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhIKCnJlbGVhc2VfaWQYCSABKAkijgEKE1ByZXZpZXdDaGFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRI2Cg92YWxpZGl0eV9wZXJpb2QYBCABKAsyHS5jb250ZW50aHViLnYxLlZhbGlkaXR5UGVyaW9kIkQKFFByZXZpZXdDaGFpblJlc3BvbnNlEiwKB3ByZXZpZXcYASABKAsyGy5jb250ZW50aHViLnYxLkNoYWluUHJldmlldyKUAgoMQ2hhaW5QcmV2aWV3EhcKD2ZvcmtfcmVsZWFzZV9pZBgBIAEoCRIhChljYXJyeV9mb3J3YXJkX3JlbGVhc2VfaWRzGAIgAygJEhMKC21lcmdlc19tYWluGAMgASgIEjYKD3ZhbGlkaXR5X3BlcmlvZBgEIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSKAoIY3V0X2ludG8YBSADKAsyFi5jb250ZW50aHViLnYxLkN1dEludG8SGwoTY292ZXJlZF9yZWxlYXNlX2lkcxgGIAMoCRI0CgpzdXBlcnNlZGVkGAcgAygLMiAuY29udGVudGh1Yi52MS5TdXBlcnNlZGVkUmVsZWFzZSKIAQoHQ3V0SW50bxISCgpyZWxlYXNlX2lkGAEgASgJEg8KB3BsYW5uZWQYAiABKAgSKwoEa2VwdBgDIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSKwoEdGFpbBgEIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QiRgoRU3VwZXJzZWRlZFJlbGVhc2USEgoKcmVsZWFzZV9pZBgBIAEoCRIdChVieV9wbGFubmVkX3JlbGVhc2VfaWQYAiABKAkibQoRU3RhcnRDaGFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkibQoSU3RhcnRDaGFpblJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBIQCghjaGFpbl9pZBgCIAEoCRIXCg9mb3JrX3JlbGVhc2VfaWQYAyABKAkibQoTQXBwZW5kQnJhbmNoUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhAKCGNoYWluX2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiVwoUQXBwZW5kQnJhbmNoUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EhEKCWJyYW5jaF9pZBgCIAEoCSJUChBEcm9wQ2hhaW5SZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEAoIY2hhaW5faWQYAiABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIkEKEURyb3BDaGFpblJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCKIAQoTU3RhcnRFZGl0aW5nUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEhUKDWNoYW5nZV9zZXRfaWQYAiABKAkSFAoMZWZmZWN0aXZlX29uGAMgASgJEhcKD2NoYW5nZV9zZXRfbmFtZRgEIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBSABKAkihgEKFFN0YXJ0RWRpdGluZ1Jlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBInCgdjb250ZW50GAIgASgLMhYuY29udGVudGh1Yi52MS5Db250ZW50EhcKD2ZvcmtfcmVsZWFzZV9pZBgDIAEoCSJZChVVcGRhdGVGcm9tTWFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIQCghjaGFpbl9pZBgCIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAyABKAki2gEKFlVwZGF0ZUZyb21NYWluUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EhkKEW1lcmdlZF9icmFuY2hfaWRzGAIgAygJEi8KCmNvbmZsaWN0ZWQYAyADKAsyGy5jb250ZW50aHViLnYxLlBlbmRpbmdNZXJnZRIsCgdwZW5kaW5nGAQgAygLMhsuY29udGVudGh1Yi52MS5QZW5kaW5nTWVyZ2USGAoQZW5kZWRfYnJhbmNoX2lkcxgFIAMoCSIrChZHZXRQZW5kaW5nTWVyZ2VSZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCSK/AQoXR2V0UGVuZGluZ01lcmdlUmVzcG9uc2USMgoNcGVuZGluZ19tZXJnZRgBIAEoCzIbLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAIgASgJEikKBmZpZWxkcxgDIAMoCzIZLmNvbnRlbnRodWIudjEuTWVyZ2VGaWVsZBInCgZtZXJnZWQYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0IpABChNSZXNvbHZlTWVyZ2VSZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAIgASgJEjMKC3Jlc29sdXRpb25zGAMgAygLMh4uY29udGVudGh1Yi52MS5GaWVsZFJlc29sdXRpb24SFwoPaWRlbXBvdGVuY3lfa2V5GAQgASgJIj8KFFJlc29sdmVNZXJnZVJlc3BvbnNlEicKB2NvbnRlbnQYASABKAsyFi5jb250ZW50aHViLnYxLkNvbnRlbnQiPwoRQWJvcnRNZXJnZVJlcXVlc3QSEQoJYnJhbmNoX2lkGAEgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgCIAEoCSJCChJBYm9ydE1lcmdlUmVzcG9uc2USLAoHYWJvcnRlZBgBIAEoCzIbLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlImgKFEFkZERlcGVuZGVuY3lSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSIAoYZGVwZW5kc19vbl9jaGFuZ2Vfc2V0X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJFChVBZGREZXBlbmRlbmN5UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0ImsKF1JlbW92ZURlcGVuZGVuY3lSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSIAoYZGVwZW5kc19vbl9jaGFuZ2Vfc2V0X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJIChhSZW1vdmVEZXBlbmRlbmN5UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0It4BChJQbGFuUmVsZWFzZVJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIRCglicmFuY2hfaWQYAiABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAMgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0Eh4KFnN1cGVyc2VkZXNfcmVsZWFzZV9pZHMYBSADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAYgASgJIk0KE1BsYW5SZWxlYXNlUmVzcG9uc2USNgoPcGxhbm5lZF9yZWxlYXNlGAEgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZSKCAgobVXBkYXRlUGxhbm5lZFJlbGVhc2VSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSGgoScGxhbm5lZF9yZWxlYXNlX2lkGAIgASgJEjYKD3ZhbGlkaXR5X3BlcmlvZBgDIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSLQoMcmVsZWFzZV9zcGVjGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIwCgpzdXBlcnNlZGVzGAUgASgLMhwuY29udGVudGh1Yi52MS5SZWxlYXNlSWRMaXN0EhcKD2lkZW1wb3RlbmN5X2tleRgGIAEoCSJWChxVcGRhdGVQbGFubmVkUmVsZWFzZVJlc3BvbnNlEjYKD3BsYW5uZWRfcmVsZWFzZRgBIAEoCzIdLmNvbnRlbnRodWIudjEuUGxhbm5lZFJlbGVhc2UiPQoNVXBncmFkZVRhcmdldBISCgpjb250ZW50X2lkGAEgASgJEhgKEGV4cGVjdGVkX2hlYWRfaWQYAiABKAki+gEKFVVwZ3JhZGVDb250ZW50UmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAIgASgJEi4KCGNvbnRlbnRzGAMgAygLMhwuY29udGVudGh1Yi52MS5VcGdyYWRlVGFyZ2V0EhkKEWFsbF9waW5uaW5nX29sZGVyGAQgASgIEhMKC2Ryb3BfZmllbGRzGAUgAygJEjMKDGZpcnN0X3BlcmlvZBgGIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSFwoPaWRlbXBvdGVuY3lfa2V5GAcgASgJInAKFlVwZ3JhZGVDb250ZW50UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EigKCGNvbnRlbnRzGAIgAygLMhYuY29udGVudGh1Yi52MS5Db250ZW50IpICChhSZWNvcmRDaGVja1Jlc3VsdFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIZChFyZXF1aXJlZF9jaGVja19pZBgCIAEoCRJBCgVoZWFkcxgDIAMoCzIyLmNvbnRlbnRodWIudjEuUmVjb3JkQ2hlY2tSZXN1bHRSZXF1ZXN0LkhlYWRzRW50cnkSLAoHb3V0Y29tZRgEIAEoDjIbLmNvbnRlbnRodWIudjEuQ2hlY2tPdXRjb21lEgwKBG5vdGUYBSABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAYgASgJGiwKCkhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJNChlSZWNvcmRDaGVja1Jlc3VsdFJlc3BvbnNlEjAKDGNoZWNrX3Jlc3VsdBgBIAEoCzIaLmNvbnRlbnRodWIudjEuQ2hlY2tSZXN1bHQisQIKC0NoZWNrUmVzdWx0EgoKAmlkGAEgASgJEhUKDWNoYW5nZV9zZXRfaWQYAiABKAkSGQoRcmVxdWlyZWRfY2hlY2tfaWQYAyABKAkSNAoFaGVhZHMYBCADKAsyJS5jb250ZW50aHViLnYxLkNoZWNrUmVzdWx0LkhlYWRzRW50cnkSLAoHb3V0Y29tZRgFIAEoDjIbLmNvbnRlbnRodWIudjEuQ2hlY2tPdXRjb21lEgwKBG5vdGUYBiABKAkSEwoLcmVjb3JkZWRfYnkYByABKAkSLwoLcmVjb3JkX3RpbWUYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGiwKCkhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIwChdMaXN0Q2hlY2tSZXN1bHRzUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJIksKGExpc3RDaGVja1Jlc3VsdHNSZXNwb25zZRIvCglzdGFuZGluZ3MYASADKAsyHC5jb250ZW50aHViLnYxLkNoZWNrU3RhbmRpbmciswIKDUNoZWNrU3RhbmRpbmcSNAoOcmVxdWlyZWRfY2hlY2sYASABKAsyHC5jb250ZW50aHViLnYxLlJlcXVpcmVkQ2hlY2sSEgoKY29udGVudF9pZBgCIAEoCRIRCglicmFuY2hfaWQYAyABKAkSEgoKcmVsZWFzZV9pZBgEIAEoCRI2CgVoZWFkcxgFIAMoCzInLmNvbnRlbnRodWIudjEuQ2hlY2tTdGFuZGluZy5IZWFkc0VudHJ5EisKB3Jlc3VsdHMYBiADKAsyGi5jb250ZW50aHViLnYxLkNoZWNrUmVzdWx0Eg0KBXN0YWxlGAcgASgIEg8KB2NsZWFyZWQYCCABKAgaLAoKSGVhZHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrcBChZWYWxpZGF0ZVB1Ymxpc2hSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSUAoOcmV2aWV3ZWRfaGVhZHMYAiADKAsyOC5jb250ZW50aHViLnYxLlZhbGlkYXRlUHVibGlzaFJlcXVlc3QuUmV2aWV3ZWRIZWFkc0VudHJ5GjQKElJldmlld2VkSGVhZHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrgBChdWYWxpZGF0ZVB1Ymxpc2hSZXNwb25zZRIvCghibG9ja2VycxgBIAMoCzIdLmNvbnRlbnRodWIudjEuUHVibGlzaEJsb2NrZXISKAoIcmVsZWFzZXMYAiADKAsyFi5jb250ZW50aHViLnYxLlJlbGVhc2USEQoJcHVibGlzaGVkGAMgASgIEi8KCHdhcm5pbmdzGAQgAygLMh0uY29udGVudGh1Yi52MS5QdWJsaXNoV2FybmluZyLAAQoOUHVibGlzaFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRJICg5yZXZpZXdlZF9oZWFkcxgCIAMoCzIwLmNvbnRlbnRodWIudjEuUHVibGlzaFJlcXVlc3QuUmV2aWV3ZWRIZWFkc0VudHJ5EhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCRo0ChJSZXZpZXdlZEhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASKbAQoPUHVibGlzaFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBIwCgxwdWJsaXNoX3RpbWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEigKCHJlbGVhc2VzGAMgAygLMhYuY29udGVudGh1Yi52MS5SZWxlYXNlImUKCVN0YWxlSGVhZBISCgpjb250ZW50X2lkGAEgASgJEhEKCWJyYW5jaF9pZBgCIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAMgASgJEhcKD2N1cnJlbnRfaGVhZF9pZBgEIAEoCSJWCg9DaGFuZ2VTZXRDbG9zZWQSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIsCgVzdGF0ZRgCIAEoDjIdLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0U3RhdGUiJQoMV2l0aGhlbGRXb3JrEhUKDWNoYW5nZV9zZXRfaWQYASABKAkiVQoLU3RhbGVTdGF0dXMSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIXCg9leHBlY3RlZF9zdGF0dXMYAiABKAkSFgoOY3VycmVudF9zdGF0dXMYAyABKAkihQEKF1N0YXR1c1RyYW5zaXRpb25SZWZ1c2VkEhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEwoLZnJvbV9zdGF0dXMYAiABKAkSEQoJdG9fc3RhdHVzGAMgASgJEg4KBnJlYXNvbhgEIAEoCRIbChNyZXF1aXJlc19wZXJtaXNzaW9uGAUgASgIIpABCglWaW9sYXRpb24SDgoGc291cmNlGAEgASgJEgwKBGNvZGUYAiABKAkSDAoEcGF0aBgDIAEoCRInCgZwYXJhbXMYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EhIKCmNvbnRlbnRfaWQYBSABKAkSGgoScGxhbm5lZF9yZWxlYXNlX2lkGAYgASgJKo0BCg5DaGFuZ2VTZXRTdGF0ZRIgChxDSEFOR0VfU0VUX1NUQVRFX1VOU1BFQ0lGSUVEEAASGQoVQ0hBTkdFX1NFVF9TVEFURV9PUEVOEAESHgoaQ0hBTkdFX1NFVF9TVEFURV9QVUJMSVNIRUQQAhIeChpDSEFOR0VfU0VUX1NUQVRFX0RJU0NBUkRFRBADKmMKCkJyYW5jaEtpbmQSGwoXQlJBTkNIX0tJTkRfVU5TUEVDSUZJRUQQABIZChVCUkFOQ0hfS0lORF9FRElUT1JJQUwQARIdChlCUkFOQ0hfS0lORF9DQVJSWV9GT1JXQVJEEAIqewoMQ2hlY2tPdXRjb21lEh0KGUNIRUNLX09VVENPTUVfVU5TUEVDSUZJRUQQABIYChRDSEVDS19PVVRDT01FX1BBU1NFRBABEhgKFENIRUNLX09VVENPTUVfRkFJTEVEEAISGAoUQ0hFQ0tfT1VUQ09NRV9XQUlWRUQQAzKuFgoQQ2hhbmdlU2V0U2VydmljZRJgCg9DcmVhdGVDaGFuZ2VTZXQSJS5jb250ZW50aHViLnYxLkNyZWF0ZUNoYW5nZVNldFJlcXVlc3QaJi5jb250ZW50aHViLnYxLkNyZWF0ZUNoYW5nZVNldFJlc3BvbnNlElcKDEdldENoYW5nZVNldBIiLmNvbnRlbnRodWIudjEuR2V0Q2hhbmdlU2V0UmVxdWVzdBojLmNvbnRlbnRodWIudjEuR2V0Q2hhbmdlU2V0UmVzcG9uc2USYAoPVXBkYXRlQ2hhbmdlU2V0EiUuY29udGVudGh1Yi52MS5VcGRhdGVDaGFuZ2VTZXRSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5VcGRhdGVDaGFuZ2VTZXRSZXNwb25zZRJjChBEaXNjYXJkQ2hhbmdlU2V0EiYuY29udGVudGh1Yi52MS5EaXNjYXJkQ2hhbmdlU2V0UmVxdWVzdBonLmNvbnRlbnRodWIudjEuRGlzY2FyZENoYW5nZVNldFJlc3BvbnNlEmkKElNldENoYW5nZVNldFN0YXR1cxIoLmNvbnRlbnRodWIudjEuU2V0Q2hhbmdlU2V0U3RhdHVzUmVxdWVzdBopLmNvbnRlbnRodWIudjEuU2V0Q2hhbmdlU2V0U3RhdHVzUmVzcG9uc2UScgoVU2V0Q2hhbmdlU2V0QXNzaWduZWVzEisuY29udGVudGh1Yi52MS5TZXRDaGFuZ2VTZXRBc3NpZ25lZXNSZXF1ZXN0GiwuY29udGVudGh1Yi52MS5TZXRDaGFuZ2VTZXRBc3NpZ25lZXNSZXNwb25zZRJaCg1DcmVhdGVDb250ZW50EiMuY29udGVudGh1Yi52MS5DcmVhdGVDb250ZW50UmVxdWVzdBokLmNvbnRlbnRodWIudjEuQ3JlYXRlQ29udGVudFJlc3BvbnNlElcKDFNhdmVSZXZpc2lvbhIiLmNvbnRlbnRodWIudjEuU2F2ZVJldmlzaW9uUmVxdWVzdBojLmNvbnRlbnRodWIudjEuU2F2ZVJldmlzaW9uUmVzcG9uc2USVwoMUHJldmlld0NoYWluEiIuY29udGVudGh1Yi52MS5QcmV2aWV3Q2hhaW5SZXF1ZXN0GiMuY29udGVudGh1Yi52MS5QcmV2aWV3Q2hhaW5SZXNwb25zZRJRCgpTdGFydENoYWluEiAuY29udGVudGh1Yi52MS5TdGFydENoYWluUmVxdWVzdBohLmNvbnRlbnRodWIudjEuU3RhcnRDaGFpblJlc3BvbnNlElcKDEFwcGVuZEJyYW5jaBIiLmNvbnRlbnRodWIudjEuQXBwZW5kQnJhbmNoUmVxdWVzdBojLmNvbnRlbnRodWIudjEuQXBwZW5kQnJhbmNoUmVzcG9uc2USTgoJRHJvcENoYWluEh8uY29udGVudGh1Yi52MS5Ecm9wQ2hhaW5SZXF1ZXN0GiAuY29udGVudGh1Yi52MS5Ecm9wQ2hhaW5SZXNwb25zZRJXCgxTdGFydEVkaXRpbmcSIi5jb250ZW50aHViLnYxLlN0YXJ0RWRpdGluZ1JlcXVlc3QaIy5jb250ZW50aHViLnYxLlN0YXJ0RWRpdGluZ1Jlc3BvbnNlEl0KDlVwZGF0ZUZyb21NYWluEiQuY29udGVudGh1Yi52MS5VcGRhdGVGcm9tTWFpblJlcXVlc3QaJS5jb250ZW50aHViLnYxLlVwZGF0ZUZyb21NYWluUmVzcG9uc2USYAoPR2V0UGVuZGluZ01lcmdlEiUuY29udGVudGh1Yi52MS5HZXRQZW5kaW5nTWVyZ2VSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5HZXRQZW5kaW5nTWVyZ2VSZXNwb25zZRJXCgxSZXNvbHZlTWVyZ2USIi5jb250ZW50aHViLnYxLlJlc29sdmVNZXJnZVJlcXVlc3QaIy5jb250ZW50aHViLnYxLlJlc29sdmVNZXJnZVJlc3BvbnNlElEKCkFib3J0TWVyZ2USIC5jb250ZW50aHViLnYxLkFib3J0TWVyZ2VSZXF1ZXN0GiEuY29udGVudGh1Yi52MS5BYm9ydE1lcmdlUmVzcG9uc2USWgoNQWRkRGVwZW5kZW5jeRIjLmNvbnRlbnRodWIudjEuQWRkRGVwZW5kZW5jeVJlcXVlc3QaJC5jb250ZW50aHViLnYxLkFkZERlcGVuZGVuY3lSZXNwb25zZRJjChBSZW1vdmVEZXBlbmRlbmN5EiYuY29udGVudGh1Yi52MS5SZW1vdmVEZXBlbmRlbmN5UmVxdWVzdBonLmNvbnRlbnRodWIudjEuUmVtb3ZlRGVwZW5kZW5jeVJlc3BvbnNlElQKC1BsYW5SZWxlYXNlEiEuY29udGVudGh1Yi52MS5QbGFuUmVsZWFzZVJlcXVlc3QaIi5jb250ZW50aHViLnYxLlBsYW5SZWxlYXNlUmVzcG9uc2USbwoUVXBkYXRlUGxhbm5lZFJlbGVhc2USKi5jb250ZW50aHViLnYxLlVwZGF0ZVBsYW5uZWRSZWxlYXNlUmVxdWVzdBorLmNvbnRlbnRodWIudjEuVXBkYXRlUGxhbm5lZFJlbGVhc2VSZXNwb25zZRJsChNQbGFuRGF0ZU9ubHlSZWxlYXNlEikuY29udGVudGh1Yi52MS5QbGFuRGF0ZU9ubHlSZWxlYXNlUmVxdWVzdBoqLmNvbnRlbnRodWIudjEuUGxhbkRhdGVPbmx5UmVsZWFzZVJlc3BvbnNlElEKClBsYW5SZXBlYWwSIC5jb250ZW50aHViLnYxLlBsYW5SZXBlYWxSZXF1ZXN0GiEuY29udGVudGh1Yi52MS5QbGFuUmVwZWFsUmVzcG9uc2USXQoOUGxhbldpdGhkcmF3YWwSJC5jb250ZW50aHViLnYxLlBsYW5XaXRoZHJhd2FsUmVxdWVzdBolLmNvbnRlbnRodWIudjEuUGxhbldpdGhkcmF3YWxSZXNwb25zZRJpChJEcm9wUGxhbm5lZFJlbGVhc2USKC5jb250ZW50aHViLnYxLkRyb3BQbGFubmVkUmVsZWFzZVJlcXVlc3QaKS5jb250ZW50aHViLnYxLkRyb3BQbGFubmVkUmVsZWFzZVJlc3BvbnNlEl0KDlVwZ3JhZGVDb250ZW50EiQuY29udGVudGh1Yi52MS5VcGdyYWRlQ29udGVudFJlcXVlc3QaJS5jb250ZW50aHViLnYxLlVwZ3JhZGVDb250ZW50UmVzcG9uc2USZgoRUmVjb3JkQ2hlY2tSZXN1bHQSJy5jb250ZW50aHViLnYxLlJlY29yZENoZWNrUmVzdWx0UmVxdWVzdBooLmNvbnRlbnRodWIudjEuUmVjb3JkQ2hlY2tSZXN1bHRSZXNwb25zZRJjChBMaXN0Q2hlY2tSZXN1bHRzEiYuY29udGVudGh1Yi52MS5MaXN0Q2hlY2tSZXN1bHRzUmVxdWVzdBonLmNvbnRlbnRodWIudjEuTGlzdENoZWNrUmVzdWx0c1Jlc3BvbnNlEmAKD1ZhbGlkYXRlUHVibGlzaBIlLmNvbnRlbnRodWIudjEuVmFsaWRhdGVQdWJsaXNoUmVxdWVzdBomLmNvbnRlbnRodWIudjEuVmFsaWRhdGVQdWJsaXNoUmVzcG9uc2USSAoHUHVibGlzaBIdLmNvbnRlbnRodWIudjEuUHVibGlzaFJlcXVlc3QaHi5jb250ZW50aHViLnYxLlB1Ymxpc2hSZXNwb25zZUI8WjpnaXRodWIuY29tL2tua2NzL2NvbnRlbnRodWIvZ2VuL2NvbnRlbnRodWIvdjE7Y29udGVudGh1YnYxYgZwcm90bzM\", [file_contenthub_v1_graph_warnings, file_contenthub_v1_merge, file_contenthub_v1_planning, file_contenthub_v1_release, file_contenthub_v1_workspace_config, file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * Source is the publication that triggered a Change Set (CONTEXT.md), such\n * as 2026-09-20, \"BGBl. 2026 I Nr. 270\". Release Spec fields can be prefilled\n * from either part.\n *\n * @generated from message contenthub.v1.Source\n */\nexport type Source = Message<\"contenthub.v1.Source\"> & {\n /**\n * The day it was published, as YYYY-MM-DD.\n *\n * @generated from field: string date = 1;\n */\n date: string;\n\n /**\n * How it is cited. At most 500 characters, one line.\n *\n * @generated from field: string reference = 2;\n */\n reference: string;\n};\n\n/**\n * Describes the message contenthub.v1.Source.\n * Use `create(SourceSchema)` to create a new message.\n */\nexport const SourceSchema: GenMessage<Source> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 0);\n\n/**\n * ChangeSet is a Change Set as editors see it.\n *\n * @generated from message contenthub.v1.ChangeSet\n */\nexport type ChangeSet = Message<\"contenthub.v1.ChangeSet\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The Source it records; absent when it records none, as a one-off\n * correction does.\n *\n * @generated from field: contenthub.v1.Source source = 3;\n */\n source?: Source | undefined;\n\n /**\n * @generated from field: contenthub.v1.ChangeSetState state = 4;\n */\n state: ChangeSetState;\n\n /**\n * Who opened it: the token's subject.\n *\n * @generated from field: string created_by = 5;\n */\n createdBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * When it was published or discarded; absent while it is open.\n *\n * @generated from field: google.protobuf.Timestamp close_time = 7;\n */\n closeTime?: Timestamp | undefined;\n\n /**\n * Its Chains, in the order they were started. Empty in ListChangeSets, and\n * for a discarded Change Set: the Content born in it is gone.\n *\n * @generated from field: repeated contenthub.v1.Chain chains = 8;\n */\n chains: Chain[];\n\n /**\n * The Change Sets it depends on, whatever their state. Empty in\n * ListChangeSets.\n *\n * @generated from field: repeated string depends_on_change_set_ids = 9;\n */\n dependsOnChangeSetIds: string[];\n\n /**\n * Its Planned Releases, proposed ones included, in the order they were\n * planned. Empty in ListChangeSets.\n *\n * @generated from field: repeated contenthub.v1.PlannedRelease planned_releases = 10;\n */\n plannedReleases: PlannedRelease[];\n\n /**\n * The slug of its status in statushub's `contenthub/change_set` catalogue\n * (ADR 0014); empty for an unknown status, which a Change Set has until\n * someone first sets one. A slug the catalogue no longer holds is unknown\n * too. Frozen once the Change Set is closed.\n *\n * @generated from field: string status = 11;\n */\n status: string;\n\n /**\n * Who is working on it now: odon user ids, in the order they were set.\n *\n * @generated from field: repeated string assignee_ids = 12;\n */\n assigneeIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSet.\n * Use `create(ChangeSetSchema)` to create a new message.\n */\nexport const ChangeSetSchema: GenMessage<ChangeSet> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 1);\n\n/**\n * Chain is the ordered Branches of one Content inside a Change Set.\n *\n * @generated from message contenthub.v1.Chain\n */\nexport type Chain = Message<\"contenthub.v1.Chain\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * True when the Content was born in this Change Set, and so has no Main\n * Branch until it is published.\n *\n * @generated from field: bool born = 3;\n */\n born: boolean;\n\n /**\n * Its Branches, by position.\n *\n * @generated from field: repeated contenthub.v1.Branch branches = 4;\n */\n branches: Branch[];\n};\n\n/**\n * Describes the message contenthub.v1.Chain.\n * Use `create(ChainSchema)` to create a new message.\n */\nexport const ChainSchema: GenMessage<Chain> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 2);\n\n/**\n * Branch is one Branch of a Chain, with its head.\n *\n * @generated from message contenthub.v1.Branch\n */\nexport type Branch = Message<\"contenthub.v1.Branch\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Its place in its Chain, from 0.\n *\n * @generated from field: int32 position = 2;\n */\n position: number;\n\n /**\n * @generated from field: contenthub.v1.BranchKind kind = 3;\n */\n kind: BranchKind;\n\n /**\n * The Revision the Branch points at: what a save on it names as\n * expected_head_id.\n *\n * @generated from field: string head_revision_id = 4;\n */\n headRevisionId: string;\n\n /**\n * On a Chain on Dated Content, the date its change takes effect, as\n * YYYY-MM-DD: an editorial Branch's date, or the first day of the Release\n * a Carry-forward link carries. Empty on a final link merging Main's head\n * and on undated Content.\n *\n * @generated from field: string effective_on = 5;\n */\n effectiveOn: string;\n\n /**\n * On a Chain on Dated Content, the Release the Branch carries: the first\n * Branch's fork Release, or the later Release a Carry-forward link\n * carries. Empty where it carries Main's head or nothing.\n *\n * @generated from field: string carried_release_id = 6;\n */\n carriedReleaseId: string;\n\n /**\n * Whether a Pending Merge is stored on it, which GetPendingMerge reads.\n *\n * @generated from field: bool has_pending_merge = 7;\n */\n hasPendingMerge: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.Branch.\n * Use `create(BranchSchema)` to create a new message.\n */\nexport const BranchSchema: GenMessage<Branch> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 3);\n\n/**\n * @generated from message contenthub.v1.CreateChangeSetRequest\n */\nexport type CreateChangeSetRequest = Message<\"contenthub.v1.CreateChangeSetRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, one line. Surrounding\n * whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * The Source, when the Change Set has one. Both its date and its\n * reference are then required.\n *\n * @generated from field: contenthub.v1.Source source = 2;\n */\n source?: Source | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateChangeSetRequest.\n * Use `create(CreateChangeSetRequestSchema)` to create a new message.\n */\nexport const CreateChangeSetRequestSchema: GenMessage<CreateChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 4);\n\n/**\n * @generated from message contenthub.v1.CreateChangeSetResponse\n */\nexport type CreateChangeSetResponse = Message<\"contenthub.v1.CreateChangeSetResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateChangeSetResponse.\n * Use `create(CreateChangeSetResponseSchema)` to create a new message.\n */\nexport const CreateChangeSetResponseSchema: GenMessage<CreateChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 5);\n\n/**\n * @generated from message contenthub.v1.GetChangeSetRequest\n */\nexport type GetChangeSetRequest = Message<\"contenthub.v1.GetChangeSetRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetChangeSetRequest.\n * Use `create(GetChangeSetRequestSchema)` to create a new message.\n */\nexport const GetChangeSetRequestSchema: GenMessage<GetChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 6);\n\n/**\n * @generated from message contenthub.v1.GetChangeSetResponse\n */\nexport type GetChangeSetResponse = Message<\"contenthub.v1.GetChangeSetResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetChangeSetResponse.\n * Use `create(GetChangeSetResponseSchema)` to create a new message.\n */\nexport const GetChangeSetResponseSchema: GenMessage<GetChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 7);\n\n/**\n * @generated from message contenthub.v1.UpdateChangeSetRequest\n */\nexport type UpdateChangeSetRequest = Message<\"contenthub.v1.UpdateChangeSetRequest\"> & {\n /**\n * The Change Set to change.\n *\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The new name, when update_mask names `name`. Required then, as at\n * CreateChangeSet: not blank, at most 200 characters, one line.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The new Source, when update_mask names `source`: both its date and its\n * reference, or absent to clear it (AIP-134), as a one-off correction\n * records none.\n *\n * @generated from field: contenthub.v1.Source source = 3;\n */\n source?: Source | undefined;\n\n /**\n * Required, and naming at least one of `name` and `source`: what to\n * change. A field it doesn't name is left as it is, whatever the request\n * holds for it; any other name is InvalidArgument.\n *\n * @generated from field: contenthub.v1.FieldMask update_mask = 4;\n */\n updateMask?: FieldMask | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateChangeSetRequest.\n * Use `create(UpdateChangeSetRequestSchema)` to create a new message.\n */\nexport const UpdateChangeSetRequestSchema: GenMessage<UpdateChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 8);\n\n/**\n * @generated from message contenthub.v1.UpdateChangeSetResponse\n */\nexport type UpdateChangeSetResponse = Message<\"contenthub.v1.UpdateChangeSetResponse\"> & {\n /**\n * The Change Set, as GetChangeSet reads it after the change.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateChangeSetResponse.\n * Use `create(UpdateChangeSetResponseSchema)` to create a new message.\n */\nexport const UpdateChangeSetResponseSchema: GenMessage<UpdateChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 9);\n\n/**\n * @generated from message contenthub.v1.DiscardChangeSetRequest\n */\nexport type DiscardChangeSetRequest = Message<\"contenthub.v1.DiscardChangeSetRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DiscardChangeSetRequest.\n * Use `create(DiscardChangeSetRequestSchema)` to create a new message.\n */\nexport const DiscardChangeSetRequestSchema: GenMessage<DiscardChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 10);\n\n/**\n * @generated from message contenthub.v1.DiscardChangeSetResponse\n */\nexport type DiscardChangeSetResponse = Message<\"contenthub.v1.DiscardChangeSetResponse\"> & {\n /**\n * The Change Set, discarded.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.DiscardChangeSetResponse.\n * Use `create(DiscardChangeSetResponseSchema)` to create a new message.\n */\nexport const DiscardChangeSetResponseSchema: GenMessage<DiscardChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 11);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetStatusRequest\n */\nexport type SetChangeSetStatusRequest = Message<\"contenthub.v1.SetChangeSetStatusRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The status the caller last saw, exactly as ChangeSet.status read it:\n * empty when it read empty, and the slug itself when it read a slug the\n * catalogue no longer holds. Required in that sense: a move is made from\n * a status the caller saw, never from whatever it is now.\n *\n * @generated from field: string expected_status = 2;\n */\n expectedStatus: string;\n\n /**\n * The slug to move to. Required: there is no move to an unknown status.\n *\n * @generated from field: string status = 3;\n */\n status: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetStatusRequest.\n * Use `create(SetChangeSetStatusRequestSchema)` to create a new message.\n */\nexport const SetChangeSetStatusRequestSchema: GenMessage<SetChangeSetStatusRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 12);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetStatusResponse\n */\nexport type SetChangeSetStatusResponse = Message<\"contenthub.v1.SetChangeSetStatusResponse\"> & {\n /**\n * The Change Set, with its new status.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetStatusResponse.\n * Use `create(SetChangeSetStatusResponseSchema)` to create a new message.\n */\nexport const SetChangeSetStatusResponseSchema: GenMessage<SetChangeSetStatusResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 13);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetAssigneesRequest\n */\nexport type SetChangeSetAssigneesRequest = Message<\"contenthub.v1.SetChangeSetAssigneesRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The whole new set: odon user ids, each given once, at most 50. Empty\n * unassigns everyone.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetAssigneesRequest.\n * Use `create(SetChangeSetAssigneesRequestSchema)` to create a new message.\n */\nexport const SetChangeSetAssigneesRequestSchema: GenMessage<SetChangeSetAssigneesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 14);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetAssigneesResponse\n */\nexport type SetChangeSetAssigneesResponse = Message<\"contenthub.v1.SetChangeSetAssigneesResponse\"> & {\n /**\n * The Change Set, with its assignees.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetAssigneesResponse.\n * Use `create(SetChangeSetAssigneesResponseSchema)` to create a new message.\n */\nexport const SetChangeSetAssigneesResponseSchema: GenMessage<SetChangeSetAssigneesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 15);\n\n/**\n * CopyFrom names what new Content is a copy of: a Release, or a Revision,\n * of any Content of the workspace. The copy records it as its origin.\n *\n * @generated from message contenthub.v1.CopyFrom\n */\nexport type CopyFrom = Message<\"contenthub.v1.CopyFrom\"> & {\n /**\n * @generated from oneof contenthub.v1.CopyFrom.source\n */\n source: {\n /**\n * @generated from field: string release_id = 1;\n */\n value: string;\n case: \"releaseId\";\n } | {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.CopyFrom.\n * Use `create(CopyFromSchema)` to create a new message.\n */\nexport const CopyFromSchema: GenMessage<CopyFrom> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 16);\n\n/**\n * @generated from message contenthub.v1.CreateContentRequest\n */\nexport type CreateContentRequest = Message<\"contenthub.v1.CreateContentRequest\"> & {\n /**\n * The open Change Set to create the Content in.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Content's id, when the client reserved one (a KSUID it minted), so\n * that an import can write first Revisions that already reference each\n * other (ADR 0003). Empty mints one. An id already taken in the workspace\n * is AlreadyExists.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The Blueprint Release the Content pins: a Release of a content\n * Blueprint. With copy_from it may be left empty, to pin what the source\n * pins.\n *\n * @generated from field: string blueprint_release_id = 3;\n */\n blueprintReleaseId: string;\n\n /**\n * The first Revision's data, a JSON object keyed by field accessor. With\n * copy_from it may be left absent, to take the source's data unchanged;\n * given, it is the whole data, stored as given.\n *\n * @generated from field: google.protobuf.Struct data = 4;\n */\n data?: JsonObject | undefined;\n\n /**\n * What the Content is a copy of, if anything.\n *\n * @generated from field: contenthub.v1.CopyFrom copy_from = 5;\n */\n copyFrom?: CopyFrom | undefined;\n\n /**\n * The Collections to file the Content in as it is created, at most 100,\n * as SetContentCollections files it. Content created in a Restricted\n * Collection is never visible to anyone else, not even briefly (ADR\n * 0017); filing into a Restricted Collection needs `editor` on it. A copy\n * of a citer files its Footnote Bodies' copies in the same Collections.\n *\n * @generated from field: repeated string collection_ids = 6;\n */\n collectionIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 7;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateContentRequest.\n * Use `create(CreateContentRequestSchema)` to create a new message.\n */\nexport const CreateContentRequestSchema: GenMessage<CreateContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 17);\n\n/**\n * @generated from message contenthub.v1.CreateContentResponse\n */\nexport type CreateContentResponse = Message<\"contenthub.v1.CreateContentResponse\"> & {\n /**\n * The Content, as GetContent reads it in the Change Set.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateContentResponse.\n * Use `create(CreateContentResponseSchema)` to create a new message.\n */\nexport const CreateContentResponseSchema: GenMessage<CreateContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 18);\n\n/**\n * FieldMask names the fields a partial write carries: a partial save's\n * Content fields, or the Change Set fields UpdateChangeSet changes.\n *\n * @generated from message contenthub.v1.FieldMask\n */\nexport type FieldMask = Message<\"contenthub.v1.FieldMask\"> & {\n /**\n * Top-level field accessors.\n *\n * @generated from field: repeated string fields = 1;\n */\n fields: string[];\n};\n\n/**\n * Describes the message contenthub.v1.FieldMask.\n * Use `create(FieldMaskSchema)` to create a new message.\n */\nexport const FieldMaskSchema: GenMessage<FieldMask> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 19);\n\n/**\n * @generated from message contenthub.v1.SaveRevisionRequest\n */\nexport type SaveRevisionRequest = Message<\"contenthub.v1.SaveRevisionRequest\"> & {\n /**\n * The Branch to save on.\n *\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * The head Revision the author edited. Required: a save that names no head\n * could silently overwrite someone else's.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n\n /**\n * The data. Without a field_mask it is the whole new Revision. With one,\n * it holds only the fields the mask names.\n *\n * @generated from field: google.protobuf.Struct data = 3;\n */\n data?: JsonObject | undefined;\n\n /**\n * Makes the save partial: the new Revision is the head's data with each\n * field the mask names replaced by its value in data, or removed when data\n * doesn't hold it. Every other field is carried over unchanged, so the new\n * Revision is still whole. A field in data that the mask doesn't name is\n * InvalidArgument.\n *\n * @generated from field: contenthub.v1.FieldMask field_mask = 4;\n */\n fieldMask?: FieldMask | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SaveRevisionRequest.\n * Use `create(SaveRevisionRequestSchema)` to create a new message.\n */\nexport const SaveRevisionRequestSchema: GenMessage<SaveRevisionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 20);\n\n/**\n * @generated from message contenthub.v1.SaveRevisionResponse\n */\nexport type SaveRevisionResponse = Message<\"contenthub.v1.SaveRevisionResponse\"> & {\n /**\n * The Content, as GetContent reads it in the Change Set: its data is the\n * saved Revision's.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SaveRevisionResponse.\n * Use `create(SaveRevisionResponseSchema)` to create a new message.\n */\nexport const SaveRevisionResponseSchema: GenMessage<SaveRevisionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 21);\n\n/**\n * Content is one Content as read at one Revision: in a Change Set, the head\n * of its Chain's last Branch; on Main, the head of its Main Branch.\n *\n * @generated from message contenthub.v1.Content\n */\nexport type Content = Message<\"contenthub.v1.Content\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Blueprint, and the Blueprint Release the Revision pins.\n *\n * @generated from field: string blueprint_id = 2;\n */\n blueprintId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 3;\n */\n blueprintReleaseId: string;\n\n /**\n * The Revision read.\n *\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * Its data, a JSON object keyed by field accessor.\n *\n * @generated from field: google.protobuf.Struct data = 5;\n */\n data?: JsonObject | undefined;\n\n /**\n * The Change Set and Branch it was read on; empty when read on Main.\n *\n * @generated from field: string change_set_id = 6;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string branch_id = 7;\n */\n branchId: string;\n\n /**\n * When the Revision was written.\n *\n * @generated from field: google.protobuf.Timestamp revision_create_time = 8;\n */\n revisionCreateTime?: Timestamp | undefined;\n\n /**\n * The Release it was read at, in ListContents' In Force view; empty\n * elsewhere.\n *\n * @generated from field: string release_id = 9;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Content.\n * Use `create(ContentSchema)` to create a new message.\n */\nexport const ContentSchema: GenMessage<Content> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 22);\n\n/**\n * @generated from message contenthub.v1.PreviewChainRequest\n */\nexport type PreviewChainRequest = Message<\"contenthub.v1.PreviewChainRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Content the Chain would start on.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Required: the date the change takes effect, as YYYY-MM-DD.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * The period to preview against the Content's Releases; absent previews\n * one from effective_on, with an open end.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 4;\n */\n validityPeriod?: ValidityPeriod | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PreviewChainRequest.\n * Use `create(PreviewChainRequestSchema)` to create a new message.\n */\nexport const PreviewChainRequestSchema: GenMessage<PreviewChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 23);\n\n/**\n * @generated from message contenthub.v1.PreviewChainResponse\n */\nexport type PreviewChainResponse = Message<\"contenthub.v1.PreviewChainResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChainPreview preview = 1;\n */\n preview?: ChainPreview | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PreviewChainResponse.\n * Use `create(PreviewChainResponseSchema)` to create a new message.\n */\nexport const PreviewChainResponseSchema: GenMessage<PreviewChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 24);\n\n/**\n * ChainPreview is what a Chain would be and meet, as PreviewChain found it.\n *\n * @generated from message contenthub.v1.ChainPreview\n */\nexport type ChainPreview = Message<\"contenthub.v1.ChainPreview\"> & {\n /**\n * The Release the Chain would fork from: the Release In Force on the date\n * (in a Change Set with dependencies, possibly a dependency's Planned\n * Release, under the id it will be cut with). Empty in a gap, where it\n * forks from Main's head.\n *\n * @generated from field: string fork_release_id = 1;\n */\n forkReleaseId: string;\n\n /**\n * The later Releases In Force it would carry forward through, by date:\n * one Carry-forward link each.\n *\n * @generated from field: repeated string carry_forward_release_ids = 2;\n */\n carryForwardReleaseIds: string[];\n\n /**\n * Whether a final link would merge Main's head, which is not the last\n * Release's Revision.\n *\n * @generated from field: bool merges_main = 3;\n */\n mergesMain: boolean;\n\n /**\n * The period previewed, an open end resolved as Publish would resolve it\n * now.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 4;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * The Releases the period cuts into, by first day: planning it would\n * propose a date-only cut of each.\n *\n * @generated from field: repeated contenthub.v1.CutInto cut_into = 5;\n */\n cutInto: CutInto[];\n\n /**\n * The Releases the period covers entirely, by first day: planning it as\n * it is would be refused.\n *\n * @generated from field: repeated string covered_release_ids = 6;\n */\n coveredReleaseIds: string[];\n\n /**\n * The Releases of the Content that the Change Set's Planned Releases\n * supersede already, so the period meets none of them.\n *\n * @generated from field: repeated contenthub.v1.SupersededRelease superseded = 7;\n */\n superseded: SupersededRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.ChainPreview.\n * Use `create(ChainPreviewSchema)` to create a new message.\n */\nexport const ChainPreviewSchema: GenMessage<ChainPreview> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 25);\n\n/**\n * CutInto is one Release a period cuts into.\n *\n * @generated from message contenthub.v1.CutInto\n */\nexport type CutInto = Message<\"contenthub.v1.CutInto\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * Whether it is a Planned Release (of this Change Set or of one it\n * depends on) rather than a published one.\n *\n * @generated from field: bool planned = 2;\n */\n planned: boolean;\n\n /**\n * What is left of its Validity Period: the period the proposed date-only\n * cut would give it.\n *\n * @generated from field: contenthub.v1.ValidityPeriod kept = 3;\n */\n kept?: ValidityPeriod | undefined;\n\n /**\n * When the period lies strictly inside it, the part after: a second\n * proposed cut resumes its wording then. Absent otherwise.\n *\n * @generated from field: contenthub.v1.ValidityPeriod tail = 4;\n */\n tail?: ValidityPeriod | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CutInto.\n * Use `create(CutIntoSchema)` to create a new message.\n */\nexport const CutIntoSchema: GenMessage<CutInto> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 26);\n\n/**\n * SupersededRelease is one Release a Planned Release supersedes.\n *\n * @generated from message contenthub.v1.SupersededRelease\n */\nexport type SupersededRelease = Message<\"contenthub.v1.SupersededRelease\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * @generated from field: string by_planned_release_id = 2;\n */\n byPlannedReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.SupersededRelease.\n * Use `create(SupersededReleaseSchema)` to create a new message.\n */\nexport const SupersededReleaseSchema: GenMessage<SupersededRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 27);\n\n/**\n * @generated from message contenthub.v1.StartChainRequest\n */\nexport type StartChainRequest = Message<\"contenthub.v1.StartChainRequest\"> & {\n /**\n * The open Change Set to start the Chain in.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Content to change.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The date the change takes effect, as YYYY-MM-DD: required for Dated\n * Content, refused for undated Content.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartChainRequest.\n * Use `create(StartChainRequestSchema)` to create a new message.\n */\nexport const StartChainRequestSchema: GenMessage<StartChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 28);\n\n/**\n * @generated from message contenthub.v1.StartChainResponse\n */\nexport type StartChainResponse = Message<\"contenthub.v1.StartChainResponse\"> & {\n /**\n * The Change Set, with the new Chain.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * The Release the Chain forked from, as ChainPreview.fork_release_id;\n * empty for undated Content and in a gap.\n *\n * @generated from field: string fork_release_id = 3;\n */\n forkReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartChainResponse.\n * Use `create(StartChainResponseSchema)` to create a new message.\n */\nexport const StartChainResponseSchema: GenMessage<StartChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 29);\n\n/**\n * @generated from message contenthub.v1.AppendBranchRequest\n */\nexport type AppendBranchRequest = Message<\"contenthub.v1.AppendBranchRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Required: the date the new Branch's change takes effect, as\n * YYYY-MM-DD, after the Chain's last editorial Branch's.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AppendBranchRequest.\n * Use `create(AppendBranchRequestSchema)` to create a new message.\n */\nexport const AppendBranchRequestSchema: GenMessage<AppendBranchRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 30);\n\n/**\n * @generated from message contenthub.v1.AppendBranchResponse\n */\nexport type AppendBranchResponse = Message<\"contenthub.v1.AppendBranchResponse\"> & {\n /**\n * The Change Set, with the Chain re-laid.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The new editorial Branch.\n *\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.AppendBranchResponse.\n * Use `create(AppendBranchResponseSchema)` to create a new message.\n */\nexport const AppendBranchResponseSchema: GenMessage<AppendBranchResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 31);\n\n/**\n * @generated from message contenthub.v1.DropChainRequest\n */\nexport type DropChainRequest = Message<\"contenthub.v1.DropChainRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DropChainRequest.\n * Use `create(DropChainRequestSchema)` to create a new message.\n */\nexport const DropChainRequestSchema: GenMessage<DropChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 32);\n\n/**\n * @generated from message contenthub.v1.DropChainResponse\n */\nexport type DropChainResponse = Message<\"contenthub.v1.DropChainResponse\"> & {\n /**\n * The Change Set, without the Chain.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.DropChainResponse.\n * Use `create(DropChainResponseSchema)` to create a new message.\n */\nexport const DropChainResponseSchema: GenMessage<DropChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 33);\n\n/**\n * @generated from message contenthub.v1.StartEditingRequest\n */\nexport type StartEditingRequest = Message<\"contenthub.v1.StartEditingRequest\"> & {\n /**\n * The published Content to change.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The open Change Set to start the Chain in; empty opens a new one.\n *\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n\n /**\n * As StartChainRequest.effective_on.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * The new Change Set's name, when change_set_id is empty: at most 200\n * characters, one line. Empty names it after the Content.\n *\n * @generated from field: string change_set_name = 4;\n */\n changeSetName: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartEditingRequest.\n * Use `create(StartEditingRequestSchema)` to create a new message.\n */\nexport const StartEditingRequestSchema: GenMessage<StartEditingRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 34);\n\n/**\n * @generated from message contenthub.v1.StartEditingResponse\n */\nexport type StartEditingResponse = Message<\"contenthub.v1.StartEditingResponse\"> & {\n /**\n * The Change Set the Chain was started in, new or given.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Content as read on the Branch to edit, the Chain's first: what a\n * save names as branch_id and expected_head_id.\n *\n * @generated from field: contenthub.v1.Content content = 2;\n */\n content?: Content | undefined;\n\n /**\n * As StartChainResponse.fork_release_id.\n *\n * @generated from field: string fork_release_id = 3;\n */\n forkReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartEditingResponse.\n * Use `create(StartEditingResponseSchema)` to create a new message.\n */\nexport const StartEditingResponseSchema: GenMessage<StartEditingResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 35);\n\n/**\n * @generated from message contenthub.v1.UpdateFromMainRequest\n */\nexport type UpdateFromMainRequest = Message<\"contenthub.v1.UpdateFromMainRequest\"> & {\n /**\n * The open Change Set.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * One of its Chains to update alone; empty updates every Chain.\n *\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateFromMainRequest.\n * Use `create(UpdateFromMainRequestSchema)` to create a new message.\n */\nexport const UpdateFromMainRequestSchema: GenMessage<UpdateFromMainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 36);\n\n/**\n * @generated from message contenthub.v1.UpdateFromMainResponse\n */\nexport type UpdateFromMainResponse = Message<\"contenthub.v1.UpdateFromMainResponse\"> & {\n /**\n * The Change Set as the update left it.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Branches whose heads moved to a merge Revision, by id.\n *\n * @generated from field: repeated string merged_branch_ids = 2;\n */\n mergedBranchIds: string[];\n\n /**\n * The Pending Merges this update stored, by Branch id.\n *\n * @generated from field: repeated contenthub.v1.PendingMerge conflicted = 3;\n */\n conflicted: PendingMerge[];\n\n /**\n * The Pending Merges stored before it, on Branches it left alone, by\n * Branch id: resolve or abort them, then update again.\n *\n * @generated from field: repeated contenthub.v1.PendingMerge pending = 4;\n */\n pending: PendingMerge[];\n\n /**\n * The Carry-forward links a re-lay took out of their Chains, because the\n * Release they carried no longer counts: their life ended, as with\n * DropChain.\n *\n * @generated from field: repeated string ended_branch_ids = 5;\n */\n endedBranchIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.UpdateFromMainResponse.\n * Use `create(UpdateFromMainResponseSchema)` to create a new message.\n */\nexport const UpdateFromMainResponseSchema: GenMessage<UpdateFromMainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 37);\n\n/**\n * @generated from message contenthub.v1.GetPendingMergeRequest\n */\nexport type GetPendingMergeRequest = Message<\"contenthub.v1.GetPendingMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetPendingMergeRequest.\n * Use `create(GetPendingMergeRequestSchema)` to create a new message.\n */\nexport const GetPendingMergeRequestSchema: GenMessage<GetPendingMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 38);\n\n/**\n * @generated from message contenthub.v1.GetPendingMergeResponse\n */\nexport type GetPendingMergeResponse = Message<\"contenthub.v1.GetPendingMergeResponse\"> & {\n /**\n * The Pending Merge; unset, as is everything below, when the Branch has\n * none.\n *\n * @generated from field: contenthub.v1.PendingMerge pending_merge = 1;\n */\n pendingMerge?: PendingMerge | undefined;\n\n /**\n * The Blueprint Release a resolution pins: the newer of the two sides'.\n *\n * @generated from field: string blueprint_release_id = 2;\n */\n blueprintReleaseId: string;\n\n /**\n * The fields a resolution must decide, by path.\n *\n * @generated from field: repeated contenthub.v1.MergeField fields = 3;\n */\n fields: MergeField[];\n\n /**\n * The data a resolution starts from: every field but those in fields\n * merged, those at their base value.\n *\n * @generated from field: google.protobuf.Struct merged = 4;\n */\n merged?: JsonObject | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetPendingMergeResponse.\n * Use `create(GetPendingMergeResponseSchema)` to create a new message.\n */\nexport const GetPendingMergeResponseSchema: GenMessage<GetPendingMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 39);\n\n/**\n * @generated from message contenthub.v1.ResolveMergeRequest\n */\nexport type ResolveMergeRequest = Message<\"contenthub.v1.ResolveMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * The Branch's head, the Pending Merge's ours: required, as for a save.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n\n /**\n * One decision per field GetPendingMerge lists, no more.\n *\n * @generated from field: repeated contenthub.v1.FieldResolution resolutions = 3;\n */\n resolutions: FieldResolution[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.ResolveMergeRequest.\n * Use `create(ResolveMergeRequestSchema)` to create a new message.\n */\nexport const ResolveMergeRequestSchema: GenMessage<ResolveMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 40);\n\n/**\n * @generated from message contenthub.v1.ResolveMergeResponse\n */\nexport type ResolveMergeResponse = Message<\"contenthub.v1.ResolveMergeResponse\"> & {\n /**\n * The Content as read on the Branch: its data is the resolution's.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ResolveMergeResponse.\n * Use `create(ResolveMergeResponseSchema)` to create a new message.\n */\nexport const ResolveMergeResponseSchema: GenMessage<ResolveMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 41);\n\n/**\n * @generated from message contenthub.v1.AbortMergeRequest\n */\nexport type AbortMergeRequest = Message<\"contenthub.v1.AbortMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AbortMergeRequest.\n * Use `create(AbortMergeRequestSchema)` to create a new message.\n */\nexport const AbortMergeRequestSchema: GenMessage<AbortMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 42);\n\n/**\n * @generated from message contenthub.v1.AbortMergeResponse\n */\nexport type AbortMergeResponse = Message<\"contenthub.v1.AbortMergeResponse\"> & {\n /**\n * The Pending Merge it dropped.\n *\n * @generated from field: contenthub.v1.PendingMerge aborted = 1;\n */\n aborted?: PendingMerge | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.AbortMergeResponse.\n * Use `create(AbortMergeResponseSchema)` to create a new message.\n */\nexport const AbortMergeResponseSchema: GenMessage<AbortMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 43);\n\n/**\n * @generated from message contenthub.v1.AddDependencyRequest\n */\nexport type AddDependencyRequest = Message<\"contenthub.v1.AddDependencyRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The open Change Set it is to depend on.\n *\n * @generated from field: string depends_on_change_set_id = 2;\n */\n dependsOnChangeSetId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AddDependencyRequest.\n * Use `create(AddDependencyRequestSchema)` to create a new message.\n */\nexport const AddDependencyRequestSchema: GenMessage<AddDependencyRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 44);\n\n/**\n * @generated from message contenthub.v1.AddDependencyResponse\n */\nexport type AddDependencyResponse = Message<\"contenthub.v1.AddDependencyResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.AddDependencyResponse.\n * Use `create(AddDependencyResponseSchema)` to create a new message.\n */\nexport const AddDependencyResponseSchema: GenMessage<AddDependencyResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 45);\n\n/**\n * @generated from message contenthub.v1.RemoveDependencyRequest\n */\nexport type RemoveDependencyRequest = Message<\"contenthub.v1.RemoveDependencyRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string depends_on_change_set_id = 2;\n */\n dependsOnChangeSetId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveDependencyRequest.\n * Use `create(RemoveDependencyRequestSchema)` to create a new message.\n */\nexport const RemoveDependencyRequestSchema: GenMessage<RemoveDependencyRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 46);\n\n/**\n * @generated from message contenthub.v1.RemoveDependencyResponse\n */\nexport type RemoveDependencyResponse = Message<\"contenthub.v1.RemoveDependencyResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveDependencyResponse.\n * Use `create(RemoveDependencyResponseSchema)` to create a new message.\n */\nexport const RemoveDependencyResponseSchema: GenMessage<RemoveDependencyResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 47);\n\n/**\n * @generated from message contenthub.v1.PlanReleaseRequest\n */\nexport type PlanReleaseRequest = Message<\"contenthub.v1.PlanReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The editorial Branch whose head at Publish the Release pins.\n *\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n\n /**\n * Required for Dated Content, refused for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Release Spec values, keyed by the Release Spec Field's accessor and\n * checked against the Release Spec of the Blueprint Release the Branch's\n * head pins.\n *\n * @generated from field: google.protobuf.Struct release_spec = 4;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Releases of the Content the new Release will Supersede: a correction\n * names the Release it corrects. Superseding a Release the Validity\n * Period would cover is how a cover is resolved.\n *\n * @generated from field: repeated string supersedes_release_ids = 5;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanReleaseRequest.\n * Use `create(PlanReleaseRequestSchema)` to create a new message.\n */\nexport const PlanReleaseRequestSchema: GenMessage<PlanReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 48);\n\n/**\n * @generated from message contenthub.v1.PlanReleaseResponse\n */\nexport type PlanReleaseResponse = Message<\"contenthub.v1.PlanReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PlanReleaseResponse.\n * Use `create(PlanReleaseResponseSchema)` to create a new message.\n */\nexport const PlanReleaseResponseSchema: GenMessage<PlanReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 49);\n\n/**\n * @generated from message contenthub.v1.UpdatePlannedReleaseRequest\n */\nexport type UpdatePlannedReleaseRequest = Message<\"contenthub.v1.UpdatePlannedReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string planned_release_id = 2;\n */\n plannedReleaseId: string;\n\n /**\n * The new Validity Period; absent keeps it.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * The new Release Spec values, all of them; absent keeps them.\n *\n * @generated from field: google.protobuf.Struct release_spec = 4;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * The new list of Releases it supersedes, for a Release of a Branch's\n * head; absent keeps it, an empty list clears it.\n *\n * @generated from field: contenthub.v1.ReleaseIdList supersedes = 5;\n */\n supersedes?: ReleaseIdList | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdatePlannedReleaseRequest.\n * Use `create(UpdatePlannedReleaseRequestSchema)` to create a new message.\n */\nexport const UpdatePlannedReleaseRequestSchema: GenMessage<UpdatePlannedReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 50);\n\n/**\n * @generated from message contenthub.v1.UpdatePlannedReleaseResponse\n */\nexport type UpdatePlannedReleaseResponse = Message<\"contenthub.v1.UpdatePlannedReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdatePlannedReleaseResponse.\n * Use `create(UpdatePlannedReleaseResponseSchema)` to create a new message.\n */\nexport const UpdatePlannedReleaseResponseSchema: GenMessage<UpdatePlannedReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 51);\n\n/**\n * UpgradeTarget is one Content an upgrade names, with the head the caller\n * saw: the head of the last Branch of its Chain in the Change Set.\n *\n * @generated from message contenthub.v1.UpgradeTarget\n */\nexport type UpgradeTarget = Message<\"contenthub.v1.UpgradeTarget\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Required: an upgrade that names no head could silently build on a save\n * the caller never saw.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeTarget.\n * Use `create(UpgradeTargetSchema)` to create a new message.\n */\nexport const UpgradeTargetSchema: GenMessage<UpgradeTarget> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 52);\n\n/**\n * @generated from message contenthub.v1.UpgradeContentRequest\n */\nexport type UpgradeContentRequest = Message<\"contenthub.v1.UpgradeContentRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Blueprint Release to move to.\n *\n * @generated from field: string blueprint_release_id = 2;\n */\n blueprintReleaseId: string;\n\n /**\n * The Content to upgrade, each with the head the caller saw. Exactly one\n * of contents and all_pinning_older is given.\n *\n * @generated from field: repeated contenthub.v1.UpgradeTarget contents = 3;\n */\n contents: UpgradeTarget[];\n\n /**\n * Upgrades every Content of the Change Set whose Chain's last Branch pins\n * an older Release of the same Blueprint, at the heads it reads. None is\n * no change.\n *\n * @generated from field: bool all_pinning_older = 4;\n */\n allPinningOlder: boolean;\n\n /**\n * Top-level field accessors whose values the upgrade removes; every other\n * field is carried over unchanged.\n *\n * @generated from field: repeated string drop_fields = 5;\n */\n dropFields: string[];\n\n /**\n * The first Validity Period of Content the upgrade makes Dated: required\n * when blueprint_release_id is dated and a Content's current one isn't,\n * refused otherwise. A Blueprint never stops being dated, so an upgrade\n * from a dated Release to an undated one is FailedPrecondition.\n *\n * @generated from field: contenthub.v1.ValidityPeriod first_period = 6;\n */\n firstPeriod?: ValidityPeriod | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 7;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeContentRequest.\n * Use `create(UpgradeContentRequestSchema)` to create a new message.\n */\nexport const UpgradeContentRequestSchema: GenMessage<UpgradeContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 53);\n\n/**\n * @generated from message contenthub.v1.UpgradeContentResponse\n */\nexport type UpgradeContentResponse = Message<\"contenthub.v1.UpgradeContentResponse\"> & {\n /**\n * The Change Set with its Chains, at their new heads.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * Each upgraded Content as GetContent reads it in the Change Set, in the\n * order the request named them (by id for all_pinning_older).\n *\n * @generated from field: repeated contenthub.v1.Content contents = 2;\n */\n contents: Content[];\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeContentResponse.\n * Use `create(UpgradeContentResponseSchema)` to create a new message.\n */\nexport const UpgradeContentResponseSchema: GenMessage<UpgradeContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 54);\n\n/**\n * @generated from message contenthub.v1.RecordCheckResultRequest\n */\nexport type RecordCheckResultRequest = Message<\"contenthub.v1.RecordCheckResultRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string required_check_id = 2;\n */\n requiredCheckId: string;\n\n /**\n * The heads the check saw, id to Revision id. For a Branch-scope check,\n * exactly one: a Branch id to its head, or a Branch-less Planned\n * Release's id to the Revision it re-pins. For a Change Set-scope check,\n * every head of the Change Set: each Branch's, and each Branch-less\n * Planned Release's.\n *\n * @generated from field: map<string, string> heads = 3;\n */\n heads: { [key: string]: string };\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.CheckOutcome outcome = 4;\n */\n outcome: CheckOutcome;\n\n /**\n * Required for waived, saying why; optional otherwise. At most 2000\n * characters.\n *\n * @generated from field: string note = 5;\n */\n note: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.RecordCheckResultRequest.\n * Use `create(RecordCheckResultRequestSchema)` to create a new message.\n */\nexport const RecordCheckResultRequestSchema: GenMessage<RecordCheckResultRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 55);\n\n/**\n * @generated from message contenthub.v1.RecordCheckResultResponse\n */\nexport type RecordCheckResultResponse = Message<\"contenthub.v1.RecordCheckResultResponse\"> & {\n /**\n * @generated from field: contenthub.v1.CheckResult check_result = 1;\n */\n checkResult?: CheckResult | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RecordCheckResultResponse.\n * Use `create(RecordCheckResultResponseSchema)` to create a new message.\n */\nexport const RecordCheckResultResponseSchema: GenMessage<RecordCheckResultResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 56);\n\n/**\n * CheckResult is one recorded outcome of a Required Check (CONTEXT.md).\n *\n * @generated from message contenthub.v1.CheckResult\n */\nexport type CheckResult = Message<\"contenthub.v1.CheckResult\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string required_check_id = 3;\n */\n requiredCheckId: string;\n\n /**\n * @generated from field: map<string, string> heads = 4;\n */\n heads: { [key: string]: string };\n\n /**\n * @generated from field: contenthub.v1.CheckOutcome outcome = 5;\n */\n outcome: CheckOutcome;\n\n /**\n * @generated from field: string note = 6;\n */\n note: string;\n\n /**\n * The token's subject of whoever recorded it: a person, or a flow's\n * Run-as user.\n *\n * @generated from field: string recorded_by = 7;\n */\n recordedBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp record_time = 8;\n */\n recordTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CheckResult.\n * Use `create(CheckResultSchema)` to create a new message.\n */\nexport const CheckResultSchema: GenMessage<CheckResult> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 57);\n\n/**\n * @generated from message contenthub.v1.ListCheckResultsRequest\n */\nexport type ListCheckResultsRequest = Message<\"contenthub.v1.ListCheckResultsRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListCheckResultsRequest.\n * Use `create(ListCheckResultsRequestSchema)` to create a new message.\n */\nexport const ListCheckResultsRequestSchema: GenMessage<ListCheckResultsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 58);\n\n/**\n * @generated from message contenthub.v1.ListCheckResultsResponse\n */\nexport type ListCheckResultsResponse = Message<\"contenthub.v1.ListCheckResultsResponse\"> & {\n /**\n * By check name, then in the Change Set's order: Branches by Chain, then\n * Branch-less Planned Releases.\n *\n * @generated from field: repeated contenthub.v1.CheckStanding standings = 1;\n */\n standings: CheckStanding[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCheckResultsResponse.\n * Use `create(ListCheckResultsResponseSchema)` to create a new message.\n */\nexport const ListCheckResultsResponseSchema: GenMessage<ListCheckResultsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 59);\n\n/**\n * CheckStanding is where one Required Check stands on one thing it applies\n * to: a Branch or a Branch-less Planned Release for Branch scope, the whole\n * Change Set for Change Set scope.\n *\n * @generated from message contenthub.v1.CheckStanding\n */\nexport type CheckStanding = Message<\"contenthub.v1.CheckStanding\"> & {\n /**\n * The check, as declared now.\n *\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n\n /**\n * For Branch scope, the Content and the Branch or the Branch-less Planned\n * Release the result is about; empty for Change Set scope.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 3;\n */\n branchId: string;\n\n /**\n * @generated from field: string release_id = 4;\n */\n releaseId: string;\n\n /**\n * What a result recorded now names, as RecordCheckResultRequest.heads.\n *\n * @generated from field: map<string, string> heads = 5;\n */\n heads: { [key: string]: string };\n\n /**\n * Every result on it, newest first: the first is the latest, the one that\n * counts.\n *\n * @generated from field: repeated contenthub.v1.CheckResult results = 6;\n */\n results: CheckResult[];\n\n /**\n * Whether the latest result names heads other than these.\n *\n * @generated from field: bool stale = 7;\n */\n stale: boolean;\n\n /**\n * Whether the latest result is passed or waived and not stale: no\n * outstanding_check blocker for it while the heads stay.\n *\n * @generated from field: bool cleared = 8;\n */\n cleared: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CheckStanding.\n * Use `create(CheckStandingSchema)` to create a new message.\n */\nexport const CheckStandingSchema: GenMessage<CheckStanding> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 60);\n\n/**\n * @generated from message contenthub.v1.ValidatePublishRequest\n */\nexport type ValidatePublishRequest = Message<\"contenthub.v1.ValidatePublishRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The heads the caller would publish, Branch id to head Revision id.\n *\n * @generated from field: map<string, string> reviewed_heads = 2;\n */\n reviewedHeads: { [key: string]: string };\n};\n\n/**\n * Describes the message contenthub.v1.ValidatePublishRequest.\n * Use `create(ValidatePublishRequestSchema)` to create a new message.\n */\nexport const ValidatePublishRequestSchema: GenMessage<ValidatePublishRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 61);\n\n/**\n * @generated from message contenthub.v1.ValidatePublishResponse\n */\nexport type ValidatePublishResponse = Message<\"contenthub.v1.ValidatePublishResponse\"> & {\n /**\n * Every blocker; none means a Publish with these heads would succeed now.\n *\n * @generated from field: repeated contenthub.v1.PublishBlocker blockers = 1;\n */\n blockers: PublishBlocker[];\n\n /**\n * The Releases the Publish would cut, without a Publish Time; for a\n * Change Set published already with these heads, the ones it cut.\n *\n * @generated from field: repeated contenthub.v1.Release releases = 2;\n */\n releases: Release[];\n\n /**\n * Whether the Change Set is published already with these heads: Publish\n * would return its stored outcome.\n *\n * @generated from field: bool published = 3;\n */\n published: boolean;\n\n /**\n * Advice that never blocks Publish: the referrers each Repeal or\n * Withdrawal will leave with a gap (ADR 0015). None for a Change Set\n * published already.\n *\n * @generated from field: repeated contenthub.v1.PublishWarning warnings = 4;\n */\n warnings: PublishWarning[];\n};\n\n/**\n * Describes the message contenthub.v1.ValidatePublishResponse.\n * Use `create(ValidatePublishResponseSchema)` to create a new message.\n */\nexport const ValidatePublishResponseSchema: GenMessage<ValidatePublishResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 62);\n\n/**\n * @generated from message contenthub.v1.PublishRequest\n */\nexport type PublishRequest = Message<\"contenthub.v1.PublishRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The heads the caller reviewed, Branch id to head Revision id: every\n * Branch of the Change Set, each at its current head.\n *\n * @generated from field: map<string, string> reviewed_heads = 2;\n */\n reviewedHeads: { [key: string]: string };\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PublishRequest.\n * Use `create(PublishRequestSchema)` to create a new message.\n */\nexport const PublishRequestSchema: GenMessage<PublishRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 63);\n\n/**\n * @generated from message contenthub.v1.PublishResponse\n */\nexport type PublishResponse = Message<\"contenthub.v1.PublishResponse\"> & {\n /**\n * The Change Set, published.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Publish Time every Release carries.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 2;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * The Releases cut, under their planned ids.\n *\n * @generated from field: repeated contenthub.v1.Release releases = 3;\n */\n releases: Release[];\n};\n\n/**\n * Describes the message contenthub.v1.PublishResponse.\n * Use `create(PublishResponseSchema)` to create a new message.\n */\nexport const PublishResponseSchema: GenMessage<PublishResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 64);\n\n/**\n * StaleHead is the detail of an Aborted save: the head the save named has\n * moved. Apply the edit to current_head_id and save again.\n *\n * @generated from message contenthub.v1.StaleHead\n */\nexport type StaleHead = Message<\"contenthub.v1.StaleHead\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n\n /**\n * @generated from field: string expected_head_id = 3;\n */\n expectedHeadId: string;\n\n /**\n * @generated from field: string current_head_id = 4;\n */\n currentHeadId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StaleHead.\n * Use `create(StaleHeadSchema)` to create a new message.\n */\nexport const StaleHeadSchema: GenMessage<StaleHead> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 65);\n\n/**\n * ChangeSetClosed is the detail of a FailedPrecondition write to a Change Set\n * that is published or discarded, and so closed for good.\n *\n * @generated from message contenthub.v1.ChangeSetClosed\n */\nexport type ChangeSetClosed = Message<\"contenthub.v1.ChangeSetClosed\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ChangeSetState state = 2;\n */\n state: ChangeSetState;\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSetClosed.\n * Use `create(ChangeSetClosedSchema)` to create a new message.\n */\nexport const ChangeSetClosedSchema: GenMessage<ChangeSetClosed> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 66);\n\n/**\n * WithheldWork is the detail of the PermissionDenied refusal of a call over\n * a whole Change Set (Publish and its dry run ValidatePublish,\n * DiscardChangeSet, UpdateFromMain without chain_id) to a caller who cannot\n * see every Content in it (ADR 0017). It names no Content: a client reads it as \"this Change\n * Set holds work you can't see\".\n *\n * @generated from message contenthub.v1.WithheldWork\n */\nexport type WithheldWork = Message<\"contenthub.v1.WithheldWork\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.WithheldWork.\n * Use `create(WithheldWorkSchema)` to create a new message.\n */\nexport const WithheldWorkSchema: GenMessage<WithheldWork> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 67);\n\n/**\n * StaleStatus is the detail of an Aborted SetChangeSetStatus: the status\n * moved since the caller saw it. Read current_status and choose again.\n *\n * @generated from message contenthub.v1.StaleStatus\n */\nexport type StaleStatus = Message<\"contenthub.v1.StaleStatus\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string expected_status = 2;\n */\n expectedStatus: string;\n\n /**\n * Empty for an unknown status.\n *\n * @generated from field: string current_status = 3;\n */\n currentStatus: string;\n};\n\n/**\n * Describes the message contenthub.v1.StaleStatus.\n * Use `create(StaleStatusSchema)` to create a new message.\n */\nexport const StaleStatusSchema: GenMessage<StaleStatus> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 68);\n\n/**\n * StatusTransitionRefused is the detail of a SetChangeSetStatus statushub\n * refused: the workspace's catalogue has no such move, or it is guarded.\n *\n * @generated from message contenthub.v1.StatusTransitionRefused\n */\nexport type StatusTransitionRefused = Message<\"contenthub.v1.StatusTransitionRefused\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string from_status = 2;\n */\n fromStatus: string;\n\n /**\n * @generated from field: string to_status = 3;\n */\n toStatus: string;\n\n /**\n * statushub's reason, as it gave it.\n *\n * @generated from field: string reason = 4;\n */\n reason: string;\n\n /**\n * True for a guarded move (PermissionDenied), which statushub refuses\n * while it runs without Guardian.\n *\n * @generated from field: bool requires_permission = 5;\n */\n requiresPermission: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.StatusTransitionRefused.\n * Use `create(StatusTransitionRefusedSchema)` to create a new message.\n */\nexport const StatusTransitionRefusedSchema: GenMessage<StatusTransitionRefused> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 69);\n\n/**\n * Violation is one detail of an InvalidArgument write: one reason its data\n * was refused, in the shape blueprinthub's Violation has.\n *\n * @generated from message contenthub.v1.Violation\n */\nexport type Violation = Message<\"contenthub.v1.Violation\"> & {\n /**\n * Whose rule it is: \"fieldkit\" (a code from fieldkit's data contract,\n * unchanged), \"knkeditor\" (a rich-text code of knkeditor's, unchanged) or\n * \"contenthub\" (contenthub's own). Until fieldkit enforces them\n * (knkCS/fieldkit#347), contenthub reports two fieldkit rules itself, with\n * the codes fieldkit will use: \"unknown_field\" at a key no Field declares,\n * and \"invalid_format\" at a date that isn't YYYY-MM-DD.\n *\n * @generated from field: string source = 1;\n */\n source: string;\n\n /**\n * The rule's own code, such as fieldkit's \"required\" or knkeditor's\n * \"unknown-node\".\n *\n * @generated from field: string code = 2;\n */\n code: string;\n\n /**\n * A /-separated location in the data, such as \"/title\" or\n * \"/body/content/0\"; \"\" is the data itself.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * Detail a message may interpolate; empty when the code says everything.\n *\n * @generated from field: google.protobuf.Struct params = 4;\n */\n params?: JsonObject | undefined;\n\n /**\n * The Content whose data or Release Spec values it is in, set where one\n * call checks several (UpgradeContent); empty elsewhere.\n *\n * @generated from field: string content_id = 5;\n */\n contentId: string;\n\n /**\n * The Planned Release whose Release Spec values it is in, set by\n * UpgradeContent, which checks them again against the new Blueprint\n * Release; empty when it is in the Content's data.\n *\n * @generated from field: string planned_release_id = 6;\n */\n plannedReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Violation.\n * Use `create(ViolationSchema)` to create a new message.\n */\nexport const ViolationSchema: GenMessage<Violation> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 70);\n\n/**\n * ChangeSetState is where a Change Set is in its life: open, then published\n * or discarded, and closed for good after either.\n *\n * @generated from enum contenthub.v1.ChangeSetState\n */\nexport enum ChangeSetState {\n /**\n * @generated from enum value: CHANGE_SET_STATE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_OPEN = 1;\n */\n OPEN = 1,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_PUBLISHED = 2;\n */\n PUBLISHED = 2,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_DISCARDED = 3;\n */\n DISCARDED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.ChangeSetState.\n */\nexport const ChangeSetStateSchema: GenEnum<ChangeSetState> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 0);\n\n/**\n * BranchKind is what a Branch is for.\n *\n * @generated from enum contenthub.v1.BranchKind\n */\nexport enum BranchKind {\n /**\n * @generated from enum value: BRANCH_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * A Branch an editor works on.\n *\n * @generated from enum value: BRANCH_KIND_EDITORIAL = 1;\n */\n EDITORIAL = 1,\n\n /**\n * A Carry-forward link (CONTEXT.md).\n *\n * @generated from enum value: BRANCH_KIND_CARRY_FORWARD = 2;\n */\n CARRY_FORWARD = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.BranchKind.\n */\nexport const BranchKindSchema: GenEnum<BranchKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 1);\n\n/**\n * CheckOutcome is what a Check Result says.\n *\n * @generated from enum contenthub.v1.CheckOutcome\n */\nexport enum CheckOutcome {\n /**\n * @generated from enum value: CHECK_OUTCOME_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: CHECK_OUTCOME_PASSED = 1;\n */\n PASSED = 1,\n\n /**\n * @generated from enum value: CHECK_OUTCOME_FAILED = 2;\n */\n FAILED = 2,\n\n /**\n * Waived, for the reason the note gives: the check gates no more on these\n * heads, as if passed.\n *\n * @generated from enum value: CHECK_OUTCOME_WAIVED = 3;\n */\n WAIVED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.CheckOutcome.\n */\nexport const CheckOutcomeSchema: GenEnum<CheckOutcome> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 2);\n\n/**\n * ChangeSetService holds every write to history, and is the only service\n * whose requests name Branches or Revisions (ADR 0015). A Change Set is the\n * only path to a Release: Content is born inside one, edited on its Branches\n * and released when it is published (ADRs 0002, 0003).\n *\n * Every RPC acts in the caller's workspace, which comes from the token's\n * active workspace and never from a request field. Reads need `viewer`,\n * writes `editor` (ADR 0017).\n *\n * Every write that changes history announces it in its own transaction\n * (ADR 0016): contenthub.change_set.created, contenthub.change_set.updated,\n * contenthub.change_set.discarded, contenthub.change_set.status_changed,\n * contenthub.change_set.assignees_changed,\n * contenthub.change_set.updated_from_main and contenthub.branch.head_moved,\n * in contenthub.events.v1; Publish\n * announces contenthub.change_set.published, contenthub.content.released and\n * contenthub.content.in_force_changed.\n *\n * @generated from service contenthub.v1.ChangeSetService\n */\nexport const ChangeSetService: GenService<{\n /**\n * CreateChangeSet opens a Change Set, the container for the work one\n * publishing event triggers. It publishes contenthub.change_set.created.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.CreateChangeSet\n */\n createChangeSet: {\n methodKind: \"unary\";\n input: typeof CreateChangeSetRequestSchema;\n output: typeof CreateChangeSetResponseSchema;\n },\n /**\n * GetChangeSet returns a Change Set with its Chains, their Branches and\n * each Branch's head: the heads a save names as expected_head_id.\n *\n * A Change Set is visible to every viewer, but its Chains and Planned\n * Releases on Restricted Content are left out for a caller not granted on\n * that Content (ADR 0017), here and in every response that returns a\n * Change Set.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.GetChangeSet\n */\n getChangeSet: {\n methodKind: \"unary\";\n input: typeof GetChangeSetRequestSchema;\n output: typeof GetChangeSetResponseSchema;\n },\n /**\n * UpdateChangeSet changes an open Change Set's name and Source, as\n * update_mask says (#126): a gazette citation with a typo is corrected\n * before it travels into contenthub.change_set.published and every\n * Release. It publishes contenthub.change_set.updated, naming the fields\n * whose value changed; a write that changes nothing publishes nothing.\n *\n * The Source freezes at Publish: a published or discarded Change Set is\n * FailedPrecondition with a ChangeSetClosed detail, and nothing changes.\n * A Change Set's name and Source are its own, not its Content's, so a\n * caller who can't see some of its work may still correct them (ADR 0017).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdateChangeSet\n */\n updateChangeSet: {\n methodKind: \"unary\";\n input: typeof UpdateChangeSetRequestSchema;\n output: typeof UpdateChangeSetResponseSchema;\n },\n /**\n * DiscardChangeSet closes an open Change Set for good without publishing\n * it. Its Branches end, and Content born in it is gone from every read; the\n * Revisions written in it stay in history (ADR 0003). It publishes\n * contenthub.change_set.discarded. A Change Set that is already published\n * or discarded is FailedPrecondition, with a ChangeSetClosed detail.\n *\n * A caller who cannot see every Content in the Change Set is\n * PermissionDenied, as Publish refuses them, naming no Content (ADR 0017),\n * with a WithheldWork detail: nobody ends work they were never shown.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DiscardChangeSet\n */\n discardChangeSet: {\n methodKind: \"unary\";\n input: typeof DiscardChangeSetRequestSchema;\n output: typeof DiscardChangeSetResponseSchema;\n },\n /**\n * SetChangeSetStatus moves a Change Set's status label, a status of\n * statushub's `contenthub/change_set` catalogue (ADR 0014), and publishes\n * contenthub.change_set.status_changed. The label never gates Publish, and\n * contenthub never sets it itself: not at birth, where it is unset (an\n * unknown status), and not at Publish or discard, after which it is frozen.\n *\n * statushub decides whether the move is allowed, asked with the caller's\n * token. A move it refuses is FailedPrecondition, or PermissionDenied for a\n * guarded one, with a StatusTransitionRefused detail carrying its reason.\n * A move away from an unknown status is never validated, so a Change Set is\n * never stuck on a deleted status. A status not in the workspace's\n * catalogue is InvalidArgument. If the status is no longer expected_status,\n * nothing is written and the call is Aborted with a StaleStatus detail\n * naming the current one. A published or discarded Change Set is\n * FailedPrecondition with a ChangeSetClosed detail. While statushub can't\n * be reached the call is Unavailable: retry it unchanged.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SetChangeSetStatus\n */\n setChangeSetStatus: {\n methodKind: \"unary\";\n input: typeof SetChangeSetStatusRequestSchema;\n output: typeof SetChangeSetStatusResponseSchema;\n },\n /**\n * SetChangeSetAssignees replaces who is working on a Change Set now. It is\n * outside history (ADR 0015): no save, no Change Set state, and allowed\n * whatever the state. It publishes contenthub.change_set.assignees_changed\n * when the set changes, and nothing when it doesn't.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SetChangeSetAssignees\n */\n setChangeSetAssignees: {\n methodKind: \"unary\";\n input: typeof SetChangeSetAssigneesRequestSchema;\n output: typeof SetChangeSetAssigneesResponseSchema;\n },\n /**\n * CreateContent creates Content inside an open Change Set, on a Blueprint\n * Release it pins. The Content has one Chain of one Branch, whose head is\n * its first Revision, and exists only inside the Change Set until Publish\n * gives it a Main Branch. It publishes contenthub.branch.head_moved with\n * cause create (and copied_from, for a copy).\n *\n * The first Revision is validated like any save: data fieldkit or\n * knkeditor refuses against the Blueprint Release is InvalidArgument, with\n * one Violation detail per problem, but required Fields may be left empty\n * (empty data included) until Publish. A Blueprint Release contenthub can't\n * load is InvalidArgument with one Refusal detail per reason.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.CreateContent\n */\n createContent: {\n methodKind: \"unary\";\n input: typeof CreateContentRequestSchema;\n output: typeof CreateContentResponseSchema;\n },\n /**\n * SaveRevision writes a new immutable Revision on a Branch, on top of the\n * head the author edited (ADR 0003), against the Blueprint Release that\n * head pins.\n *\n * If the head has moved since, nothing is written and the call is Aborted\n * with a StaleHead detail naming the current head: load it, apply the edit\n * there, and save again. A value fieldkit or knkeditor refuses is\n * InvalidArgument with one Violation detail per problem, and nothing is\n * written. A required Field left empty is not refused: Publish is,\n * with a missing_required_field blocker, until it is filled. It\n * publishes contenthub.branch.head_moved with cause save.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SaveRevision\n */\n saveRevision: {\n methodKind: \"unary\";\n input: typeof SaveRevisionRequestSchema;\n output: typeof SaveRevisionResponseSchema;\n },\n /**\n * PreviewChain is StartChain's dry run for Dated Content: what a Chain on\n * a published Content, effective on a date, would fork from (the Release\n * In Force then, or a Planned Release of a Change Set it depends on), the\n * later Releases it would carry forward through, whether a final link\n * would merge Main's head, and the Releases a period from that date would\n * cut into or cover entirely (ADR 0015). It refuses what StartChain would\n * refuse, so undated Content, whose Chain takes no date, is\n * InvalidArgument. It writes nothing and waits on nothing: a Publish in\n * between may change the answer.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PreviewChain\n */\n previewChain: {\n methodKind: \"unary\";\n input: typeof PreviewChainRequestSchema;\n output: typeof PreviewChainResponseSchema;\n },\n /**\n * StartChain starts a Chain on a published Content in an open Change Set,\n * so that editors can change it there (ADR 0002). Editors choose the date\n * the change takes effect, never a Branch or a Revision: on Dated Content\n * the Chain forks from the Release In Force on effective_on (in a Change\n * Set with dependencies, possibly a dependency's Planned Release), and when\n * that is behind Main's head the Chain gets a Carry-forward link for each\n * later Release In Force, and a final link merging Main's head where that\n * isn't the last Release's Revision. Undated Content takes no date: its\n * Chain is one Branch forked from Main's head.\n *\n * It writes no Revision: each Branch starts at a Revision that exists.\n * It publishes contenthub.branch.head_moved with cause start for each\n * Branch. A Content with a Chain in the Change Set already, or born in it,\n * is AlreadyExists; one with no Main Branch yet (born in another open\n * Change Set) is FailedPrecondition; a missing or wrongly given date is\n * InvalidArgument.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.StartChain\n */\n startChain: {\n methodKind: \"unary\";\n input: typeof StartChainRequestSchema;\n output: typeof StartChainResponseSchema;\n },\n /**\n * AppendBranch adds an editorial Branch to a Chain on Dated Content, for a\n * later date: one announcement amending a paragraph from 2027 and again\n * from 2028 is two stacked Branches, the second starting at the head of\n * the one before. The Chain is re-laid around it, so Carry-forward links\n * for Releases starting after the date build on the new Branch. A date\n * not after the Chain's last editorial Branch's is InvalidArgument; a\n * Chain without dates (undated Content, or Content born in the Change\n * Set) is FailedPrecondition. It publishes contenthub.branch.head_moved\n * with cause start for each Branch it adds.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AppendBranch\n */\n appendBranch: {\n methodKind: \"unary\";\n input: typeof AppendBranchRequestSchema;\n output: typeof AppendBranchResponseSchema;\n },\n /**\n * DropChain removes a Chain from an open Change Set: its Branches end, its\n * Planned Releases go and the Change Set's proposals are derived again\n * without them; every Revision written on it stays in history. The\n * Content may get a new Chain in the Change Set afterwards. The Chain of\n * Content born in the Change Set can't be dropped (FailedPrecondition):\n * discard the Change Set instead. It announces nothing (ADR 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DropChain\n */\n dropChain: {\n methodKind: \"unary\";\n input: typeof DropChainRequestSchema;\n output: typeof DropChainResponseSchema;\n },\n /**\n * StartEditing bundles the steps of a one-off edit (ADR 0015): it starts a\n * Chain on a published Content as StartChain does, in change_set_id or,\n * without one, in a new Change Set it opens. It never reuses an open\n * Change Set silently. The new Change Set and the Chain are written in one\n * transaction, so a refused Chain leaves no Change Set behind. It\n * publishes contenthub.change_set.created for a new Change Set and\n * contenthub.branch.head_moved with cause start for each Branch.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.StartEditing\n */\n startEditing: {\n methodKind: \"unary\";\n input: typeof StartEditingRequestSchema;\n output: typeof StartEditingResponseSchema;\n },\n /**\n * UpdateFromMain replays the Chains of an open Change Set (or only\n * chain_id's) onto their current bases: Main's head, a dependency's Branch\n * head, or on Dated Content the Releases In Force a Chain carries, re-laying\n * a Chain whose later Releases changed (CONTEXT.md, Update from Main). It is\n * synchronous and one transaction, and returns its outcome.\n *\n * Each Branch that is behind is merged field by field. A clean merge is a\n * merge Revision, pinned to the newer of the two Blueprint Releases, that\n * becomes the Branch's head; a merge with Conflicts, or whose data the\n * Blueprint Release refuses, moves nothing and stays on the Branch as a\n * Pending Merge. A Branch that already has one is left alone and reported\n * in pending. A moved head makes earlier Check Results on it stale.\n *\n * It publishes contenthub.branch.head_moved for each head it moves (cause\n * merge, or start for a link a re-lay adds) and\n * contenthub.change_set.updated_from_main. Two Blueprint Releases of\n * different Blueprints can't be ordered: a merge meeting them refuses the\n * whole call, FailedPrecondition, nothing written.\n *\n * Without chain_id, a caller who cannot see every Content in the Change\n * Set is PermissionDenied, as Publish refuses them, naming no Content (ADR\n * 0017), with a WithheldWork detail. A Chain on Content they see they\n * update alone, with chain_id.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdateFromMain\n */\n updateFromMain: {\n methodKind: \"unary\";\n input: typeof UpdateFromMainRequestSchema;\n output: typeof UpdateFromMainResponseSchema;\n },\n /**\n * GetPendingMerge returns the Pending Merge on a Branch, with every field\n * a resolution must decide and each side's value, or none when the Branch\n * has none.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.GetPendingMerge\n */\n getPendingMerge: {\n methodKind: \"unary\";\n input: typeof GetPendingMergeRequestSchema;\n output: typeof GetPendingMergeResponseSchema;\n },\n /**\n * ResolveMerge resolves the Pending Merge on a Branch field by field: each\n * field GetPendingMerge lists takes one side's value or the editor's, every\n * other field its merged value. The result is validated like a save,\n * against the Blueprint Release the merge pins, and written as a merge\n * Revision that becomes the Branch's head. A head that moved is Aborted\n * with a StaleHead detail; a field left undecided, decided twice or not\n * listed is InvalidArgument; a Branch without a Pending Merge is\n * FailedPrecondition. It publishes contenthub.branch.head_moved with cause\n * resolve.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ResolveMerge\n */\n resolveMerge: {\n methodKind: \"unary\";\n input: typeof ResolveMergeRequestSchema;\n output: typeof ResolveMergeResponseSchema;\n },\n /**\n * AbortMerge drops the Pending Merge on a Branch and leaves the Branch at\n * its head: it takes saves again, but stays behind its base, so Publish\n * waits for another Update from Main. A Branch without a Pending Merge is\n * FailedPrecondition. It announces nothing (ADR 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AbortMerge\n */\n abortMerge: {\n methodKind: \"unary\";\n input: typeof AbortMergeRequestSchema;\n output: typeof AbortMergeResponseSchema;\n },\n /**\n * AddDependency makes a Change Set depend on another open one: its Chains\n * then build on the other's Planned Releases and Branch heads, and it can\n * be published only after the other (ADR 0002). Adding one it has already\n * changes nothing. A dependency that would close a cycle, or names a\n * closed Change Set, is FailedPrecondition. It announces nothing (ADR\n * 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AddDependency\n */\n addDependency: {\n methodKind: \"unary\";\n input: typeof AddDependencyRequestSchema;\n output: typeof AddDependencyResponseSchema;\n },\n /**\n * RemoveDependency undoes AddDependency while the Change Set is open.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.RemoveDependency\n */\n removeDependency: {\n methodKind: \"unary\";\n input: typeof RemoveDependencyRequestSchema;\n output: typeof RemoveDependencyResponseSchema;\n },\n /**\n * PlanRelease plans the Release the Change Set's Publish will cut of an\n * editorial Branch's head, with its Validity Period (required for Dated\n * Content, refused for undated) and Release Spec values, and returns it\n * with its final Release id. Release Spec values the Blueprint Release\n * refuses are InvalidArgument with one Violation detail per problem. A\n * Branch is released once: planning it again is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanRelease\n */\n planRelease: {\n methodKind: \"unary\";\n input: typeof PlanReleaseRequestSchema;\n output: typeof PlanReleaseResponseSchema;\n },\n /**\n * UpdatePlannedRelease changes a Planned Release's Validity Period,\n * Release Spec values or the Releases it supersedes while the Change Set\n * is open. The values given are the ones that count from then on. A\n * proposal's Validity Period is derived from the plans and can't be set\n * (InvalidArgument); a new Validity Period that would cover a Release\n * entirely is FailedPrecondition with a CoversRelease detail.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdatePlannedRelease\n */\n updatePlannedRelease: {\n methodKind: \"unary\";\n input: typeof UpdatePlannedReleaseRequestSchema;\n output: typeof UpdatePlannedReleaseResponseSchema;\n },\n /**\n * PlanDateOnlyRelease plans a date-only Release that re-pins a published\n * Release's Revision with a corrected Validity Period and supersedes it, so\n * a date correction needs no new Revision. Dated Content only.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanDateOnlyRelease\n */\n planDateOnlyRelease: {\n methodKind: \"unary\";\n input: typeof PlanDateOnlyReleaseRequestSchema;\n output: typeof PlanDateOnlyReleaseResponseSchema;\n },\n /**\n * PlanRepeal plans a Repeal of Dated Content: a date-only Release ending\n * the Release In Force on last_day, which also supersedes every Release\n * starting after last_day, so that nothing is In Force after it.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanRepeal\n */\n planRepeal: {\n methodKind: \"unary\";\n input: typeof PlanRepealRequestSchema;\n output: typeof PlanRepealResponseSchema;\n },\n /**\n * PlanWithdrawal plans a Withdrawal of undated Content: a Release that\n * re-pins the Revision In Force at Publish and ends its force from that\n * Publish Time on.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanWithdrawal\n */\n planWithdrawal: {\n methodKind: \"unary\";\n input: typeof PlanWithdrawalRequestSchema;\n output: typeof PlanWithdrawalResponseSchema;\n },\n /**\n * DropPlannedRelease drops a Planned Release from an open Change Set; its\n * id is never cut. A proposed date-only cut is derived from the plans and\n * not dropped on its own (FailedPrecondition).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DropPlannedRelease\n */\n dropPlannedRelease: {\n methodKind: \"unary\";\n input: typeof DropPlannedReleaseRequestSchema;\n output: typeof DropPlannedReleaseResponseSchema;\n },\n /**\n * UpgradeContent moves Content to a newer Blueprint Release of its\n * Blueprint inside an open Change Set, so that a schema change reaches\n * Content through review like any other change (ADR 0015). For each\n * Content it saves one Revision on the last Branch of its Chain (the tip\n * Main moves to at Publish): the head's data, without the fields\n * drop_fields names, pinned to blueprint_release_id. It is synchronous and\n * one transaction, and refused as a whole, with nothing written:\n *\n * - a head that has moved is Aborted with one StaleHead detail per\n * moved head;\n * - data or Release Spec values the new Blueprint Release refuses are\n * InvalidArgument with one Violation detail per problem, each naming\n * its Content (and its Planned Release, for Release Spec values). A\n * required Field the data leaves empty is not refused: Publish asks\n * for it (missing_required_field);\n * - a Blueprint Release contenthub can't load (CheckBlueprintRelease\n * refuses it) is InvalidArgument with one Refusal detail per reason;\n * - a Content without a Chain in the Change Set, of another Blueprint,\n * or pinning that Release or a newer one already, is\n * FailedPrecondition.\n *\n * Releases of one Blueprint are ordered by their ids, which blueprinthub\n * mints as KSUIDs when it cuts them: a later cut sorts after.\n *\n * It extends ADR 0015's UpgradeContent(change_set, blueprint_release,\n * content_ids | all_pinning_older, drop_fields) by two fields: each named\n * Content carries the head its caller saw, since ADR 0015 refuses an\n * upgrade on a stale head and a head that is never named can't be stale;\n * and first_period, the first Validity Period CONTEXT.md's Dated Content\n * says the upgrading Change Set gives Content its Blueprint makes dated.\n *\n * It publishes contenthub.branch.head_moved with cause upgrade for each\n * Content.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpgradeContent\n */\n upgradeContent: {\n methodKind: \"unary\";\n input: typeof UpgradeContentRequestSchema;\n output: typeof UpgradeContentResponseSchema;\n },\n /**\n * RecordCheckResult records the outcome of a Required Check against the\n * heads its recorder saw (ADR 0014): passed, failed, or waived with a\n * note. A Branch-scope result names one head: a Branch's, or the Revision\n * a Branch-less Planned Release re-pins. A Change Set-scope result names\n * every head of the Change Set, both kinds. Results are kept; the latest of a\n * check on one Branch, Planned Release or Change Set counts, and only while\n * its heads are the ones being published: any later save makes it stale.\n *\n * Heads that aren't current are Aborted with a StaleHead detail, nothing\n * recorded. A check that doesn't apply to what the heads name is\n * InvalidArgument. On an independent check, passed and waived from someone\n * who authored a Revision on the Branches the result covers are\n * PermissionDenied; failed is accepted from anyone. It publishes\n * contenthub.change_set.check_result_recorded.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.RecordCheckResult\n */\n recordCheckResult: {\n methodKind: \"unary\";\n input: typeof RecordCheckResultRequestSchema;\n output: typeof RecordCheckResultResponseSchema;\n },\n /**\n * ListCheckResults reads where each Required Check that applies to the\n * Change Set stands: per Branch and per Branch-less Planned Release of\n * covered Content for Branch scope, once for Change Set scope. Each\n * standing carries the heads a result recorded now names, the results\n * recorded on it, newest first, and whether the latest is stale (it names\n * other heads, so a save since made it count for nothing) or clears the\n * check. A check that applies to nothing in the Change Set is left out.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ListCheckResults\n */\n listCheckResults: {\n methodKind: \"unary\";\n input: typeof ListCheckResultsRequestSchema;\n output: typeof ListCheckResultsResponseSchema;\n },\n /**\n * ValidatePublish is Publish's dry run: every blocker a Publish with the\n * same reviewed heads would be refused with now, and the Releases it would\n * cut. It writes nothing and waits on nothing; Publish decides again.\n * It also warns, without blocking, about the referrers a Repeal or\n * Withdrawal will leave with a gap. It is PermissionDenied when Publish\n * would be, for a caller who cannot see every Content in the Change Set.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ValidatePublish\n */\n validatePublish: {\n methodKind: \"unary\";\n input: typeof ValidatePublishRequestSchema;\n output: typeof ValidatePublishResponseSchema;\n },\n /**\n * Publish closes an open Change Set in one transaction: Main moves to the\n * tip of each Chain (born Content gets its Main Branch) and every Planned\n * Release is cut, or nothing is. reviewed_heads must be exactly the\n * current head of every Branch of the Change Set; any other is refused.\n * So is a Change Set where any Required Check that applies lacks a latest\n * passed or waived result on the reviewed heads (outstanding_check).\n *\n * A refusal is FailedPrecondition with one PublishBlocker detail per\n * blocker, and nothing is written. Repeating a Publish that succeeded,\n * with the same reviewed heads, returns its stored outcome and announces\n * nothing again; with other heads it is FailedPrecondition with a\n * ChangeSetClosed detail.\n *\n * A caller who cannot see every Content in the Change Set, because some\n * is Restricted and they are not granted on it, is PermissionDenied before\n * anything else is looked at (ADR 0017): Publish takes explicit reviewed\n * heads, and nobody publishes work they were never shown. The refusal\n * names no Content, and carries a WithheldWork detail.\n *\n * It publishes contenthub.change_set.published, one\n * contenthub.content.released per Release, and one\n * contenthub.content.in_force_changed (cause publish) per Content whose\n * Release In Force today changed.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.Publish\n */\n publish: {\n methodKind: \"unary\";\n input: typeof PublishRequestSchema;\n output: typeof PublishResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_change_set, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/collection.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/collection.proto.\n */\nexport const file_contenthub_v1_collection: GenFile = /*@__PURE__*/\n fileDesc(\"Ch5jb250ZW50aHViL3YxL2NvbGxlY3Rpb24ucHJvdG8SDWNvbnRlbnRodWIudjEirwEKCkNvbGxlY3Rpb24SCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIRCglwYXJlbnRfaWQYAyABKAkSEgoKcmVzdHJpY3RlZBgEIAEoCBIvCgtjcmVhdGVfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLdXBkYXRlX3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIk4KF0NyZWF0ZUNvbGxlY3Rpb25SZXF1ZXN0EgwKBG5hbWUYASABKAkSEQoJcGFyZW50X2lkGAIgASgJEhIKCnJlc3RyaWN0ZWQYAyABKAgiSQoYQ3JlYXRlQ29sbGVjdGlvblJlc3BvbnNlEi0KCmNvbGxlY3Rpb24YASABKAsyGS5jb250ZW50aHViLnYxLkNvbGxlY3Rpb24iGAoWTGlzdENvbGxlY3Rpb25zUmVxdWVzdCJJChdMaXN0Q29sbGVjdGlvbnNSZXNwb25zZRIuCgtjb2xsZWN0aW9ucxgBIAMoCzIZLmNvbnRlbnRodWIudjEuQ29sbGVjdGlvbiIzChdSZW5hbWVDb2xsZWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJIkkKGFJlbmFtZUNvbGxlY3Rpb25SZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIjYKFU1vdmVDb2xsZWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIRCglwYXJlbnRfaWQYAiABKAkiRwoWTW92ZUNvbGxlY3Rpb25SZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIiUKF1JlbW92ZUNvbGxlY3Rpb25SZXF1ZXN0EgoKAmlkGAEgASgJIjcKGFJlbW92ZUNvbGxlY3Rpb25SZXNwb25zZRIbChN1bmZpbGVkX2NvbnRlbnRfaWRzGAEgAygJImAKHlNldENvbGxlY3Rpb25SZXN0cmljdGVkUmVxdWVzdBIKCgJpZBgBIAEoCRISCgpyZXN0cmljdGVkGAIgASgIEh4KFmFja25vd2xlZGdlX2Rpc2Nsb3N1cmUYAyABKAgiUAofU2V0Q29sbGVjdGlvblJlc3RyaWN0ZWRSZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIlcKD0NvbGxlY3Rpb25HcmFudBIPCgd1c2VyX2lkGAEgASgJEjMKBWxldmVsGAIgASgOMiQuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uQWNjZXNzTGV2ZWwiewocR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJEg8KB3VzZXJfaWQYAiABKAkSMwoFbGV2ZWwYAyABKA4yJC5jb250ZW50aHViLnYxLkNvbGxlY3Rpb25BY2Nlc3NMZXZlbCIfCh1HcmFudENvbGxlY3Rpb25BY2Nlc3NSZXNwb25zZSJHCh1SZXZva2VDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJEg8KB3VzZXJfaWQYAiABKAkiIAoeUmV2b2tlQ29sbGVjdGlvbkFjY2Vzc1Jlc3BvbnNlIjQKG0xpc3RDb2xsZWN0aW9uR3JhbnRzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJIk4KHExpc3RDb2xsZWN0aW9uR3JhbnRzUmVzcG9uc2USLgoGZ3JhbnRzGAEgAygLMh4uY29udGVudGh1Yi52MS5Db2xsZWN0aW9uR3JhbnQqqwEKFUNvbGxlY3Rpb25BY2Nlc3NMZXZlbBInCiNDT0xMRUNUSU9OX0FDQ0VTU19MRVZFTF9VTlNQRUNJRklFRBAAEiIKHkNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX1ZJRVdFUhABEiIKHkNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX0VESVRPUhACEiEKHUNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX09XTkVSEAMy2QcKEUNvbGxlY3Rpb25TZXJ2aWNlEmMKEENyZWF0ZUNvbGxlY3Rpb24SJi5jb250ZW50aHViLnYxLkNyZWF0ZUNvbGxlY3Rpb25SZXF1ZXN0GicuY29udGVudGh1Yi52MS5DcmVhdGVDb2xsZWN0aW9uUmVzcG9uc2USYAoPTGlzdENvbGxlY3Rpb25zEiUuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbnNSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbnNSZXNwb25zZRJjChBSZW5hbWVDb2xsZWN0aW9uEiYuY29udGVudGh1Yi52MS5SZW5hbWVDb2xsZWN0aW9uUmVxdWVzdBonLmNvbnRlbnRodWIudjEuUmVuYW1lQ29sbGVjdGlvblJlc3BvbnNlEl0KDk1vdmVDb2xsZWN0aW9uEiQuY29udGVudGh1Yi52MS5Nb3ZlQ29sbGVjdGlvblJlcXVlc3QaJS5jb250ZW50aHViLnYxLk1vdmVDb2xsZWN0aW9uUmVzcG9uc2USYwoQUmVtb3ZlQ29sbGVjdGlvbhImLmNvbnRlbnRodWIudjEuUmVtb3ZlQ29sbGVjdGlvblJlcXVlc3QaJy5jb250ZW50aHViLnYxLlJlbW92ZUNvbGxlY3Rpb25SZXNwb25zZRJ4ChdTZXRDb2xsZWN0aW9uUmVzdHJpY3RlZBItLmNvbnRlbnRodWIudjEuU2V0Q29sbGVjdGlvblJlc3RyaWN0ZWRSZXF1ZXN0Gi4uY29udGVudGh1Yi52MS5TZXRDb2xsZWN0aW9uUmVzdHJpY3RlZFJlc3BvbnNlEnIKFUdyYW50Q29sbGVjdGlvbkFjY2VzcxIrLmNvbnRlbnRodWIudjEuR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBosLmNvbnRlbnRodWIudjEuR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVzcG9uc2USdQoWUmV2b2tlQ29sbGVjdGlvbkFjY2VzcxIsLmNvbnRlbnRodWIudjEuUmV2b2tlQ29sbGVjdGlvbkFjY2Vzc1JlcXVlc3QaLS5jb250ZW50aHViLnYxLlJldm9rZUNvbGxlY3Rpb25BY2Nlc3NSZXNwb25zZRJvChRMaXN0Q29sbGVjdGlvbkdyYW50cxIqLmNvbnRlbnRodWIudjEuTGlzdENvbGxlY3Rpb25HcmFudHNSZXF1ZXN0GisuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbkdyYW50c1Jlc3BvbnNlQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_google_protobuf_timestamp]);\n\n/**\n * Collection is one node of the workspace's tree.\n *\n * @generated from message contenthub.v1.Collection\n */\nexport type Collection = Message<\"contenthub.v1.Collection\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * One line, at most 200 characters, unique among its siblings.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The Collection it sits in; empty at the root.\n *\n * @generated from field: string parent_id = 3;\n */\n parentId: string;\n\n /**\n * Whether it is a Restricted Collection (ADR 0017): the Content filed in\n * it is visible in editing only to those granted on it.\n *\n * @generated from field: bool restricted = 4;\n */\n restricted: boolean;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 5;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 6;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Collection.\n * Use `create(CollectionSchema)` to create a new message.\n */\nexport const CollectionSchema: GenMessage<Collection> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 0);\n\n/**\n * @generated from message contenthub.v1.CreateCollectionRequest\n */\nexport type CreateCollectionRequest = Message<\"contenthub.v1.CreateCollectionRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, one line. Surrounding\n * whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * The Collection to create it in; empty for the root.\n *\n * @generated from field: string parent_id = 2;\n */\n parentId: string;\n\n /**\n * Create it as a Restricted Collection; needs `admin`.\n *\n * @generated from field: bool restricted = 3;\n */\n restricted: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CreateCollectionRequest.\n * Use `create(CreateCollectionRequestSchema)` to create a new message.\n */\nexport const CreateCollectionRequestSchema: GenMessage<CreateCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 1);\n\n/**\n * @generated from message contenthub.v1.CreateCollectionResponse\n */\nexport type CreateCollectionResponse = Message<\"contenthub.v1.CreateCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateCollectionResponse.\n * Use `create(CreateCollectionResponseSchema)` to create a new message.\n */\nexport const CreateCollectionResponseSchema: GenMessage<CreateCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 2);\n\n/**\n * @generated from message contenthub.v1.ListCollectionsRequest\n */\nexport type ListCollectionsRequest = Message<\"contenthub.v1.ListCollectionsRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionsRequest.\n * Use `create(ListCollectionsRequestSchema)` to create a new message.\n */\nexport const ListCollectionsRequestSchema: GenMessage<ListCollectionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 3);\n\n/**\n * @generated from message contenthub.v1.ListCollectionsResponse\n */\nexport type ListCollectionsResponse = Message<\"contenthub.v1.ListCollectionsResponse\"> & {\n /**\n * Every Collection of the workspace, by name, then id.\n *\n * @generated from field: repeated contenthub.v1.Collection collections = 1;\n */\n collections: Collection[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionsResponse.\n * Use `create(ListCollectionsResponseSchema)` to create a new message.\n */\nexport const ListCollectionsResponseSchema: GenMessage<ListCollectionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 4);\n\n/**\n * @generated from message contenthub.v1.RenameCollectionRequest\n */\nexport type RenameCollectionRequest = Message<\"contenthub.v1.RenameCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * As CreateCollectionRequest's name.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.RenameCollectionRequest.\n * Use `create(RenameCollectionRequestSchema)` to create a new message.\n */\nexport const RenameCollectionRequestSchema: GenMessage<RenameCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 5);\n\n/**\n * @generated from message contenthub.v1.RenameCollectionResponse\n */\nexport type RenameCollectionResponse = Message<\"contenthub.v1.RenameCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RenameCollectionResponse.\n * Use `create(RenameCollectionResponseSchema)` to create a new message.\n */\nexport const RenameCollectionResponseSchema: GenMessage<RenameCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 6);\n\n/**\n * @generated from message contenthub.v1.MoveCollectionRequest\n */\nexport type MoveCollectionRequest = Message<\"contenthub.v1.MoveCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Collection to move it under; empty for the root.\n *\n * @generated from field: string parent_id = 2;\n */\n parentId: string;\n};\n\n/**\n * Describes the message contenthub.v1.MoveCollectionRequest.\n * Use `create(MoveCollectionRequestSchema)` to create a new message.\n */\nexport const MoveCollectionRequestSchema: GenMessage<MoveCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 7);\n\n/**\n * @generated from message contenthub.v1.MoveCollectionResponse\n */\nexport type MoveCollectionResponse = Message<\"contenthub.v1.MoveCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.MoveCollectionResponse.\n * Use `create(MoveCollectionResponseSchema)` to create a new message.\n */\nexport const MoveCollectionResponseSchema: GenMessage<MoveCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 8);\n\n/**\n * @generated from message contenthub.v1.RemoveCollectionRequest\n */\nexport type RemoveCollectionRequest = Message<\"contenthub.v1.RemoveCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveCollectionRequest.\n * Use `create(RemoveCollectionRequestSchema)` to create a new message.\n */\nexport const RemoveCollectionRequestSchema: GenMessage<RemoveCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 9);\n\n/**\n * @generated from message contenthub.v1.RemoveCollectionResponse\n */\nexport type RemoveCollectionResponse = Message<\"contenthub.v1.RemoveCollectionResponse\"> & {\n /**\n * The Content the removal unfiled, by id.\n *\n * @generated from field: repeated string unfiled_content_ids = 1;\n */\n unfiledContentIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.RemoveCollectionResponse.\n * Use `create(RemoveCollectionResponseSchema)` to create a new message.\n */\nexport const RemoveCollectionResponseSchema: GenMessage<RemoveCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 10);\n\n/**\n * @generated from message contenthub.v1.SetCollectionRestrictedRequest\n */\nexport type SetCollectionRestrictedRequest = Message<\"contenthub.v1.SetCollectionRestrictedRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: bool restricted = 2;\n */\n restricted: boolean;\n\n /**\n * Confirms that unrestricting discloses the Collection's Content to every\n * viewer. Required to unrestrict; ignored otherwise.\n *\n * @generated from field: bool acknowledge_disclosure = 3;\n */\n acknowledgeDisclosure: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.SetCollectionRestrictedRequest.\n * Use `create(SetCollectionRestrictedRequestSchema)` to create a new message.\n */\nexport const SetCollectionRestrictedRequestSchema: GenMessage<SetCollectionRestrictedRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 11);\n\n/**\n * @generated from message contenthub.v1.SetCollectionRestrictedResponse\n */\nexport type SetCollectionRestrictedResponse = Message<\"contenthub.v1.SetCollectionRestrictedResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetCollectionRestrictedResponse.\n * Use `create(SetCollectionRestrictedResponseSchema)` to create a new message.\n */\nexport const SetCollectionRestrictedResponseSchema: GenMessage<SetCollectionRestrictedResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 12);\n\n/**\n * CollectionGrant is one user's access to a Restricted Collection.\n *\n * @generated from message contenthub.v1.CollectionGrant\n */\nexport type CollectionGrant = Message<\"contenthub.v1.CollectionGrant\"> & {\n /**\n * @generated from field: string user_id = 1;\n */\n userId: string;\n\n /**\n * @generated from field: contenthub.v1.CollectionAccessLevel level = 2;\n */\n level: CollectionAccessLevel;\n};\n\n/**\n * Describes the message contenthub.v1.CollectionGrant.\n * Use `create(CollectionGrantSchema)` to create a new message.\n */\nexport const CollectionGrantSchema: GenMessage<CollectionGrant> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 13);\n\n/**\n * @generated from message contenthub.v1.GrantCollectionAccessRequest\n */\nexport type GrantCollectionAccessRequest = Message<\"contenthub.v1.GrantCollectionAccessRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * The grantee, a member of the workspace; may be the caller.\n *\n * @generated from field: string user_id = 2;\n */\n userId: string;\n\n /**\n * VIEWER or EDITOR.\n *\n * @generated from field: contenthub.v1.CollectionAccessLevel level = 3;\n */\n level: CollectionAccessLevel;\n};\n\n/**\n * Describes the message contenthub.v1.GrantCollectionAccessRequest.\n * Use `create(GrantCollectionAccessRequestSchema)` to create a new message.\n */\nexport const GrantCollectionAccessRequestSchema: GenMessage<GrantCollectionAccessRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 14);\n\n/**\n * @generated from message contenthub.v1.GrantCollectionAccessResponse\n */\nexport type GrantCollectionAccessResponse = Message<\"contenthub.v1.GrantCollectionAccessResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.GrantCollectionAccessResponse.\n * Use `create(GrantCollectionAccessResponseSchema)` to create a new message.\n */\nexport const GrantCollectionAccessResponseSchema: GenMessage<GrantCollectionAccessResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 15);\n\n/**\n * @generated from message contenthub.v1.RevokeCollectionAccessRequest\n */\nexport type RevokeCollectionAccessRequest = Message<\"contenthub.v1.RevokeCollectionAccessRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * @generated from field: string user_id = 2;\n */\n userId: string;\n};\n\n/**\n * Describes the message contenthub.v1.RevokeCollectionAccessRequest.\n * Use `create(RevokeCollectionAccessRequestSchema)` to create a new message.\n */\nexport const RevokeCollectionAccessRequestSchema: GenMessage<RevokeCollectionAccessRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 16);\n\n/**\n * @generated from message contenthub.v1.RevokeCollectionAccessResponse\n */\nexport type RevokeCollectionAccessResponse = Message<\"contenthub.v1.RevokeCollectionAccessResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.RevokeCollectionAccessResponse.\n * Use `create(RevokeCollectionAccessResponseSchema)` to create a new message.\n */\nexport const RevokeCollectionAccessResponseSchema: GenMessage<RevokeCollectionAccessResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 17);\n\n/**\n * @generated from message contenthub.v1.ListCollectionGrantsRequest\n */\nexport type ListCollectionGrantsRequest = Message<\"contenthub.v1.ListCollectionGrantsRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionGrantsRequest.\n * Use `create(ListCollectionGrantsRequestSchema)` to create a new message.\n */\nexport const ListCollectionGrantsRequestSchema: GenMessage<ListCollectionGrantsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 18);\n\n/**\n * @generated from message contenthub.v1.ListCollectionGrantsResponse\n */\nexport type ListCollectionGrantsResponse = Message<\"contenthub.v1.ListCollectionGrantsResponse\"> & {\n /**\n * Every user granted, the owner included, by user id. Unpaginated, as\n * mediahub's: grants are bounded by the workspace's members.\n *\n * @generated from field: repeated contenthub.v1.CollectionGrant grants = 1;\n */\n grants: CollectionGrant[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionGrantsResponse.\n * Use `create(ListCollectionGrantsResponseSchema)` to create a new message.\n */\nexport const ListCollectionGrantsResponseSchema: GenMessage<ListCollectionGrantsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 19);\n\n/**\n * CollectionAccessLevel is a level of access to a Restricted Collection.\n *\n * @generated from enum contenthub.v1.CollectionAccessLevel\n */\nexport enum CollectionAccessLevel {\n /**\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Sees the Content filed in it.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_VIEWER = 1;\n */\n VIEWER = 1,\n\n /**\n * Also saves that Content and files Content into or out of it.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_EDITOR = 2;\n */\n EDITOR = 2,\n\n /**\n * Also manages the grants. Given to whoever restricted it; never granted.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_OWNER = 3;\n */\n OWNER = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.CollectionAccessLevel.\n */\nexport const CollectionAccessLevelSchema: GenEnum<CollectionAccessLevel> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_collection, 0);\n\n/**\n * CollectionService manages a workspace's Collection tree (ADR 0015): the\n * Collections editors file Content in. A Collection is editorial organisation,\n * never versioned and never released (CONTEXT.md); filing Content into\n * Collections is ContentService's SetContentCollections, and narrowing a list\n * by one is ListContents' filter.\n *\n * Every RPC acts in the caller's workspace, from the token. Reading the tree\n * needs `viewer`, editing it `editor` (ADR 0017). Tree edits announce no\n * Event (ADR 0016), except that removing a Collection changes the filing of\n * the Content in it, which is announced per Content.\n *\n * A Restricted Collection (ADR 0017) hides the Content filed in it from\n * everyone in editing but those granted on it: `owner → editor → viewer` on\n * `contenthub/collection:<id>` in Guardian. Only a workspace `admin` creates\n * one or toggles restriction, and its owner (whoever restricted it) or a\n * workspace `admin` manages its grants, as mediahub's GrantService does. An\n * admin is granted nothing by being admin: they see Restricted Content only\n * by granting themselves, which is announced like any grant (ADR 0017's\n * 2026-10-03 amendment). In `authz.mode: workspace` every restriction and\n * grant is FailedPrecondition, since nothing could enforce it, with a\n * GuardianModeRequired detail whose feature is \"collection_restriction\".\n *\n * The tree itself, names included, stays visible to every viewer: a\n * restriction hides the Content filed in a Collection, not the Collection.\n *\n * @generated from service contenthub.v1.CollectionService\n */\nexport const CollectionService: GenService<{\n /**\n * CreateCollection creates a Collection at the root of the tree, or inside\n * parent_id. A sibling of the same name is AlreadyExists. Creating it\n * restricted needs `admin`, makes the caller its owner and publishes\n * contenthub.collection.restricted.\n *\n * @generated from rpc contenthub.v1.CollectionService.CreateCollection\n */\n createCollection: {\n methodKind: \"unary\";\n input: typeof CreateCollectionRequestSchema;\n output: typeof CreateCollectionResponseSchema;\n },\n /**\n * ListCollections returns the whole tree, every Collection with its\n * parent, ordered by name. A workspace's tree is small enough to draw at\n * once.\n *\n * @generated from rpc contenthub.v1.CollectionService.ListCollections\n */\n listCollections: {\n methodKind: \"unary\";\n input: typeof ListCollectionsRequestSchema;\n output: typeof ListCollectionsResponseSchema;\n },\n /**\n * RenameCollection renames a Collection, keeping its id, its place and\n * what is filed in it. A sibling of the new name is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.CollectionService.RenameCollection\n */\n renameCollection: {\n methodKind: \"unary\";\n input: typeof RenameCollectionRequestSchema;\n output: typeof RenameCollectionResponseSchema;\n },\n /**\n * MoveCollection moves a Collection, with everything under it, to the\n * root or under another Collection. A move under itself or anything under\n * it would make a cycle and is InvalidArgument; a sibling of the same name\n * at the destination is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.CollectionService.MoveCollection\n */\n moveCollection: {\n methodKind: \"unary\";\n input: typeof MoveCollectionRequestSchema;\n output: typeof MoveCollectionResponseSchema;\n },\n /**\n * RemoveCollection removes a Collection and unfiles the Content filed in\n * it. The Content itself is untouched: no Revision, no Change Set, and it\n * stays in its other Collections. Each Content it unfiles is announced\n * with contenthub.content.collections_changed. A Collection with\n * Collections under it is FailedPrecondition: remove or move those first,\n * so that one call never removes a whole subtree by accident.\n *\n * @generated from rpc contenthub.v1.CollectionService.RemoveCollection\n */\n removeCollection: {\n methodKind: \"unary\";\n input: typeof RemoveCollectionRequestSchema;\n output: typeof RemoveCollectionResponseSchema;\n },\n /**\n * SetCollectionRestricted restricts a Collection, or opens a Restricted\n * one again; `admin` only. Restricting makes the caller its owner and\n * publishes contenthub.collection.restricted. Unrestricting discloses its\n * Content to every viewer, so it must be confirmed with\n * acknowledge_disclosure, or it is FailedPrecondition; it publishes\n * contenthub.collection.unrestricted. Setting what is already set changes\n * and announces nothing.\n *\n * @generated from rpc contenthub.v1.CollectionService.SetCollectionRestricted\n */\n setCollectionRestricted: {\n methodKind: \"unary\";\n input: typeof SetCollectionRestrictedRequestSchema;\n output: typeof SetCollectionRestrictedResponseSchema;\n },\n /**\n * GrantCollectionAccess grants a member of the workspace viewer or editor\n * on a Restricted Collection, replacing what they held there. It needs the\n * Collection's owner or a workspace `admin`, who may grant themselves\n * (break-glass). An open Collection takes no grants (FailedPrecondition);\n * a grantee who is not a member is InvalidArgument. It publishes\n * contenthub.collection.access_granted.\n *\n * @generated from rpc contenthub.v1.CollectionService.GrantCollectionAccess\n */\n grantCollectionAccess: {\n methodKind: \"unary\";\n input: typeof GrantCollectionAccessRequestSchema;\n output: typeof GrantCollectionAccessResponseSchema;\n },\n /**\n * RevokeCollectionAccess takes a user's grant on a Restricted Collection,\n * whatever its level; revoking one who holds none succeeds. The owner\n * stays owner. Who may call it is as for GrantCollectionAccess. It\n * publishes contenthub.collection.access_revoked.\n *\n * @generated from rpc contenthub.v1.CollectionService.RevokeCollectionAccess\n */\n revokeCollectionAccess: {\n methodKind: \"unary\";\n input: typeof RevokeCollectionAccessRequestSchema;\n output: typeof RevokeCollectionAccessResponseSchema;\n },\n /**\n * ListCollectionGrants reads who is granted on a Restricted Collection,\n * its owner included. A grantee sees the Content, never the roster: it\n * needs the owner or a workspace `admin`.\n *\n * @generated from rpc contenthub.v1.CollectionService.ListCollectionGrants\n */\n listCollectionGrants: {\n methodKind: \"unary\";\n input: typeof ListCollectionGrantsRequestSchema;\n output: typeof ListCollectionGrantsResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_collection, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/revision.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp, Value } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/revision.proto.\n */\nexport const file_contenthub_v1_revision: GenFile = /*@__PURE__*/\n fileDesc(\"Chxjb250ZW50aHViL3YxL3JldmlzaW9uLnByb3RvEg1jb250ZW50aHViLnYxInIKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhQKCmNvbnRlbnRfaWQYASABKAlIABITCglicmFuY2hfaWQYAiABKAlIABIRCglwYWdlX3NpemUYAyABKAUSEgoKcGFnZV90b2tlbhgEIAEoCUIICgZ0YXJnZXQiXAoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEioKCXJldmlzaW9ucxgBIAMoCzIXLmNvbnRlbnRodWIudjEuUmV2aXNpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIo0CCghSZXZpc2lvbhIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhEKCXBhcmVudF9pZBgDIAEoCRIYChBzZWNvbmRfcGFyZW50X2lkGAQgASgJEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAUgASgJEi8KC2NyZWF0ZV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIOCgZhdXRob3IYByABKAkSKwoFY2F1c2UYCCABKA4yHC5jb250ZW50aHViLnYxLlJldmlzaW9uQ2F1c2USEQoJYnJhbmNoX2lkGAkgASgJEhUKDWNoYW5nZV9zZXRfaWQYCiABKAkiewoOQ29tcGFyZVJlcXVlc3QSEwoLcmV2aXNpb25faWQYASABKAkSGgoQYmFzZV9yZXZpc2lvbl9pZBgCIAEoCUgAEhsKEWZvcmtfb2ZfYnJhbmNoX2lkGAMgASgJSAASEwoJbWFpbl9oZWFkGAQgASgISABCBgoEYmFzZSKQAQoPQ29tcGFyZVJlc3BvbnNlEiUKBGJhc2UYASABKAsyFy5jb250ZW50aHViLnYxLlJldmlzaW9uEikKCHJldmlzaW9uGAIgASgLMhcuY29udGVudGh1Yi52MS5SZXZpc2lvbhIrCgdjaGFuZ2VzGAMgAygLMhouY29udGVudGh1Yi52MS5GaWVsZENoYW5nZSL1AQoLRmllbGRDaGFuZ2USDAoEcGF0aBgBIAEoCRIsCgRraW5kGAIgASgOMh4uY29udGVudGh1Yi52MS5GaWVsZENoYW5nZUtpbmQSJgoGYmVmb3JlGAMgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEiUKBWFmdGVyGAQgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEhkKEWJlZm9yZV9maWVsZF90eXBlGAUgASgJEhgKEGFmdGVyX2ZpZWxkX3R5cGUYBiABKAkSJgoGZGV0YWlsGAcgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlKrUBCg1SZXZpc2lvbkNhdXNlEh4KGlJFVklTSU9OX0NBVVNFX1VOU1BFQ0lGSUVEEAASGQoVUkVWSVNJT05fQ0FVU0VfQ1JFQVRFEAESFwoTUkVWSVNJT05fQ0FVU0VfU0FWRRACEhgKFFJFVklTSU9OX0NBVVNFX01FUkdFEAMSGgoWUkVWSVNJT05fQ0FVU0VfUkVTT0xWRRAEEhoKFlJFVklTSU9OX0NBVVNFX1VQR1JBREUQBSqPAQoPRmllbGRDaGFuZ2VLaW5kEiEKHUZJRUxEX0NIQU5HRV9LSU5EX1VOU1BFQ0lGSUVEEAASGwoXRklFTERfQ0hBTkdFX0tJTkRfQURERUQQARIdChlGSUVMRF9DSEFOR0VfS0lORF9SRU1PVkVEEAISHQoZRklFTERfQ0hBTkdFX0tJTkRfQ0hBTkdFRBADQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * @generated from message contenthub.v1.ListRevisionsRequest\n */\nexport type ListRevisionsRequest = Message<\"contenthub.v1.ListRevisionsRequest\"> & {\n /**\n * Whose Revisions to list.\n *\n * @generated from oneof contenthub.v1.ListRevisionsRequest.target\n */\n target: {\n /**\n * Every Revision of the Content, on every Branch it was written on. The\n * Content must be published: Content born in an open Change Set exists\n * only inside it, so its Revisions are listed by its Branch.\n *\n * @generated from field: string content_id = 1;\n */\n value: string;\n case: \"contentId\";\n } | {\n /**\n * The Revisions written on this Branch, a link of a Chain. A Branch\n * that ended with a published Change Set still lists them; one whose\n * born Content vanished with a discard is NotFound, as every read of\n * that Content is.\n *\n * @generated from field: string branch_id = 2;\n */\n value: string;\n case: \"branchId\";\n } | { case: undefined; value?: undefined };\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRevisionsRequest.\n * Use `create(ListRevisionsRequestSchema)` to create a new message.\n */\nexport const ListRevisionsRequestSchema: GenMessage<ListRevisionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 0);\n\n/**\n * @generated from message contenthub.v1.ListRevisionsResponse\n */\nexport type ListRevisionsResponse = Message<\"contenthub.v1.ListRevisionsResponse\"> & {\n /**\n * Newest first.\n *\n * @generated from field: repeated contenthub.v1.Revision revisions = 1;\n */\n revisions: Revision[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRevisionsResponse.\n * Use `create(ListRevisionsResponseSchema)` to create a new message.\n */\nexport const ListRevisionsResponseSchema: GenMessage<ListRevisionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 1);\n\n/**\n * Revision is one immutable Revision of a Content, without its data: who\n * wrote it, when, why, and where.\n *\n * @generated from message contenthub.v1.Revision\n */\nexport type Revision = Message<\"contenthub.v1.Revision\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The Revision it was built on; empty for the Content's first.\n *\n * @generated from field: string parent_id = 3;\n */\n parentId: string;\n\n /**\n * The other side of a merge Revision; empty otherwise.\n *\n * @generated from field: string second_parent_id = 4;\n */\n secondParentId: string;\n\n /**\n * The Blueprint Release it pins.\n *\n * @generated from field: string blueprint_release_id = 5;\n */\n blueprintReleaseId: string;\n\n /**\n * When it was written.\n *\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * The token subject of who wrote it.\n *\n * @generated from field: string author = 7;\n */\n author: string;\n\n /**\n * @generated from field: contenthub.v1.RevisionCause cause = 8;\n */\n cause: RevisionCause;\n\n /**\n * The Branch it was written on, and that Branch's Change Set.\n *\n * @generated from field: string branch_id = 9;\n */\n branchId: string;\n\n /**\n * @generated from field: string change_set_id = 10;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Revision.\n * Use `create(RevisionSchema)` to create a new message.\n */\nexport const RevisionSchema: GenMessage<Revision> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 2);\n\n/**\n * CompareRequest names two Revisions of one Content: revision_id, whose\n * changes are reported, and a base it is compared against.\n *\n * @generated from message contenthub.v1.CompareRequest\n */\nexport type CompareRequest = Message<\"contenthub.v1.CompareRequest\"> & {\n /**\n * The after side.\n *\n * @generated from field: string revision_id = 1;\n */\n revisionId: string;\n\n /**\n * The before side. One is required.\n *\n * @generated from oneof contenthub.v1.CompareRequest.base\n */\n base: {\n /**\n * Any other Revision of the same Content.\n *\n * @generated from field: string base_revision_id = 2;\n */\n value: string;\n case: \"baseRevisionId\";\n } | {\n /**\n * The Revision this Branch of the same Content forked from, as review\n * compares it: what the Branch last took from upstream (its Main, a\n * dependency's Branch or the previous link), or on a Chain on Dated\n * Content the Revision of the Release the link carries. Content born in\n * its Change Set has no fork: FailedPrecondition.\n *\n * @generated from field: string fork_of_branch_id = 3;\n */\n value: string;\n case: \"forkOfBranchId\";\n } | {\n /**\n * The head of the Content's Main Branch; must be true. Content not\n * published yet has no Main Branch: FailedPrecondition.\n *\n * @generated from field: bool main_head = 4;\n */\n value: boolean;\n case: \"mainHead\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.CompareRequest.\n * Use `create(CompareRequestSchema)` to create a new message.\n */\nexport const CompareRequestSchema: GenMessage<CompareRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 3);\n\n/**\n * @generated from message contenthub.v1.CompareResponse\n */\nexport type CompareResponse = Message<\"contenthub.v1.CompareResponse\"> & {\n /**\n * The before side, as resolved from the request's base.\n *\n * @generated from field: contenthub.v1.Revision base = 1;\n */\n base?: Revision | undefined;\n\n /**\n * The after side.\n *\n * @generated from field: contenthub.v1.Revision revision = 2;\n */\n revision?: Revision | undefined;\n\n /**\n * The fields that differ, in the after side's Blueprint order, then those\n * only the before side's declares, then data no Blueprint declares. An\n * unchanged field is left out.\n *\n * @generated from field: repeated contenthub.v1.FieldChange changes = 3;\n */\n changes: FieldChange[];\n};\n\n/**\n * Describes the message contenthub.v1.CompareResponse.\n * Use `create(CompareResponseSchema)` to create a new message.\n */\nexport const CompareResponseSchema: GenMessage<CompareResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 4);\n\n/**\n * FieldChange is one field that differs between two Revisions.\n *\n * @generated from message contenthub.v1.FieldChange\n */\nexport type FieldChange = Message<\"contenthub.v1.FieldChange\"> & {\n /**\n * The field's path from the data's root, as a Violation's path is spelled:\n * \"/\" and its accessor.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from field: contenthub.v1.FieldChangeKind kind = 2;\n */\n kind: FieldChangeKind;\n\n /**\n * The value in the base and in the revision; unset on the side that\n * doesn't hold the field.\n *\n * @generated from field: google.protobuf.Value before = 3;\n */\n before?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value after = 4;\n */\n after?: Value | undefined;\n\n /**\n * The field's type under each side's Blueprint Release; empty on a side\n * whose Release doesn't declare it.\n *\n * @generated from field: string before_field_type = 5;\n */\n beforeFieldType: string;\n\n /**\n * @generated from field: string after_field_type = 6;\n */\n afterFieldType: string;\n\n /**\n * How the value changed within, for a type that compares finer than a\n * whole value (rows, a record, references, rich text): fieldkit's\n * CompareDetail as it comes. Unset otherwise, and on a type change.\n *\n * @generated from field: google.protobuf.Value detail = 7;\n */\n detail?: Value | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.FieldChange.\n * Use `create(FieldChangeSchema)` to create a new message.\n */\nexport const FieldChangeSchema: GenMessage<FieldChange> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 5);\n\n/**\n * RevisionCause is why a Revision was written: the cause of the head move it\n * made, as contenthub.branch.head_moved names it. A Branch started on an\n * existing Revision writes none, so `start` is not a cause here.\n *\n * @generated from enum contenthub.v1.RevisionCause\n */\nexport enum RevisionCause {\n /**\n * Not recorded.\n *\n * @generated from enum value: REVISION_CAUSE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * The Content's first Revision (CreateContent).\n *\n * @generated from enum value: REVISION_CAUSE_CREATE = 1;\n */\n CREATE = 1,\n\n /**\n * A save on a Branch (SaveRevision).\n *\n * @generated from enum value: REVISION_CAUSE_SAVE = 2;\n */\n SAVE = 2,\n\n /**\n * A clean merge written by Update from Main.\n *\n * @generated from enum value: REVISION_CAUSE_MERGE = 3;\n */\n MERGE = 3,\n\n /**\n * A merge whose Conflicts the editor resolved.\n *\n * @generated from enum value: REVISION_CAUSE_RESOLVE = 4;\n */\n RESOLVE = 4,\n\n /**\n * A move to a newer Blueprint Release (UpgradeContent).\n *\n * @generated from enum value: REVISION_CAUSE_UPGRADE = 5;\n */\n UPGRADE = 5,\n}\n\n/**\n * Describes the enum contenthub.v1.RevisionCause.\n */\nexport const RevisionCauseSchema: GenEnum<RevisionCause> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_revision, 0);\n\n/**\n * @generated from enum contenthub.v1.FieldChangeKind\n */\nexport enum FieldChangeKind {\n /**\n * @generated from enum value: FIELD_CHANGE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Only the revision holds the field.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_ADDED = 1;\n */\n ADDED = 1,\n\n /**\n * Only the base holds the field.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_REMOVED = 2;\n */\n REMOVED = 2,\n\n /**\n * Both hold it with different values, or its type changed.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_CHANGED = 3;\n */\n CHANGED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.FieldChangeKind.\n */\nexport const FieldChangeKindSchema: GenEnum<FieldChangeKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_revision, 1);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/content.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { ChangeSet, ChangeSetState, Content } from \"./change_set_pb\";\nimport { file_contenthub_v1_change_set } from \"./change_set_pb\";\nimport type { InForceAt, ListReferencesRequestSchema, ListReferencesResponseSchema, ListReferrersRequestSchema, ListReferrersResponseSchema } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { ListOutdatedPinsRequestSchema, ListOutdatedPinsResponseSchema } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { GetReleasesRequestSchema, GetReleasesResponseSchema, GetTimelineRequestSchema, GetTimelineResponseSchema } from \"./release_read_pb\";\nimport { file_contenthub_v1_release_read } from \"./release_read_pb\";\nimport type { CompareRequestSchema, CompareResponseSchema, ListRevisionsRequestSchema, ListRevisionsResponseSchema } from \"./revision_pb\";\nimport { file_contenthub_v1_revision } from \"./revision_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/content.proto.\n */\nexport const file_contenthub_v1_content: GenFile = /*@__PURE__*/\n fileDesc(\"Chtjb250ZW50aHViL3YxL2NvbnRlbnQucHJvdG8SDWNvbnRlbnRodWIudjEiNgoRR2V0Q29udGVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNY2hhbmdlX3NldF9pZBgCIAEoCSKNAQoSR2V0Q29udGVudFJlc3BvbnNlEicKB2NvbnRlbnQYASABKAsyFi5jb250ZW50aHViLnYxLkNvbnRlbnQSGAoQcmVzb2x2ZWRfcmVsZWFzZRgCIAEoDBI0CgphdHRyaWJ1dGVzGAMgASgLMiAuY29udGVudGh1Yi52MS5Db250ZW50QXR0cmlidXRlcyKYAQoRQ29udGVudEF0dHJpYnV0ZXMSFgoOY29sbGVjdGlvbl9pZHMYASADKAkSFAoMYXNzaWduZWVfaWRzGAIgAygJEiMKBWJsb2NrGAMgASgLMhQuY29udGVudGh1Yi52MS5CbG9jaxIwCgxhcmNoaXZlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIn4KBUJsb2NrEhcKD2Jsb2NrX3JlYXNvbl9pZBgBIAEoCRIYChBhbGxvd2VkX3VzZXJfaWRzGAIgAygJEhIKCmJsb2NrZWRfYnkYAyABKAkSLgoKYmxvY2tfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAilQEKFUxpc3RDaGFuZ2VTZXRzUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEiwKBXN0YXRlGAIgASgOMh0uY29udGVudGh1Yi52MS5DaGFuZ2VTZXRTdGF0ZRIRCglwYWdlX3NpemUYAyABKAUSEgoKcGFnZV90b2tlbhgEIAEoCRITCgthc3NpZ25lZV9pZBgFIAEoCSK5AQoTTGlzdENvbnRlbnRzUmVxdWVzdBIsCgZmaWx0ZXIYASABKAsyHC5jb250ZW50aHViLnYxLkNvbnRlbnRGaWx0ZXISFwoNY2hhbmdlX3NldF9pZBgCIAEoCUgAEiwKCGluX2ZvcmNlGAUgASgLMhguY29udGVudGh1Yi52MS5JbkZvcmNlQXRIABIRCglwYWdlX3NpemUYAyABKAUSEgoKcGFnZV90b2tlbhgEIAEoCUIGCgR2aWV3InwKDUNvbnRlbnRGaWx0ZXISFQoNY29sbGVjdGlvbl9pZBgBIAEoCRIOCgZzZWFyY2gYAiABKAkSEwoLYXNzaWduZWVfaWQYAyABKAkSGAoQaW5jbHVkZV9hcmNoaXZlZBgEIAEoCBIVCg1ibHVlcHJpbnRfaWRzGAUgAygJIlkKFExpc3RDb250ZW50c1Jlc3BvbnNlEigKCGNvbnRlbnRzGAEgAygLMhYuY29udGVudGh1Yi52MS5Db250ZW50EhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSJjChxTZXRDb250ZW50Q29sbGVjdGlvbnNSZXF1ZXN0EhIKCmNvbnRlbnRfaWQYASABKAkSFgoOY29sbGVjdGlvbl9pZHMYAiADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIksKHVNldENvbnRlbnRDb2xsZWN0aW9uc1Jlc3BvbnNlEhIKCmNvbnRlbnRfaWQYASABKAkSFgoOY29sbGVjdGlvbl9pZHMYAiADKAkiXwoaU2V0Q29udGVudEFzc2lnbmVlc1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIUCgxhc3NpZ25lZV9pZHMYAiADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJImcKG1NldENvbnRlbnRBc3NpZ25lZXNSZXNwb25zZRISCgpjb250ZW50X2lkGAEgASgJEjQKCmF0dHJpYnV0ZXMYAiABKAsyIC5jb250ZW50aHViLnYxLkNvbnRlbnRBdHRyaWJ1dGVzInUKE0Jsb2NrQ29udGVudFJlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIXCg9ibG9ja19yZWFzb25faWQYAiABKAkSGAoQYWxsb3dlZF91c2VyX2lkcxgDIAMoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiYAoUQmxvY2tDb250ZW50UmVzcG9uc2USEgoKY29udGVudF9pZBgBIAEoCRI0CgphdHRyaWJ1dGVzGAIgASgLMiAuY29udGVudGh1Yi52MS5Db250ZW50QXR0cmlidXRlcyJEChVVbmJsb2NrQ29udGVudFJlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAiABKAkiYgoWVW5ibG9ja0NvbnRlbnRSZXNwb25zZRISCgpjb250ZW50X2lkGAEgASgJEjQKCmF0dHJpYnV0ZXMYAiABKAsyIC5jb250ZW50aHViLnYxLkNvbnRlbnRBdHRyaWJ1dGVzIkQKFUFyY2hpdmVDb250ZW50UmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgCIAEoCSJiChZBcmNoaXZlQ29udGVudFJlc3BvbnNlEhIKCmNvbnRlbnRfaWQYASABKAkSNAoKYXR0cmlidXRlcxgCIAEoCzIgLmNvbnRlbnRodWIudjEuQ29udGVudEF0dHJpYnV0ZXMiRgoXVW5hcmNoaXZlQ29udGVudFJlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAiABKAkiZAoYVW5hcmNoaXZlQ29udGVudFJlc3BvbnNlEhIKCmNvbnRlbnRfaWQYASABKAkSNAoKYXR0cmlidXRlcxgCIAEoCzIgLmNvbnRlbnRodWIudjEuQ29udGVudEF0dHJpYnV0ZXMiPQoOQ29udGVudEJsb2NrZWQSEgoKY29udGVudF9pZBgBIAEoCRIXCg9ibG9ja19yZWFzb25faWQYAiABKAkiJQoPQ29udGVudEFyY2hpdmVkEhIKCmNvbnRlbnRfaWQYASABKAkiYAoWTGlzdENoYW5nZVNldHNSZXNwb25zZRItCgtjaGFuZ2Vfc2V0cxgBIAMoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EhcKD25leHRfcGFnZV90b2tlbhgCIAEoCTLrCwoOQ29udGVudFNlcnZpY2USUQoKR2V0Q29udGVudBIgLmNvbnRlbnRodWIudjEuR2V0Q29udGVudFJlcXVlc3QaIS5jb250ZW50aHViLnYxLkdldENvbnRlbnRSZXNwb25zZRJdCg5MaXN0Q2hhbmdlU2V0cxIkLmNvbnRlbnRodWIudjEuTGlzdENoYW5nZVNldHNSZXF1ZXN0GiUuY29udGVudGh1Yi52MS5MaXN0Q2hhbmdlU2V0c1Jlc3BvbnNlElcKDExpc3RDb250ZW50cxIiLmNvbnRlbnRodWIudjEuTGlzdENvbnRlbnRzUmVxdWVzdBojLmNvbnRlbnRodWIudjEuTGlzdENvbnRlbnRzUmVzcG9uc2UScgoVU2V0Q29udGVudENvbGxlY3Rpb25zEisuY29udGVudGh1Yi52MS5TZXRDb250ZW50Q29sbGVjdGlvbnNSZXF1ZXN0GiwuY29udGVudGh1Yi52MS5TZXRDb250ZW50Q29sbGVjdGlvbnNSZXNwb25zZRJsChNTZXRDb250ZW50QXNzaWduZWVzEikuY29udGVudGh1Yi52MS5TZXRDb250ZW50QXNzaWduZWVzUmVxdWVzdBoqLmNvbnRlbnRodWIudjEuU2V0Q29udGVudEFzc2lnbmVlc1Jlc3BvbnNlElcKDEJsb2NrQ29udGVudBIiLmNvbnRlbnRodWIudjEuQmxvY2tDb250ZW50UmVxdWVzdBojLmNvbnRlbnRodWIudjEuQmxvY2tDb250ZW50UmVzcG9uc2USXQoOVW5ibG9ja0NvbnRlbnQSJC5jb250ZW50aHViLnYxLlVuYmxvY2tDb250ZW50UmVxdWVzdBolLmNvbnRlbnRodWIudjEuVW5ibG9ja0NvbnRlbnRSZXNwb25zZRJdCg5BcmNoaXZlQ29udGVudBIkLmNvbnRlbnRodWIudjEuQXJjaGl2ZUNvbnRlbnRSZXF1ZXN0GiUuY29udGVudGh1Yi52MS5BcmNoaXZlQ29udGVudFJlc3BvbnNlEmMKEFVuYXJjaGl2ZUNvbnRlbnQSJi5jb250ZW50aHViLnYxLlVuYXJjaGl2ZUNvbnRlbnRSZXF1ZXN0GicuY29udGVudGh1Yi52MS5VbmFyY2hpdmVDb250ZW50UmVzcG9uc2USXQoOTGlzdFJlZmVyZW5jZXMSJC5jb250ZW50aHViLnYxLkxpc3RSZWZlcmVuY2VzUmVxdWVzdBolLmNvbnRlbnRodWIudjEuTGlzdFJlZmVyZW5jZXNSZXNwb25zZRJaCg1MaXN0UmVmZXJyZXJzEiMuY29udGVudGh1Yi52MS5MaXN0UmVmZXJyZXJzUmVxdWVzdBokLmNvbnRlbnRodWIudjEuTGlzdFJlZmVycmVyc1Jlc3BvbnNlEmMKEExpc3RPdXRkYXRlZFBpbnMSJi5jb250ZW50aHViLnYxLkxpc3RPdXRkYXRlZFBpbnNSZXF1ZXN0GicuY29udGVudGh1Yi52MS5MaXN0T3V0ZGF0ZWRQaW5zUmVzcG9uc2USVAoLR2V0UmVsZWFzZXMSIS5jb250ZW50aHViLnYxLkdldFJlbGVhc2VzUmVxdWVzdBoiLmNvbnRlbnRodWIudjEuR2V0UmVsZWFzZXNSZXNwb25zZRJUCgtHZXRUaW1lbGluZRIhLmNvbnRlbnRodWIudjEuR2V0VGltZWxpbmVSZXF1ZXN0GiIuY29udGVudGh1Yi52MS5HZXRUaW1lbGluZVJlc3BvbnNlEloKDUxpc3RSZXZpc2lvbnMSIy5jb250ZW50aHViLnYxLkxpc3RSZXZpc2lvbnNSZXF1ZXN0GiQuY29udGVudGh1Yi52MS5MaXN0UmV2aXNpb25zUmVzcG9uc2USSAoHQ29tcGFyZRIdLmNvbnRlbnRodWIudjEuQ29tcGFyZVJlcXVlc3QaHi5jb250ZW50aHViLnYxLkNvbXBhcmVSZXNwb25zZUI8WjpnaXRodWIuY29tL2tua2NzL2NvbnRlbnRodWIvZ2VuL2NvbnRlbnRodWIvdjE7Y29udGVudGh1YnYxYgZwcm90bzM\", [file_contenthub_v1_change_set, file_contenthub_v1_content_graph, file_contenthub_v1_graph_warnings, file_contenthub_v1_release_read, file_contenthub_v1_revision, file_google_protobuf_timestamp]);\n\n/**\n * @generated from message contenthub.v1.GetContentRequest\n */\nexport type GetContentRequest = Message<\"contenthub.v1.GetContentRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Change Set to read the Content in; empty reads it on Main.\n *\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetContentRequest.\n * Use `create(GetContentRequestSchema)` to create a new message.\n */\nexport const GetContentRequestSchema: GenMessage<GetContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 0);\n\n/**\n * @generated from message contenthub.v1.GetContentResponse\n */\nexport type GetContentResponse = Message<\"contenthub.v1.GetContentResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n\n /**\n * The Resolved Release of content.blueprint_release_id, byte for byte as\n * blueprinthub served it when contenthub loaded it.\n *\n * @generated from field: bytes resolved_release = 2;\n */\n resolvedRelease: Uint8Array;\n\n /**\n * The Content's unversioned attributes: the same wherever it is read,\n * since they belong to the Content and not to a Revision.\n *\n * @generated from field: contenthub.v1.ContentAttributes attributes = 3;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetContentResponse.\n * Use `create(GetContentResponseSchema)` to create a new message.\n */\nexport const GetContentResponseSchema: GenMessage<GetContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 1);\n\n/**\n * ContentAttributes are a Content's unversioned attributes (ADR 0015).\n *\n * @generated from message contenthub.v1.ContentAttributes\n */\nexport type ContentAttributes = Message<\"contenthub.v1.ContentAttributes\"> & {\n /**\n * The Collections it is filed in, by id, in id order.\n *\n * @generated from field: repeated string collection_ids = 1;\n */\n collectionIds: string[];\n\n /**\n * Who maintains it: odon user ids, in the order they were set.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Its Block; absent while it is not blocked.\n *\n * @generated from field: contenthub.v1.Block block = 3;\n */\n block?: Block | undefined;\n\n /**\n * When it was archived; absent while it is not Archived.\n *\n * @generated from field: google.protobuf.Timestamp archive_time = 4;\n */\n archiveTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ContentAttributes.\n * Use `create(ContentAttributesSchema)` to create a new message.\n */\nexport const ContentAttributesSchema: GenMessage<ContentAttributes> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 2);\n\n/**\n * Block is a Content's Block (CONTEXT.md).\n *\n * @generated from message contenthub.v1.Block\n */\nexport type Block = Message<\"contenthub.v1.Block\"> & {\n /**\n * @generated from field: string block_reason_id = 1;\n */\n blockReasonId: string;\n\n /**\n * Who may still edit it; empty is nobody.\n *\n * @generated from field: repeated string allowed_user_ids = 2;\n */\n allowedUserIds: string[];\n\n /**\n * The odon user who set it, and when.\n *\n * @generated from field: string blocked_by = 3;\n */\n blockedBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp block_time = 4;\n */\n blockTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Block.\n * Use `create(BlockSchema)` to create a new message.\n */\nexport const BlockSchema: GenMessage<Block> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 3);\n\n/**\n * @generated from message contenthub.v1.ListChangeSetsRequest\n */\nexport type ListChangeSetsRequest = Message<\"contenthub.v1.ListChangeSetsRequest\"> & {\n /**\n * Only Change Sets with a Chain on this Content; empty for all.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only Change Sets in this state; unspecified for all.\n *\n * @generated from field: contenthub.v1.ChangeSetState state = 2;\n */\n state: ChangeSetState;\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n\n /**\n * Only Change Sets this odon user is assigned to; empty for all.\n *\n * @generated from field: string assignee_id = 5;\n */\n assigneeId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListChangeSetsRequest.\n * Use `create(ListChangeSetsRequestSchema)` to create a new message.\n */\nexport const ListChangeSetsRequestSchema: GenMessage<ListChangeSetsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 4);\n\n/**\n * @generated from message contenthub.v1.ListContentsRequest\n */\nexport type ListContentsRequest = Message<\"contenthub.v1.ListContentsRequest\"> & {\n /**\n * Narrows the list; the zero filter keeps all.\n *\n * @generated from field: contenthub.v1.ContentFilter filter = 1;\n */\n filter?: ContentFilter | undefined;\n\n /**\n * Where each Content is read. Unset reads Main: the Content that has been\n * published, at its Main head.\n *\n * @generated from oneof contenthub.v1.ListContentsRequest.view\n */\n view: {\n /**\n * Reads the Content with a Chain in this Change Set, at the head of its\n * Chain's last Branch, as GetContent with this change_set_id does.\n *\n * @generated from field: string change_set_id = 2;\n */\n value: string;\n case: \"changeSetId\";\n } | {\n /**\n * Reads the Content with a Release In Force at this date and moment, at\n * the Revision that Release pins; content.release_id names it. Unset\n * fields are today and now.\n *\n * @generated from field: contenthub.v1.InForceAt in_force = 5;\n */\n value: InForceAt;\n case: \"inForce\";\n } | { case: undefined; value?: undefined };\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListContentsRequest.\n * Use `create(ListContentsRequestSchema)` to create a new message.\n */\nexport const ListContentsRequestSchema: GenMessage<ListContentsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 5);\n\n/**\n * ContentFilter narrows ListContents. Each field set must hold.\n *\n * @generated from message contenthub.v1.ContentFilter\n */\nexport type ContentFilter = Message<\"contenthub.v1.ContentFilter\"> & {\n /**\n * Only Content filed directly in this Collection, not in Collections\n * under it. An unknown Collection is NotFound.\n *\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * Editor Search (ADR 0019): only Content whose head holds this name, number\n * or phrase, letter for letter but ignoring case, within one field whose\n * `search` isn't `off`; runs of whitespace match any run. At most 200\n * characters.\n *\n * On Main it searches Main heads and every open Branch head alike, so\n * Content born in an open Change Set is found before Publish: a hit on a\n * Branch is read there and names its Change Set and Branch, and a Content\n * is listed once per head that matched. Inside a Change Set it searches\n * that Change Set's open Branch heads. Ordered by Content id, then Branch.\n * With the In Force view it is InvalidArgument: Editor Search covers Main\n * heads and open Branch heads only, never Releases (that is Delivery\n * Search's).\n *\n * @generated from field: string search = 2;\n */\n search: string;\n\n /**\n * Only Content this odon user maintains (SetContentAssignees).\n *\n * @generated from field: string assignee_id = 3;\n */\n assigneeId: string;\n\n /**\n * Archived Content too. Unset, every view leaves it out, since it is put\n * aside (ADR 0015).\n *\n * @generated from field: bool include_archived = 4;\n */\n includeArchived: boolean;\n\n /**\n * Only Content of one of these Blueprints, each Content judged by the\n * Blueprint of the Revision the view reads; empty for every Blueprint. At\n * most 100. A Blueprint named twice counts once, and an unknown one matches\n * nothing.\n *\n * @generated from field: repeated string blueprint_ids = 5;\n */\n blueprintIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ContentFilter.\n * Use `create(ContentFilterSchema)` to create a new message.\n */\nexport const ContentFilterSchema: GenMessage<ContentFilter> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 6);\n\n/**\n * @generated from message contenthub.v1.ListContentsResponse\n */\nexport type ListContentsResponse = Message<\"contenthub.v1.ListContentsResponse\"> & {\n /**\n * As GetContent reads each, without the Resolved Release.\n *\n * @generated from field: repeated contenthub.v1.Content contents = 1;\n */\n contents: Content[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListContentsResponse.\n * Use `create(ListContentsResponseSchema)` to create a new message.\n */\nexport const ListContentsResponseSchema: GenMessage<ListContentsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 7);\n\n/**\n * @generated from message contenthub.v1.SetContentCollectionsRequest\n */\nexport type SetContentCollectionsRequest = Message<\"contenthub.v1.SetContentCollectionsRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Every Collection the Content is to be filed in, at most 100. A\n * Collection named twice counts once.\n *\n * @generated from field: repeated string collection_ids = 2;\n */\n collectionIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentCollectionsRequest.\n * Use `create(SetContentCollectionsRequestSchema)` to create a new message.\n */\nexport const SetContentCollectionsRequestSchema: GenMessage<SetContentCollectionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 8);\n\n/**\n * @generated from message contenthub.v1.SetContentCollectionsResponse\n */\nexport type SetContentCollectionsResponse = Message<\"contenthub.v1.SetContentCollectionsResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The Collections it is now filed in, by id, in id order.\n *\n * @generated from field: repeated string collection_ids = 2;\n */\n collectionIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.SetContentCollectionsResponse.\n * Use `create(SetContentCollectionsResponseSchema)` to create a new message.\n */\nexport const SetContentCollectionsResponseSchema: GenMessage<SetContentCollectionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 9);\n\n/**\n * @generated from message contenthub.v1.SetContentAssigneesRequest\n */\nexport type SetContentAssigneesRequest = Message<\"contenthub.v1.SetContentAssigneesRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The whole new set; empty unassigns everyone.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentAssigneesRequest.\n * Use `create(SetContentAssigneesRequestSchema)` to create a new message.\n */\nexport const SetContentAssigneesRequestSchema: GenMessage<SetContentAssigneesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 10);\n\n/**\n * @generated from message contenthub.v1.SetContentAssigneesResponse\n */\nexport type SetContentAssigneesResponse = Message<\"contenthub.v1.SetContentAssigneesResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentAssigneesResponse.\n * Use `create(SetContentAssigneesResponseSchema)` to create a new message.\n */\nexport const SetContentAssigneesResponseSchema: GenMessage<SetContentAssigneesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 11);\n\n/**\n * @generated from message contenthub.v1.BlockContentRequest\n */\nexport type BlockContentRequest = Message<\"contenthub.v1.BlockContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * One of the workspace's Block Reasons.\n *\n * @generated from field: string block_reason_id = 2;\n */\n blockReasonId: string;\n\n /**\n * Who may still edit it, at most 50 odon user ids, each once; empty is\n * nobody.\n *\n * @generated from field: repeated string allowed_user_ids = 3;\n */\n allowedUserIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.BlockContentRequest.\n * Use `create(BlockContentRequestSchema)` to create a new message.\n */\nexport const BlockContentRequestSchema: GenMessage<BlockContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 12);\n\n/**\n * @generated from message contenthub.v1.BlockContentResponse\n */\nexport type BlockContentResponse = Message<\"contenthub.v1.BlockContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.BlockContentResponse.\n * Use `create(BlockContentResponseSchema)` to create a new message.\n */\nexport const BlockContentResponseSchema: GenMessage<BlockContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 13);\n\n/**\n * @generated from message contenthub.v1.UnblockContentRequest\n */\nexport type UnblockContentRequest = Message<\"contenthub.v1.UnblockContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UnblockContentRequest.\n * Use `create(UnblockContentRequestSchema)` to create a new message.\n */\nexport const UnblockContentRequestSchema: GenMessage<UnblockContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 14);\n\n/**\n * @generated from message contenthub.v1.UnblockContentResponse\n */\nexport type UnblockContentResponse = Message<\"contenthub.v1.UnblockContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UnblockContentResponse.\n * Use `create(UnblockContentResponseSchema)` to create a new message.\n */\nexport const UnblockContentResponseSchema: GenMessage<UnblockContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 15);\n\n/**\n * @generated from message contenthub.v1.ArchiveContentRequest\n */\nexport type ArchiveContentRequest = Message<\"contenthub.v1.ArchiveContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.ArchiveContentRequest.\n * Use `create(ArchiveContentRequestSchema)` to create a new message.\n */\nexport const ArchiveContentRequestSchema: GenMessage<ArchiveContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 16);\n\n/**\n * @generated from message contenthub.v1.ArchiveContentResponse\n */\nexport type ArchiveContentResponse = Message<\"contenthub.v1.ArchiveContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ArchiveContentResponse.\n * Use `create(ArchiveContentResponseSchema)` to create a new message.\n */\nexport const ArchiveContentResponseSchema: GenMessage<ArchiveContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 17);\n\n/**\n * @generated from message contenthub.v1.UnarchiveContentRequest\n */\nexport type UnarchiveContentRequest = Message<\"contenthub.v1.UnarchiveContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UnarchiveContentRequest.\n * Use `create(UnarchiveContentRequestSchema)` to create a new message.\n */\nexport const UnarchiveContentRequestSchema: GenMessage<UnarchiveContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 18);\n\n/**\n * @generated from message contenthub.v1.UnarchiveContentResponse\n */\nexport type UnarchiveContentResponse = Message<\"contenthub.v1.UnarchiveContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UnarchiveContentResponse.\n * Use `create(UnarchiveContentResponseSchema)` to create a new message.\n */\nexport const UnarchiveContentResponseSchema: GenMessage<UnarchiveContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 19);\n\n/**\n * ContentBlocked is a detail of a FailedPrecondition write on blocked\n * Content by a caller its Block doesn't allow: StartChain, StartEditing,\n * SaveRevision, UpdateFromMain's merges, ResolveMerge, UpgradeContent,\n * PlanRelease and UpdatePlannedRelease. A write changing several blocked\n * Contents carries one per Content. Ask someone it allows, or have it\n * unblocked.\n *\n * @generated from message contenthub.v1.ContentBlocked\n */\nexport type ContentBlocked = Message<\"contenthub.v1.ContentBlocked\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: string block_reason_id = 2;\n */\n blockReasonId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ContentBlocked.\n * Use `create(ContentBlockedSchema)` to create a new message.\n */\nexport const ContentBlockedSchema: GenMessage<ContentBlocked> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 20);\n\n/**\n * ContentArchived is the detail of a FailedPrecondition StartChain or\n * StartEditing on Archived Content: unarchive it first.\n *\n * @generated from message contenthub.v1.ContentArchived\n */\nexport type ContentArchived = Message<\"contenthub.v1.ContentArchived\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ContentArchived.\n * Use `create(ContentArchivedSchema)` to create a new message.\n */\nexport const ContentArchivedSchema: GenMessage<ContentArchived> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 21);\n\n/**\n * @generated from message contenthub.v1.ListChangeSetsResponse\n */\nexport type ListChangeSetsResponse = Message<\"contenthub.v1.ListChangeSetsResponse\"> & {\n /**\n * Without their chains.\n *\n * @generated from field: repeated contenthub.v1.ChangeSet change_sets = 1;\n */\n changeSets: ChangeSet[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListChangeSetsResponse.\n * Use `create(ListChangeSetsResponseSchema)` to create a new message.\n */\nexport const ListChangeSetsResponseSchema: GenMessage<ListChangeSetsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 22);\n\n/**\n * ContentService covers editor reads across Change Sets (ADR 0015). It never\n * writes history: that is ChangeSetService's.\n *\n * It also holds Content's unversioned attributes, which are not history:\n * setting one needs no Change Set and writes no Revision, so nothing about it\n * ever reaches a Release (ADR 0015).\n *\n * Every RPC acts in the caller's workspace, from the token. Reads need\n * `viewer`, the attribute setters `editor` (ADR 0017).\n *\n * @generated from service contenthub.v1.ContentService\n */\nexport const ContentService: GenService<{\n /**\n * GetContent reads one Content with the Blueprint Release its Revision\n * pins, as contenthub validated and cached it, so a form is drawn from\n * exactly what contenthub accepted.\n *\n * With change_set_id it reads the Content inside that Change Set; without,\n * on Main. Content born in a Change Set exists only inside it until\n * Publish: read anywhere else, or after the Change Set was discarded, it is\n * NotFound.\n *\n * @generated from rpc contenthub.v1.ContentService.GetContent\n */\n getContent: {\n methodKind: \"unary\";\n input: typeof GetContentRequestSchema;\n output: typeof GetContentResponseSchema;\n },\n /**\n * ListChangeSets lists Change Sets, newest first, optionally only those\n * with a Chain on one Content, or in one state.\n *\n * @generated from rpc contenthub.v1.ContentService.ListChangeSets\n */\n listChangeSets: {\n methodKind: \"unary\";\n input: typeof ListChangeSetsRequestSchema;\n output: typeof ListChangeSetsResponseSchema;\n },\n /**\n * ListContents lists Content in one view, optionally narrowed to one\n * Collection and by Editor Search (ContentFilter.search), ordered by id.\n *\n * @generated from rpc contenthub.v1.ContentService.ListContents\n */\n listContents: {\n methodKind: \"unary\";\n input: typeof ListContentsRequestSchema;\n output: typeof ListContentsResponseSchema;\n },\n /**\n * SetContentCollections files a Content into exactly the Collections\n * named, unfiling it from any other: an empty list unfiles it from all.\n * Content born in an open Change Set can be filed before it is published.\n *\n * Filing is not a save: it needs no Change Set, writes no Revision, moves\n * no head and never reaches a Release (ADR 0015). A change is announced\n * with contenthub.content.collections_changed; setting the Collections the\n * Content is already in changes nothing and announces nothing. An unknown\n * Content or Collection is NotFound.\n *\n * @generated from rpc contenthub.v1.ContentService.SetContentCollections\n */\n setContentCollections: {\n methodKind: \"unary\";\n input: typeof SetContentCollectionsRequestSchema;\n output: typeof SetContentCollectionsResponseSchema;\n },\n /**\n * SetContentAssignees replaces who maintains a Content (ADR 0015): at most\n * 50 odon user ids, each once. Like filing it is no save, needs no Change\n * Set and writes no Revision. A change is announced with\n * contenthub.content.assignees_changed; the same set again, in any order,\n * changes and announces nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.SetContentAssignees\n */\n setContentAssignees: {\n methodKind: \"unary\";\n input: typeof SetContentAssigneesRequestSchema;\n output: typeof SetContentAssigneesResponseSchema;\n },\n /**\n * BlockContent blocks a Content with one of the workspace's Block Reasons\n * and, optionally, the users still allowed to edit it (CONTEXT.md, Block).\n * While it holds, every write that edits the Content (StartChain,\n * StartEditing, SaveRevision, UpdateFromMain's merges, ResolveMerge,\n * UpgradeContent, PlanRelease, UpdatePlannedRelease) is\n * FailedPrecondition with a ContentBlocked detail for every other caller,\n * on Chains started before the Block too, and a Publish of a\n * Change Set that changes it lists a blocked_content PublishBlocker. A\n * Block controls editing, not seeing: every read is unchanged.\n *\n * Blocking a blocked Content replaces its Block. It is announced with\n * contenthub.content.blocked; the same Block again announces nothing. An\n * unknown Block Reason is NotFound. Like filing it is no save.\n *\n * @generated from rpc contenthub.v1.ContentService.BlockContent\n */\n blockContent: {\n methodKind: \"unary\";\n input: typeof BlockContentRequestSchema;\n output: typeof BlockContentResponseSchema;\n },\n /**\n * UnblockContent lifts a Content's Block, announced with\n * contenthub.content.unblocked. Lifting none changes nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.UnblockContent\n */\n unblockContent: {\n methodKind: \"unary\";\n input: typeof UnblockContentRequestSchema;\n output: typeof UnblockContentResponseSchema;\n },\n /**\n * ArchiveContent puts aside a published Content that has no Release In\n * Force today or later, after a Repeal or a Withdrawal ended its force.\n * ListContents (and so Editor Search and every picker) leaves it out unless\n * asked; StartChain and StartEditing are FailedPrecondition with a\n * ContentArchived detail; a save adding a Reference to it is InvalidArgument\n * with an archived_target Violation; and a Publish that would change it\n * lists an archived_content PublishBlocker. Its Releases stay readable and\n * every pin to them keeps resolving (ADR 0015).\n *\n * Content with a Release In Force today or later, or not yet published, is\n * FailedPrecondition. It is announced with contenthub.content.archived;\n * archiving Archived Content changes nothing. Like filing it is no save.\n *\n * @generated from rpc contenthub.v1.ContentService.ArchiveContent\n */\n archiveContent: {\n methodKind: \"unary\";\n input: typeof ArchiveContentRequestSchema;\n output: typeof ArchiveContentResponseSchema;\n },\n /**\n * UnarchiveContent brings Archived Content back into editing, announced\n * with contenthub.content.unarchived. Unarchiving other Content changes\n * nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.UnarchiveContent\n */\n unarchiveContent: {\n methodKind: \"unary\";\n input: typeof UnarchiveContentRequestSchema;\n output: typeof UnarchiveContentResponseSchema;\n },\n /**\n * ListReferences reads a Content's outgoing edges in the Content Graph, at\n * one Revision, at the Revision a Release pins, or at the Release In Force,\n * and to a depth: References, TOC subtrees and everything else a Revision\n * points at (ADR 0009).\n *\n * @generated from rpc contenthub.v1.ContentService.ListReferences\n */\n listReferences: {\n methodKind: \"unary\";\n input: typeof ListReferencesRequestSchema;\n output: typeof ListReferencesResponseSchema;\n },\n /**\n * ListReferrers reads the incoming edges of a Content, or of an Anchor in\n * it: those of the Releases In Force at a date and moment, and optionally\n * those of the Branch heads of open Change Sets, each naming the Release\n * or the Change Set and Branch it was found in.\n *\n * @generated from rpc contenthub.v1.ContentService.ListReferrers\n */\n listReferrers: {\n methodKind: \"unary\";\n input: typeof ListReferrersRequestSchema;\n output: typeof ListReferrersResponseSchema;\n },\n /**\n * ListOutdatedPins lists the pinned edges of a Branch's head or of a\n * Revision whose Release is superseded, or is not the one In Force on\n * valid_on, each with its target's Timeline as the candidates to re-pin\n * to (#79). A pin is never moved on by itself: re-pinning is a save.\n *\n * @generated from rpc contenthub.v1.ContentService.ListOutdatedPins\n */\n listOutdatedPins: {\n methodKind: \"unary\";\n input: typeof ListOutdatedPinsRequestSchema;\n output: typeof ListOutdatedPinsResponseSchema;\n },\n /**\n * GetReleases reads Releases by id, superseded ones included and marked,\n * as ReleaseService.GetReleases does (#68).\n *\n * @generated from rpc contenthub.v1.ContentService.GetReleases\n */\n getReleases: {\n methodKind: \"unary\";\n input: typeof GetReleasesRequestSchema;\n output: typeof GetReleasesResponseSchema;\n },\n /**\n * GetTimeline reads a Content's Timeline, as ReleaseService.GetTimeline\n * does, with the Planned Releases of open Change Sets beside it (#68).\n * Content born in an open Change Set has only those.\n *\n * @generated from rpc contenthub.v1.ContentService.GetTimeline\n */\n getTimeline: {\n methodKind: \"unary\";\n input: typeof GetTimelineRequestSchema;\n output: typeof GetTimelineResponseSchema;\n },\n /**\n * ListRevisions lists the Revisions of a Content or of one Branch, newest\n * first, each with its author, time and cause.\n *\n * @generated from rpc contenthub.v1.ContentService.ListRevisions\n */\n listRevisions: {\n methodKind: \"unary\";\n input: typeof ListRevisionsRequestSchema;\n output: typeof ListRevisionsResponseSchema;\n },\n /**\n * Compare reports how one Revision differs from a base, field by field,\n * through fieldkit's Compare: another Revision, the fork of a Branch, or\n * Main's head. It only displays; it never decides a merge.\n *\n * @generated from rpc contenthub.v1.ContentService.Compare\n */\n compare: {\n methodKind: \"unary\";\n input: typeof CompareRequestSchema;\n output: typeof CompareResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_content, 0);\n\n","import { fromJson, type JsonObject, type JsonValue, toJson } from \"@bufbuild/protobuf\";\nimport { type Timestamp, timestampDate, ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport { Code, ConnectError, createClient, type Transport } from \"@connectrpc/connect\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport {\n\tBlueprintCatalogService,\n\tChangeSetClosedSchema,\n\tChangeSetService,\n\tCollectionService,\n\tContentArchivedSchema,\n\tContentBlockedSchema,\n\tContentService,\n\tCoversReleaseSchema,\n\tGuardianModeRequiredSchema,\n\ttype ProtoBlockReason,\n\tProtoBranchKind,\n\ttype ProtoCatalogRelease,\n\ttype ProtoChangeSet,\n\tProtoChangeSetState,\n\tProtoCheckOutcome,\n\ttype ProtoCheckResult,\n\tProtoCheckScope,\n\ttype ProtoCollection,\n\tProtoCollectionAccessLevel,\n\ttype ProtoContent,\n\ttype ProtoContentAttributes,\n\ttype ProtoEdge,\n\tProtoEdgeKind,\n\tProtoFieldChangeKind,\n\ttype ProtoGapReferrer,\n\ttype ProtoMergeField,\n\tProtoMergeSide,\n\ttype ProtoPendingMerge,\n\tProtoPendingMergeReason,\n\ttype ProtoPlannedRelease,\n\ttype ProtoPublishBlocker,\n\ttype ProtoRelease,\n\tProtoReleaseKind,\n\ttype ProtoRequiredCheck,\n\ttype ProtoRevision,\n\tProtoRevisionCause,\n\ttype ProtoTimelineEntry,\n\ttype ProtoValidityPeriod,\n\tPublishBlockerSchema,\n\tRefusalSchema,\n\tReleaseService,\n\tStaleHeadSchema,\n\tStaleStatusSchema,\n\tStatusTransitionRefusedSchema,\n\tViolationSchema,\n\tWithheldWorkSchema,\n\tWorkspaceConfigService,\n} from \"../gen-bridge\";\nimport type {\n\tBlockReason,\n\tBlueprintReleaseInfo,\n\tChangeSet,\n\tChangeSetState,\n\tCheckOutcome,\n\tCheckResult,\n\tCollection,\n\tCollectionAccessLevel,\n\tContent,\n\tContentAttributes,\n\tEdge,\n\tEdgeKind,\n\tMergeField,\n\tPendingMerge,\n\tPendingMergeRef,\n\tPlannedEnd,\n\tPlannedRelease,\n\tPublishBlocker,\n\tRecorderGrant,\n\tRelease,\n\tReleaseKind,\n\tRequiredCheck,\n\tResolvedBlueprintRelease,\n\tRevision,\n\tRevisionCause,\n\tTimelineEntry,\n\tValidityPeriod,\n} from \"../types\";\nimport {\n\tAccessDeniedError,\n\tBlockReasonNameTakenError,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tContentArchivedError,\n\tContentBlockedError,\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n\tNameTakenError,\n\tPublishRefusedError,\n\tRestrictionUnavailableError,\n\tServiceUnavailableError,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n\tWithheldWorkError,\n} from \"./contenthub-client\";\n\nexport interface CreateConnectContenthubClientOptions {\n\t/**\n\t * Base URL on the host origin, under which `/contenthub.v1.…/…` is served:\n\t * \"\" when contenthub serves the page itself (the harness), the mount prefix\n\t * (`/api/contenthub`) when core proxies it.\n\t */\n\tbaseUrl: string;\n\t/** The fetch every call goes through; a host adds its credentials here. */\n\tfetch?: typeof fetch;\n\t/** A pre-built transport (tests: `createRouterTransport`). Overrides baseUrl/fetch. */\n\ttransport?: Transport;\n}\n\nfunction iso(ts: Timestamp | undefined): string {\n\treturn ts ? timestampDate(ts).toISOString() : \"\";\n}\n\nfunction catalogReleaseFromProto(r: ProtoCatalogRelease): BlueprintReleaseInfo {\n\treturn {\n\t\tid: r.id,\n\t\tblueprintId: r.blueprintId,\n\t\tname: r.name,\n\t\treleaseTime: iso(r.releaseTime),\n\t\trefusals: r.refusals.map((v) => ({ source: v.source, code: v.code, path: v.path })),\n\t};\n}\n\n/** blueprinthub giving no answer through contenthub reads as the service down. */\nasync function catalogRead<T>(call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tconst ce = ConnectError.from(err);\n\t\tif (ce.code === Code.Unavailable) throw new ServiceUnavailableError(ce.rawMessage);\n\t\tthrow err;\n\t}\n}\n\nfunction blockReasonFromProto(r: ProtoBlockReason | undefined): BlockReason {\n\tif (!r) throw new Error(\"the response carried no Block Reason\");\n\treturn { id: r.id, name: r.name, createTime: iso(r.createTime), updateTime: iso(r.updateTime) };\n}\n\nconst STATE_FROM_PROTO: Record<ProtoChangeSetState, ChangeSetState | undefined> = {\n\t[ProtoChangeSetState.UNSPECIFIED]: undefined,\n\t[ProtoChangeSetState.OPEN]: \"open\",\n\t[ProtoChangeSetState.PUBLISHED]: \"published\",\n\t[ProtoChangeSetState.DISCARDED]: \"discarded\",\n};\n\nconst STATE_TO_PROTO: Record<ChangeSetState, ProtoChangeSetState> = {\n\topen: ProtoChangeSetState.OPEN,\n\tpublished: ProtoChangeSetState.PUBLISHED,\n\tdiscarded: ProtoChangeSetState.DISCARDED,\n};\n\nfunction stateFromProto(state: ProtoChangeSetState): ChangeSetState {\n\t// The service never answers UNSPECIFIED; an enum value this build doesn't\n\t// know yet reads as open, the one state that offers no closed-only promise.\n\treturn STATE_FROM_PROTO[state] ?? \"open\";\n}\n\nfunction changeSetFromProto(cs: ProtoChangeSet | undefined): ChangeSet {\n\tif (!cs) throw new Error(\"the response carried no Change Set\");\n\treturn {\n\t\tid: cs.id,\n\t\tname: cs.name,\n\t\tsource: cs.source ? { date: cs.source.date, reference: cs.source.reference } : undefined,\n\t\tstate: stateFromProto(cs.state),\n\t\tcreatedBy: cs.createdBy,\n\t\tcreateTime: iso(cs.createTime),\n\t\tcloseTime: cs.closeTime ? iso(cs.closeTime) : undefined,\n\t\tchains: cs.chains.map((chain) => ({\n\t\t\tid: chain.id,\n\t\t\tcontentId: chain.contentId,\n\t\t\tborn: chain.born,\n\t\t\tbranches: chain.branches.map((b) => ({\n\t\t\t\tid: b.id,\n\t\t\t\tposition: b.position,\n\t\t\t\tkind: b.kind === ProtoBranchKind.CARRY_FORWARD ? \"carry_forward\" : \"editorial\",\n\t\t\t\theadRevisionId: b.headRevisionId,\n\t\t\t\teffectiveOn: b.effectiveOn,\n\t\t\t\tcarriedReleaseId: b.carriedReleaseId,\n\t\t\t\thasPendingMerge: b.hasPendingMerge,\n\t\t\t})),\n\t\t})),\n\t\tdependsOnChangeSetIds: [...cs.dependsOnChangeSetIds],\n\t\tstatus: cs.status,\n\t\tassigneeIds: [...cs.assigneeIds],\n\t\tplannedReleases: cs.plannedReleases.map(plannedReleaseFromProto),\n\t};\n}\n\nconst KIND_FROM_PROTO: Record<ProtoReleaseKind, ReleaseKind> = {\n\t// The service never answers UNSPECIFIED; read it as the common kind.\n\t[ProtoReleaseKind.UNSPECIFIED]: \"revision\",\n\t[ProtoReleaseKind.REVISION]: \"revision\",\n\t[ProtoReleaseKind.DATE_ONLY]: \"date_only\",\n\t[ProtoReleaseKind.REPEAL]: \"repeal\",\n\t[ProtoReleaseKind.WITHDRAWAL]: \"withdrawal\",\n};\n\nfunction periodFromProto(p: ProtoValidityPeriod | undefined): ValidityPeriod | undefined {\n\treturn p ? { firstDay: p.firstDay, lastDay: p.lastDay } : undefined;\n}\n\nfunction plannedReleaseFromProto(pr: ProtoPlannedRelease): PlannedRelease {\n\treturn {\n\t\tid: pr.id,\n\t\tcontentId: pr.contentId,\n\t\tkind: KIND_FROM_PROTO[pr.kind] ?? \"revision\",\n\t\tbranchId: pr.branchId,\n\t\trevisionId: pr.revisionId,\n\t\tvalidityPeriod: periodFromProto(pr.validityPeriod),\n\t\treleaseSpec: pr.releaseSpec ? { ...pr.releaseSpec } : undefined,\n\t\tsupersedesReleaseIds: [...pr.supersedesReleaseIds],\n\t\tproposed: pr.proposed,\n\t\tproposedForReleaseId: pr.proposedForReleaseId,\n\t\tsplitFromReleaseId: pr.splitFromReleaseId,\n\t\twithheld: pr.withheld,\n\t};\n}\n\nfunction releaseFromProto(r: ProtoRelease): Release {\n\treturn {\n\t\tid: r.id,\n\t\tcontentId: r.contentId,\n\t\tkind: KIND_FROM_PROTO[r.kind] ?? \"revision\",\n\t\tbranchId: r.branchId,\n\t\trevisionId: r.revisionId,\n\t\tfirst: r.first,\n\t\tsupersedesReleaseIds: [...r.supersedesReleaseIds],\n\t\tvalidityPeriod: periodFromProto(r.validityPeriod),\n\t};\n}\n\nfunction blockerFromProto(b: ProtoPublishBlocker): PublishBlocker {\n\treturn {\n\t\tcode: b.code,\n\t\tcontentId: b.contentId,\n\t\tbranchId: b.branchId,\n\t\texpectedHeadId: b.expectedHeadId,\n\t\tcurrentHeadId: b.currentHeadId,\n\t\treleaseId: b.releaseId,\n\t\toverlapsReleaseId: b.overlapsReleaseId,\n\t\tdependencyChangeSetId: b.dependencyChangeSetId,\n\t\tpath: b.path,\n\t\ttargetContentId: b.targetContentId,\n\t\tassetId: b.assetId,\n\t\tparentContentIds: [...b.parentContentIds],\n\t\trequiredCheckId: b.requiredCheckId,\n\t\tcoveredReleaseId: b.coveredReleaseId,\n\t\trevisionId: b.revisionId,\n\t};\n}\n\nfunction pendingFromProto(p: ProtoPendingMerge): PendingMergeRef {\n\treturn { branchId: p.branchId, contentId: p.contentId };\n}\n\n/** A google.protobuf.Value as JSON; absent stays absent (a side without the field). */\nfunction jsonOf(v: Parameters<typeof toJson<typeof ValueSchema>>[1] | undefined): unknown {\n\treturn v ? toJson(ValueSchema, v) : undefined;\n}\n\nfunction mergeFieldFromProto(f: ProtoMergeField): MergeField {\n\treturn {\n\t\tpath: f.path,\n\t\tconflictPaths: [...f.conflictPaths],\n\t\tbase: jsonOf(f.base),\n\t\tours: jsonOf(f.ours),\n\t\ttheirs: jsonOf(f.theirs),\n\t};\n}\n\n/**\n * A plan's refusals: Release Spec values the Blueprint Release refuses as\n * one `ContentRefusedError`, a period covering Releases as\n * `CoversReleaseError`, otherwise an edit's.\n */\nfunction planRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst covers = ce.findDetails(CoversReleaseSchema)[0];\n\tif (covers) return new CoversReleaseError(covers.contentId, [...covers.coveredReleaseIds]);\n\treturn saveRefusal(changeSetId, err);\n}\n\n/** A Struct through JSON: a Struct holds no `undefined`, which a form's values may carry. */\nfunction struct(values: Record<string, unknown>): JsonObject {\n\treturn JSON.parse(JSON.stringify(values)) as JsonObject;\n}\n\nconst OUTCOME_FROM_PROTO: Record<ProtoCheckOutcome, CheckOutcome | undefined> = {\n\t[ProtoCheckOutcome.UNSPECIFIED]: undefined,\n\t[ProtoCheckOutcome.PASSED]: \"passed\",\n\t[ProtoCheckOutcome.FAILED]: \"failed\",\n\t[ProtoCheckOutcome.WAIVED]: \"waived\",\n};\n\nconst OUTCOME_TO_PROTO: Record<CheckOutcome, ProtoCheckOutcome> = {\n\tpassed: ProtoCheckOutcome.PASSED,\n\tfailed: ProtoCheckOutcome.FAILED,\n\twaived: ProtoCheckOutcome.WAIVED,\n};\n\nfunction checkResultFromProto(r: ProtoCheckResult | undefined): CheckResult {\n\tif (!r) throw new Error(\"the response carried no Check Result\");\n\treturn {\n\t\tid: r.id,\n\t\trequiredCheckId: r.requiredCheckId,\n\t\theads: { ...r.heads },\n\t\t// An outcome this build doesn't know counts for nothing, as failed does.\n\t\toutcome: OUTCOME_FROM_PROTO[r.outcome] ?? \"failed\",\n\t\tnote: r.note,\n\t\trecordedBy: r.recordedBy,\n\t\trecordTime: iso(r.recordTime),\n\t};\n}\n\nfunction requiredCheckFromProto(c: ProtoRequiredCheck | undefined): RequiredCheck {\n\tif (!c) throw new Error(\"the response carried no Required Check\");\n\treturn {\n\t\tid: c.id,\n\t\tname: c.name,\n\t\tscope: c.scope === ProtoCheckScope.CHANGE_SET ? \"change_set\" : \"branch\",\n\t\tblueprintAccessors: [...c.blueprintAccessors],\n\t\tindependent: c.independent,\n\t};\n}\n\nfunction collectionFromProto(c: ProtoCollection | undefined): Collection {\n\tif (!c) throw new Error(\"the response carried no Collection\");\n\treturn { id: c.id, name: c.name, parentId: c.parentId, restricted: c.restricted };\n}\n\nconst SCOPE_TO_PROTO = {\n\tbranch: ProtoCheckScope.BRANCH,\n\tchange_set: ProtoCheckScope.CHANGE_SET,\n} as const;\n\nconst LEVEL_FROM_PROTO: Record<ProtoCollectionAccessLevel, CollectionAccessLevel> = {\n\t// The service never answers UNSPECIFIED; read it as the least access.\n\t[ProtoCollectionAccessLevel.UNSPECIFIED]: \"viewer\",\n\t[ProtoCollectionAccessLevel.VIEWER]: \"viewer\",\n\t[ProtoCollectionAccessLevel.EDITOR]: \"editor\",\n\t[ProtoCollectionAccessLevel.OWNER]: \"owner\",\n};\n\n/**\n * GuardianModeRequired's feature on workspace mode's refusal of every\n * restriction and grant (internal/authz.RestrictionRefused): the screens\n * read it as `RestrictionUnavailableError`, by the detail and never the text.\n */\nconst COLLECTION_RESTRICTION = \"collection_restriction\";\n\n/**\n * The refusals of a Required Check's or Collection's write, as typed errors.\n * `name` is the one asked for, for AlreadyExists, which carries no detail.\n */\nfunction settingsRefusal(err: unknown, name = \"\"): unknown {\n\tconst ce = ConnectError.from(err);\n\tswitch (ce.code) {\n\t\tcase Code.AlreadyExists:\n\t\t\treturn new NameTakenError(name.trim());\n\t\tcase Code.PermissionDenied:\n\t\t\treturn new AccessDeniedError(ce.rawMessage);\n\t\tcase Code.FailedPrecondition: {\n\t\t\tconst [guardianMode] = ce.findDetails(GuardianModeRequiredSchema);\n\t\t\tif (guardianMode?.feature === COLLECTION_RESTRICTION) {\n\t\t\t\treturn new RestrictionUnavailableError(ce.rawMessage);\n\t\t\t}\n\t\t\tif (guardianMode) return new GuardianModeRequiredError(guardianMode.feature, ce.rawMessage);\n\t\t\treturn new InvalidInputError(ce.rawMessage);\n\t\t}\n\t\tcase Code.InvalidArgument:\n\t\t\treturn new InvalidInputError(ce.rawMessage);\n\t\tcase Code.Unavailable:\n\t\t\treturn new ServiceUnavailableError(ce.rawMessage);\n\t\tdefault:\n\t\t\treturn err;\n\t}\n}\n\n/** A recorder grant as the wire's Recorder oneof. */\nfunction recorderToProto(r: RecorderGrant) {\n\treturn \"everyMember\" in r\n\t\t? { recorder: { case: \"everyMember\" as const, value: true } }\n\t\t: { recorder: { case: \"userId\" as const, value: r.userId } };\n}\n\n/** Runs a settings write, its refusals turned into typed errors. */\nasync function settingsWrite<T>(call: () => Promise<T>, name?: string): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tthrow settingsRefusal(err, name);\n\t}\n}\n\nfunction contentFromProto(c: ProtoContent | undefined): Content {\n\tif (!c) throw new Error(\"the response carried no Content\");\n\treturn {\n\t\tid: c.id,\n\t\tblueprintId: c.blueprintId,\n\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\trevisionId: c.revisionId,\n\t\tdata: { ...(c.data ?? {}) },\n\t\tchangeSetId: c.changeSetId,\n\t\tbranchId: c.branchId,\n\t\trevisionCreateTime: iso(c.revisionCreateTime),\n\t\treleaseId: c.releaseId,\n\t};\n}\n\nfunction attributesFromProto(a: ProtoContentAttributes | undefined): ContentAttributes {\n\treturn {\n\t\tcollectionIds: [...(a?.collectionIds ?? [])],\n\t\tassigneeIds: [...(a?.assigneeIds ?? [])],\n\t\tblock: a?.block\n\t\t\t? {\n\t\t\t\t\tblockReasonId: a.block.blockReasonId,\n\t\t\t\t\tallowedUserIds: [...a.block.allowedUserIds],\n\t\t\t\t\tblockedBy: a.block.blockedBy,\n\t\t\t\t\tblockTime: iso(a.block.blockTime),\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tarchiveTime: a?.archiveTime ? iso(a.archiveTime) : undefined,\n\t};\n}\n\n/**\n * The Resolved Release's few keys the screens read. It crosses as bytes\n * (blueprinthub ADR 0004) and only grows by optional keys, so a reader takes\n * what it knows and ignores the rest; bytes that aren't such a document read\n * as none, and the page falls back to the bare data.\n */\nexport function resolvedReleaseFromBytes(bytes: Uint8Array): ResolvedBlueprintRelease | undefined {\n\tif (bytes.length === 0) return undefined;\n\ttry {\n\t\tconst doc = JSON.parse(new TextDecoder().decode(bytes)) as {\n\t\t\tdisplay_name?: unknown;\n\t\t\tdated?: unknown;\n\t\t\trelease_spec?: unknown;\n\t\t\tspec?: { fields?: unknown; parts?: unknown } | null;\n\t\t};\n\t\tconst fields = Array.isArray(doc.spec?.fields) ? doc.spec.fields : [];\n\t\tconst parts =\n\t\t\tdoc.spec?.parts && typeof doc.spec.parts === \"object\"\n\t\t\t\t? (doc.spec.parts as ResolvedBlueprintRelease[\"parts\"])\n\t\t\t\t: {};\n\t\treturn {\n\t\t\tdisplayName: typeof doc.display_name === \"string\" ? doc.display_name : \"\",\n\t\t\tdated: doc.dated === true,\n\t\t\tfields: fields as ResolvedBlueprintRelease[\"fields\"],\n\t\t\t// The Release Spec: fieldkit fields, beside the spec's (blueprinthub ADR 0004).\n\t\t\treleaseSpec: Array.isArray(doc.release_spec)\n\t\t\t\t? (doc.release_spec as ResolvedBlueprintRelease[\"fields\"])\n\t\t\t\t: [],\n\t\t\tparts,\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction timelineEntryFromProto(e: ProtoTimelineEntry): TimelineEntry {\n\treturn {\n\t\tordinal: e.ordinal,\n\t\treleaseId: e.releaseId,\n\t\tkind: KIND_FROM_PROTO[e.kind] ?? \"revision\",\n\t\trevisionId: e.revisionId,\n\t\tblueprintReleaseId: e.blueprintReleaseId,\n\t\tvalidityPeriod: periodFromProto(e.validityPeriod),\n\t\tpublishTime: iso(e.publishTime),\n\t\tfirst: e.first,\n\t};\n}\n\n/** A Planned Release a response must carry. */\nfunction requiredPlannedRelease(p: ProtoPlannedRelease | undefined): PlannedRelease {\n\tif (!p) throw new Error(\"the response carried no Planned Release\");\n\treturn plannedReleaseFromProto(p);\n}\n\nconst CAUSES: Record<ProtoRevisionCause, RevisionCause> = {\n\t[ProtoRevisionCause.UNSPECIFIED]: \"unspecified\",\n\t[ProtoRevisionCause.CREATE]: \"create\",\n\t[ProtoRevisionCause.SAVE]: \"save\",\n\t[ProtoRevisionCause.MERGE]: \"merge\",\n\t[ProtoRevisionCause.RESOLVE]: \"resolve\",\n\t[ProtoRevisionCause.UPGRADE]: \"upgrade\",\n};\n\nfunction revisionFromProto(r: ProtoRevision | undefined): Revision {\n\tif (!r) throw new Error(\"the response carried no Revision\");\n\treturn {\n\t\tid: r.id,\n\t\tcontentId: r.contentId,\n\t\tparentId: r.parentId,\n\t\tsecondParentId: r.secondParentId,\n\t\tblueprintReleaseId: r.blueprintReleaseId,\n\t\tcreateTime: iso(r.createTime),\n\t\tauthor: r.author,\n\t\tcause: CAUSES[r.cause] ?? \"unspecified\",\n\t\tbranchId: r.branchId,\n\t\tchangeSetId: r.changeSetId,\n\t};\n}\n\nconst EDGE_KINDS: Record<ProtoEdgeKind, EdgeKind> = {\n\t[ProtoEdgeKind.UNSPECIFIED]: \"unspecified\",\n\t[ProtoEdgeKind.REFERENCE]: \"reference\",\n\t[ProtoEdgeKind.TOC]: \"toc\",\n\t[ProtoEdgeKind.INCLUDE]: \"include\",\n\t[ProtoEdgeKind.EXCLUDE]: \"exclude\",\n\t[ProtoEdgeKind.REPLACE]: \"replace\",\n\t[ProtoEdgeKind.ANNOTATE]: \"annotate\",\n\t[ProtoEdgeKind.LINK]: \"link\",\n\t[ProtoEdgeKind.FOOTNOTE]: \"footnote\",\n\t[ProtoEdgeKind.ANCHOR]: \"anchor\",\n\t[ProtoEdgeKind.MEDIA]: \"media\",\n\t[ProtoEdgeKind.BLUEPRINT]: \"blueprint\",\n};\n\nfunction edgeFromProto(e: ProtoEdge | undefined): Edge {\n\treturn {\n\t\tsourceContentId: e?.sourceContentId ?? \"\",\n\t\tsourceRevisionId: e?.sourceRevisionId ?? \"\",\n\t\tpath: e?.path ?? \"\",\n\t\tkind: e ? (EDGE_KINDS[e.kind] ?? \"unspecified\") : \"unspecified\",\n\t\ttargetContentId: e?.targetContentId ?? \"\",\n\t\ttargetAssetId: e?.targetAssetId ?? \"\",\n\t\ttargetBlueprintReleaseId: e?.targetBlueprintReleaseId ?? \"\",\n\t\tpinReleaseId: e?.pinReleaseId ?? \"\",\n\t};\n}\n\nfunction plannedEndFromProto(res: {\n\tplannedRelease?: ProtoPlannedRelease;\n\tgapReferrers: ProtoGapReferrer[];\n}): PlannedEnd {\n\treturn {\n\t\tplannedRelease: requiredPlannedRelease(res.plannedRelease),\n\t\tgapReferrers: res.gapReferrers.map((g) => ({\n\t\t\tedge: edgeFromProto(g.edge),\n\t\t\treleaseId: g.releaseId,\n\t\t})),\n\t};\n}\n\n/**\n * An edit's refusals on a Content: its Block, its being Archived, and\n * otherwise any Change Set write's.\n */\nfunction editRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst blocked = ce.findDetails(ContentBlockedSchema)[0];\n\tif (blocked) return new ContentBlockedError(blocked.contentId, blocked.blockReasonId);\n\tconst archived = ce.findDetails(ContentArchivedSchema)[0];\n\tif (archived) return new ContentArchivedError(archived.contentId);\n\treturn changeSetRefusal(changeSetId, err);\n}\n\n/** An attribute setter's refusal: the service's guidance, fit to show. */\nasync function attributeWrite<T>(call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tconst ce = ConnectError.from(err);\n\t\tif (ce.code === Code.InvalidArgument || ce.code === Code.FailedPrecondition) {\n\t\t\tthrow new InvalidInputError(ce.rawMessage);\n\t\t}\n\t\tthrow err;\n\t}\n}\n\n/**\n * A new Content's refusals: the data's Violations or the Release's Refusals\n * as one `ContentRefusedError`, everything else as any Change Set write's.\n */\nfunction contentRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst reasons = [...ce.findDetails(ViolationSchema), ...ce.findDetails(RefusalSchema)].map(\n\t\t(r) => ({ source: r.source, code: r.code, path: r.path }),\n\t);\n\tif (reasons.length > 0) return new ContentRefusedError(ce.rawMessage, reasons);\n\treturn changeSetRefusal(changeSetId, err);\n}\n\n/**\n * A save's refusals: the data's Violations (or the Release's Refusals) as one `ContentRefusedError`,\n * otherwise an edit's (the Content's Block or Archive, a moved head, a\n * closed Change Set).\n */\nfunction saveRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst reasons = [...ce.findDetails(ViolationSchema), ...ce.findDetails(RefusalSchema)].map(\n\t\t(r) => ({ source: r.source, code: r.code, path: r.path }),\n\t);\n\tif (reasons.length > 0) return new ContentRefusedError(ce.rawMessage, reasons);\n\treturn editRefusal(changeSetId, err);\n}\n\n/**\n * The refusals any write to Change Set `id` can meet, as typed errors: the\n * Change Set closed, and (for a status move) statushub's no, a stale status\n * and statushub out of reach. InvalidArgument and the remaining\n * FailedPreconditions (a dependency cycle, a closed dependency, whose\n * ChangeSetClosed detail names the other Change Set) carry the service's\n * guidance, fit to show.\n */\nfunction changeSetRefusal(id: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst refused = ce.findDetails(StatusTransitionRefusedSchema)[0];\n\tif (refused) {\n\t\treturn new StatusTransitionRefusedError({\n\t\t\tfromStatus: refused.fromStatus,\n\t\t\ttoStatus: refused.toStatus,\n\t\t\treason: refused.reason,\n\t\t\trequiresPermission: refused.requiresPermission,\n\t\t});\n\t}\n\tconst stale = ce.findDetails(StaleStatusSchema)[0];\n\tif (stale) return new StaleStatusError(stale.currentStatus);\n\tconst closed = ce.findDetails(ChangeSetClosedSchema)[0];\n\tif (closed && (closed.changeSetId === id || closed.changeSetId === \"\")) {\n\t\treturn new ChangeSetClosedError(stateFromProto(closed.state));\n\t}\n\tconst blockers = ce.findDetails(PublishBlockerSchema);\n\tif (blockers.length > 0) return new PublishRefusedError(blockers.map(blockerFromProto));\n\tconst moved = ce.findDetails(StaleHeadSchema)[0];\n\tif (moved) return new StaleHeadError(moved);\n\tif (ce.findDetails(WithheldWorkSchema).length > 0) return new WithheldWorkError(ce.rawMessage);\n\tif (ce.code === Code.Unavailable) return new ServiceUnavailableError(ce.rawMessage);\n\tif (ce.code === Code.InvalidArgument || ce.code === Code.FailedPrecondition) {\n\t\treturn new InvalidInputError(ce.rawMessage);\n\t}\n\treturn err;\n}\n\n/** Runs a write to Change Set `id`, its refusals turned into typed errors. */\nasync function changeSetWrite<T>(id: string, call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tthrow changeSetRefusal(id, err);\n\t}\n}\n\n/**\n * Turns the service's refusals of a name into the typed errors the screens\n * act on. `name` is the one asked for: AlreadyExists carries no detail, and\n * the caller knows what it sent. InvalidArgument's message is the service's\n * guidance (commons surfaces it), so it is passed on as it is.\n */\nfunction nameRefusal(err: unknown, name: string): unknown {\n\tconst ce = ConnectError.from(err);\n\tif (ce.code === Code.AlreadyExists) return new BlockReasonNameTakenError(name.trim());\n\tif (ce.code === Code.InvalidArgument) return new InvalidInputError(ce.rawMessage);\n\treturn err;\n}\n\n/** The production `ContenthubClient`, over Connect. */\nexport function createConnectContenthubClient(\n\toptions: CreateConnectContenthubClientOptions,\n): ContenthubClient {\n\tconst transport =\n\t\toptions.transport ?? createConnectTransport({ baseUrl: options.baseUrl, fetch: options.fetch });\n\tconst config = createClient(WorkspaceConfigService, transport);\n\tconst changeSets = createClient(ChangeSetService, transport);\n\tconst contents = createClient(ContentService, transport);\n\tconst collections = createClient(CollectionService, transport);\n\tconst releases = createClient(ReleaseService, transport);\n\tconst catalog = createClient(BlueprintCatalogService, transport);\n\n\treturn {\n\t\tasync listBlockReasons() {\n\t\t\tconst res = await config.listBlockReasons({});\n\t\t\treturn res.blockReasons.map(blockReasonFromProto);\n\t\t},\n\t\tasync createBlockReason({ name }) {\n\t\t\ttry {\n\t\t\t\tconst res = await config.createBlockReason({ name });\n\t\t\t\treturn blockReasonFromProto(res.blockReason);\n\t\t\t} catch (err) {\n\t\t\t\tthrow nameRefusal(err, name);\n\t\t\t}\n\t\t},\n\t\tasync renameBlockReason({ id, name }) {\n\t\t\ttry {\n\t\t\t\tconst res = await config.renameBlockReason({ id, name });\n\t\t\t\treturn blockReasonFromProto(res.blockReason);\n\t\t\t} catch (err) {\n\t\t\t\tthrow nameRefusal(err, name);\n\t\t\t}\n\t\t},\n\t\tasync deleteBlockReason({ id }) {\n\t\t\tawait config.deleteBlockReason({ id });\n\t\t},\n\n\t\tasync listChangeSets(input = {}) {\n\t\t\tconst res = await contents.listChangeSets({\n\t\t\t\tstate: input.state ? STATE_TO_PROTO[input.state] : ProtoChangeSetState.UNSPECIFIED,\n\t\t\t\tassigneeId: input.assigneeId ?? \"\",\n\t\t\t\tcontentId: input.contentId ?? \"\",\n\t\t\t\tpageSize: input.pageSize ?? 0,\n\t\t\t\tpageToken: input.pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tchangeSets: res.changeSets.map(changeSetFromProto),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync createChangeSet({ name, source }) {\n\t\t\tconst res = await changeSetWrite(\"\", () => changeSets.createChangeSet({ name, source }));\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync getChangeSet(id) {\n\t\t\tconst res = await changeSets.getChangeSet({ id });\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync updateChangeSet({ id, updateMask, name, source, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.updateChangeSet({\n\t\t\t\t\tid,\n\t\t\t\t\tname: name ?? \"\",\n\t\t\t\t\tsource,\n\t\t\t\t\tupdateMask: { fields: updateMask },\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync setChangeSetStatus({ id, expectedStatus, status }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.setChangeSetStatus({ changeSetId: id, expectedStatus, status }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync setChangeSetAssignees({ id, assigneeIds }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.setChangeSetAssignees({ changeSetId: id, assigneeIds }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync addDependency({ id, dependsOnId }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.addDependency({ changeSetId: id, dependsOnChangeSetId: dependsOnId }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync removeDependency({ id, dependsOnId }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.removeDependency({ changeSetId: id, dependsOnChangeSetId: dependsOnId }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync validatePublish({ id, reviewedHeads }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.validatePublish({ changeSetId: id, reviewedHeads }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tblockers: res.blockers.map(blockerFromProto),\n\t\t\t\treleases: res.releases.map(releaseFromProto),\n\t\t\t\tpublished: res.published,\n\t\t\t};\n\t\t},\n\t\tasync publish({ id, reviewedHeads }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.publish({ changeSetId: id, reviewedHeads }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\tpublishTime: iso(res.publishTime),\n\t\t\t\treleases: res.releases.map(releaseFromProto),\n\t\t\t};\n\t\t},\n\t\tasync updateFromMain({ id, chainId, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.updateFromMain({\n\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\tchainId: chainId ?? \"\",\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\tmergedBranchIds: [...res.mergedBranchIds],\n\t\t\t\tconflicted: res.conflicted.map(pendingFromProto),\n\t\t\t\tpending: res.pending.map(pendingFromProto),\n\t\t\t\tendedBranchIds: [...res.endedBranchIds],\n\t\t\t};\n\t\t},\n\t\tasync discardChangeSet(id) {\n\t\t\tconst res = await changeSetWrite(id, () => changeSets.discardChangeSet({ id }));\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync listCheckResults(changeSetId) {\n\t\t\tconst res = await changeSets.listCheckResults({ changeSetId });\n\t\t\treturn res.standings.map((st) => ({\n\t\t\t\tcheck: requiredCheckFromProto(st.requiredCheck),\n\t\t\t\tcontentId: st.contentId,\n\t\t\t\tbranchId: st.branchId,\n\t\t\t\treleaseId: st.releaseId,\n\t\t\t\theads: { ...st.heads },\n\t\t\t\tresults: st.results.map(checkResultFromProto),\n\t\t\t\tstale: st.stale,\n\t\t\t\tcleared: st.cleared,\n\t\t\t}));\n\t\t},\n\t\tasync recordCheckResult({ changeSetId, requiredCheckId, heads, outcome, note }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.recordCheckResult({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\trequiredCheckId,\n\t\t\t\t\theads,\n\t\t\t\t\toutcome: OUTCOME_TO_PROTO[outcome],\n\t\t\t\t\tnote,\n\t\t\t\t});\n\t\t\t\treturn checkResultFromProto(res.checkResult);\n\t\t\t} catch (err) {\n\t\t\t\tconst ce = ConnectError.from(err);\n\t\t\t\t// The service's reason says which check and why: fit to show.\n\t\t\t\tif (ce.code === Code.PermissionDenied) throw new CheckResultDeniedError(ce.rawMessage);\n\t\t\t\tthrow changeSetRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\n\t\tasync listRequiredChecks() {\n\t\t\tconst res = await config.listRequiredChecks({});\n\t\t\treturn res.requiredChecks.map(requiredCheckFromProto);\n\t\t},\n\t\tasync createRequiredCheck(input) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() =>\n\t\t\t\t\tconfig.createRequiredCheck({\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\tscope: SCOPE_TO_PROTO[input.scope],\n\t\t\t\t\t\tblueprintAccessors: input.blueprintAccessors,\n\t\t\t\t\t\tindependent: input.independent,\n\t\t\t\t\t}),\n\t\t\t\tinput.name,\n\t\t\t);\n\t\t\treturn requiredCheckFromProto(res.requiredCheck);\n\t\t},\n\t\tasync updateRequiredCheck(input) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() =>\n\t\t\t\t\tconfig.updateRequiredCheck({\n\t\t\t\t\t\tid: input.id,\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\tscope: SCOPE_TO_PROTO[input.scope],\n\t\t\t\t\t\tblueprintAccessors: input.blueprintAccessors,\n\t\t\t\t\t\tindependent: input.independent,\n\t\t\t\t\t}),\n\t\t\t\tinput.name,\n\t\t\t);\n\t\t\treturn requiredCheckFromProto(res.requiredCheck);\n\t\t},\n\t\tasync deleteRequiredCheck({ id }) {\n\t\t\tawait settingsWrite(() => config.deleteRequiredCheck({ id }));\n\t\t},\n\t\tasync listRequiredCheckRecorders(requiredCheckId) {\n\t\t\tconst res = await settingsWrite(() => config.listRequiredCheckRecorders({ requiredCheckId }));\n\t\t\treturn { everyMember: res.everyMember, userIds: [...res.userIds] };\n\t\t},\n\t\tasync grantRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tconfig.grantRequiredCheckRecorder({ requiredCheckId, recorder: recorderToProto(recorder) }),\n\t\t\t);\n\t\t},\n\t\tasync revokeRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tconfig.revokeRequiredCheckRecorder({\n\t\t\t\t\trequiredCheckId,\n\t\t\t\t\trecorder: recorderToProto(recorder),\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\n\t\tasync searchBlueprints({ query, pageToken = \"\", signal }) {\n\t\t\tconst res = await catalogRead(() =>\n\t\t\t\tcatalog.searchBlueprints({ query, pageToken }, { signal }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tblueprints: res.blueprints.map((b) => ({ id: b.id, name: b.name })),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync listBlueprintReleases(blueprintId) {\n\t\t\tconst res = await catalogRead(() => catalog.listBlueprintReleases({ blueprintId }));\n\t\t\treturn res.releases.map(catalogReleaseFromProto);\n\t\t},\n\n\t\tasync listCollections() {\n\t\t\tconst res = await collections.listCollections({});\n\t\t\treturn res.collections.map(collectionFromProto);\n\t\t},\n\t\tasync createCollection({ name, parentId = \"\", restricted = false }) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() => collections.createCollection({ name, parentId, restricted }),\n\t\t\t\tname,\n\t\t\t);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync renameCollection({ id, name }) {\n\t\t\tconst res = await settingsWrite(() => collections.renameCollection({ id, name }), name);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync moveCollection({ id, parentId }) {\n\t\t\t// AlreadyExists names the moved Collection's own name, which the\n\t\t\t// caller has and the request doesn't carry.\n\t\t\tconst res = await settingsWrite(() => collections.moveCollection({ id, parentId }));\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync removeCollection({ id }) {\n\t\t\tconst res = await settingsWrite(() => collections.removeCollection({ id }));\n\t\t\treturn [...res.unfiledContentIds];\n\t\t},\n\t\tasync setCollectionRestricted({ id, restricted, acknowledgeDisclosure = false }) {\n\t\t\tconst res = await settingsWrite(() =>\n\t\t\t\tcollections.setCollectionRestricted({ id, restricted, acknowledgeDisclosure }),\n\t\t\t);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync listCollectionGrants(collectionId) {\n\t\t\tconst res = await settingsWrite(() => collections.listCollectionGrants({ collectionId }));\n\t\t\treturn res.grants.map((g) => ({\n\t\t\t\tuserId: g.userId,\n\t\t\t\tlevel: LEVEL_FROM_PROTO[g.level] ?? \"viewer\",\n\t\t\t}));\n\t\t},\n\t\tasync grantCollectionAccess({ collectionId, userId, level }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tcollections.grantCollectionAccess({\n\t\t\t\t\tcollectionId,\n\t\t\t\t\tuserId,\n\t\t\t\t\tlevel:\n\t\t\t\t\t\tlevel === \"editor\"\n\t\t\t\t\t\t\t? ProtoCollectionAccessLevel.EDITOR\n\t\t\t\t\t\t\t: ProtoCollectionAccessLevel.VIEWER,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\tasync revokeCollectionAccess({ collectionId, userId }) {\n\t\t\tawait settingsWrite(() => collections.revokeCollectionAccess({ collectionId, userId }));\n\t\t},\n\t\tasync listContents(input = {}) {\n\t\t\tconst view = input.view ?? { kind: \"main\" };\n\t\t\ttry {\n\t\t\t\tconst res = await contents.listContents({\n\t\t\t\t\tfilter: {\n\t\t\t\t\t\tcollectionId: input.collectionId ?? \"\",\n\t\t\t\t\t\tsearch: input.search ?? \"\",\n\t\t\t\t\t\tassigneeId: input.assigneeId ?? \"\",\n\t\t\t\t\t\tblueprintIds: input.blueprintIds ?? [],\n\t\t\t\t\t},\n\t\t\t\t\tview:\n\t\t\t\t\t\tview.kind === \"change_set\"\n\t\t\t\t\t\t\t? { case: \"changeSetId\", value: view.changeSetId }\n\t\t\t\t\t\t\t: view.kind === \"in_force\"\n\t\t\t\t\t\t\t\t? { case: \"inForce\", value: {} }\n\t\t\t\t\t\t\t\t: { case: undefined },\n\t\t\t\t\tpageSize: input.pageSize ?? 0,\n\t\t\t\t\tpageToken: input.pageToken ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn { contents: res.contents.map(contentFromProto), nextPageToken: res.nextPageToken };\n\t\t\t} catch (err) {\n\t\t\t\tconst ce = ConnectError.from(err);\n\t\t\t\tif (ce.code === Code.InvalidArgument) throw new InvalidInputError(ce.rawMessage);\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t\tasync createContent({ changeSetId, blueprintReleaseId, copyFrom }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.createContent({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tblueprintReleaseId,\n\t\t\t\t\t// A copy takes the source's data when none is given; a new\n\t\t\t\t\t// Content starts from empty data.\n\t\t\t\t\tdata: copyFrom ? undefined : {},\n\t\t\t\t\tcopyFrom: copyFrom\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tsource:\n\t\t\t\t\t\t\t\t\t\"revisionId\" in copyFrom\n\t\t\t\t\t\t\t\t\t\t? { case: \"revisionId\", value: copyFrom.revisionId }\n\t\t\t\t\t\t\t\t\t\t: { case: \"releaseId\", value: copyFrom.releaseId },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow contentRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync saveRevision({ changeSetId, branchId, expectedHeadId, data, fieldMask, idempotencyKey }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.saveRevision({\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId,\n\t\t\t\t\t// Through JSON: a Struct holds no `undefined`, which a form's\n\t\t\t\t\t// values may still carry under a key.\n\t\t\t\t\tdata: JSON.parse(JSON.stringify(data)) as JsonObject,\n\t\t\t\t\tfieldMask: fieldMask ? { fields: fieldMask } : undefined,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow saveRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\n\t\tasync getContent({ id, changeSetId }) {\n\t\t\tconst res = await contents.getContent({ id, changeSetId: changeSetId ?? \"\" });\n\t\t\treturn {\n\t\t\t\tcontent: contentFromProto(res.content),\n\t\t\t\tblueprintRelease: resolvedReleaseFromBytes(res.resolvedRelease),\n\t\t\t\tattributes: attributesFromProto(res.attributes),\n\t\t\t};\n\t\t},\n\t\tasync getTimeline(contentId) {\n\t\t\tconst res = await contents.getTimeline({ contentId });\n\t\t\treturn {\n\t\t\t\tentries: res.entries.map(timelineEntryFromProto),\n\t\t\t\tplannedReleases: res.plannedReleases.map((p) => ({\n\t\t\t\t\tchangeSetId: p.changeSetId,\n\t\t\t\t\tplannedRelease: requiredPlannedRelease(p.plannedRelease),\n\t\t\t\t})),\n\t\t\t};\n\t\t},\n\t\tasync listRevisions({ target, pageSize, pageToken }) {\n\t\t\tconst res = await contents.listRevisions({\n\t\t\t\ttarget:\n\t\t\t\t\t\"contentId\" in target\n\t\t\t\t\t\t? { case: \"contentId\", value: target.contentId }\n\t\t\t\t\t\t: { case: \"branchId\", value: target.branchId },\n\t\t\t\tpageSize: pageSize ?? 0,\n\t\t\t\tpageToken: pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\trevisions: res.revisions.map(revisionFromProto),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync compare({ revisionId, base }) {\n\t\t\tconst res = await contents.compare({\n\t\t\t\trevisionId,\n\t\t\t\tbase:\n\t\t\t\t\tbase.kind === \"revision\"\n\t\t\t\t\t\t? { case: \"baseRevisionId\", value: base.revisionId }\n\t\t\t\t\t\t: base.kind === \"fork\"\n\t\t\t\t\t\t\t? { case: \"forkOfBranchId\", value: base.branchId }\n\t\t\t\t\t\t\t: { case: \"mainHead\", value: true },\n\t\t\t});\n\t\t\tconst kinds: Record<ProtoFieldChangeKind, \"added\" | \"removed\" | \"changed\"> = {\n\t\t\t\t[ProtoFieldChangeKind.UNSPECIFIED]: \"changed\",\n\t\t\t\t[ProtoFieldChangeKind.ADDED]: \"added\",\n\t\t\t\t[ProtoFieldChangeKind.REMOVED]: \"removed\",\n\t\t\t\t[ProtoFieldChangeKind.CHANGED]: \"changed\",\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tbase: revisionFromProto(res.base),\n\t\t\t\trevision: revisionFromProto(res.revision),\n\t\t\t\tchanges: res.changes.map((c) => ({\n\t\t\t\t\tpath: c.path,\n\t\t\t\t\tkind: kinds[c.kind] ?? \"changed\",\n\t\t\t\t\tbefore: c.before ? toJson(ValueSchema, c.before) : undefined,\n\t\t\t\t\tafter: c.after ? toJson(ValueSchema, c.after) : undefined,\n\t\t\t\t})),\n\t\t\t};\n\t\t},\n\t\tasync listReferences({ contentId, revisionId }) {\n\t\t\tconst res = await contents.listReferences({\n\t\t\t\tcontentId,\n\t\t\t\tat: { case: \"revisionId\", value: revisionId },\n\t\t\t\tdepth: 1,\n\t\t\t});\n\t\t\treturn res.references.map((r) => edgeFromProto(r.edge));\n\t\t},\n\t\tasync listReferrers({ contentId, includeOpenChangeSets, pageSize, pageToken }) {\n\t\t\tconst res = await contents.listReferrers({\n\t\t\t\tcontentId,\n\t\t\t\tincludeOpenChangeSets: includeOpenChangeSets ?? false,\n\t\t\t\tpageSize: pageSize ?? 0,\n\t\t\t\tpageToken: pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\treferrers: res.referrers.map((r) => ({\n\t\t\t\t\tedge: edgeFromProto(r.edge),\n\t\t\t\t\treleaseId: r.releaseId,\n\t\t\t\t\tchangeSetId: r.changeSetId,\n\t\t\t\t\tbranchId: r.branchId,\n\t\t\t\t})),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync listOutdatedPins(input) {\n\t\t\tconst res = await contents.listOutdatedPins({\n\t\t\t\tsource:\n\t\t\t\t\t\"branchId\" in input\n\t\t\t\t\t\t? { case: \"branchId\", value: input.branchId }\n\t\t\t\t\t\t: { case: \"revisionId\", value: input.revisionId },\n\t\t\t});\n\t\t\treturn res.pins.map((p) => ({\n\t\t\t\tedge: edgeFromProto(p.edge),\n\t\t\t\tsupersededByReleaseId: p.supersededByReleaseId,\n\t\t\t\tinForceReleaseId: p.inForceReleaseId,\n\t\t\t}));\n\t\t},\n\n\t\tasync setContentCollections({ contentId, collectionIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.setContentCollections({ contentId, collectionIds }),\n\t\t\t);\n\t\t\treturn [...res.collectionIds];\n\t\t},\n\t\tasync setContentAssignees({ contentId, assigneeIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.setContentAssignees({ contentId, assigneeIds }),\n\t\t\t);\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync blockContent({ contentId, blockReasonId, allowedUserIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.blockContent({ contentId, blockReasonId, allowedUserIds }),\n\t\t\t);\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync unblockContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.unblockContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync archiveContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.archiveContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync unarchiveContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.unarchiveContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\n\t\tasync startEditing({ contentId, changeSetId, effectiveOn, changeSetName }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.startEditing({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tchangeSetId: changeSetId ?? \"\",\n\t\t\t\t\teffectiveOn: effectiveOn ?? \"\",\n\t\t\t\t\tchangeSetName: changeSetName ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\t\tcontent: contentFromProto(res.content),\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId ?? \"\", err);\n\t\t\t}\n\t\t},\n\t\tasync previewChain({ changeSetId, contentId, effectiveOn, validityPeriod }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.previewChain({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tcontentId,\n\t\t\t\t\teffectiveOn,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t});\n\t\t\t\tconst p = res.preview;\n\t\t\t\treturn {\n\t\t\t\t\tforkReleaseId: p?.forkReleaseId ?? \"\",\n\t\t\t\t\tcarryForwardReleaseIds: [...(p?.carryForwardReleaseIds ?? [])],\n\t\t\t\t\tmergesMain: p?.mergesMain ?? false,\n\t\t\t\t\tcutIntoReleaseIds: (p?.cutInto ?? []).map((c) => c.releaseId),\n\t\t\t\t\tcoveredReleaseIds: [...(p?.coveredReleaseIds ?? [])],\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tthrow changeSetRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planRepeal({ changeSetId, contentId, lastDay }) {\n\t\t\ttry {\n\t\t\t\treturn plannedEndFromProto(\n\t\t\t\t\tawait changeSets.planRepeal({ changeSetId, contentId, lastDay }),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planWithdrawal({ changeSetId, contentId }) {\n\t\t\ttry {\n\t\t\t\treturn plannedEndFromProto(await changeSets.planWithdrawal({ changeSetId, contentId }));\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planRelease({\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\tvalidityPeriod,\n\t\t\treleaseSpec,\n\t\t\tsupersedesReleaseIds,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.planRelease({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\treleaseSpec: releaseSpec ? struct(releaseSpec) : undefined,\n\t\t\t\t\tsupersedesReleaseIds: supersedesReleaseIds ?? [],\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn requiredPlannedRelease(res.plannedRelease);\n\t\t\t} catch (err) {\n\t\t\t\tthrow planRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync updatePlannedRelease({\n\t\t\tchangeSetId,\n\t\t\tplannedReleaseId,\n\t\t\tvalidityPeriod,\n\t\t\treleaseSpec,\n\t\t\tsupersedesReleaseIds,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.updatePlannedRelease({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tplannedReleaseId,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\treleaseSpec: releaseSpec ? struct(releaseSpec) : undefined,\n\t\t\t\t\tsupersedes: supersedesReleaseIds ? { releaseIds: supersedesReleaseIds } : undefined,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn requiredPlannedRelease(res.plannedRelease);\n\t\t\t} catch (err) {\n\t\t\t\tthrow planRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync appendBranch({ changeSetId, chainId, effectiveOn, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.appendBranch({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tchainId,\n\t\t\t\t\teffectiveOn,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn { changeSet: changeSetFromProto(res.changeSet), branchId: res.branchId };\n\t\t},\n\t\tasync dropChain({ changeSetId, chainId, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.dropChain({ changeSetId, chainId, idempotencyKey: idempotencyKey ?? \"\" }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync getPendingMerge(branchId) {\n\t\t\tconst res = await changeSets.getPendingMerge({ branchId });\n\t\t\tconst p = res.pendingMerge;\n\t\t\tif (!p) return null;\n\t\t\treturn {\n\t\t\t\tbranchId: p.branchId,\n\t\t\t\tcontentId: p.contentId,\n\t\t\t\treason: p.reason === ProtoPendingMergeReason.INVALID ? \"invalid\" : \"conflict\",\n\t\t\t\toursRevisionId: p.oursRevisionId,\n\t\t\t\ttheirsRevisionId: p.theirsRevisionId,\n\t\t\t\tcarried: p.carried,\n\t\t\t\tfields: res.fields.map(mergeFieldFromProto),\n\t\t\t\tmerged: res.merged ? { ...res.merged } : {},\n\t\t\t} satisfies PendingMerge;\n\t\t},\n\t\tasync resolveMerge({ changeSetId, branchId, expectedHeadId, resolutions, idempotencyKey }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.resolveMerge({\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId,\n\t\t\t\t\tresolutions: resolutions.map((r) => ({\n\t\t\t\t\t\tpath: r.path,\n\t\t\t\t\t\tchoice:\n\t\t\t\t\t\t\t\"side\" in r\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcase: \"side\" as const,\n\t\t\t\t\t\t\t\t\t\tvalue: r.side === \"ours\" ? ProtoMergeSide.OURS : ProtoMergeSide.THEIRS,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\tcase: \"value\" as const,\n\t\t\t\t\t\t\t\t\t\tvalue: fromJson(ValueSchema, (r.value ?? null) as JsonValue),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t})),\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow saveRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync abortMerge({ changeSetId, branchId, idempotencyKey }) {\n\t\t\tawait changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.abortMerge({ branchId, idempotencyKey: idempotencyKey ?? \"\" }),\n\t\t\t);\n\t\t},\n\t\tasync previewInForce({ contentId, changeSetId, validOn }) {\n\t\t\tconst res = await releases.getInForce({\n\t\t\t\tcontentIds: [contentId],\n\t\t\t\tat: { validOn: validOn ?? \"\" },\n\t\t\t\tpreviewChangeSetId: changeSetId,\n\t\t\t});\n\t\t\tconst row = res.contents.find((c) => c.contentId === contentId);\n\t\t\tif (!row) return null;\n\t\t\treturn {\n\t\t\t\treleaseId: row.releaseId,\n\t\t\t\trevisionId: row.revisionId,\n\t\t\t\tplanned: row.planned,\n\t\t\t\twithheld: row.withheld,\n\t\t\t\tvalidityPeriod: periodFromProto(row.validityPeriod),\n\t\t\t\tdata: row.data ? { ...row.data } : {},\n\t\t\t};\n\t\t},\n\t};\n}\n","import { createContext, type ReactNode, useContext } from \"react\";\n\n/** The settings page's tabs, as `?tab=` names them. */\nexport type ContenthubSettingsTab = \"required-checks\" | \"block-reasons\" | \"collections\";\n\n/**\n * Where the host mounts this package's screens, for the links the screens draw\n * themselves (breadcrumbs), which have to be a plain `to`. Navigation a\n * screen asks for is never a path from here: only the host knows its router,\n * so that goes through callbacks (knkcms/core ADR 0003). Keys join as\n * screens arrive.\n */\nexport interface ContenthubPaths {\n\t/**\n\t * The host's settings index, which contenthub's settings screens sit under\n\t * in its navigation. Without one, their \"Settings\" breadcrumb is text.\n\t */\n\tsettings?: string;\n\t/**\n\t * contenthub's settings page (`ContenthubSettings`). Its tabs are\n\t * addressed as `?tab=`: build a link to one with `contenthubSettingsPath`.\n\t */\n\tcontenthubSettings: string;\n\t/** The Change Sets index, which a Change Set's page leads back to. */\n\tchangeSets: string;\n\t/** The Content Library, which a Content's page leads back to. */\n\tcontents: string;\n}\n\n/** The harness's paths (ADR 0020): it has no settings index of its own. */\nexport const STANDALONE_CONTENTHUB_PATHS: ContenthubPaths = {\n\tcontenthubSettings: \"/settings\",\n\tchangeSets: \"/change-sets\",\n\tcontents: \"/content\",\n};\n\n/**\n * contenthub's settings page in `paths`, at `tab` when one is named\n * (`?tab=block-reasons`); without one it opens on its first tab.\n */\nexport function contenthubSettingsPath(\n\tpaths: ContenthubPaths,\n\ttab?: ContenthubSettingsTab,\n): string {\n\treturn tab ? `${paths.contenthubSettings}?tab=${tab}` : paths.contenthubSettings;\n}\n\nconst PathsContext = createContext<ContenthubPaths>(STANDALONE_CONTENTHUB_PATHS);\n\nexport interface ContenthubPathsProviderProps {\n\tpaths: ContenthubPaths;\n\tchildren: ReactNode;\n}\n\nexport function ContenthubPathsProvider({ paths, children }: ContenthubPathsProviderProps) {\n\treturn <PathsContext.Provider value={paths}>{children}</PathsContext.Provider>;\n}\n\nexport function useContenthubPaths(): ContenthubPaths {\n\treturn useContext(PathsContext);\n}\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { z } from \"zod\";\nimport {\n\tBLOCK_REASON_NAME_MAX,\n\tBlockReasonNameTakenError,\n\tInvalidInputError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\n\ntype NameValues = { name: string };\n\nexport interface BlockReasonNameModalProps {\n\topen: boolean;\n\t/** Which of the two the modal is: its title, its submit and its form id follow. */\n\tmode: \"create\" | \"rename\";\n\t/** The name the field starts from each time the modal opens. */\n\tinitialName: string;\n\tonClose: () => void;\n\t/**\n\t * Sends the name. A `BlockReasonNameTakenError` or `InvalidInputError` it\n\t * rejects with is shown on the field; anything else above it.\n\t */\n\tonSubmit: (name: string) => Promise<void>;\n}\n\n/**\n * Asks for a Block Reason's name, for a create or a rename. The form checks\n * the service's rule first (internal/workspaceconfig: trimmed, not blank, at\n * most 200 characters, one line) so most mistakes are said before a request;\n * the service's own refusals land on the same field.\n *\n * Kept mounted and driven by `open`, with `lazyMount unmountOnExit`, as\n * anker's Modal rule says; every opening resets the form, since an\n * interrupted exit never unmounts the content.\n */\nexport function BlockReasonNameModal({\n\topen,\n\tmode,\n\tinitialName,\n\tonClose,\n\tonSubmit,\n}: BlockReasonNameModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst formId = `contenthub-block-reason-${mode}`;\n\tconst schema = useMemo(\n\t\t() =>\n\t\t\tz.object({\n\t\t\t\tname: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.trim()\n\t\t\t\t\t.min(1, t(\"blockReasons.form.nameRequired\"))\n\t\t\t\t\t.max(\n\t\t\t\t\t\tBLOCK_REASON_NAME_MAX,\n\t\t\t\t\t\tt(\"blockReasons.form.nameTooLong\", { max: BLOCK_REASON_NAME_MAX }),\n\t\t\t\t\t)\n\t\t\t\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\t\t\t\t.regex(/^[^\\u0000-\\u001f\\u007f]*$/, t(\"blockReasons.form.oneLine\")),\n\t\t\t}),\n\t\t[t],\n\t);\n\tconst methods = useForm<NameValues>({\n\t\tresolver: zodResolver(schema),\n\t\tdefaultValues: { name: initialName },\n\t});\n\tconst [failed, setFailed] = useState(false);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ name: initialName });\n\t\t\tsetFailed(false);\n\t\t}\n\t}, [open, initialName, methods]);\n\n\tconst submit = methods.handleSubmit(async ({ name }) => {\n\t\tsetFailed(false);\n\t\ttry {\n\t\t\tawait onSubmit(name);\n\t\t} catch (err) {\n\t\t\tif (err instanceof BlockReasonNameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"blockReasons.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tmethods.setError(\"name\", { message: err.message });\n\t\t\t} else {\n\t\t\t\tsetFailed(true);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\n\t\t\t\tmode === \"create\" ? \"blockReasons.form.createTitle\" : \"blockReasons.form.renameTitle\",\n\t\t\t)}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={formId} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\n\t\t\t\t\t\t\tmode === \"create\"\n\t\t\t\t\t\t\t\t? \"blockReasons.form.createSubmit\"\n\t\t\t\t\t\t\t\t: \"blockReasons.form.renameSubmit\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={formId}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<NameValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"blockReasons.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"blockReasons.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{failed ? <Alert status=\"error\" title={t(\"blockReasons.form.failed\")} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlockReason } from \"../types\";\n\nexport interface RemoveBlockReasonModalProps {\n\t/** The Block Reason to remove; null while the modal is closed. */\n\treason: BlockReason | null;\n\tonClose: () => void;\n\tonConfirm: (reason: BlockReason) => Promise<void>;\n}\n\n/**\n * Confirms removing a Block Reason. The screen renders it rather than relying\n * on a host's confirm provider: a host mounting this screen owes it nothing\n * beyond the host contract.\n */\nexport function RemoveBlockReasonModal({\n\treason,\n\tonClose,\n\tonConfirm,\n}: RemoveBlockReasonModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst open = reason !== null;\n\t// Latched, so the name doesn't go blank while the modal animates out.\n\tconst [shown, setShown] = useState<BlockReason | null>(reason);\n\tif (reason && reason !== shown) setShown(reason);\n\tconst [removing, setRemoving] = useState(false);\n\tconst [failed, setFailed] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetRemoving(false);\n\t\t\tsetFailed(false);\n\t\t}\n\t}, [open]);\n\n\tconst confirm = async () => {\n\t\tif (!reason) return;\n\t\tsetRemoving(true);\n\t\tsetFailed(false);\n\t\ttry {\n\t\t\tawait onConfirm(reason);\n\t\t} catch {\n\t\t\tsetFailed(true);\n\t\t} finally {\n\t\t\tsetRemoving(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"blockReasons.removeDialog.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={removing}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"blockReasons.removeDialog.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text>{t(\"blockReasons.removeDialog.message\", { name: shown?.name ?? \"\" })}</Text>\n\t\t\t\t{failed ? <Alert status=\"error\" title={t(\"blockReasons.removeDialog.failed\")} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DateCell, MenuCell, Toolbar, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { IndexPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { Lock, Pencil, Plus, Trash2 } from \"lucide-react\";\nimport { type ReactNode, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubSettingsPath, useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlockReason } from \"../types\";\nimport { BlockReasonNameModal } from \"./block-reason-name-modal\";\nimport { RemoveBlockReasonModal } from \"./remove-block-reason-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype BlockReasonRow = BlockReason & Record<string, unknown>;\n\nexport interface BlockReasonsSettingsProps {\n\tclient: ContenthubClient;\n}\n\nfunction useBlockReasons(client: ContenthubClient) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t});\n}\n\n/**\n * The create button. Its label is passed in, never translated here: as a\n * reported header action it renders outside the screen's providers.\n */\nfunction CreateBlockReasonButton({ label, onClick }: { label: string; onClick: () => void }) {\n\treturn (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClick}>\n\t\t\t<Plus size={16} />\n\t\t\t{label}\n\t\t</Button>\n\t);\n}\n\ninterface BlockReasonsBodyProps {\n\tclient: ContenthubClient;\n\t/** The create Modal is open; the caller places the button that opens it. */\n\tcreating: boolean;\n\tonCreatingChange: (creating: boolean) => void;\n\t/** Drawn above the table: the Toolbar, wherever the caller wants its create button. */\n\ttoolbar?: ReactNode;\n}\n\n/**\n * The Block Reasons table with its Modals, shared by the settings page's tab\n * and the standalone screen, which differ only in where the create button\n * sits. Every change goes through the client and is then read back, so the\n * list shows what contenthub holds.\n */\nfunction BlockReasonsBody({ client, creating, onCreatingChange, toolbar }: BlockReasonsBodyProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst [renaming, setRenaming] = useState<BlockReason | null>(null);\n\tconst [removing, setRemoving] = useState<BlockReason | null>(null);\n\tconst query = useBlockReasons(client);\n\tconst reasons = query.data ?? [];\n\tconst refresh = () => queryClient.invalidateQueries({ queryKey: contenthubKeys.blockReasons() });\n\n\tconst columns = useMemo<ColumnDef<BlockReasonRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"blockReasons.columns.name\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={row.original.name} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"updated\",\n\t\t\t\theader: t(\"blockReasons.columns.updated\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.updateTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"blockReasons.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<MenuCell\n\t\t\t\t\t\t// Both inline: two actions are no menu's worth.\n\t\t\t\t\t\tmenuThreshold={2}\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"blockReasons.rename\"),\n\t\t\t\t\t\t\t\ticon: Pencil,\n\t\t\t\t\t\t\t\tonClick: () => setRenaming(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"blockReasons.remove\"),\n\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\tonClick: () => setRemoving(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t{toolbar}\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"blockReasons.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={reasons as BlockReasonRow[]}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<Lock size={32} />}\n\t\t\t\t\t\theader={t(\"blockReasons.empty\")}\n\t\t\t\t\t\tdescription={t(\"blockReasons.emptyHint\")}\n\t\t\t\t\t\tactions={\n\t\t\t\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\t\t\t\tonClick={() => onCreatingChange(true)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<BlockReasonNameModal\n\t\t\t\topen={creating}\n\t\t\t\tmode=\"create\"\n\t\t\t\tinitialName=\"\"\n\t\t\t\tonClose={() => onCreatingChange(false)}\n\t\t\t\tonSubmit={async (name) => {\n\t\t\t\t\tawait client.createBlockReason({ name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tonCreatingChange(false);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<BlockReasonNameModal\n\t\t\t\topen={renaming !== null}\n\t\t\t\tmode=\"rename\"\n\t\t\t\tinitialName={renaming?.name ?? \"\"}\n\t\t\t\tonClose={() => setRenaming(null)}\n\t\t\t\tonSubmit={async (name) => {\n\t\t\t\t\tif (!renaming) return;\n\t\t\t\t\tawait client.renameBlockReason({ id: renaming.id, name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRenaming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<RemoveBlockReasonModal\n\t\t\t\treason={removing}\n\t\t\t\tonClose={() => setRemoving(null)}\n\t\t\t\tonConfirm={async (reason) => {\n\t\t\t\t\tawait client.deleteBlockReason({ id: reason.id });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRemoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n\nfunction BlockReasonsCount({ client }: { client: ContenthubClient }) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst count = useBlockReasons(client).data?.length ?? 0;\n\treturn <Toolbar.Count>{t(\"blockReasons.count\", { count })}</Toolbar.Count>;\n}\n\n/**\n * The Block Reasons as a tab of the settings page (`ContenthubSettings`):\n * its create button sits in the tab's Toolbar, as anker places a tab's add.\n */\nexport function BlockReasonsTab({ client }: BlockReasonsSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [creating, setCreating] = useState(false);\n\treturn (\n\t\t<BlockReasonsBody\n\t\t\tclient={client}\n\t\t\tcreating={creating}\n\t\t\tonCreatingChange={setCreating}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<BlockReasonsCount client={client} />\n\t\t\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t/>\n\t);\n}\n\n/**\n * The workspace's Block Reasons (CONTEXT.md) on a page of their own, for a\n * host that mounts them apart from `ContenthubSettings`, which holds them as\n * a tab: listed by name, created from the header in a Modal (anker: no\n * inline create form above a DataTable), renamed and removed from each row.\n *\n * An index page, not a settings template: it is one list, and\n * SettingsPageTemplate is for two or more tabs.\n */\nexport function BlockReasonsSettings({ client }: BlockReasonsSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst [creating, setCreating] = useState(false);\n\n\treturn (\n\t\t<IndexPageTemplate\n\t\t\ttitle={t(\"blockReasons.title\")}\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"settings.section\"), to: paths.settings },\n\t\t\t\t{ label: t(\"settings.title\"), to: contenthubSettingsPath(paths) },\n\t\t\t\t{ label: t(\"blockReasons.title\") },\n\t\t\t]}\n\t\t\t// Rendered by the host away from the screen's providers: it closes\n\t\t\t// over state, and the Modal it opens is rendered by the screen.\n\t\t\tactions={\n\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t/>\n\t\t\t}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<BlockReasonsCount client={client} />\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t>\n\t\t\t<BlockReasonsBody client={client} creating={creating} onCreatingChange={setCreating} />\n\t\t</IndexPageTemplate>\n\t);\n}\n\nBlockReasonsSettings.displayName = \"BlockReasonsSettings\";\n","import { useCallback, useRef } from \"react\";\nimport {\n\tChangeSetClosedError,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tInvalidInputError,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\n\n/**\n * Whether a failure is the service's answer to the write (a refusal), so\n * its key is spent and the next attempt is a new one; anything else (the\n * network, the service away) leaves the outcome unknown and the key kept.\n */\nexport function isAnswer(err: unknown): boolean {\n\treturn (\n\t\terr instanceof InvalidInputError ||\n\t\terr instanceof StaleHeadError ||\n\t\terr instanceof ContentRefusedError ||\n\t\terr instanceof ChangeSetClosedError ||\n\t\terr instanceof CoversReleaseError\n\t);\n}\n\n/**\n * A fresh Idempotency Key for one write attempt (CONTEXT.md, Idempotency\n * Key): sent again only when the same attempt is retried after a failure\n * whose outcome is unknown, so a write that did commit is answered rather\n * than repeated.\n */\nexport function newIdempotencyKey(what: string): string {\n\treturn `contenthub-ui/${what}/${globalThis.crypto.randomUUID()}`;\n}\n\n/**\n * The keys of one kind of write: `keyFor(asked)` answers the key of the\n * attempt still unanswered when it asked the same (a retry), and a new key\n * otherwise; `settle()` after any answer, success or refusal, so the next\n * write is a new attempt.\n */\nexport function useAttemptKey(what: string) {\n\tconst attempt = useRef<{ asked: string; key: string } | null>(null);\n\tconst keyFor = useCallback(\n\t\t(asked: unknown) => {\n\t\t\tconst json = JSON.stringify(asked);\n\t\t\tif (attempt.current?.asked !== json) {\n\t\t\t\tattempt.current = { asked: json, key: newIdempotencyKey(what) };\n\t\t\t}\n\t\t\treturn attempt.current.key;\n\t\t},\n\t\t[what],\n\t);\n\tconst settle = useCallback(() => {\n\t\tattempt.current = null;\n\t}, []);\n\treturn { keyFor, settle };\n}\n","import { Card, DescriptionList } from \"@knkcs/anker/components\";\nimport { Box, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentDetail, ResolvedField } from \"../types\";\n\nconst ContentDataFields = lazy(() => import(\"./content-data-fields\"));\n\n/** A value shown as text: strings as they are, anything else as JSON. */\nexport function valueText(value: unknown): string {\n\tif (value === undefined || value === null || value === \"\") return \"—\";\n\treturn typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\n/**\n * The fields to show without fieldkit: the Blueprint Release's, by their\n * names, then any data no field declares, by its accessor.\n */\nexport function plainRows(fields: ResolvedField[], data: Record<string, unknown>) {\n\tconst declared = fields\n\t\t.filter((f) => !f.config.hidden)\n\t\t.map((f) => ({\n\t\t\tkey: f.config.api_accessor,\n\t\t\tlabel: f.config.name,\n\t\t\tvalue: data[f.config.api_accessor],\n\t\t}));\n\tconst known = new Set(fields.map((f) => f.config.api_accessor));\n\tconst rest = Object.keys(data)\n\t\t.filter((k) => !known.has(k))\n\t\t.map((k) => ({ key: k, label: k, value: data[k] }));\n\treturn [...declared, ...rest];\n}\n\n/**\n * The Data tab (spec #56, story 90): the Content's data as read, Main's head\n * or, for Content born in a Change Set, its Branch head, read-only. Editing\n * happens in a Branch, never here. A form tab, so it pads itself.\n */\nexport function ContentDataTab({ detail }: { detail: ContentDetail }) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { content, blueprintRelease } = detail;\n\tconst labels = useMemo(\n\t\t() => ({\n\t\t\tdefaultTab: t(\"content.data.general\"),\n\t\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\t\tsearchLabel: t(\"content.data.find\"),\n\t\t\tnoResults: t(\"content.data.noFields\"),\n\t\t\tbooleanYes: t(\"content.data.yes\"),\n\t\t\tbooleanNo: t(\"content.data.no\"),\n\t\t}),\n\t\t[t],\n\t);\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{content.changeSetId\n\t\t\t\t\t\t? t(\"content.data.readOnBranch\", { revision: content.revisionId })\n\t\t\t\t\t\t: t(\"content.data.readOnMain\", { revision: content.revisionId })}\n\t\t\t\t</Text>\n\t\t\t\t{blueprintRelease && blueprintRelease.fields.length > 0 ? (\n\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t<ContentDataFields\n\t\t\t\t\t\t\tfields={blueprintRelease.fields}\n\t\t\t\t\t\t\tdata={content.data}\n\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Suspense>\n\t\t\t\t) : (\n\t\t\t\t\t<Card>\n\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t{plainRows(blueprintRelease?.fields ?? [], content.data).map((row) => (\n\t\t\t\t\t\t\t\t<DescriptionList.Row key={row.key} label={row.label}>\n\t\t\t\t\t\t\t\t\t{valueText(row.value)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t</Card>\n\t\t\t\t)}\n\t\t\t</Stack>\n\t\t</Box>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CompareBase, FieldChange } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\nimport { valueText } from \"./content-data-tab\";\n\ntype ChangeRow = FieldChange & Record<string, unknown>;\n\n/** What the Compare tab compares the Branch's head against. */\nexport type BranchCompareBase = \"fork\" | \"main\";\n\n/**\n * The Compare tab (spec #56, story 23): the Branch's head against the\n * Revision its Branch forked from, or against Main's head, field by field.\n * It compares what is saved: a draft not yet saved isn't in it. Content born\n * in the Change Set has no Main to compare with. A table, so flush below its\n * own padded switch.\n */\nexport function BranchCompareTab({\n\tclient,\n\tcontentId,\n\tbranchId,\n\theadRevisionId,\n\tchain,\n\tcompareBase,\n\tonCompareBase,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst born = chain?.born ?? false;\n\tconst against: BranchCompareBase = born ? \"fork\" : compareBase;\n\tconst base: CompareBase = against === \"main\" ? { kind: \"main_head\" } : { kind: \"fork\", branchId };\n\tconst comparison = useQuery({\n\t\tqueryKey: contenthubKeys.contentCompare(contentId, headRevisionId, base),\n\t\tqueryFn: () => client.compare({ revisionId: headRevisionId, base }),\n\t\tenabled: headRevisionId !== \"\",\n\t});\n\tconst columns = useMemo<ColumnDef<ChangeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"field\",\n\t\t\t\theader: t(\"content.compare.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.compare.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.compare.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"before\",\n\t\t\t\theader: t(\"content.compare.columns.before\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.before)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"after\",\n\t\t\t\theader: t(\"content.compare.columns.after\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.after)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"6\" pb=\"4\">\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant={against === \"fork\" ? \"solid\" : \"outline\"}\n\t\t\t\t\t\taria-pressed={against === \"fork\"}\n\t\t\t\t\t\tonClick={() => onCompareBase(\"fork\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.compare.fork\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant={against === \"main\" ? \"solid\" : \"outline\"}\n\t\t\t\t\t\taria-pressed={against === \"main\"}\n\t\t\t\t\t\tdisabled={born}\n\t\t\t\t\t\tonClick={() => onCompareBase(\"main\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.compare.main\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t\t{comparison.data ? (\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.compare.between\", {\n\t\t\t\t\t\t\thead: comparison.data.revision.id,\n\t\t\t\t\t\t\tbase: comparison.data.base.id,\n\t\t\t\t\t\t})}\n\t\t\t\t\t</Text>\n\t\t\t\t) : null}\n\t\t\t\t{born ? (\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.compare.born\")}\n\t\t\t\t\t</Text>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t\t{comparison.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.compare.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : !comparison.data ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={comparison.data.changes as ChangeRow[]}\n\t\t\t\t\tgetRowId={(row) => row.path}\n\t\t\t\t\temptyState={<EmptyState header={t(\"content.compare.same\")} />}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\nconst BranchContentFields = lazy(() => import(\"./branch-content-fields\"));\n\n/**\n * The Content tab (spec #56): the Branch's data in the Blueprint Release's\n * form. Its draft is the form the editor holds above the tabs; this tab only\n * draws it, so leaving and coming back loses nothing. A form tab, so it pads\n * itself.\n */\nexport function BranchContentTab({\n\tclient,\n\tchangeSetId,\n\tbranchId,\n\trecord,\n\treadOnly,\n\tmediaSource,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst labels = useMemo(\n\t\t() => ({\n\t\t\tdefaultTab: t(\"content.data.general\"),\n\t\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\t\tsearchLabel: t(\"content.data.find\"),\n\t\t\tnoResults: t(\"content.data.noFields\"),\n\t\t\tunsavedChanges: t(\"branch.unsavedChanges\"),\n\t\t\tbooleanYes: t(\"content.data.yes\"),\n\t\t\tbooleanNo: t(\"content.data.no\"),\n\t\t}),\n\t\t[t],\n\t);\n\tconst release = record.blueprintRelease;\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t{release ? (\n\t\t\t\t// noValidate: fieldkit's fields render the native `required`, and a\n\t\t\t\t// browser refuses to submit a form whose invalid control sits in a\n\t\t\t\t// hidden section; the resolver validates (fieldkit's spec-form.mdx).\n\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t<BranchContentFields\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\t\t\t\tbranchId={branchId}\n\t\t\t\t\t\t\tfields={release.fields}\n\t\t\t\t\t\t\tparts={release.parts}\n\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\tmediaSource={mediaSource}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Suspense>\n\t\t\t\t</form>\n\t\t\t) : (\n\t\t\t\t<Alert status=\"warning\" title={t(\"branch.noRelease\")} />\n\t\t\t)}\n\t\t</Box>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DescriptionList, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField } from \"@knkcs/anker/forms\";\nimport { Alert, Box, Heading, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { CalendarPlus } from \"lucide-react\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { type FieldValues, FormProvider, type UseFormReturn, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedRelease, ResolvedField, ValidityPeriod } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\nconst BranchContentFields = lazy(() => import(\"./branch-content-fields\"));\n\n/** The Release tab's period and supersedes: the Planned Release's own, beside its Release Spec values. */\nexport interface PlanValues {\n\tfirstDay: string;\n\tlastDay: string;\n\tsupersedes: string[];\n\t/** Whether the Branch's Release is planned, or is to be by the next Save. */\n\tplan: boolean;\n}\n\n/**\n * The Release tab's draft, held above the tabs as the Content's form is\n * (anker ADR 0004): the plan's period and supersedes in one form, its\n * Release Spec values in fieldkit's form over the Blueprint Release's\n * Release Spec. The editor's Save sends it after the Content.\n */\nexport interface ReleaseDraft {\n\tplan: UseFormReturn<PlanValues>;\n\tspec: UseFormReturn<FieldValues>;\n\t/** The Branch's Planned Release as the editor loaded or last saved it; absent while unplanned. */\n\tplanned?: PlannedRelease;\n\t/** The Release Spec Fields of the Blueprint Release the Branch's head pins. */\n\tspecFields: ResolvedField[];\n\t/** Whether the drafts are seeded: until then the tab shows a spinner. */\n\tseeded: boolean;\n}\n\n/** A Validity Period as a line: \"2026-10-01 – …\" for an open end. */\nexport function periodText(p: ValidityPeriod | undefined): string {\n\treturn p ? `${p.firstDay} – ${p.lastDay || \"…\"}` : \"—\";\n}\n\n/**\n * The plan's own check, before anything is sent: a first day for Dated\n * Content, and a last day, if any, on or after it. The service checks again.\n */\nexport function planIssues(\n\tvalues: PlanValues,\n\tdated: boolean,\n): { path: \"firstDay\" | \"lastDay\"; key: string }[] {\n\tif (!values.plan || !dated) return [];\n\tconst issues: { path: \"firstDay\" | \"lastDay\"; key: string }[] = [];\n\tif (!DAY.test(values.firstDay))\n\t\tissues.push({ path: \"firstDay\", key: \"branch.release.firstDayRequired\" });\n\tif (values.lastDay !== \"\" && (!DAY.test(values.lastDay) || values.lastDay < values.firstDay)) {\n\t\tissues.push({ path: \"lastDay\", key: \"branch.release.lastDayBefore\" });\n\t}\n\treturn issues;\n}\n\ntype ProposalRow = PlannedRelease & Record<string, unknown>;\n\n/**\n * The Release tab (spec #56, stories 27 to 31): the Branch's Planned Release\n * (its Validity Period and Release Spec values, and the Releases it\n * supersedes) as a draft the header's Save sends, and, read-only, what the\n * plan causes: the cuts and tails the Change Set proposes for the Content,\n * and the Releases a period would cover entirely. Proposals are derived from\n * the plans by the service, never edited here. A form tab, so it pads itself.\n *\n * Release Spec values are typed; prefilling them from the Source or a\n * Content field waits on blueprinthub declaring where they come from (#108).\n */\nexport function BranchReleaseTab(ctx: BranchTabContext) {\n\tconst { client, changeSetId, contentId, branchId, record, readOnly, release, changeSet, chain } =\n\t\tctx;\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst dated = record.blueprintRelease?.dated ?? false;\n\tconst planning = useWatch({ control: release.plan.control, name: \"plan\" });\n\tconst firstDay = useWatch({ control: release.plan.control, name: \"firstDay\" }) ?? \"\";\n\tconst lastDay = useWatch({ control: release.plan.control, name: \"lastDay\" }) ?? \"\";\n\tconst published = chain ? !chain.born : false;\n\n\tconst timeline = useQuery({\n\t\tqueryKey: contenthubKeys.contentTimeline(contentId),\n\t\tqueryFn: () => client.getTimeline(contentId),\n\t\tenabled: published,\n\t});\n\tconst releaseOptions = useMemo(\n\t\t() =>\n\t\t\t(timeline.data?.entries ?? []).map((e) => ({\n\t\t\t\tid: e.releaseId,\n\t\t\t\tlabel: e.validityPeriod\n\t\t\t\t\t? `#${e.ordinal} · ${periodText(e.validityPeriod)}`\n\t\t\t\t\t: `#${e.ordinal} · ${e.publishTime.slice(0, 10)}`,\n\t\t\t})),\n\t\t[timeline.data],\n\t);\n\n\t// What the drafted period would cut into and cover, before it is saved:\n\t// PreviewChain's answer for the period, which writes nothing.\n\tconst canPreview =\n\t\tplanning && dated && published && DAY.test(firstDay) && (lastDay === \"\" || DAY.test(lastDay));\n\tconst preview = useQuery({\n\t\tqueryKey: contenthubKeys.chainPreview(contentId, changeSetId, firstDay, lastDay),\n\t\tqueryFn: () =>\n\t\t\tclient.previewChain({\n\t\t\t\tchangeSetId,\n\t\t\t\tcontentId,\n\t\t\t\teffectiveOn: firstDay,\n\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t}),\n\t\tenabled: canPreview,\n\t});\n\n\tconst proposals = useMemo(\n\t\t() =>\n\t\t\t(changeSet?.plannedReleases ?? []).filter(\n\t\t\t\t(p) => p.contentId === contentId && p.proposed,\n\t\t\t) as ProposalRow[],\n\t\t[changeSet, contentId],\n\t);\n\tconst columns = useMemo<ColumnDef<ProposalRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"branch.release.columns.ends\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.proposedForReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"what\",\n\t\t\t\theader: t(\"branch.release.columns.what\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.splitFromReleaseId\n\t\t\t\t\t\t\t\t? t(\"branch.release.tail\", { release: row.original.splitFromReleaseId })\n\t\t\t\t\t\t\t\t: t(\"branch.release.cut\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsubText={row.original.withheld ? t(\"branch.release.withheld\") : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"branch.release.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(row.original.validityPeriod)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\tif (!release.seeded) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\n\tconst labels = {\n\t\tdefaultTab: t(\"branch.release.specTitle\"),\n\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\tsearchLabel: t(\"content.data.find\"),\n\t\tnoResults: t(\"content.data.noFields\"),\n\t\tunsavedChanges: t(\"branch.unsavedChanges\"),\n\t\tbooleanYes: t(\"content.data.yes\"),\n\t\tbooleanNo: t(\"content.data.no\"),\n\t};\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t{!planning ? (\n\t\t\t\t\t<Stack gap=\"3\" align=\"start\">\n\t\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.release.unplanned\")} />\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\trelease.plan.setValue(\"plan\", true, { shouldDirty: true, shouldTouch: true })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CalendarPlus size={16} />\n\t\t\t\t\t\t\t{t(\"branch.release.planIt\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t) : (\n\t\t\t\t\t<Stack gap=\"5\">\n\t\t\t\t\t\t<FormProvider {...release.plan}>\n\t\t\t\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t\t\t\t<HStack gap=\"4\" align=\"start\">\n\t\t\t\t\t\t\t\t\t\t\t<InputField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\t\tname=\"firstDay\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.firstDay\")}\n\t\t\t\t\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t<InputField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\t\tname=\"lastDay\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.lastDay\")}\n\t\t\t\t\t\t\t\t\t\t\t\thelperText={t(\"branch.release.lastDayHelp\")}\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"branch.release.undated\")}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{published ? (\n\t\t\t\t\t\t\t\t\t\t<BaseSelectField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\tname=\"supersedes\"\n\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.supersedes\")}\n\t\t\t\t\t\t\t\t\t\t\thelperText={t(\"branch.release.supersedesHelp\")}\n\t\t\t\t\t\t\t\t\t\t\toptions={releaseOptions}\n\t\t\t\t\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\t\t\t\t\tplaceholder={t(\"branch.release.supersedesNone\")}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</FormProvider>\n\t\t\t\t\t\t{release.specFields.length > 0 ? (\n\t\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t\t<Heading size=\"sm\">{t(\"branch.release.specTitle\")}</Heading>\n\t\t\t\t\t\t\t\t<FormProvider {...release.spec}>\n\t\t\t\t\t\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t\t\t\t\t\t<BranchContentFields\n\t\t\t\t\t\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\t\t\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\t\t\t\t\t\t\t\t\t// SpecForm's record key: the Release Spec's form is\n\t\t\t\t\t\t\t\t\t\t\t\t// its own record, apart from the Content's.\n\t\t\t\t\t\t\t\t\t\t\t\tbranchId={`${branchId}/release`}\n\t\t\t\t\t\t\t\t\t\t\t\tfields={release.specFields}\n\t\t\t\t\t\t\t\t\t\t\t\tparts={record.blueprintRelease?.parts ?? {}}\n\t\t\t\t\t\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</Suspense>\n\t\t\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t\t\t</FormProvider>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data ? (\n\t\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.release.cutsInto\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.cutIntoReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.release.covers\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.coveredReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data && preview.data.coveredReleaseIds.length > 0 ? (\n\t\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\t\ttitle={t(\"branch.release.coversWarning\", {\n\t\t\t\t\t\t\t\t\treleases: preview.data.coveredReleaseIds.join(\", \"),\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t)}\n\t\t\t</Box>\n\t\t\t<Box role=\"region\" aria-label={t(\"branch.release.proposals\")}>\n\t\t\t\t<Box px=\"8\" pb=\"2\">\n\t\t\t\t\t<Heading size=\"sm\">{t(\"branch.release.proposals\")}</Heading>\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.release.proposalsHelp\")}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={proposals}\n\t\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\t\temptyState={<EmptyState header={t(\"branch.release.noProposals\")} />}\n\t\t\t\t/>\n\t\t\t</Box>\n\t\t</Stack>\n\t);\n}\n","import type { TFunction } from \"i18next\";\nimport {\n\tChangeSetClosedError,\n\tContentArchivedError,\n\tContentBlockedError,\n\tContentRefusedError,\n\tInvalidInputError,\n\tServiceUnavailableError,\n} from \"../client/contenthub-client\";\n\n/**\n * Why a write on a Content was refused, in the page's words: its Block, its\n * being Archived, a closed Change Set, or the service's own guidance, which\n * is fit to show as it comes.\n */\nexport function contentRefusalText(t: TFunction, err: unknown): string {\n\tif (err instanceof ContentBlockedError) return t(\"content.refused.blocked\");\n\tif (err instanceof ContentArchivedError) return t(\"content.refused.archived\");\n\tif (err instanceof ChangeSetClosedError) return t(\"library.create.changeSetClosed\");\n\tif (err instanceof ServiceUnavailableError) return t(\"changeSet.refused.unavailable\");\n\tif (err instanceof ContentRefusedError) {\n\t\tconst reasons = err.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \");\n\t\treturn t(\"library.create.refused\", { reasons });\n\t}\n\tif (err instanceof InvalidInputError) return err.message;\n\treturn t(\"content.refused.failed\");\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { DescriptionList, Modal } from \"@knkcs/anker/components\";\nimport { InputField, RadioGroupField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, StaleHeadError } from \"../client/contenthub-client\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PendingMerge, ResolvedField, UpdateFromMainOutcome } from \"../types\";\nimport { periodText } from \"./branch-release-tab\";\nimport { plainRows, valueText } from \"./content-data-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\n// The dialogs the Branch editor's rail opens (anker ADR 0004: a rail node\n// renders outside the screen's providers, so the screen renders these).\n// Each stays mounted, driven by `open`, with `lazyMount unmountOnExit`\n// (anker's Modal rule), and starts afresh on every opening. Every write\n// sends an Idempotency Key, the same one again only when it retries the\n// same request after a failure whose outcome is unknown.\n\n/** Update from Main for the Branch's Chain alone, and what it did to this Branch. */\nexport function BranchUpdateModal({\n\topen,\n\tbranchId,\n\tonClose,\n\tonConfirm,\n\tonResolve,\n}: {\n\topen: boolean;\n\tbranchId: string;\n\tonClose: () => void;\n\t/** Runs the update under the key given; its outcome is shown until the dialog closes. */\n\tonConfirm: (idempotencyKey: string) => Promise<UpdateFromMainOutcome>;\n\t/** Opens the merge resolution of this Branch. */\n\tonResolve: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { keyFor, settle } = useAttemptKey(\"update-from-main\");\n\tconst [outcome, setOutcome] = useState<UpdateFromMainOutcome | null>(null);\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetOutcome(null);\n\t\t\tsetFailure(null);\n\t\t\tsettle();\n\t\t}\n\t}, [open, settle]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tsetOutcome(await onConfirm(keyFor([\"update\", branchId])));\n\t\t\tsettle();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\tconst stopped = outcome\n\t\t? [...outcome.conflicted, ...outcome.pending].some((p) => p.branchId === branchId)\n\t\t: false;\n\tconst merged = outcome?.mergedBranchIds.includes(branchId) ?? false;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"branch.update.title\")}\n\t\t\tfooter={\n\t\t\t\toutcome ? (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t{stopped ? (\n\t\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onResolve}>\n\t\t\t\t\t\t\t\t{t(\"branch.update.resolve\")}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<Button size=\"sm\" variant={stopped ? \"ghost\" : \"solid\"} onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={running} onClick={() => void run()}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.confirm\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{outcome ? (\n\t\t\t\t\tstopped ? (\n\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.update.stopped\")} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"success\"\n\t\t\t\t\t\t\ttitle={merged ? t(\"branch.update.merged\") : t(\"branch.update.upToDate\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t) : (\n\t\t\t\t\t<Text fontSize=\"sm\">{t(\"branch.update.message\")}</Text>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\ntype MergeValues = { choices: string[] };\n\n/**\n * The Pending Merge on the Branch, resolved field by field: each field it\n * lists takes the Branch's value or the merged-in one, every other field\n * its merged value (ResolveMerge). Or aborted, which leaves the Branch at\n * its head, still behind its base.\n */\nexport function ResolveMergeModal({\n\topen,\n\tclient,\n\tchangeSetId,\n\tbranchId,\n\tfields,\n\tonClose,\n\tonDone,\n}: {\n\topen: boolean;\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\tbranchId: string;\n\t/** The Blueprint Release's fields, for their names. */\n\tfields: ResolvedField[];\n\tonClose: () => void;\n\t/** The merge was resolved (a new head) or aborted. */\n\tonDone: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst resolveKey = useAttemptKey(\"resolve-merge\");\n\tconst abortKey = useAttemptKey(\"abort-merge\");\n\tconst pending = useQuery({\n\t\tqueryKey: contenthubKeys.pendingMerge(branchId),\n\t\tqueryFn: () => client.getPendingMerge(branchId),\n\t\tenabled: open,\n\t\tgcTime: 0,\n\t});\n\tconst methods = useForm<MergeValues>({ defaultValues: { choices: [] } });\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState<\"resolve\" | \"abort\" | null>(null);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\t// The form outlives a closing (the dialog stays mounted): every\n\t\t\t// opening starts with no choice made.\n\t\t\tmethods.reset({ choices: [] });\n\t\t\tsetFailure(null);\n\t\t\tresolveKey.settle();\n\t\t\tabortKey.settle();\n\t\t}\n\t}, [open, methods, resolveKey.settle, abortKey.settle]);\n\tconst pm: PendingMerge | null | undefined = pending.data;\n\tuseEffect(() => {\n\t\tif (open && pm) methods.reset({ choices: pm.fields.map(() => \"\") });\n\t}, [open, pm, methods]);\n\n\tconst nameOf = (path: string) => {\n\t\tconst accessor = path.replace(/^\\//, \"\");\n\t\treturn fields.find((f) => f.config.api_accessor === accessor)?.config.name ?? accessor;\n\t};\n\n\tconst resolve = methods.handleSubmit(async ({ choices }) => {\n\t\tif (!pm) return;\n\t\tconst undecided = pm.fields.findIndex(\n\t\t\t(_, i) => choices[i] !== \"ours\" && choices[i] !== \"theirs\",\n\t\t);\n\t\tif (undecided >= 0) {\n\t\t\tmethods.setError(`choices.${undecided}`, { message: t(\"branch.merge.decide\") });\n\t\t\treturn;\n\t\t}\n\t\tconst request = {\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\texpectedHeadId: pm.oursRevisionId,\n\t\t\tresolutions: pm.fields.map((f, i) => ({\n\t\t\t\tpath: f.path,\n\t\t\t\tside: choices[i] as \"ours\" | \"theirs\",\n\t\t\t})),\n\t\t};\n\t\tsetBusy(\"resolve\");\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait client.resolveMerge({ ...request, idempotencyKey: resolveKey.keyFor(request) });\n\t\t\tresolveKey.settle();\n\t\t\tonDone();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) resolveKey.settle();\n\t\t\tsetFailure(\n\t\t\t\terr instanceof StaleHeadError ? t(\"branch.merge.stale\") : contentRefusalText(t, err),\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(null);\n\t\t}\n\t});\n\n\tconst abort = async () => {\n\t\tsetBusy(\"abort\");\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait client.abortMerge({\n\t\t\t\tchangeSetId,\n\t\t\t\tbranchId,\n\t\t\t\tidempotencyKey: abortKey.keyFor([\"abort\", branchId]),\n\t\t\t});\n\t\t\tabortKey.settle();\n\t\t\tonDone();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) abortKey.settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetBusy(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"branch.merge.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tdisabled={!pm}\n\t\t\t\t\t\tloading={busy === \"abort\"}\n\t\t\t\t\t\tonClick={() => void abort()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.merge.abort\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tdisabled={!pm}\n\t\t\t\t\t\tloading={busy === \"resolve\"}\n\t\t\t\t\t\tonClick={() => void resolve()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.merge.resolve\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t{pending.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"branch.merge.loadError\")} />\n\t\t\t\t) : pending.data === undefined ? (\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t) : !pm ? (\n\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.merge.none\")} />\n\t\t\t\t) : (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<Text fontSize=\"sm\">\n\t\t\t\t\t\t\t{pm.reason === \"invalid\" ? t(\"branch.merge.invalid\") : t(\"branch.merge.conflict\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{pm.fields.map((f, i) => (\n\t\t\t\t\t\t\t<RadioGroupField<MergeValues>\n\t\t\t\t\t\t\t\tkey={f.path}\n\t\t\t\t\t\t\t\tname={`choices.${i}`}\n\t\t\t\t\t\t\t\tlabel={nameOf(f.path)}\n\t\t\t\t\t\t\t\thelperText={t(\"branch.merge.base\", { value: valueText(f.base) })}\n\t\t\t\t\t\t\t\toptions={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: \"ours\",\n\t\t\t\t\t\t\t\t\t\tlabel: t(\"branch.merge.ours\", { value: valueText(f.ours) }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: \"theirs\",\n\t\t\t\t\t\t\t\t\t\tlabel: t(\"branch.merge.theirs\", { value: valueText(f.theirs) }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</FormProvider>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\ntype DayValues = { day: string };\n\n/**\n * Preview (ADR 0006): the Content In Force on a day as if the Change Set\n * were published now, through ReleaseService, which reads it the way\n * template and export will.\n */\nexport function PreviewModal({\n\topen,\n\tclient,\n\tchangeSetId,\n\tcontentId,\n\tfields,\n\tdefaultDay,\n\tonClose,\n}: {\n\topen: boolean;\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\tcontentId: string;\n\tfields: ResolvedField[];\n\t/** The day to start from; today when \"\". */\n\tdefaultDay: string;\n\tonClose: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst methods = useForm<DayValues>({ defaultValues: { day: defaultDay } });\n\tuseEffect(() => {\n\t\tif (open) methods.reset({ day: defaultDay });\n\t}, [open, defaultDay, methods]);\n\tconst day = useWatch({ control: methods.control, name: \"day\" }) ?? \"\";\n\tconst valid = day === \"\" || DAY.test(day);\n\tconst preview = useQuery({\n\t\tqueryKey: contenthubKeys.previewInForce(contentId, changeSetId, day),\n\t\tqueryFn: () => client.previewInForce({ contentId, changeSetId, validOn: day || undefined }),\n\t\tenabled: open && valid,\n\t\tgcTime: 0,\n\t});\n\tconst row = preview.data;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"branch.preview.title\")}\n\t\t\tfooter={\n\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t<InputField<DayValues>\n\t\t\t\t\t\tname=\"day\"\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tlabel={t(\"branch.preview.day\")}\n\t\t\t\t\t\thelperText={t(\"branch.preview.dayHelp\")}\n\t\t\t\t\t/>\n\t\t\t\t</FormProvider>\n\t\t\t\t{preview.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={contentRefusalText(t, preview.error)} />\n\t\t\t\t) : !valid ? (\n\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.preview.badDay\")} />\n\t\t\t\t) : preview.data === undefined ? (\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t) : row === null ? (\n\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.preview.nothing\")} />\n\t\t\t\t) : row ? (\n\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus={row.planned ? \"success\" : \"info\"}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\trow.withheld\n\t\t\t\t\t\t\t\t\t? t(\"branch.preview.withheld\")\n\t\t\t\t\t\t\t\t\t: row.planned\n\t\t\t\t\t\t\t\t\t\t? t(\"branch.preview.planned\", { release: row.releaseId })\n\t\t\t\t\t\t\t\t\t\t: t(\"branch.preview.published\", { release: row.releaseId })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t{row.validityPeriod ? (\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.preview.period\")}>\n\t\t\t\t\t\t\t\t\t{periodText(row.validityPeriod)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{plainRows(fields, row.data).map((r) => (\n\t\t\t\t\t\t\t\t<DescriptionList.Row key={r.key} label={r.label}>\n\t\t\t\t\t\t\t\t\t{valueText(r.value)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\n/** Append a Branch: the Chain amended again from a later date. */\nexport function AppendBranchModal({\n\topen,\n\tafter,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\t/** The Chain's last editorial Branch's date, which the new one comes after; \"\" for none. */\n\tafter: string;\n\tonClose: () => void;\n\tonConfirm: (effectiveOn: string, idempotencyKey: string) => Promise<void>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { keyFor, settle } = useAttemptKey(\"append-branch\");\n\tconst methods = useForm<{ effectiveOn: string }>({ defaultValues: { effectiveOn: \"\" } });\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ effectiveOn: \"\" });\n\t\t\tsetFailure(null);\n\t\t\tsettle();\n\t\t}\n\t}, [open, methods, settle]);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst submit = methods.handleSubmit(async ({ effectiveOn }) => {\n\t\tsetFailure(null);\n\t\tif (!DAY.test(effectiveOn) || (after !== \"\" && effectiveOn <= after)) {\n\t\t\tmethods.setError(\"effectiveOn\", {\n\t\t\t\tmessage: after ? t(\"branch.append.after\", { day: after }) : t(\"branch.append.required\"),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait onConfirm(effectiveOn, keyFor([\"append\", effectiveOn]));\n\t\t\tsettle();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"branch.append.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={submitting} onClick={() => void submit()}>\n\t\t\t\t\t\t{t(\"branch.append.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tnoValidate\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"3\">\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"branch.append.message\")}</Text>\n\t\t\t\t\t\t<InputField<{ effectiveOn: string }>\n\t\t\t\t\t\t\tname=\"effectiveOn\"\n\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\tlabel={t(\"branch.append.effectiveOn\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { ContextRail, DescriptionList } from \"@knkcs/anker/components\";\nimport {\n\tEye,\n\tGitCompare,\n\tGitMerge,\n\tGitPullRequestArrow,\n\tInfo,\n\tTrash2,\n\tWrench,\n\tZap,\n} from \"lucide-react\";\n\n/** One of the rail's actions; absent from `BranchRailProps.actions` when it isn't offered. */\nexport type BranchRailAction =\n\t| \"updateFromMain\"\n\t| \"resolveMerge\"\n\t| \"compareFork\"\n\t| \"preview\"\n\t| \"appendBranch\"\n\t| \"dropChain\";\n\nconst ICONS: Record<BranchRailAction, typeof Eye> = {\n\tupdateFromMain: GitMerge,\n\tresolveMerge: Wrench,\n\tcompareFork: GitCompare,\n\tpreview: Eye,\n\tappendBranch: GitPullRequestArrow,\n\tdropChain: Trash2,\n};\n\nexport interface BranchRailProps {\n\ttitle: string;\n\t/** Every string the rail shows, translated by the screen. */\n\tlabels: {\n\t\teyebrow: string;\n\t\tactions: string;\n\t\tabout: string;\n\t\tfork: string;\n\t\teffectiveOn: string;\n\t\tposition: string;\n\t\thead: string;\n\t\tpendingMerge: string;\n\t\taction: Record<BranchRailAction, string>;\n\t};\n\t/** The actions offered, in the order shown. */\n\tactions: BranchRailAction[];\n\tonAction: (action: BranchRailAction) => void;\n\tabout: {\n\t\tfork: string;\n\t\teffectiveOn: string;\n\t\tposition: string;\n\t\thead: string;\n\t\t/** Present while a Pending Merge waits on the Branch. */\n\t\tpendingMerge?: string;\n\t};\n}\n\n/**\n * The Branch editor's rail (anker ADR 0004; spec #56, story 99): what one\n * does to the Branch and its Chain in Actions, never Save; the Branch's\n * place at a glance in About. Reported to the host and drawn away from the\n * screen's providers, so it reads no context: every string arrives\n * translated, and every action is a callback that sets screen state, the\n * screen rendering the dialog.\n */\nexport function BranchRail({ title, labels, actions, onAction, about }: BranchRailProps) {\n\treturn (\n\t\t<ContextRail storageKey=\"contenthub-branch-rail\">\n\t\t\t<ContextRail.Header eyebrow={labels.eyebrow} title={title} />\n\t\t\t{actions.length > 0 ? (\n\t\t\t\t<ContextRail.Section id=\"actions\" icon={<Zap size={16} />} label={labels.actions}>\n\t\t\t\t\t{actions.map((action) => {\n\t\t\t\t\t\tconst Icon = ICONS[action];\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\t\tkey={action}\n\t\t\t\t\t\t\t\tlabel={labels.action[action]}\n\t\t\t\t\t\t\t\ticon={<Icon size={16} />}\n\t\t\t\t\t\t\t\ttone={\n\t\t\t\t\t\t\t\t\taction === \"dropChain\"\n\t\t\t\t\t\t\t\t\t\t? \"outline-red\"\n\t\t\t\t\t\t\t\t\t\t: action === \"resolveMerge\"\n\t\t\t\t\t\t\t\t\t\t\t? \"primary\"\n\t\t\t\t\t\t\t\t\t\t\t: \"default\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonClick={() => onAction(action)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</ContextRail.Section>\n\t\t\t) : null}\n\t\t\t<ContextRail.Section id=\"about\" icon={<Info size={16} />} label={labels.about}>\n\t\t\t\t<DescriptionList>\n\t\t\t\t\t<DescriptionList.Row label={labels.fork}>{about.fork}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.effectiveOn}>{about.effectiveOn}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.position}>{about.position}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.head}>{about.head}</DescriptionList.Row>\n\t\t\t\t\t{about.pendingMerge ? (\n\t\t\t\t\t\t<DescriptionList.Row label={labels.pendingMerge}>\n\t\t\t\t\t\t\t{about.pendingMerge}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t) : null}\n\t\t\t\t</DescriptionList>\n\t\t\t</ContextRail.Section>\n\t\t</ContextRail>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { type UseQueryResult, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Edge, OutdatedPin } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\ntype EdgeRow = Edge & Record<string, unknown>;\ntype PinRow = OutdatedPin & Record<string, unknown>;\n\n/** What an edge points at: a Content, an Asset or a Blueprint Release, by id. */\nfunction targetOf(edge: Edge): string {\n\treturn edge.targetContentId || edge.targetAssetId || edge.targetBlueprintReleaseId;\n}\n\nfunction Section<T>({\n\ttitle,\n\tquery,\n\tchildren,\n}: {\n\ttitle: string;\n\tquery: UseQueryResult<T>;\n\tchildren: (data: T) => ReactNode;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"0\" role=\"region\" aria-label={title}>\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{title}</Heading>\n\t\t\t</Box>\n\t\t\t{query.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.references.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : query.data === undefined ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\tchildren(query.data)\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * The References tab (spec #56; ADR 0009): the outgoing edges of the\n * Branch's head as saved, and its pins outdated today, which a save\n * re-pins (#79). What a draft not yet saved references isn't here. Tables,\n * so flush.\n */\nexport function BranchReferencesTab({\n\tclient,\n\tcontentId,\n\tbranchId,\n\theadRevisionId,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst outgoing = useQuery({\n\t\tqueryKey: contenthubKeys.contentReferences(contentId, headRevisionId),\n\t\tqueryFn: () => client.listReferences({ contentId, revisionId: headRevisionId }),\n\t\tenabled: headRevisionId !== \"\",\n\t});\n\t// Keyed by the head too: a save may re-pin, and the pins are the head's.\n\tconst pins = useQuery({\n\t\tqueryKey: contenthubKeys.contentOutdatedPins(contentId, { branchId, headRevisionId }),\n\t\tqueryFn: () => client.listOutdatedPins({ branchId }),\n\t});\n\n\tconst outgoingColumns = useMemo<ColumnDef<EdgeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.pinReleaseId || t(\"content.references.followsInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst pinColumns = useMemo<ColumnDef<PinRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original.edge)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.pinReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.references.columns.inForceNow\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={row.original.inForceReleaseId || t(\"content.references.gap\")} />\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Section title={t(\"content.references.outgoing\")} query={outgoing}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={outgoingColumns}\n\t\t\t\t\t\tdata={data as EdgeRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutgoing\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t<Section title={t(\"content.references.outdated\")} query={pins}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={pinColumns}\n\t\t\t\t\t\tdata={data as PinRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutdated\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { InvalidInputError } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\n\nexport interface ConfirmModalProps {\n\topen: boolean;\n\ttitle: string;\n\t/** What confirming does, said in full. */\n\tmessage: string;\n\tconfirmLabel: string;\n\t/** A destructive or disclosing confirm is red. */\n\tdanger?: boolean;\n\t/** Shown when `onConfirm` rejects with anything but an `InvalidInputError`. */\n\tfailedMessage: string;\n\tonClose: () => void;\n\t/**\n\t * Does it. An `InvalidInputError` it rejects with shows the service's\n\t * guidance; anything else `failedMessage`. The caller closes the modal.\n\t */\n\tonConfirm: () => Promise<void>;\n}\n\n/**\n * Asks before a settings write that can't be taken back or discloses\n * something: removing a Required Check or Collection, restricting or opening\n * a Collection. The screen renders it rather than relying on a host's confirm\n * provider: a host owes these screens nothing beyond the host contract.\n */\nexport function ConfirmModal({\n\topen,\n\ttitle,\n\tmessage,\n\tconfirmLabel,\n\tdanger = false,\n\tfailedMessage,\n\tonClose,\n\tonConfirm,\n}: ConfirmModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\t// Latched while open, so a caller that clears its subject on close\n\t// doesn't blank or swap the text while the modal animates out.\n\tconst [shown, setShown] = useState({ title, message, confirmLabel, danger, failedMessage });\n\tif (\n\t\topen &&\n\t\t(shown.title !== title ||\n\t\t\tshown.message !== message ||\n\t\t\tshown.confirmLabel !== confirmLabel ||\n\t\t\tshown.danger !== danger ||\n\t\t\tshown.failedMessage !== failedMessage)\n\t) {\n\t\tsetShown({ title, message, confirmLabel, danger, failedMessage });\n\t}\n\tconst [busy, setBusy] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetBusy(false);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open]);\n\n\tconst confirm = async () => {\n\t\tsetBusy(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onConfirm();\n\t\t} catch (err) {\n\t\t\tsetRefusal(err instanceof InvalidInputError ? err.message : shown.failedMessage);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={shown.title}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette={shown.danger ? \"red\" : undefined}\n\t\t\t\t\t\tloading={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{shown.confirmLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text>{shown.message}</Text>\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { ResolvedField } from \"../types\";\n\n/**\n * The fields with none required, at any depth: a field's children, and the\n * fields its settings hold (a Block Type's, a Reference's embedded\n * Reference Spec), found as fieldkit finds them, an object with a\n * `field_type` and a `config`.\n *\n * A save may leave required fields empty, and Publish refuses until they are\n * filled (#180, decision D1 of #176), so the Branch editor validates a save\n * against these. The form is still drawn from the fields as declared, which\n * keeps each required field marked. The input is never changed.\n */\nexport function withoutRequired(fields: ResolvedField[]): ResolvedField[] {\n\treturn fields.map((f) => clear(f) as ResolvedField);\n}\n\nfunction clear(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(clear);\n\tif (value === null || typeof value !== \"object\") return value;\n\tconst out: Record<string, unknown> = {};\n\tfor (const [key, v] of Object.entries(value)) out[key] = clear(v);\n\tconst config = out.config;\n\tif (\n\t\t\"field_type\" in out &&\n\t\tconfig !== null &&\n\t\ttypeof config === \"object\" &&\n\t\t\"required\" in config\n\t) {\n\t\tout.config = { ...config, required: false };\n\t}\n\treturn out;\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { usePageRail } from \"@knkcs/anker/host\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { TFunction } from \"i18next\";\nimport { RotateCcw, Save } from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n\ttype FieldPath,\n\ttype FieldValues,\n\tFormProvider,\n\ttype UseFormReturn,\n\tuseForm,\n} from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport {\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\ttype RefusalReason,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type {\n\tChangeSet,\n\tChangeSetBranch,\n\tChangeSetChain,\n\tContentDetail,\n\tMediaSource,\n\tPlannedRelease,\n\tValidityPeriod,\n} from \"../types\";\nimport { type BranchCompareBase, BranchCompareTab } from \"./branch-compare-tab\";\nimport { BranchContentTab } from \"./branch-content-tab\";\nimport {\n\tAppendBranchModal,\n\tBranchUpdateModal,\n\tPreviewModal,\n\tResolveMergeModal,\n} from \"./branch-dialogs\";\nimport type { BranchFormKit } from \"./branch-form-kit\";\nimport { BranchRail, type BranchRailAction } from \"./branch-rail\";\nimport { BranchReferencesTab } from \"./branch-references-tab\";\nimport {\n\tBranchReleaseTab,\n\ttype PlanValues,\n\tplanIssues,\n\ttype ReleaseDraft,\n} from \"./branch-release-tab\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { ConfirmModal } from \"./confirm-modal\";\nimport { contentLabel } from \"./content-library\";\nimport { contentRefusalText } from \"./content-refusal\";\nimport { withoutRequired } from \"./required-fields\";\n\nexport interface BranchEditorProps {\n\tclient: ContenthubClient;\n\t/** The Change Set the Branch is in. */\n\tchangeSetId: string;\n\tcontentId: string;\n\t/** The Branch to edit: the Chain's last editorial one, as the Contents tab opens it. */\n\tbranchId: string;\n\t/**\n\t * mediahub, for media fields and images in rich text. Without it a media\n\t * field offers nothing to pick (ADR 0020).\n\t */\n\tmediaSource?: MediaSource;\n\t/**\n\t * Host navigation to another Branch: where the rail's Append a Branch\n\t * takes the editor. Without it, the new Branch is announced but not opened.\n\t */\n\tonOpenBranch?: (target: OpenBranchTarget) => void;\n\t/** The Chain was dropped from the Change Set: the Branch is gone, so leave the editor. */\n\tonDeleted?: () => void;\n}\n\n/**\n * What one of the editor's header tabs is handed: the Branch, the record it\n * was loaded at, and whether it may be edited. The tabs are contenthub's own\n * (ADR 0020: Content, Release, Compare, References); a Blueprint's sections\n * render inside the Content tab, never here.\n */\nexport interface BranchTabContext extends BranchEditorProps {\n\trecord: ContentDetail;\n\treadOnly: boolean;\n\t/** The Change Set as last read; absent until it is. */\n\tchangeSet?: ChangeSet;\n\t/** The Content's Chain in it, and the Branch; absent until the Change Set is read. */\n\tchain?: ChangeSetChain;\n\tbranch?: ChangeSetBranch;\n\t/**\n\t * The Branch's head as saved: the Change Set's word for it, which an\n\t * earlier Branch of the Chain has too, else the record's.\n\t */\n\theadRevisionId: string;\n\t/** The Release tab's draft, held above the tabs. */\n\trelease: ReleaseDraft;\n\t/** What the Compare tab compares against, which the rail's Compare to the fork sets. */\n\tcompareBase: BranchCompareBase;\n\tonCompareBase: (base: BranchCompareBase) => void;\n}\n\n/** One header tab: its key (the URL's `?tab=` and its dirty mark) and its body. */\nexport interface BranchEditorTab {\n\tid: string;\n\tlabel: (t: TFunction) => string;\n\trender: (ctx: BranchTabContext) => ReactNode;\n}\n\nconst CONTENT = \"content\";\nconst RELEASE = \"release\";\nconst COMPARE = \"compare\";\n\n/**\n * The editor's header tabs, in order. Content and Release hold their\n * drafts above the tabs and publish their dirty marks under their own ids;\n * Compare and References read what is saved.\n */\nexport const BRANCH_EDITOR_TABS: BranchEditorTab[] = [\n\t{\n\t\tid: CONTENT,\n\t\tlabel: (t) => t(\"branch.tabs.content\"),\n\t\trender: (ctx) => <BranchContentTab {...ctx} />,\n\t},\n\t{\n\t\tid: RELEASE,\n\t\tlabel: (t) => t(\"branch.tabs.release\"),\n\t\trender: (ctx) => <BranchReleaseTab {...ctx} />,\n\t},\n\t{\n\t\tid: COMPARE,\n\t\tlabel: (t) => t(\"branch.tabs.compare\"),\n\t\trender: (ctx) => <BranchCompareTab {...ctx} />,\n\t},\n\t{\n\t\tid: \"references\",\n\t\tlabel: (t) => t(\"branch.tabs.references\"),\n\t\trender: (ctx) => <BranchReferencesTab {...ctx} />,\n\t},\n];\n\n/**\n * The Branch editor (spec #56; ADR 0020): one Content inside a Change Set,\n * at one of its Branches. The Content tab renders the Blueprint Release's\n * form, the Release tab the Branch's Planned Release; the header's one Save\n * (anker ADR 0004) persists every changed tab: one `SaveRevision` on top of\n * the head the editor loaded, with a field mask of what changed, then the\n * plan. A moved head is refused with Reload, never merged. The rail holds\n * what one does to the Branch and its Chain: Update from Main and the merge\n * it may leave, Preview, Append a Branch and Drop Chain.\n *\n * The draft registry and the forms are keyed by the Branch, so another\n * Content or Branch starts clean, with forms of its own.\n */\nexport function BranchEditor(props: BranchEditorProps) {\n\treturn <BranchEditorFrame {...props} />;\n}\n\nBranchEditor.displayName = \"BranchEditor\";\n\n/** The editor over a given set of tabs: `BranchEditor` with its own, a test with more. */\nexport function BranchEditorFrame({\n\ttabs = BRANCH_EDITOR_TABS,\n\t...props\n}: BranchEditorProps & { tabs?: BranchEditorTab[] }) {\n\treturn (\n\t\t<TabDirtyProvider key={`${props.changeSetId}/${props.contentId}/${props.branchId}`}>\n\t\t\t<BranchScreen {...props} tabs={tabs} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\n// fieldkit's schema layer, loaded once per page: see branch-form-kit.ts.\nlet kitLoad: Promise<BranchFormKit> | undefined;\nfunction loadKit(): Promise<BranchFormKit> {\n\tkitLoad ??= import(\"./branch-form-kit\").then((m) => m.branchFormKit);\n\treturn kitLoad;\n}\n\nfunction useFormKit(): BranchFormKit | undefined {\n\tconst [kit, setKit] = useState<BranchFormKit>();\n\tuseEffect(() => {\n\t\tlet live = true;\n\t\tvoid loadKit().then((loaded) => {\n\t\t\tif (live) setKit(loaded);\n\t\t});\n\t\treturn () => {\n\t\t\tlive = false;\n\t\t};\n\t}, []);\n\treturn kit;\n}\n\n/** Why the last Save stopped. A Release refusal says whether the Content was saved first. */\ntype Refusal =\n\t| { kind: \"stale\"; currentHeadId: string }\n\t| { kind: \"violations\"; reasons: RefusalReason[] }\n\t| { kind: \"invalid\" }\n\t| { kind: \"other\"; message: string }\n\t| { kind: \"releaseInvalid\" }\n\t| { kind: \"covers\"; releaseIds: string[]; contentSaved: boolean }\n\t| { kind: \"releaseViolations\"; reasons: RefusalReason[]; contentSaved: boolean }\n\t| { kind: \"release\"; message: string; contentSaved: boolean };\n\n/** Equal as JSON, whatever the order of an object's keys. */\nfunction sameJSON(a: unknown, b: unknown): boolean {\n\tconst canonical = (value: unknown) =>\n\t\tJSON.stringify(value ?? null, (_, v) =>\n\t\t\tv && typeof v === \"object\" && !Array.isArray(v)\n\t\t\t\t? Object.fromEntries(Object.entries(v).sort(([x], [y]) => x.localeCompare(y)))\n\t\t\t\t: v,\n\t\t);\n\treturn canonical(a) === canonical(b);\n}\n\n/** The top-level fields whose value differs from the baseline: the save's field mask. */\nfunction changedFields(baseline: Record<string, unknown>, draft: Record<string, unknown>) {\n\tconst keys = new Set([...Object.keys(baseline), ...Object.keys(draft)]);\n\treturn [...keys].filter((key) => !sameJSON(baseline[key], draft[key])).sort();\n}\n\n/** A Violation's path (\"/body/0/text\") as the form names the field (\"body.0.text\"). */\nfunction formPath(path: string): string {\n\t// JSON Pointer escapes: \"~1\" is \"/\", \"~0\" is \"~\" (RFC 6901).\n\treturn path\n\t\t.replace(/^\\//, \"\")\n\t\t.split(\"/\")\n\t\t.map((part) => part.replace(/~1/g, \"/\").replace(/~0/g, \"~\"))\n\t\t.join(\".\");\n}\n\n/** The Release tab's period and supersedes as a plan has them, or as an unplanned Branch starts. */\nfunction planValuesOf(planned: PlannedRelease | undefined, branch?: ChangeSetBranch): PlanValues {\n\treturn planned\n\t\t? {\n\t\t\t\tfirstDay: planned.validityPeriod?.firstDay ?? \"\",\n\t\t\t\tlastDay: planned.validityPeriod?.lastDay ?? \"\",\n\t\t\t\tsupersedes: [...planned.supersedesReleaseIds],\n\t\t\t\tplan: true,\n\t\t\t}\n\t\t: { firstDay: branch?.effectiveOn ?? \"\", lastDay: \"\", supersedes: [], plan: false };\n}\n\n/** Resets a form to `sent`, keeping its values: edits made since stay dirty against it. */\nfunction settleForm(form: UseFormReturn<FieldValues>, sent: FieldValues) {\n\tform.reset(sent, { keepValues: true, keepSubmitCount: true });\n\tform.reset(form.getValues(), { keepDefaultValues: true, keepSubmitCount: true });\n}\n\nfunction BranchScreen({ tabs, ...props }: BranchEditorProps & { tabs: BranchEditorTab[] }) {\n\tconst { client, changeSetId, contentId, branchId, onOpenBranch, onDeleted } = props;\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\");\n\tconst tab = tabs.some((each) => each.id === tabParam) ? (tabParam as string) : CONTENT;\n\tconst kit = useFormKit();\n\n\tconst readKey = useMemo(\n\t\t() => contenthubKeys.contentRead(contentId, changeSetId),\n\t\t[contentId, changeSetId],\n\t);\n\tconst query = useQuery({\n\t\tqueryKey: readKey,\n\t\tqueryFn: () => client.getContent({ id: contentId, changeSetId }),\n\t});\n\tconst changeSetKey = contenthubKeys.changeSet(changeSetId);\n\tconst changeSet = useQuery({\n\t\tqueryKey: changeSetKey,\n\t\tqueryFn: () => client.getChangeSet(changeSetId),\n\t});\n\tconst chain = changeSet.data?.chains.find((each) => each.contentId === contentId);\n\tconst branch = chain?.branches.find((each) => each.id === branchId);\n\n\t// The RECORD: the Content as the editor loaded it, the head its next Save\n\t// builds on. Latched from the first read, moved only by this editor's own\n\t// saves and by Reload: a refetch must neither change the expected head\n\t// under the author nor re-seed the form over their edits (fieldkit#340).\n\tconst [record, setRecord] = useState<ContentDetail | null>(null);\n\tif (record === null && query.data) setRecord(query.data);\n\tconst head = useRef(\"\");\n\tconst baseline = useRef<Record<string, unknown>>({});\n\tconst contentKey = useAttemptKey(\"save\");\n\tconst releaseKey = useAttemptKey(\"plan\");\n\n\t// The Content tab's draft: the form IS the draft, held here above the\n\t// tabs, so it outlives the tab's mount (anker ADR 0004; fieldkit's\n\t// spec-form.mdx). The resolver is fieldkit's schema for the record's\n\t// fields, read through a ref because the schema layer loads lazily.\n\tconst resolverRef = useRef<ReturnType<BranchFormKit[\"resolver\"]> | null>(null);\n\tconst methods = useForm<FieldValues>({\n\t\tresolver: (values, context, options) =>\n\t\t\tresolverRef.current ? resolverRef.current(values, context, options) : { values, errors: {} },\n\t});\n\tconst [seeded, setSeeded] = useState(false);\n\n\t// The Release tab's draft, likewise above the tabs: the plan's period and\n\t// supersedes, and its Release Spec values in fieldkit's form over the\n\t// Blueprint Release's Release Spec.\n\tconst planForm = useForm<PlanValues>({\n\t\tdefaultValues: { firstDay: \"\", lastDay: \"\", supersedes: [], plan: false },\n\t});\n\tconst specResolverRef = useRef<ReturnType<BranchFormKit[\"resolver\"]> | null>(null);\n\tconst specForm = useForm<FieldValues>({\n\t\tresolver: (values, context, options) =>\n\t\t\tspecResolverRef.current\n\t\t\t\t? specResolverRef.current(values, context, options)\n\t\t\t\t: { values, errors: {} },\n\t});\n\tconst [planned, setPlanned] = useState<PlannedRelease | undefined>(undefined);\n\tconst [releaseSeeded, setReleaseSeeded] = useState(false);\n\n\t/** Seeds the form from a record, as loaded: a new baseline and head, the draft gone. */\n\tconst seed = useCallback(\n\t\t(detail: ContentDetail, loaded: BranchFormKit) => {\n\t\t\tconst fields = detail.blueprintRelease?.fields ?? [];\n\t\t\t// A save may leave required fields empty; Publish asks for them\n\t\t\t// (#180). The form still marks them, drawn from the fields as\n\t\t\t// declared. Release Spec values stay required (specResolverRef).\n\t\t\tresolverRef.current = loaded.resolver(withoutRequired(fields));\n\t\t\tconst defaults = loaded.defaults(fields, detail.content.data);\n\t\t\tbaseline.current = structuredClone(defaults);\n\t\t\thead.current = detail.content.revisionId;\n\t\t\t// keepSubmitCount: a Reload re-seeds the same record, and SpecForm\n\t\t\t// tells a new failed save from one it has handled by submitCount\n\t\t\t// (fieldkit's spec-form.mdx, \"Known limitations\").\n\t\t\tmethods.reset(defaults, { keepSubmitCount: true });\n\t\t\tsetSeeded(true);\n\t\t},\n\t\t[methods],\n\t);\n\t// Once per record: the editor remounts for another Content or Branch, so\n\t// this never re-seeds over the author's edits.\n\tuseEffect(() => {\n\t\tif (record && kit && !seeded) seed(record, kit);\n\t}, [record, kit, seeded, seed]);\n\n\t// The Release draft, once the Change Set says what is planned: later\n\t// reads of it (proposals recomputed) never re-seed over the author's edits.\n\tuseEffect(() => {\n\t\tif (releaseSeeded || !record || !kit || !changeSet.data) return;\n\t\tconst specFields = record.blueprintRelease?.releaseSpec ?? [];\n\t\tspecResolverRef.current = kit.resolver(specFields);\n\t\tconst plan = changeSet.data.plannedReleases.find((p) => p.branchId === branchId && !p.proposed);\n\t\tplanForm.reset(planValuesOf(plan, branch));\n\t\tspecForm.reset(kit.defaults(specFields, plan?.releaseSpec ?? {}), { keepSubmitCount: true });\n\t\tsetPlanned(plan);\n\t\tsetReleaseSeeded(true);\n\t}, [releaseSeeded, record, kit, changeSet.data, branchId, branch, planForm, specForm]);\n\n\tconst contentDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(CONTENT, contentDirty), [contentDirty, setTabDirty]);\n\tconst releaseDirty = planForm.formState.isDirty || specForm.formState.isDirty;\n\tuseEffect(() => setTabDirty(RELEASE, releaseDirty), [releaseDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [saved, setSaved] = useState(false);\n\tconst changed = dirtyTabs.length;\n\tuseEffect(() => {\n\t\tif (changed > 0) setSaved(false);\n\t}, [changed]);\n\n\tconst [compareBase, setCompareBase] = useState<BranchCompareBase>(\"fork\");\n\ttype Dialog = \"update\" | \"merge\" | \"preview\" | \"append\" | \"drop\";\n\tconst [dialog, setDialog] = useState<Dialog | null>(null);\n\tconst closeDialog = useCallback(() => setDialog(null), []);\n\tconst dropKey = useAttemptKey(\"drop-chain\");\n\n\tconst selectTab = useCallback(\n\t\t(next: string) => {\n\t\t\tsetSearchParams(\n\t\t\t\t(current) => {\n\t\t\t\t\tconst params = new URLSearchParams(current);\n\t\t\t\t\tparams.set(\"tab\", next);\n\t\t\t\t\treturn params;\n\t\t\t\t},\n\t\t\t\t{ replace: true },\n\t\t\t);\n\t\t},\n\t\t[setSearchParams],\n\t);\n\n\tconst dated = record?.blueprintRelease?.dated ?? false;\n\n\t/**\n\t * The Content's SaveRevision, of the fields that changed, on the head the\n\t * editor loaded. The baseline afterwards is what was SENT (the snapshot\n\t * taken as Save started), so an edit made while the save was in flight\n\t * stays dirty (fieldkit's spec-form.mdx). True when it saved or had\n\t * nothing to send.\n\t */\n\tconst saveContent = useCallback(\n\t\tasync (parsed: FieldValues, snapshot: FieldValues): Promise<boolean> => {\n\t\t\tconst mask = changedFields(baseline.current, snapshot);\n\t\t\tif (mask.length === 0) {\n\t\t\t\t// Edited back to what was loaded: nothing to write, only the\n\t\t\t\t// dirty mark to clear.\n\t\t\t\tmethods.reset(snapshot, { keepValues: true, keepSubmitCount: true });\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst data = Object.fromEntries(\n\t\t\t\tmask.filter((key) => key in parsed).map((key) => [key, parsed[key]]),\n\t\t\t);\n\t\t\t// One Idempotency Key per save attempt, sent again when the author\n\t\t\t// retries the same save after a failure whose outcome is unknown\n\t\t\t// (the network, the service): if the first attempt committed, the\n\t\t\t// retry answers it rather than being refused as stale.\n\t\t\tconst key = contentKey.keyFor([head.current, mask, data]);\n\t\t\ttry {\n\t\t\t\tconst content = await client.saveRevision({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId: head.current,\n\t\t\t\t\tdata,\n\t\t\t\t\tfieldMask: mask,\n\t\t\t\t\tidempotencyKey: key,\n\t\t\t\t});\n\t\t\t\tcontentKey.settle();\n\t\t\t\thead.current = content.revisionId;\n\t\t\t\tbaseline.current = snapshot;\n\t\t\t\tsettleForm(methods, snapshot);\n\t\t\t\tsetRecord((current) => (current ? { ...current, content } : current));\n\t\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (current) =>\n\t\t\t\t\tcurrent ? { ...current, content } : current,\n\t\t\t\t);\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\t// A refusal is an answer: the next Save is a new attempt.\n\t\t\t\tif (isAnswer(err)) contentKey.settle();\n\t\t\t\tif (err instanceof StaleHeadError) {\n\t\t\t\t\tsetRefusal({ kind: \"stale\", currentHeadId: err.currentHeadId });\n\t\t\t\t} else if (err instanceof ContentRefusedError) {\n\t\t\t\t\tfor (const reason of err.reasons) {\n\t\t\t\t\t\tif (!reason.path) continue;\n\t\t\t\t\t\tmethods.setError(formPath(reason.path) as FieldPath<FieldValues>, {\n\t\t\t\t\t\t\ttype: reason.code,\n\t\t\t\t\t\t\tmessage: t(\"branch.violation\", { code: reason.code, source: reason.source }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tsetRefusal({ kind: \"violations\", reasons: err.reasons });\n\t\t\t\t\tselectTab(CONTENT);\n\t\t\t\t} else {\n\t\t\t\t\tsetRefusal({ kind: \"other\", message: contentRefusalText(t, err) });\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[methods, contentKey, client, changeSetId, branchId, queryClient, readKey, selectTab, t],\n\t);\n\n\t/**\n\t * The Release tab's write: PlanRelease for an unplanned Branch,\n\t * UpdatePlannedRelease otherwise, with every Release Spec value (the\n\t * service takes them as the whole set). Proposals are the service's to\n\t * derive again, so the Change Set is read again afterwards.\n\t */\n\tconst saveRelease = useCallback(\n\t\tasync (sentPlan: PlanValues, spec: FieldValues, contentSaved: boolean) => {\n\t\t\tconst validityPeriod: ValidityPeriod | undefined = dated\n\t\t\t\t? { firstDay: sentPlan.firstDay, lastDay: sentPlan.lastDay }\n\t\t\t\t: undefined;\n\t\t\tconst releaseSpec = JSON.parse(JSON.stringify(spec)) as Record<string, unknown>;\n\t\t\tconst supersedesReleaseIds = [...sentPlan.supersedes];\n\t\t\tconst asked = {\n\t\t\t\tplanned: planned?.id ?? \"\",\n\t\t\t\tvalidityPeriod,\n\t\t\t\treleaseSpec,\n\t\t\t\tsupersedesReleaseIds,\n\t\t\t};\n\t\t\tconst idempotencyKey = releaseKey.keyFor(asked);\n\t\t\ttry {\n\t\t\t\tconst result = planned\n\t\t\t\t\t? await client.updatePlannedRelease({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tplannedReleaseId: planned.id,\n\t\t\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\t\t\treleaseSpec,\n\t\t\t\t\t\t\tsupersedesReleaseIds,\n\t\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t\t})\n\t\t\t\t\t: await client.planRelease({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\t\t\treleaseSpec,\n\t\t\t\t\t\t\tsupersedesReleaseIds,\n\t\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t\t});\n\t\t\t\treleaseKey.settle();\n\t\t\t\tsetPlanned(result);\n\t\t\t\tsettleForm(planForm as unknown as UseFormReturn<FieldValues>, sentPlan);\n\t\t\t\tsettleForm(specForm, spec);\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\tif (isAnswer(err)) releaseKey.settle();\n\t\t\t\tif (err instanceof CoversReleaseError) {\n\t\t\t\t\tsetRefusal({ kind: \"covers\", releaseIds: err.coveredReleaseIds, contentSaved });\n\t\t\t\t} else if (err instanceof ContentRefusedError) {\n\t\t\t\t\tfor (const reason of err.reasons) {\n\t\t\t\t\t\tif (!reason.path) continue;\n\t\t\t\t\t\tspecForm.setError(formPath(reason.path) as FieldPath<FieldValues>, {\n\t\t\t\t\t\t\ttype: reason.code,\n\t\t\t\t\t\t\tmessage: t(\"branch.violation\", { code: reason.code, source: reason.source }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tsetRefusal({ kind: \"releaseViolations\", reasons: err.reasons, contentSaved });\n\t\t\t\t} else {\n\t\t\t\t\tsetRefusal({ kind: \"release\", message: contentRefusalText(t, err), contentSaved });\n\t\t\t\t}\n\t\t\t\tselectTab(RELEASE);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tdated,\n\t\t\tplanned,\n\t\t\treleaseKey,\n\t\t\tclient,\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\tcontentId,\n\t\t\tplanForm,\n\t\t\tspecForm,\n\t\t\tqueryClient,\n\t\t\tselectTab,\n\t\t\tt,\n\t\t],\n\t);\n\n\t/**\n\t * The header's Save: every changed tab, as one change. Each is validated\n\t * first, whether or not its tab is mounted, and nothing is sent while one\n\t * is invalid. Then the Content's SaveRevision, then the plan: a refused\n\t * save stops there and sends no plan, so both stay changed for the next\n\t * Save; a refused plan after a saved Content leaves the Release alone\n\t * changed, and the next Save sends only it. The plan pins the Branch's\n\t * head at Publish, not at planning, so the order costs nothing.\n\t */\n\tconst save = useCallback(async () => {\n\t\tif (!seeded) return;\n\t\tconst doContent = methods.formState.isDirty;\n\t\tconst doRelease = releaseSeeded && (planForm.formState.isDirty || specForm.formState.isDirty);\n\t\tconst snapshot = structuredClone(methods.getValues());\n\t\tconst planSnapshot = structuredClone(planForm.getValues());\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tlet parsed: FieldValues | null = null;\n\t\t\tif (doContent) {\n\t\t\t\tawait methods.handleSubmit(\n\t\t\t\t\t(values) => {\n\t\t\t\t\t\tparsed = values;\n\t\t\t\t\t},\n\t\t\t\t\t() => {},\n\t\t\t\t)();\n\t\t\t\tif (!parsed) {\n\t\t\t\t\t// SpecForm, mounted there, opens the section of the first error.\n\t\t\t\t\tsetRefusal({ kind: \"invalid\" });\n\t\t\t\t\tselectTab(CONTENT);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet spec: FieldValues | null = null;\n\t\t\tif (doRelease) {\n\t\t\t\tplanForm.clearErrors();\n\t\t\t\tconst issues = planIssues(planSnapshot, dated);\n\t\t\t\tfor (const issue of issues) planForm.setError(issue.path, { message: t(issue.key) });\n\t\t\t\tawait specForm.handleSubmit(\n\t\t\t\t\t(values) => {\n\t\t\t\t\t\tspec = values;\n\t\t\t\t\t},\n\t\t\t\t\t() => {},\n\t\t\t\t)();\n\t\t\t\tif (issues.length > 0 || !spec) {\n\t\t\t\t\tsetRefusal({ kind: \"releaseInvalid\" });\n\t\t\t\t\tselectTab(RELEASE);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet contentSaved = false;\n\t\t\tif (doContent && parsed) {\n\t\t\t\tif (!(await saveContent(parsed, snapshot))) return;\n\t\t\t\tcontentSaved = true;\n\t\t\t}\n\t\t\tif (doRelease && spec) {\n\t\t\t\tif (!(await saveRelease(planSnapshot, spec, contentSaved))) return;\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} finally {\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [\n\t\tseeded,\n\t\treleaseSeeded,\n\t\tmethods,\n\t\tplanForm,\n\t\tspecForm,\n\t\tdated,\n\t\tsaveContent,\n\t\tsaveRelease,\n\t\tselectTab,\n\t\tt,\n\t]);\n\n\t/** Stale head: the author chose to throw the draft away and edit the current head. */\n\tconst reload = useCallback(async () => {\n\t\tconst fresh = await query.refetch();\n\t\tif (!fresh.data || !kit) return;\n\t\tsetRecord(fresh.data);\n\t\tseed(fresh.data, kit);\n\t\tsetRefusal(null);\n\t}, [query, kit, seed]);\n\n\t/**\n\t * The head moved by the rail's own doing (a merge, a resolution): the\n\t * Change Set is read again, and the Content too unless the author has\n\t * unsaved edits, which a later Save then offers to reload as stale.\n\t */\n\tconst headMoved = useCallback(async () => {\n\t\tawait queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\tif (!methods.formState.isDirty) await reload();\n\t}, [queryClient, changeSetId, methods, reload]);\n\n\tconst open = changeSet.data ? changeSet.data.state === \"open\" : true;\n\tconst pendingMerge = branch?.hasPendingMerge ?? false;\n\tconst born = chain?.born ?? false;\n\tconst railActions = useMemo<BranchRailAction[]>(() => {\n\t\tconst offered: BranchRailAction[] = [];\n\t\tif (open && chain) {\n\t\t\toffered.push(pendingMerge ? \"resolveMerge\" : \"updateFromMain\");\n\t\t}\n\t\toffered.push(\"compareFork\");\n\t\tif (open && chain) {\n\t\t\toffered.push(\"preview\");\n\t\t\tif (dated && !born) offered.push(\"appendBranch\");\n\t\t\tif (!born) offered.push(\"dropChain\");\n\t\t}\n\t\treturn offered;\n\t}, [open, chain, pendingMerge, dated, born]);\n\tconst onRailAction = useCallback(\n\t\t(action: BranchRailAction) => {\n\t\t\tswitch (action) {\n\t\t\t\tcase \"updateFromMain\":\n\t\t\t\t\tsetDialog(\"update\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"resolveMerge\":\n\t\t\t\t\tsetDialog(\"merge\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"compareFork\":\n\t\t\t\t\tsetCompareBase(\"fork\");\n\t\t\t\t\tselectTab(COMPARE);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"preview\":\n\t\t\t\t\tsetDialog(\"preview\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"appendBranch\":\n\t\t\t\t\tsetDialog(\"append\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"dropChain\":\n\t\t\t\t\tsetDialog(\"drop\");\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t},\n\t\t[selectTab],\n\t);\n\tconst title = record ? contentLabel(record.content.data) || record.content.id : \"\";\n\tconst headRevisionId = branch?.headRevisionId || record?.content.revisionId || \"\";\n\t// The rail closes over this screen's state and reads no context: the host\n\t// draws it away from the screen's providers (anker's host contract).\n\tusePageRail(\n\t\trecord && changeSet.data ? (\n\t\t\t<BranchRail\n\t\t\t\ttitle={title}\n\t\t\t\tlabels={{\n\t\t\t\t\teyebrow: t(\"branch.rail.eyebrow\"),\n\t\t\t\t\tactions: t(\"branch.rail.actions\"),\n\t\t\t\t\tabout: t(\"branch.rail.about\"),\n\t\t\t\t\tfork: t(\"branch.rail.fork\"),\n\t\t\t\t\teffectiveOn: t(\"branch.rail.effectiveOn\"),\n\t\t\t\t\tposition: t(\"branch.rail.position\"),\n\t\t\t\t\thead: t(\"branch.rail.head\"),\n\t\t\t\t\tpendingMerge: t(\"branch.rail.pendingMerge\"),\n\t\t\t\t\taction: {\n\t\t\t\t\t\tupdateFromMain: t(\"branch.rail.updateFromMain\"),\n\t\t\t\t\t\tresolveMerge: t(\"branch.rail.resolveMerge\"),\n\t\t\t\t\t\tcompareFork: t(\"branch.rail.compareFork\"),\n\t\t\t\t\t\tpreview: t(\"branch.rail.preview\"),\n\t\t\t\t\t\tappendBranch: t(\"branch.rail.appendBranch\"),\n\t\t\t\t\t\tdropChain: t(\"branch.rail.dropChain\"),\n\t\t\t\t\t},\n\t\t\t\t}}\n\t\t\t\tactions={railActions}\n\t\t\t\tonAction={onRailAction}\n\t\t\t\tabout={{\n\t\t\t\t\tfork:\n\t\t\t\t\t\tchain?.branches[0]?.carriedReleaseId ||\n\t\t\t\t\t\t(born ? t(\"branch.rail.forkBorn\") : t(\"branch.rail.forkMain\")),\n\t\t\t\t\teffectiveOn: branch?.effectiveOn || t(\"branch.rail.undated\"),\n\t\t\t\t\tposition: branch\n\t\t\t\t\t\t? t(\"branch.rail.positionOf\", {\n\t\t\t\t\t\t\t\tposition: branch.position + 1,\n\t\t\t\t\t\t\t\tcount: chain?.branches.length ?? 1,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: \"—\",\n\t\t\t\t\thead: headRevisionId,\n\t\t\t\t\tpendingMerge: pendingMerge ? t(\"branch.rail.pendingMergeYes\") : undefined,\n\t\t\t\t}}\n\t\t\t/>\n\t\t) : null,\n\t);\n\n\tif (!record) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\"), to: paths.changeSets }]}\n\t\t\t\ttitle={query.isError ? t(\"branch.unavailable\") : t(\"branch.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert status=\"error\" title={notFound ? t(\"branch.notFound\") : t(\"branch.loadError\")} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\t// GetContent reads a Change Set at its Chain's last Branch: an earlier\n\t// one's head can't be read here, so it isn't edited here either.\n\tconst otherBranch = record.content.branchId !== branchId;\n\t// Not while saving: an edit made during a save is kept, still dirty.\n\tconst readOnly = !open || otherBranch;\n\tconst release: ReleaseDraft = {\n\t\tplan: planForm,\n\t\tspec: specForm,\n\t\tplanned,\n\t\tspecFields: record.blueprintRelease?.releaseSpec ?? [],\n\t\tseeded: releaseSeeded,\n\t};\n\tconst ctx: BranchTabContext = {\n\t\t...props,\n\t\trecord,\n\t\treadOnly,\n\t\tchangeSet: changeSet.data,\n\t\tchain,\n\t\tbranch,\n\t\theadRevisionId,\n\t\trelease,\n\t\tcompareBase,\n\t\tonCompareBase: setCompareBase,\n\t};\n\tconst active = tabs.find((each) => each.id === tab) ?? tabs[0];\n\tconst lastEditorial = chain?.branches.filter((b) => b.kind === \"editorial\").at(-1);\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"changeSets.title\"), to: paths.changeSets },\n\t\t\t\t{ label: changeSet.data?.name ?? changeSetId },\n\t\t\t\t{ label: title },\n\t\t\t]}\n\t\t\ttitle={title}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t<TypeBadge\n\t\t\t\t\t\tname={record.blueprintRelease?.displayName || record.content.blueprintId}\n\t\t\t\t\t\tcolorPalette=\"gray\"\n\t\t\t\t\t/>\n\t\t\t\t\t{!open && changeSet.data ? (\n\t\t\t\t\t\t<TypeBadge name={t(`changeSets.state.${changeSet.data.state}`)} colorPalette=\"gray\" />\n\t\t\t\t\t) : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t// A Pending Merge takes no saves (CONTEXT.md); a plan alone may still go.\n\t\t\t\t\tdisabled={changed === 0 || readOnly || (pendingMerge && contentDirty)}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void save()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"branch.save\") : t(\"branch.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={active.id} onValueChange={(e) => selectTab(e.value)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{tabs.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each.id} value={each.id}>\n\t\t\t\t\t\t\t\t{each.label(t)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved || otherBranch || !open || pendingMerge ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{otherBranch ? <Alert status=\"info\" title={t(\"branch.otherBranch\")} /> : null}\n\t\t\t\t\t{!open && changeSet.data ? <Alert status=\"info\" title={t(\"branch.closed\")} /> : null}\n\t\t\t\t\t{pendingMerge && open ? (\n\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.pendingMerge\")} />\n\t\t\t\t\t) : null}\n\t\t\t\t\t{refusal ? (\n\t\t\t\t\t\t<RefusalAlert\n\t\t\t\t\t\t\trefusal={refusal}\n\t\t\t\t\t\t\treloading={query.isFetching}\n\t\t\t\t\t\t\tonReload={reload}\n\t\t\t\t\t\t\tonSupersede={(ids) => {\n\t\t\t\t\t\t\t\tconst current = planForm.getValues(\"supersedes\");\n\t\t\t\t\t\t\t\tplanForm.setValue(\"supersedes\", [...new Set([...current, ...ids])], {\n\t\t\t\t\t\t\t\t\tshouldDirty: true,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tsetRefusal(null);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"branch.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t{seeded ? (\n\t\t\t\t<FormProvider {...(methods as UseFormReturn<FieldValues>)}>\n\t\t\t\t\t{active.render(ctx)}\n\t\t\t\t</FormProvider>\n\t\t\t) : (\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t)}\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"branch.leave.title\")}\n\t\t\t\tmessage={t(\"branch.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"branch.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"branch.leave.cancel\")}\n\t\t\t/>\n\t\t\t<BranchUpdateModal\n\t\t\t\topen={dialog === \"update\"}\n\t\t\t\tbranchId={branchId}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonResolve={() => setDialog(\"merge\")}\n\t\t\t\tonConfirm={async (idempotencyKey) => {\n\t\t\t\t\tconst outcome = await client.updateFromMain({\n\t\t\t\t\t\tid: changeSetId,\n\t\t\t\t\t\tchainId: chain?.id,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t});\n\t\t\t\t\tqueryClient.setQueryData(changeSetKey, outcome.changeSet);\n\t\t\t\t\tif (outcome.mergedBranchIds.includes(branchId)) await headMoved();\n\t\t\t\t\treturn outcome;\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ResolveMergeModal\n\t\t\t\topen={dialog === \"merge\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\tbranchId={branchId}\n\t\t\t\tfields={record.blueprintRelease?.fields ?? []}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonDone={() => {\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tvoid headMoved();\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<PreviewModal\n\t\t\t\topen={dialog === \"preview\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tfields={record.blueprintRelease?.fields ?? []}\n\t\t\t\tdefaultDay={planned?.validityPeriod?.firstDay ?? branch?.effectiveOn ?? \"\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t/>\n\t\t\t<AppendBranchModal\n\t\t\t\topen={dialog === \"append\"}\n\t\t\t\tafter={lastEditorial?.effectiveOn ?? \"\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={async (effectiveOn, idempotencyKey) => {\n\t\t\t\t\tif (!chain) throw new Error(\"the Change Set holds no Chain on this Content\");\n\t\t\t\t\tconst appended = await client.appendBranch({\n\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\tchainId: chain.id,\n\t\t\t\t\t\teffectiveOn,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t});\n\t\t\t\t\tqueryClient.setQueryData(changeSetKey, appended.changeSet);\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tonOpenBranch?.({ changeSetId, contentId, branchId: appended.branchId });\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={dialog === \"drop\"}\n\t\t\t\ttitle={t(\"branch.drop.title\")}\n\t\t\t\tmessage={t(\"branch.drop.message\", { content: title })}\n\t\t\t\tconfirmLabel={t(\"branch.drop.confirm\")}\n\t\t\t\tdanger\n\t\t\t\tfailedMessage={t(\"branch.drop.failed\")}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!chain) throw new Error(\"the Change Set holds no Chain on this Content\");\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait client.dropChain({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tchainId: chain.id,\n\t\t\t\t\t\t\tidempotencyKey: dropKey.keyFor([\"drop\", chain.id]),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdropKey.settle();\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (isAnswer(err)) dropKey.settle();\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tonDeleted?.();\n\t\t\t\t}}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n\nfunction RefusalAlert({\n\trefusal,\n\treloading,\n\tonReload,\n\tonSupersede,\n}: {\n\trefusal: Refusal;\n\treloading: boolean;\n\tonReload: () => void;\n\t/** Adds the covered Releases to the plan's supersedes, for the next Save. */\n\tonSupersede: (releaseIds: string[]) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst savedFirst = (r: { contentSaved: boolean }) =>\n\t\tr.contentSaved ? t(\"branch.refused.contentSaved\") : undefined;\n\tswitch (refusal.kind) {\n\t\tcase \"stale\":\n\t\t\t// ADR 0020: a moved head is refused, never merged. The draft stays\n\t\t\t// until the author reloads, which throws it away.\n\t\t\treturn (\n\t\t\t\t<Alert status=\"warning\" title={t(\"branch.refused.stale\")}>\n\t\t\t\t\t<Stack gap=\"2\" align=\"start\">\n\t\t\t\t\t\t{t(\"branch.refused.staleHint\")}\n\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" loading={reloading} onClick={onReload}>\n\t\t\t\t\t\t\t<RotateCcw size={14} />\n\t\t\t\t\t\t\t{t(\"branch.reload\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"violations\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(\"branch.refused.violations\", { count: refusal.reasons.length })}\n\t\t\t\t>\n\t\t\t\t\t{refusal.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \")}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"invalid\":\n\t\t\treturn <Alert status=\"error\" title={t(\"branch.refused.invalid\")} />;\n\t\tcase \"releaseInvalid\":\n\t\t\treturn <Alert status=\"error\" title={t(\"branch.refused.releaseInvalid\")} />;\n\t\tcase \"covers\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\ttitle={t(\"branch.refused.covers\", { releases: refusal.releaseIds.join(\", \") })}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"2\" align=\"start\">\n\t\t\t\t\t\t{[savedFirst(refusal), t(\"branch.refused.coversHint\")].filter(Boolean).join(\" \")}\n\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" onClick={() => onSupersede(refusal.releaseIds)}>\n\t\t\t\t\t\t\t{t(\"branch.refused.supersede\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"releaseViolations\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(\"branch.refused.releaseViolations\", { count: refusal.reasons.length })}\n\t\t\t\t>\n\t\t\t\t\t{[\n\t\t\t\t\t\tsavedFirst(refusal),\n\t\t\t\t\t\trefusal.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \"),\n\t\t\t\t\t]\n\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t.join(\" \")}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"release\":\n\t\t\treturn (\n\t\t\t\t<Alert status=\"error\" title={refusal.message}>\n\t\t\t\t\t{savedFirst(refusal)}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn <Alert status=\"error\" title={refusal.message} />;\n\t}\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useCallback, useMemo } from \"react\";\nimport type { ChangeSetStatusInfo, StatusSource } from \"../types\";\nimport { contenthubKeys } from \"./query-keys\";\n\nconst NO_STATUSES: ChangeSetStatusInfo[] = [];\n\nexport interface ChangeSetStatuses {\n\t/** The catalogue, in statushub's order; empty without a `StatusSource`. */\n\tstatuses: ChangeSetStatusInfo[];\n\t/** Whether the host filled the port: without it there is no picker. */\n\tavailable: boolean;\n\t/**\n\t * A slug as a label: statushub's name and colour, or the bare slug when\n\t * the port is empty, still loading, or no longer holds it (ADR 0020).\n\t * \"\" (an unknown status) is `undefined`, for the caller to word.\n\t */\n\tlabelOf: (slug: string) => ChangeSetStatusInfo | undefined;\n}\n\n/** The workspace's Change Set statuses, through the host-filled port. */\nexport function useChangeSetStatuses(source: StatusSource | undefined): ChangeSetStatuses {\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.changeSetStatuses(),\n\t\tqueryFn: () => (source as StatusSource).listChangeSetStatuses(),\n\t\tenabled: source !== undefined,\n\t\t// A catalogue changes rarely and every row reads it.\n\t\tstaleTime: 60_000,\n\t});\n\tconst statuses = query.data ?? NO_STATUSES;\n\tconst labelOf = useCallback(\n\t\t(slug: string) => {\n\t\t\tif (slug === \"\") return undefined;\n\t\t\treturn statuses.find((s) => s.slug === slug) ?? { slug, name: slug };\n\t\t},\n\t\t[statuses],\n\t);\n\tconst available = source !== undefined;\n\t// One object while nothing changes, so a table's columns built from it\n\t// are not rebuilt on every render.\n\treturn useMemo(() => ({ statuses, available, labelOf }), [statuses, available, labelOf]);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ChangeSetClosedError, WithheldWorkError } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { UpdateFromMainOutcome } from \"../types\";\n\n// The rail's other two actions, each confirmed in a dialog the screen\n// renders (anker ADR 0004: a rail node renders outside the screen's\n// providers). Both kept mounted and driven by `open`, with `lazyMount\n// unmountOnExit` (anker's Modal rule); each opening starts afresh.\n\ntype Failure = \"closed\" | \"withheld\" | \"failed\";\n\n// Withheld: the Change Set holds work the caller can't see (ADR 0017), which\n// the service says by a typed detail and without naming any of it.\nconst failureOf = (err: unknown): Failure =>\n\terr instanceof ChangeSetClosedError\n\t\t? \"closed\"\n\t\t: err instanceof WithheldWorkError\n\t\t\t? \"withheld\"\n\t\t\t: \"failed\";\n\nexport function UpdateFromMainModal({\n\topen,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\tonClose: () => void;\n\t/** Runs the update; its outcome is shown here until the dialog closes. */\n\tonConfirm: () => Promise<UpdateFromMainOutcome>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [outcome, setOutcome] = useState<UpdateFromMainOutcome | null>(null);\n\tconst [failure, setFailure] = useState<Failure | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetOutcome(null);\n\t\t\tsetFailure(null);\n\t\t}\n\t}, [open]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tsetOutcome(await onConfirm());\n\t\t} catch (err) {\n\t\t\tsetFailure(failureOf(err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\t// Only which Branches were left with a Pending Merge: showing the merge\n\t// itself is the Branch editor's.\n\tconst pending = outcome ? [...outcome.conflicted, ...outcome.pending] : [];\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.update.title\")}\n\t\t\tfooter={\n\t\t\t\toutcome ? (\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={running} onClick={() => void run()}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.confirm\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{outcome ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Alert status=\"success\" title={t(\"changeSet.update.done\")}>\n\t\t\t\t\t\t\t{outcome.mergedBranchIds.length > 0\n\t\t\t\t\t\t\t\t? t(\"changeSet.update.merged\", { count: outcome.mergedBranchIds.length })\n\t\t\t\t\t\t\t\t: t(\"changeSet.update.nothingMerged\")}\n\t\t\t\t\t\t</Alert>\n\t\t\t\t\t\t{pending.length > 0 ? (\n\t\t\t\t\t\t\t<Stack gap=\"1\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.update.pendingTitle\")}</Text>\n\t\t\t\t\t\t\t\t<Stack as=\"ul\" gap=\"1\" listStyleType=\"none\">\n\t\t\t\t\t\t\t\t\t{pending.map((p) => (\n\t\t\t\t\t\t\t\t\t\t<Text as=\"li\" key={p.branchId} fontSize=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"changeSet.update.pendingLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tcontent: p.contentId,\n\t\t\t\t\t\t\t\t\t\t\t\tbranch: p.branchId,\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.update.message\")}</Text>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={t(`changeSet.update.${failure}`)} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\nexport function DiscardChangeSetModal({\n\topen,\n\tname,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\tname: string;\n\tonClose: () => void;\n\tonConfirm: () => Promise<void>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [failure, setFailure] = useState<Failure | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) setFailure(null);\n\t}, [open]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait onConfirm();\n\t\t} catch (err) {\n\t\t\tsetFailure(failureOf(err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.discard.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={running}\n\t\t\t\t\t\tonClick={() => void run()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"changeSet.discard.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.discard.message\", { name })}</Text>\n\t\t\t\t{failure ? <Alert status=\"error\" title={t(`changeSet.discard.${failure}`)} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { ActionCell, DataTable, StatusBadgeCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { ClipboardCheck, ListChecks } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckStanding } from \"../types\";\n\ntype StandingRow = CheckStanding & Record<string, unknown>;\n\n/** What a standing is about, in words: the whole Change Set, or its Content's Branch or Release. */\nexport function subjectText(t: TFunction, st: CheckStanding): string {\n\tif (st.check.scope === \"change_set\") return t(\"changeSet.checks.wholeChangeSet\");\n\tif (st.branchId) {\n\t\treturn t(\"changeSet.checks.onBranch\", { content: st.contentId, branch: st.branchId });\n\t}\n\treturn t(\"changeSet.checks.onRelease\", { content: st.contentId, release: st.releaseId });\n}\n\n/** A standing's row key: one per check and subject. */\nexport const standingKey = (st: CheckStanding) =>\n\t`${st.check.id}/${st.branchId || st.releaseId || \"change-set\"}`;\n\n/**\n * Each Required Check that applies, on each thing it applies to, with its\n * latest result and whether a save since made it stale (ADR 0014). A row's\n * action opens the screen's Record dialog: results are recorded against the\n * heads the row shows. A table tab, so flush.\n */\nexport function ChangeSetChecksTab({\n\tstandings,\n\tloading,\n\tfailed,\n\tcanRecord,\n\tonRecord,\n}: {\n\tstandings: CheckStanding[];\n\tloading: boolean;\n\tfailed: boolean;\n\t/** Whether the Change Set is open: a closed one takes no more results. */\n\tcanRecord: boolean;\n\tonRecord: (standing: CheckStanding) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst columns = useMemo<ColumnDef<StandingRow, unknown>[]>(() => {\n\t\tconst standingLabel = (st: CheckStanding) =>\n\t\t\tst.cleared\n\t\t\t\t? t(\"changeSet.checks.cleared\")\n\t\t\t\t: st.stale\n\t\t\t\t\t? t(\"changeSet.checks.stale\")\n\t\t\t\t\t: t(\"changeSet.checks.outstanding\");\n\t\tconst out: ColumnDef<StandingRow, unknown>[] = [\n\t\t\t{\n\t\t\t\tid: \"check\",\n\t\t\t\theader: t(\"changeSet.checks.columns.check\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.check.name}\n\t\t\t\t\t\tsubText={row.original.check.independent ? t(\"changeSet.checks.independent\") : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"on\",\n\t\t\t\theader: t(\"changeSet.checks.columns.on\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={subjectText(t, row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"latest\",\n\t\t\t\theader: t(\"changeSet.checks.columns.latest\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst latest = row.original.results[0];\n\t\t\t\t\tif (!latest) return <TruncatedTextCell value={t(\"changeSet.checks.none\")} />;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={t(\"changeSet.checks.latest\", {\n\t\t\t\t\t\t\t\toutcome: t(`changeSet.checks.outcome.${latest.outcome}`),\n\t\t\t\t\t\t\t\twho: members.byId(latest.recordedBy)?.displayName ?? latest.recordedBy,\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\tsubText={latest.note || undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"standing\",\n\t\t\t\theader: t(\"changeSet.checks.columns.standing\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst label = standingLabel(row.original);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\t\tvalue={label}\n\t\t\t\t\t\t\tcolorMap={{\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.cleared\")]: \"green\",\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.stale\")]: \"orange\",\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.outstanding\")]: \"red\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t\tif (canRecord) {\n\t\t\tout.push({\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"changeSet.checks.columns.actions\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<ActionCell\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ticon: ClipboardCheck,\n\t\t\t\t\t\t\t\tlabel: t(\"changeSet.checks.record\"),\n\t\t\t\t\t\t\t\tonClick: () => onRecord(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}, [t, members, canRecord, onRecord]);\n\n\tif (failed) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.checks.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (loading) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={standings as StandingRow[]}\n\t\t\tgetRowId={standingKey}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<ListChecks size={32} />}\n\t\t\t\t\theader={t(\"changeSet.checks.empty\")}\n\t\t\t\t\tdescription={t(\"changeSet.checks.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { BooleanCell, CountCell, DataTable, SlugCell } from \"@knkcs/anker/components\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FileText } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, ChangeSetChain } from \"../types\";\n\ntype ChainRow = ChangeSetChain & Record<string, unknown>;\n\n/** What the Branch editor is opened on: a Content inside a Change Set, at one of its Branches. */\nexport interface OpenBranchTarget {\n\tchangeSetId: string;\n\tcontentId: string;\n\t/**\n\t * The Branch to open: the Chain's last editorial Branch, the one a new\n\t * save continues (the tip Publish moves Main to).\n\t */\n\tbranchId: string;\n}\n\n/** The Branch a Chain's row opens: its last editorial one, or its last at all. */\nexport function branchToOpen(chain: ChangeSetChain): string {\n\tconst editorial = chain.branches.filter((b) => b.kind === \"editorial\");\n\treturn (editorial.at(-1) ?? chain.branches.at(-1))?.id ?? \"\";\n}\n\n/**\n * The Chains a Change Set holds, one row per Content, each opening the\n * Branch editor on it. A table tab, so flush (anker: only form tabs pad).\n */\nexport function ChangeSetContentsTab({\n\tchangeSet,\n\tonOpenBranch,\n}: {\n\tchangeSet: ChangeSet;\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst columns = useMemo<ColumnDef<ChainRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"content\",\n\t\t\t\theader: t(\"changeSet.contents.columns.content\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.contentId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"branches\",\n\t\t\t\theader: t(\"changeSet.contents.columns.branches\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<CountCell\n\t\t\t\t\t\tvalue={row.original.branches}\n\t\t\t\t\t\tsingular={t(\"changeSet.contents.branch\")}\n\t\t\t\t\t\tplural={t(\"changeSet.contents.branches\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"born\",\n\t\t\t\theader: t(\"changeSet.contents.columns.born\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.born}\n\t\t\t\t\t\ttrueLabel={t(\"changeSet.contents.bornHere\")}\n\t\t\t\t\t\tfalseLabel={t(\"changeSet.contents.onMain\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={changeSet.chains as ChainRow[]}\n\t\t\tgetRowId={(row) => row.id}\n\t\t\tvariant=\"hoverable\"\n\t\t\tonRowClick={(chain) =>\n\t\t\t\tonOpenBranch({\n\t\t\t\t\tchangeSetId: changeSet.id,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\tbranchId: branchToOpen(chain),\n\t\t\t\t})\n\t\t\t}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<FileText size={32} />}\n\t\t\t\t\theader={t(\"changeSet.contents.empty\")}\n\t\t\t\t\tdescription={t(\"changeSet.contents.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import type { BaseOption, LookupResolve, LookupSearch } from \"@knkcs/anker/atoms\";\nimport { Card, DescriptionList } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, LookupSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Box, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useCallback, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport type { ChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet } from \"../types\";\n\n/** The General tab's draft: what of a Change Set its page can change. */\nexport interface GeneralValues {\n\tname: string;\n\t/** The Source's day as YYYY-MM-DD; \"\" with the reference for none. */\n\tsourceDate: string;\n\tsourceReference: string;\n\t/** A status slug; \"\" for none yet. */\n\tstatus: string;\n\tassigneeIds: string[];\n\tdependsOnIds: string[];\n}\n\nexport function generalValuesOf(cs: ChangeSet): GeneralValues {\n\treturn {\n\t\tname: cs.name,\n\t\tsourceDate: cs.source?.date ?? \"\",\n\t\tsourceReference: cs.source?.reference ?? \"\",\n\t\tstatus: cs.status,\n\t\tassigneeIds: [...cs.assigneeIds],\n\t\tdependsOnIds: [...cs.dependsOnChangeSetIds],\n\t};\n}\n\n/** How many open Change Sets the dependency picker searches; the service's page limit. */\nconst DEPENDENCY_CANDIDATES = 200;\n\n/**\n * A Change Set's General tab: what it is (name, Source, state, who opened it)\n * and the things its page changes: its name and Source while it is open\n * (#126), its status label, its assignees and its dependencies. The draft is\n * the page's form, held above the tab, so it survives switching tabs; the\n * header's one Save persists it.\n *\n * A closed Change Set shows its name and Source, not edits them: the Source\n * freezes at Publish, since its Releases and their Event carry it.\n */\nexport function ChangeSetGeneralTab({\n\tclient,\n\tchangeSet,\n\tstatuses,\n}: {\n\tclient: ContenthubClient;\n\tchangeSet: ChangeSet;\n\tstatuses: ChangeSetStatuses;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst closed = changeSet.state !== \"open\";\n\n\t// A status the catalogue no longer holds stays offered, by its slug, so\n\t// the field shows where the Change Set is rather than \"no status\".\n\tconst statusOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = statuses.statuses.map((s) => ({ id: s.slug, label: s.name }));\n\t\tconst current = changeSet.status;\n\t\treturn current === \"\" || known.some((o) => o.id === current)\n\t\t\t? known\n\t\t\t: [...known, { id: current, label: current }];\n\t}, [statuses.statuses, changeSet.status]);\n\t// Members first; an assignee who is no longer one stays listed by id, so\n\t// saving never drops someone the page cannot name.\n\tconst assigneeOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = members.list().map((m) => ({ id: m.userId, label: m.displayName }));\n\t\tconst unknown = changeSet.assigneeIds\n\t\t\t.filter((id) => !members.byId(id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [members, changeSet.assigneeIds]);\n\n\tconst searchDependencies = useCallback<LookupSearch<BaseOption>>(\n\t\tasync ({ query }) => {\n\t\t\tconst { changeSets } = await client.listChangeSets({\n\t\t\t\tstate: \"open\",\n\t\t\t\tpageSize: DEPENDENCY_CANDIDATES,\n\t\t\t});\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\titems: changeSets\n\t\t\t\t\t.filter((cs) => cs.id !== changeSet.id)\n\t\t\t\t\t.filter((cs) => q === \"\" || cs.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.map((cs) => ({ id: cs.id, label: cs.name })),\n\t\t\t};\n\t\t},\n\t\t[client, changeSet.id],\n\t);\n\tconst resolveDependencies = useCallback<LookupResolve<BaseOption>>(\n\t\t({ ids }) =>\n\t\t\tPromise.all(\n\t\t\t\tids.map((id) =>\n\t\t\t\t\tclient.getChangeSet(id).then(\n\t\t\t\t\t\t(cs) => ({ id, label: cs.name }),\n\t\t\t\t\t\t// One the page can't read is still shown, by id.\n\t\t\t\t\t\t() => ({ id, label: id }),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t[client],\n\t);\n\n\tconst createdBy = members.byId(changeSet.createdBy)?.displayName ?? changeSet.createdBy;\n\tconst status = statuses.labelOf(changeSet.status);\n\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Card title={t(\"changeSet.general.about\")}>\n\t\t\t\t\t{closed ? null : (\n\t\t\t\t\t\t<Stack gap=\"4\" mb=\"4\">\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSet.general.name\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.nameHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"sourceDate\"\n\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSets.form.sourceDate\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.sourceDateHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"sourceReference\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSets.form.sourceReference\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.sourceReferenceHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t{closed ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.name\")}>\n\t\t\t\t\t\t\t\t\t{changeSet.name}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.source\")}>\n\t\t\t\t\t\t\t\t\t{changeSet.source\n\t\t\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tdate: changeSet.source.date,\n\t\t\t\t\t\t\t\t\t\t\t\treference: changeSet.source.reference,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t: t(\"changeSet.general.noSource\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.state\")}>\n\t\t\t\t\t\t\t{t(`changeSets.state.${changeSet.state}`)}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.createdBy\")}>\n\t\t\t\t\t\t\t{createdBy}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t{statuses.available ? null : (\n\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.status\")}>\n\t\t\t\t\t\t\t\t{status?.name ?? t(\"changeSet.general.noStatus\")}\n\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t{closed ? (\n\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\" mt=\"3\">\n\t\t\t\t\t\t\t{t(\"changeSet.general.frozenHint\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t) : null}\n\t\t\t\t</Card>\n\t\t\t\t<Card title={t(\"changeSet.general.work\")}>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{statuses.available ? (\n\t\t\t\t\t\t\t<BaseSelectField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"status\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSet.general.status\")}\n\t\t\t\t\t\t\t\thelperText={t(\n\t\t\t\t\t\t\t\t\tclosed ? \"changeSet.general.statusFrozen\" : \"changeSet.general.statusHelp\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\toptions={statusOptions}\n\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.noStatus\")}\n\t\t\t\t\t\t\t\tdisabled={closed}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<GeneralValues>\n\t\t\t\t\t\t\tname=\"assigneeIds\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.general.assignees\")}\n\t\t\t\t\t\t\thelperText={t(\"changeSet.general.assigneesHelp\")}\n\t\t\t\t\t\t\toptions={assigneeOptions}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<LookupSelectField<GeneralValues>\n\t\t\t\t\t\t\tname=\"dependsOnIds\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.general.dependencies\")}\n\t\t\t\t\t\t\thelperText={t(\n\t\t\t\t\t\t\t\tclosed\n\t\t\t\t\t\t\t\t\t? \"changeSet.general.dependenciesClosed\"\n\t\t\t\t\t\t\t\t\t: \"changeSet.general.dependenciesHelp\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tsearch={searchDependencies}\n\t\t\t\t\t\t\tresolve={resolveDependencies}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.noDependencies\")}\n\t\t\t\t\t\t\tdisabled={closed}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Card>\n\t\t\t</Stack>\n\t\t</Box>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, StatusBadgeCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Box, Heading, Stack, Text } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { CalendarRange } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, PlannedRelease, PublishBlocker, ValidityPeriod } from \"../types\";\n\ntype PlanRow = PlannedRelease & Record<string, unknown>;\n\n/** A published Release a plan of this Change Set covers. */\ninterface CoveredRow extends Record<string, unknown> {\n\treleaseId: string;\n\t/** The Planned Release covering it. */\n\tbyReleaseId: string;\n\tcontentId: string;\n\t/** Superseded at Publish, or blocking it (covers_release) until replanned. */\n\tsuperseded: boolean;\n}\n\nexport function periodText(t: TFunction, period: ValidityPeriod | undefined): string {\n\tif (!period) return t(\"changeSet.releases.undated\");\n\treturn t(\"changeSet.releases.period\", {\n\t\tfirst: period.firstDay,\n\t\tlast: period.lastDay || t(\"changeSet.releases.openEnd\"),\n\t});\n}\n\n/**\n * The Releases a plan covers: those a plan supersedes, which Publish\n * supersedes with it, and those the latest review reports as covered by a\n * plan that doesn't supersede them (covers_release), which block Publish.\n * A Release a proposal ends is no covered one: it is cut, not superseded\n * whole, so proposals are left out.\n */\nfunction coveredRows(changeSet: ChangeSet, blockers: PublishBlocker[]): CoveredRow[] {\n\tconst rows: CoveredRow[] = [];\n\tfor (const pr of changeSet.plannedReleases) {\n\t\tif (pr.proposed) continue;\n\t\tfor (const id of pr.supersedesReleaseIds) {\n\t\t\trows.push({ releaseId: id, byReleaseId: pr.id, contentId: pr.contentId, superseded: true });\n\t\t}\n\t}\n\tfor (const b of blockers) {\n\t\tif (b.code !== \"covers_release\") continue;\n\t\trows.push({\n\t\t\treleaseId: b.coveredReleaseId,\n\t\t\tbyReleaseId: b.releaseId,\n\t\t\tcontentId: b.contentId,\n\t\t\tsuperseded: false,\n\t\t});\n\t}\n\treturn rows;\n}\n\n/**\n * What Publish will cut: the Change Set's Planned Releases, the proposals\n * among them read-only (they follow from the planned periods and are\n * recomputed with every plan), and the published Releases its plans cover.\n * Plans are made in the Branch editor; this tab reviews them.\n */\nexport function ChangeSetReleasesTab({\n\tchangeSet,\n\tblockers,\n}: {\n\tchangeSet: ChangeSet;\n\t/** The latest review's blockers, for the covered Releases that block Publish. */\n\tblockers: PublishBlocker[];\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst columns = useMemo<ColumnDef<PlanRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"content\",\n\t\t\t\theader: t(\"changeSet.releases.columns.content\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.contentId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"changeSet.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(`changeSet.releases.kind.${row.original.kind}`)}\n\t\t\t\t\t\tfallbackColor={row.original.kind === \"revision\" ? \"blue\" : \"gray\"}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"changeSet.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(t, row.original.validityPeriod)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pins\",\n\t\t\t\theader: t(\"changeSet.releases.columns.pins\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.branchId\n\t\t\t\t\t\t\t\t? t(\"changeSet.releases.branchHead\", { branch: row.original.branchId })\n\t\t\t\t\t\t\t\t: t(\"changeSet.releases.revision\", { revision: row.original.revisionId })\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"origin\",\n\t\t\t\theader: t(\"changeSet.releases.columns.origin\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={originText(t, row.original)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst covered = coveredRows(changeSet, blockers);\n\tconst coveredColumns = useMemo<ColumnDef<CoveredRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.release\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.releaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"by\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.by\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.byReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"outcome\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.outcome\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(\n\t\t\t\t\t\t\trow.original.superseded\n\t\t\t\t\t\t\t\t? \"changeSet.releases.superseded\"\n\t\t\t\t\t\t\t\t: \"changeSet.releases.blocks\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tfallbackColor={row.original.superseded ? \"gray\" : \"orange\"}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\t// Both tables are flush (anker: table tabs reach both edges); only the\n\t// prose between them is inset, to line up with the header.\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={changeSet.plannedReleases as PlanRow[]}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarRange size={32} />}\n\t\t\t\t\t\theader={t(\"changeSet.releases.empty\")}\n\t\t\t\t\t\tdescription={t(\"changeSet.releases.emptyHint\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<Box px=\"8\" pt=\"2\">\n\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t{t(\"changeSet.releases.proposedHint\")}\n\t\t\t\t</Text>\n\t\t\t</Box>\n\t\t\t<Stack gap=\"1\" px=\"8\" pt=\"6\" pb=\"3\">\n\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t{t(\"changeSet.releases.covered\")}\n\t\t\t\t</Heading>\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"changeSet.releases.coveredHint\")}\n\t\t\t\t</Text>\n\t\t\t</Stack>\n\t\t\t<DataTable\n\t\t\t\tcolumns={coveredColumns}\n\t\t\t\tdata={covered}\n\t\t\t\tgetRowId={(row) => `${row.byReleaseId}/${row.releaseId}`}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarRange size={32} />}\n\t\t\t\t\t\theader={t(\"changeSet.releases.noCovered\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n\n/** Planned by hand, or proposed: for which Release, resuming which, withheld or not. */\nfunction originText(t: TFunction, pr: PlannedRelease): string {\n\tif (!pr.proposed) return t(\"changeSet.releases.plannedByHand\");\n\tif (pr.withheld) return t(\"changeSet.releases.withheld\");\n\tif (pr.splitFromReleaseId) {\n\t\treturn t(\"changeSet.releases.splitFrom\", { release: pr.splitFromReleaseId });\n\t}\n\treturn t(\"changeSet.releases.proposed\", { release: pr.proposedForReleaseId });\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport type { TFunction } from \"i18next\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PublishBlocker } from \"../types\";\n\n/**\n * The codes this build words. Each names what the blocker is about (ADR\n * 0015): a code the service adds later still shows, by its code.\n */\nconst KNOWN = new Set([\n\t\"moved_head\",\n\t\"unplanned_branch\",\n\t\"several_branches\",\n\t\"behind_base\",\n\t\"superseded_release\",\n\t\"overlapping_periods\",\n\t\"covers_release\",\n\t\"pending_merge\",\n\t\"nothing_in_force\",\n\t\"withdrawal_with_chain\",\n\t\"dated_changed\",\n\t\"unpublished_dependency\",\n\t\"discarded_dependency\",\n\t\"dangling_pin\",\n\t\"second_toc_parent\",\n\t\"missing_asset\",\n\t\"media_unavailable\",\n\t\"outstanding_check\",\n\t\"missing_required_field\",\n]);\n\n/**\n * One blocker in words, naming what it names: its Content, Branch, heads,\n * Releases, Revision, dependency, path, Asset, TOC parents or Required Check.\n * `checkName` turns a Required Check's id into its name, falling back to\n * the id.\n */\nexport function blockerMessage(\n\tt: TFunction,\n\tb: PublishBlocker,\n\tcheckName: (id: string) => string,\n): string {\n\tconst values = {\n\t\tcontent: b.contentId,\n\t\tbranch: b.branchId,\n\t\texpected: b.expectedHeadId,\n\t\tcurrent: b.currentHeadId,\n\t\trelease: b.releaseId,\n\t\toverlaps: b.overlapsReleaseId,\n\t\tcovered: b.coveredReleaseId,\n\t\trevision: b.revisionId,\n\t\tdependency: b.dependencyChangeSetId,\n\t\tpath: b.path,\n\t\ttarget: b.targetContentId,\n\t\tasset: b.assetId,\n\t\tparents: b.parentContentIds.join(\", \"),\n\t\tcheck: checkName(b.requiredCheckId),\n\t\tsubject: b.branchId || b.releaseId,\n\t\tcode: b.code,\n\t};\n\tif (!KNOWN.has(b.code)) return t(\"changeSet.blockers.unknown\", values);\n\tif (b.code === \"moved_head\") {\n\t\t// versionkit reports a Branch the review left out with no expected\n\t\t// head, and a reviewed one the Change Set no longer holds with no\n\t\t// current head.\n\t\tif (b.expectedHeadId === \"\") return t(\"changeSet.blockers.moved_head_unreviewed\", values);\n\t\tif (b.currentHeadId === \"\") return t(\"changeSet.blockers.moved_head_gone\", values);\n\t}\n\tif (b.code === \"outstanding_check\" && b.contentId !== \"\") {\n\t\treturn t(\"changeSet.blockers.outstanding_check_on\", values);\n\t}\n\treturn t(`changeSet.blockers.${b.code}`, values);\n}\n\n/** The blockers fixed by editing their Content, which offer to open it. */\nconst FIXED_IN_EDITOR = new Set([\"missing_required_field\"]);\n\n/**\n * Every blocker, one Alert each, in the order the service gave them. A\n * blocker fixed in its Content's Branch editor (a required field left empty)\n * links to it through `onOpenContent`, when the screen gives one.\n */\nexport function PublishBlockerList({\n\tblockers,\n\tcheckName,\n\tonOpenContent,\n}: {\n\tblockers: PublishBlocker[];\n\tcheckName: (id: string) => string;\n\tonOpenContent?: (contentId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"2\" as=\"ul\" listStyleType=\"none\">\n\t\t\t{blockers.map((b, i) => (\n\t\t\t\t// Blockers carry no id, and two can name the same things.\n\t\t\t\t// biome-ignore lint/suspicious/noArrayIndexKey: the list never reorders\n\t\t\t\t<li key={i}>\n\t\t\t\t\t<Alert\n\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\ttitle={blockerMessage(t, b, checkName)}\n\t\t\t\t\t\tendElement={\n\t\t\t\t\t\t\tonOpenContent && b.contentId !== \"\" && FIXED_IN_EDITOR.has(b.code) ? (\n\t\t\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" onClick={() => onOpenContent(b.contentId)}>\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.openContent\", { content: b.contentId })}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t) : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, Heading, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { Send } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tChangeSetClosedError,\n\ttype ContenthubClient,\n\tPublishRefusedError,\n\tWithheldWorkError,\n} from \"../client/contenthub-client\";\nimport { headsOf } from \"../common/heads\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, PublishOutcome, PublishReview } from \"../types\";\nimport { periodText } from \"./change-set-releases-tab\";\nimport { PublishBlockerList } from \"./publish-blockers\";\n\nexport interface PublishReviewModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Change Set as the page has it now; its heads are latched when a review runs. */\n\tchangeSet: ChangeSet;\n\tcheckName: (id: string) => string;\n\tonClose: () => void;\n\tonPublished: (outcome: PublishOutcome) => void;\n\t/**\n\t * Every review that ran, with the Change Set it read, for the page to\n\t * refresh what depends on the heads (the readiness tile, the Checks tab).\n\t */\n\tonReviewed?: (changeSet: ChangeSet) => void;\n\t/**\n\t * Opens a Content of the Change Set in its Branch editor, from a blocker\n\t * fixed there (a required field left empty). Without it, none links.\n\t */\n\tonOpenContent?: (contentId: string) => void;\n}\n\ntype Stage =\n\t| { kind: \"checking\" }\n\t| { kind: \"reviewed\"; review: PublishReview }\n\t| { kind: \"withheld\" }\n\t| { kind: \"failed\" };\n\ntype Refusal = \"refused\" | \"closed\" | \"withheld\" | \"failed\";\n\n/**\n * Publish's review (ADR 0020, anker ADR 0004): it reads the Change Set's\n * heads afresh and latches them, runs ValidatePublish with them, shows those\n * heads, every blocker and the Releases it would cut, and publishes exactly\n * the heads it showed. A head that moves after the review is the service's to\n * refuse (moved_head): the dialog never swaps in heads nobody reviewed.\n * \"Review again\" reads and latches the heads anew.\n *\n * Opened from the rail, rendered by the screen; kept mounted and driven by\n * `open`, with `lazyMount unmountOnExit` (anker's Modal rule).\n */\nexport function PublishReviewModal({\n\topen,\n\tclient,\n\tchangeSet,\n\tcheckName,\n\tonClose,\n\tonPublished,\n\tonReviewed,\n\tonOpenContent,\n}: PublishReviewModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [reviewed, setReviewed] = useState<Record<string, string>>({});\n\tconst [stage, setStage] = useState<Stage>({ kind: \"checking\" });\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [publishing, setPublishing] = useState(false);\n\t// Only the latest review's answer counts; an earlier one arriving late is\n\t// for heads no longer shown.\n\tconst session = useRef(0);\n\tconst latest = useRef(changeSet);\n\tlatest.current = changeSet;\n\t// Until the first read answers, no heads are shown, so none can be sent.\n\n\tconst review = useCallback(async () => {\n\t\tconst run = ++session.current;\n\t\tsetStage({ kind: \"checking\" });\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\t// The heads as the service has them now, not as the page last read\n\t\t\t// them: after a moved_head refusal, reviewing again must see the move.\n\t\t\tconst current = await client.getChangeSet(latest.current.id);\n\t\t\tif (run !== session.current) return;\n\t\t\tconst heads = headsOf(current);\n\t\t\tsetReviewed(heads);\n\t\t\tconst answer = await client.validatePublish({ id: current.id, reviewedHeads: heads });\n\t\t\tif (run !== session.current) return;\n\t\t\tsetStage({ kind: \"reviewed\", review: answer });\n\t\t\tonReviewed?.(current);\n\t\t} catch (err) {\n\t\t\t// Work the caller can't see refuses the dry run as it would Publish.\n\t\t\tif (run === session.current) {\n\t\t\t\tsetStage({ kind: err instanceof WithheldWorkError ? \"withheld\" : \"failed\" });\n\t\t\t}\n\t\t}\n\t}, [client, onReviewed]);\n\n\tuseEffect(() => {\n\t\tif (open) void review();\n\t\telse session.current++;\n\t}, [open, review]);\n\n\tconst publish = async () => {\n\t\tsetPublishing(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\t// Exactly the heads shown: never re-read here.\n\t\t\tonPublished(await client.publish({ id: changeSet.id, reviewedHeads: reviewed }));\n\t\t} catch (err) {\n\t\t\tif (err instanceof PublishRefusedError) {\n\t\t\t\tconst previous = stage.kind === \"reviewed\" ? stage.review : undefined;\n\t\t\t\tsetStage({\n\t\t\t\t\tkind: \"reviewed\",\n\t\t\t\t\treview: {\n\t\t\t\t\t\tblockers: err.blockers,\n\t\t\t\t\t\treleases: previous?.releases ?? [],\n\t\t\t\t\t\tpublished: false,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tsetRefusal(\"refused\");\n\t\t\t} else if (err instanceof ChangeSetClosedError) {\n\t\t\t\tsetRefusal(\"closed\");\n\t\t\t} else if (err instanceof WithheldWorkError) {\n\t\t\t\tsetRefusal(\"withheld\");\n\t\t\t} else {\n\t\t\t\tsetRefusal(\"failed\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetPublishing(false);\n\t\t}\n\t};\n\n\tconst contentOf = (branchId: string) =>\n\t\tchangeSet.chains.find((c) => c.branches.some((b) => b.id === branchId))?.contentId ?? \"\";\n\tconst ready =\n\t\tstage.kind === \"reviewed\" &&\n\t\t(stage.review.blockers.length === 0 || stage.review.published) &&\n\t\tchangeSet.state === \"open\";\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"changeSet.review.title\", { name: changeSet.name })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tonClick={() => void review()}\n\t\t\t\t\t\tdisabled={stage.kind === \"checking\" || publishing}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"changeSet.review.again\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tonClick={() => void publish()}\n\t\t\t\t\t\tdisabled={!ready}\n\t\t\t\t\t\tloading={publishing}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Send size={16} />\n\t\t\t\t\t\t{t(\"changeSet.review.publish\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"5\">\n\t\t\t\t{refusal ? <Alert status=\"error\" title={t(refusalKey[refusal])} /> : null}\n\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t{t(\"changeSet.review.headsTitle\")}\n\t\t\t\t\t</Heading>\n\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t{t(\"changeSet.review.headsHint\")}\n\t\t\t\t\t</Text>\n\t\t\t\t\t{Object.keys(reviewed).length === 0 ? (\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.noHeads\")}</Text>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Stack\n\t\t\t\t\t\t\tas=\"ul\"\n\t\t\t\t\t\t\tgap=\"1\"\n\t\t\t\t\t\t\tlistStyleType=\"none\"\n\t\t\t\t\t\t\taria-label={t(\"changeSet.review.headsTitle\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{Object.entries(reviewed).map(([branch, head]) => (\n\t\t\t\t\t\t\t\t<Text as=\"li\" key={branch} fontSize=\"sm\" fontFamily=\"mono\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.headLine\", { content: contentOf(branch), branch, head })}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\t\t\t\t</Stack>\n\t\t\t\t{stage.kind === \"checking\" ? (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.checking\")}</Text>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"withheld\" ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.review.withheld\")} />\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"failed\" ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.review.loadError\")} />\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"reviewed\" ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{stage.review.published ? (\n\t\t\t\t\t\t\t<Alert status=\"info\" title={t(\"changeSet.review.alreadyPublished\")} />\n\t\t\t\t\t\t) : stage.review.blockers.length === 0 ? (\n\t\t\t\t\t\t\t<Alert status=\"success\" title={t(\"changeSet.review.ready\")} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.blockersTitle\", { count: stage.review.blockers.length })}\n\t\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.blockersHint\")}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<PublishBlockerList\n\t\t\t\t\t\t\t\t\tblockers={stage.review.blockers}\n\t\t\t\t\t\t\t\t\tcheckName={checkName}\n\t\t\t\t\t\t\t\t\tonOpenContent={onOpenContent}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t\t\t{t(\"changeSet.review.releasesTitle\")}\n\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t{stage.review.releases.length === 0 ? (\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.noReleases\")}</Text>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Stack as=\"ul\" gap=\"1\" listStyleType=\"none\">\n\t\t\t\t\t\t\t\t\t{stage.review.releases.map((r) => (\n\t\t\t\t\t\t\t\t\t\t<Text as=\"li\" key={r.id} fontSize=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.releaseLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tcontent: r.contentId,\n\t\t\t\t\t\t\t\t\t\t\t\tkind: t(`changeSet.releases.kind.${r.kind}`),\n\t\t\t\t\t\t\t\t\t\t\t\tperiod: periodText(t, r.validityPeriod),\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\nconst refusalKey: Record<Refusal, string> = {\n\trefused: \"changeSet.review.refused\",\n\tclosed: \"changeSet.review.closed\",\n\twithheld: \"changeSet.review.withheld\",\n\tfailed: \"changeSet.review.failed\",\n};\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, TextareaField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { z } from \"zod\";\nimport {\n\tCHECK_NOTE_MAX,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tInvalidInputError,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckOutcome, CheckStanding } from \"../types\";\nimport { subjectText } from \"./change-set-checks-tab\";\n\ntype RecordValues = { outcome: CheckOutcome; note: string };\n\nconst EMPTY: RecordValues = { outcome: \"passed\", note: \"\" };\nconst FORM_ID = \"contenthub-record-check-result\";\nconst OUTCOMES = [\"passed\", \"failed\", \"waived\"] as const satisfies readonly CheckOutcome[];\n\nexport interface RecordCheckResultModalProps {\n\topen: boolean;\n\t/** The check and subject the result is about, latched while the dialog is open. */\n\tstanding: CheckStanding | null;\n\tonClose: () => void;\n\t/**\n\t * Records it against the standing's heads. Its typed rejections are\n\t * worded here; anything else is a generic failure.\n\t */\n\tonSubmit: (input: { outcome: CheckOutcome; note: string }) => Promise<void>;\n}\n\n/**\n * Records a Check Result: passed, failed, or waived with a note saying why\n * (ADR 0014). A waiver without a note never reaches the service: the form\n * refuses it first, as the service would.\n *\n * Kept mounted and driven by `open`, with `lazyMount unmountOnExit` (anker's\n * Modal rule); every opening resets the form.\n */\nexport function RecordCheckResultModal({\n\topen,\n\tstanding,\n\tonClose,\n\tonSubmit,\n}: RecordCheckResultModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst schema = useMemo(\n\t\t() =>\n\t\t\tz\n\t\t\t\t.object({\n\t\t\t\t\toutcome: z.enum(OUTCOMES),\n\t\t\t\t\tnote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.max(CHECK_NOTE_MAX, t(\"changeSet.checks.form.noteTooLong\", { max: CHECK_NOTE_MAX })),\n\t\t\t\t})\n\t\t\t\t.superRefine((v, ctx) => {\n\t\t\t\t\tif (v.outcome === \"waived\" && v.note.trim() === \"\") {\n\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\tcode: \"custom\",\n\t\t\t\t\t\t\tpath: [\"note\"],\n\t\t\t\t\t\t\tmessage: t(\"changeSet.checks.form.noteRequired\"),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t[t],\n\t);\n\tconst methods = useForm<RecordValues>({ resolver: zodResolver(schema), defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onSubmit({ outcome: values.outcome, note: values.note.trim() });\n\t\t} catch (err) {\n\t\t\tif (err instanceof StaleHeadError) setRefusal(t(\"changeSet.checks.form.stale\"));\n\t\t\telse if (err instanceof CheckResultDeniedError) {\n\t\t\t\tsetRefusal(`${t(\"changeSet.checks.form.denied\")} ${err.message}`);\n\t\t\t} else if (err instanceof ChangeSetClosedError) setRefusal(t(\"changeSet.checks.form.closed\"));\n\t\t\telse if (err instanceof InvalidInputError) setRefusal(err.message);\n\t\t\telse setRefusal(t(\"changeSet.checks.form.failed\"));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.checks.form.title\", { check: standing?.check.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"changeSet.checks.form.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{standing ? (\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"changeSet.checks.form.on\", { subject: subjectText(t, standing) })}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<RecordValues>\n\t\t\t\t\t\t\tname=\"outcome\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.checks.form.outcome\")}\n\t\t\t\t\t\t\toptions={OUTCOMES.map((o) => ({\n\t\t\t\t\t\t\t\tid: o,\n\t\t\t\t\t\t\t\tlabel: t(`changeSet.checks.outcome.${o}`),\n\t\t\t\t\t\t\t}))}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<TextareaField<RecordValues>\n\t\t\t\t\t\t\tname=\"note\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.checks.form.note\")}\n\t\t\t\t\t\t\thelperText={t(\"changeSet.checks.form.noteHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, StatusBadge, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { ContextRail } from \"@knkcs/anker/components\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs, Text } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate, usePageRail } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { GitMerge, Info, Save, Send, Trash2, Zap } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport {\n\tChangeSetClosedError,\n\ttype ChangeSetUpdateField,\n\ttype ContenthubClient,\n\tInvalidInputError,\n\tServiceUnavailableError,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n} from \"../client/contenthub-client\";\nimport { headsOf } from \"../common/heads\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, CheckStanding, PublishOutcome, StatusSource } from \"../types\";\nimport { DiscardChangeSetModal, UpdateFromMainModal } from \"./change-set-action-modals\";\nimport { ChangeSetChecksTab } from \"./change-set-checks-tab\";\nimport {\n\tbranchToOpen,\n\tChangeSetContentsTab,\n\ttype OpenBranchTarget,\n} from \"./change-set-contents-tab\";\nimport { ChangeSetGeneralTab, type GeneralValues, generalValuesOf } from \"./change-set-general-tab\";\nimport { ChangeSetReleasesTab } from \"./change-set-releases-tab\";\nimport { PublishReviewModal } from \"./publish-review-modal\";\nimport { RecordCheckResultModal } from \"./record-check-result-modal\";\n\nexport type { OpenBranchTarget } from \"./change-set-contents-tab\";\n\ntype Tab = \"general\" | \"contents\" | \"releases\" | \"checks\";\nconst TABS: Tab[] = [\"general\", \"contents\", \"releases\", \"checks\"];\n\n/** The rail's dialogs, which the screen renders (anker ADR 0004). */\ntype Dialog = \"publish\" | \"update\" | \"discard\" | \"record\";\nconst GENERAL: Tab = \"general\";\nconst NO_VALUES: GeneralValues = {\n\tname: \"\",\n\tsourceDate: \"\",\n\tsourceReference: \"\",\n\tstatus: \"\",\n\tassigneeIds: [],\n\tdependsOnIds: [],\n};\n\nexport interface ChangeSetPageProps {\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\t/**\n\t * statushub's labels and the status picker. Without it the status shows\n\t * as its slug and cannot be changed here (ADR 0020).\n\t */\n\tstatusSource?: StatusSource;\n\t/** Host navigation to the Branch editor, from a row of the Contents tab. */\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n\t/** Told after a Publish from the rail; the page stays, showing it published. */\n\tonPublished?: (outcome: PublishOutcome) => void;\n\t/** Told after a Discard from the rail; the page stays, showing it discarded. */\n\tonDiscarded?: (changeSetId: string) => void;\n}\n\n/**\n * A Change Set's page (spec #56, stories 102–106): General, Contents,\n * Releases and Checks, saved from the header's one Save (anker ADR 0004);\n * the rail holds what is done *to* it (Publish, Update from Main, Discard)\n * and what it is at a glance (readiness, status label, Source). Each rail\n * action opens a dialog the screen renders, since a rail node renders away\n * from the screen's providers.\n *\n * The draft registry is keyed by the Change Set, so moving to another one\n * starts clean rather than carrying the last one's dirty marks.\n */\nexport function ChangeSetPage(props: ChangeSetPageProps) {\n\treturn (\n\t\t<TabDirtyProvider key={props.changeSetId}>\n\t\t\t<ChangeSetEditor {...props} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\nChangeSetPage.displayName = \"ChangeSetPage\";\n\n/** Why the last Save stopped, in the words the page shows it with. */\ntype Refusal =\n\t| { kind: \"transition\"; from: string; to: string; reason: string; guarded: boolean }\n\t| { kind: \"staleStatus\"; current: string }\n\t| { kind: \"closed\" }\n\t| { kind: \"invalid\"; message: string }\n\t| { kind: \"unavailable\" }\n\t| { kind: \"failed\" };\n\n/**\n * The same ids, in any order: neither assignees nor dependencies mean\n * anything by their order, and the service may answer in another one.\n */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n\treturn a.length === b.length && a.every((id) => b.includes(id));\n}\n\n/** The draft as the service would store it: the name and the Source trimmed. */\nfunction trimmed(v: GeneralValues): GeneralValues {\n\treturn {\n\t\t...v,\n\t\tname: v.name.trim(),\n\t\tsourceDate: v.sourceDate.trim(),\n\t\tsourceReference: v.sourceReference.trim(),\n\t};\n}\n\n/** What of the name and the Source the draft changes, as `updateChangeSet`'s mask. */\nfunction updateMaskOf(base: ChangeSet, draft: GeneralValues): ChangeSetUpdateField[] {\n\tconst was = generalValuesOf(base);\n\tconst mask: ChangeSetUpdateField[] = [];\n\tif (draft.name !== was.name) mask.push(\"name\");\n\tif (draft.sourceDate !== was.sourceDate || draft.sourceReference !== was.sourceReference) {\n\t\tmask.push(\"source\");\n\t}\n\treturn mask;\n}\n\nfunction ChangeSetEditor({\n\tclient,\n\tchangeSetId,\n\tstatusSource,\n\tonOpenBranch,\n\tonPublished,\n\tonDiscarded,\n}: ChangeSetPageProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst statuses = useChangeSetStatuses(statusSource);\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\") as Tab | null;\n\tconst tab: Tab = tabParam && TABS.includes(tabParam) ? tabParam : GENERAL;\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.changeSet(changeSetId),\n\t\tqueryFn: () => client.getChangeSet(changeSetId),\n\t});\n\n\t// The BASELINE: the Change Set as the editor started from, moved only by\n\t// this page's own saves. Not the query's data: a refetch that brought a\n\t// colleague's status move would otherwise become the expected_status the\n\t// next Save names, and the compare-and-swap would pass exactly when it\n\t// exists to fail. Latched from the first answer, during render.\n\tconst [baseline, setBaseline] = useState<ChangeSet | null>(null);\n\tif (baseline === null && query.data) setBaseline(query.data);\n\tconst latest = useRef(baseline);\n\tlatest.current = baseline;\n\n\t// The General tab's draft, held here, above the tab, so it outlives the\n\t// tab's mount (anker ADR 0004).\n\tconst methods = useForm<GeneralValues>({ defaultValues: NO_VALUES });\n\tconst seeded = useRef(false);\n\tuseEffect(() => {\n\t\tif (baseline && !seeded.current) {\n\t\t\tseeded.current = true;\n\t\t\tmethods.reset(generalValuesOf(baseline));\n\t\t}\n\t}, [baseline, methods]);\n\tconst generalDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(GENERAL, generalDirty), [generalDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [saved, setSaved] = useState(false);\n\t// One Idempotency Key per attempt at the name and Source, sent again when\n\t// the same change is retried after a failure whose outcome is unknown, as\n\t// the Branch editor's Save does.\n\tconst { keyFor: updateKeyFor, settle: settleUpdateKey } = useAttemptKey(\"update-change-set\");\n\t// \"Saved\" speaks of the last Save only: a new edit retires it.\n\tuseEffect(() => {\n\t\tif (generalDirty) setSaved(false);\n\t}, [generalDirty]);\n\n\t/**\n\t * Persists every changed part of the draft, one RPC per kind of change:\n\t * the name and the Source in one UpdateChangeSet, dependencies, then\n\t * assignees, then the status, which statushub may refuse and so goes\n\t * last. A refusal stops there; what was saved before it becomes the new\n\t * baseline, and what wasn't stays in the draft.\n\t */\n\tconst saveAll = useCallback(async () => {\n\t\tconst base = latest.current;\n\t\tif (!base) return;\n\t\tconst draft = trimmed(methods.getValues());\n\t\tlet current = base;\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tconst updateMask = updateMaskOf(base, draft);\n\t\t\tif (updateMask.length > 0) {\n\t\t\t\t// Both Source fields empty is no Source: the masked source is\n\t\t\t\t// sent absent, which clears it.\n\t\t\t\tconst source =\n\t\t\t\t\tdraft.sourceDate === \"\" && draft.sourceReference === \"\"\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: { date: draft.sourceDate, reference: draft.sourceReference };\n\t\t\t\tconst asked = { id: base.id, updateMask, name: draft.name, source };\n\t\t\t\ttry {\n\t\t\t\t\tcurrent = await client.updateChangeSet({\n\t\t\t\t\t\t...asked,\n\t\t\t\t\t\tidempotencyKey: updateKeyFor(asked),\n\t\t\t\t\t});\n\t\t\t\t\tsettleUpdateKey();\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// A refusal is an answer: the next Save is a new attempt.\n\t\t\t\t\tif (isAnswer(err)) settleUpdateKey();\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const id of draft.dependsOnIds) {\n\t\t\t\tif (!base.dependsOnChangeSetIds.includes(id)) {\n\t\t\t\t\tcurrent = await client.addDependency({ id: base.id, dependsOnId: id });\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const id of base.dependsOnChangeSetIds) {\n\t\t\t\tif (!draft.dependsOnIds.includes(id)) {\n\t\t\t\t\tcurrent = await client.removeDependency({ id: base.id, dependsOnId: id });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!sameIds(draft.assigneeIds, base.assigneeIds)) {\n\t\t\t\tcurrent = await client.setChangeSetAssignees({\n\t\t\t\t\tid: base.id,\n\t\t\t\t\tassigneeIds: draft.assigneeIds,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (draft.status !== base.status) {\n\t\t\t\tcurrent = await client.setChangeSetStatus({\n\t\t\t\t\tid: base.id,\n\t\t\t\t\texpectedStatus: base.status,\n\t\t\t\t\tstatus: draft.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} catch (err) {\n\t\t\tif (err instanceof StatusTransitionRefusedError) {\n\t\t\t\tsetRefusal({\n\t\t\t\t\tkind: \"transition\",\n\t\t\t\t\tfrom: err.fromStatus,\n\t\t\t\t\tto: err.toStatus,\n\t\t\t\t\treason: err.reason,\n\t\t\t\t\tguarded: err.requiresPermission,\n\t\t\t\t});\n\t\t\t} else if (err instanceof StaleStatusError) {\n\t\t\t\t// The next Save moves from the status that is there now.\n\t\t\t\tcurrent = { ...current, status: err.currentStatus };\n\t\t\t\tsetRefusal({ kind: \"staleStatus\", current: err.currentStatus });\n\t\t\t} else if (err instanceof ChangeSetClosedError) {\n\t\t\t\tsetRefusal({ kind: \"closed\" });\n\t\t\t\tcurrent = await client.getChangeSet(base.id).catch(() => current);\n\t\t\t} else if (err instanceof ServiceUnavailableError) {\n\t\t\t\tsetRefusal({ kind: \"unavailable\" });\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal({ kind: \"invalid\", message: err.message });\n\t\t\t} else {\n\t\t\t\tsetRefusal({ kind: \"failed\" });\n\t\t\t}\n\t\t} finally {\n\t\t\t// The new baseline, with the unsaved rest of the draft laid back on\n\t\t\t// top of it, still dirty.\n\t\t\tconst next = generalValuesOf(current);\n\t\t\tmethods.reset(next);\n\t\t\tfor (const key of Object.keys(next) as (keyof GeneralValues)[]) {\n\t\t\t\tconst wanted = draft[key];\n\t\t\t\tconst same = Array.isArray(wanted)\n\t\t\t\t\t? sameIds(wanted, next[key] as string[])\n\t\t\t\t\t: wanted === next[key];\n\t\t\t\tif (!same) methods.setValue(key, wanted, { shouldDirty: true });\n\t\t\t}\n\t\t\tlatest.current = current;\n\t\t\tsetBaseline(current);\n\t\t\tqueryClient.setQueryData(contenthubKeys.changeSet(changeSetId), current);\n\t\t\t// The lists only: the detail was just written from the answer.\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSetLists() });\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [client, changeSetId, methods, queryClient, updateKeyFor, settleUpdateKey]);\n\n\t// The freshest Change Set: its Chains, heads and state are no draft.\n\tconst fresh = query.data ?? baseline;\n\tconst isOpen = fresh?.state === \"open\";\n\tconst freshHeads = useMemo(() => (fresh ? headsOf(fresh) : {}), [fresh]);\n\n\t// The rail's readiness tile is ValidatePublish at the current heads: the\n\t// same answer the Publish review starts from.\n\tconst readiness = useQuery({\n\t\tqueryKey: contenthubKeys.publishReadinessAt(changeSetId, freshHeads),\n\t\tqueryFn: () => client.validatePublish({ id: changeSetId, reviewedHeads: freshHeads }),\n\t\tenabled: isOpen,\n\t});\n\tconst standings = useQuery({\n\t\tqueryKey: contenthubKeys.checkStandings(changeSetId),\n\t\tqueryFn: () => client.listCheckResults(changeSetId),\n\t\tenabled: !!fresh,\n\t});\n\tconst checkNames = useMemo(() => {\n\t\tconst names = new Map<string, string>();\n\t\tfor (const st of standings.data ?? []) names.set(st.check.id, st.check.name);\n\t\treturn names;\n\t}, [standings.data]);\n\tconst checkName = useCallback((id: string) => checkNames.get(id) ?? id, [checkNames]);\n\n\tconst [dialog, setDialog] = useState<Dialog | null>(null);\n\t// The row a Record dialog is about, latched while it is open.\n\tconst [recording, setRecording] = useState<CheckStanding | null>(null);\n\tconst closeDialog = useCallback(() => setDialog(null), []);\n\n\t/** Everything that depends on the heads, asked again. */\n\tconst refreshReview = useCallback(() => {\n\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.publishReadiness(changeSetId) });\n\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.checkStandings(changeSetId) });\n\t}, [queryClient, changeSetId]);\n\n\t/** A Change Set the service just read: what depends on its heads asks again. */\n\tconst reviewed = useCallback(\n\t\t(next: ChangeSet) => {\n\t\t\tqueryClient.setQueryData(contenthubKeys.changeSet(changeSetId), next);\n\t\t\trefreshReview();\n\t\t},\n\t\t[queryClient, changeSetId, refreshReview],\n\t);\n\n\t/**\n\t * A Change Set a rail action answered with. Its state reaches the\n\t * baseline (the header shows it published or discarded); the General\n\t * fields don't: the baseline's status is the next Save's expected_status,\n\t * and taking a colleague's move from here would let that Save pass the\n\t * compare-and-swap it exists to fail.\n\t */\n\tconst adopt = useCallback(\n\t\t(next: ChangeSet) => {\n\t\t\treviewed(next);\n\t\t\tconst base = latest.current;\n\t\t\tconst kept = base\n\t\t\t\t? {\n\t\t\t\t\t\t...next,\n\t\t\t\t\t\tname: base.name,\n\t\t\t\t\t\tsource: base.source,\n\t\t\t\t\t\tstatus: base.status,\n\t\t\t\t\t\tassigneeIds: base.assigneeIds,\n\t\t\t\t\t\tdependsOnChangeSetIds: base.dependsOnChangeSetIds,\n\t\t\t\t\t}\n\t\t\t\t: next;\n\t\t\tlatest.current = kept;\n\t\t\tsetBaseline(kept);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSetLists() });\n\t\t},\n\t\t[queryClient, reviewed],\n\t);\n\n\tconst published = useCallback(\n\t\t(outcome: PublishOutcome) => {\n\t\t\tsetDialog(null);\n\t\t\tadopt(outcome.changeSet);\n\t\t\tonPublished?.(outcome);\n\t\t},\n\t\t[adopt, onPublished],\n\t);\n\tconst updateFromMain = useCallback(async () => {\n\t\tconst outcome = await client.updateFromMain({ id: changeSetId });\n\t\tadopt(outcome.changeSet);\n\t\treturn outcome;\n\t}, [client, changeSetId, adopt]);\n\tconst discard = useCallback(async () => {\n\t\tadopt(await client.discardChangeSet(changeSetId));\n\t\tsetDialog(null);\n\t\tonDiscarded?.(changeSetId);\n\t}, [client, changeSetId, adopt, onDiscarded]);\n\tconst record = useCallback(\n\t\tasync ({\n\t\t\toutcome,\n\t\t\tnote,\n\t\t}: {\n\t\t\toutcome: CheckStanding[\"results\"][number][\"outcome\"];\n\t\t\tnote: string;\n\t\t}) => {\n\t\t\tif (!recording) return;\n\t\t\ttry {\n\t\t\t\tawait client.recordCheckResult({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\trequiredCheckId: recording.check.id,\n\t\t\t\t\t// The heads the row showed: a save since is the service's to refuse.\n\t\t\t\t\theads: recording.heads,\n\t\t\t\t\toutcome,\n\t\t\t\t\tnote,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\t// The rows behind the dialog show the new heads by the time it closes.\n\t\t\t\tif (err instanceof StaleHeadError) {\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\t\trefreshReview();\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tsetDialog(null);\n\t\t\trefreshReview();\n\t\t},\n\t\t[client, changeSetId, recording, refreshReview, queryClient],\n\t);\n\tconst openRecord = useCallback((st: CheckStanding) => {\n\t\tsetRecording(st);\n\t\tsetDialog(\"record\");\n\t}, []);\n\n\tconst blockerCount = readiness.data?.blockers.length;\n\tconst railStatus = fresh ? statuses.labelOf(fresh.status) : undefined;\n\t// The rail closes over this screen's state and reads no context: the host\n\t// draws it away from the screen's providers (anker's host contract).\n\tusePageRail(\n\t\tfresh ? (\n\t\t\t<ContextRail storageKey=\"contenthub-change-set\">\n\t\t\t\t<ContextRail.Header eyebrow={t(\"changeSet.rail.eyebrow\")} title={fresh.name} />\n\t\t\t\t{isOpen ? (\n\t\t\t\t\t<ContextRail.Section\n\t\t\t\t\t\tid=\"actions\"\n\t\t\t\t\t\ticon={<Zap size={16} />}\n\t\t\t\t\t\tlabel={t(\"changeSet.rail.actions\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.publish\")}\n\t\t\t\t\t\t\ticon={<Send size={16} />}\n\t\t\t\t\t\t\ttone=\"primary\"\n\t\t\t\t\t\t\tonClick={() => setDialog(\"publish\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.updateFromMain\")}\n\t\t\t\t\t\t\ticon={<GitMerge size={16} />}\n\t\t\t\t\t\t\tonClick={() => setDialog(\"update\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.discard\")}\n\t\t\t\t\t\t\ticon={<Trash2 size={16} />}\n\t\t\t\t\t\t\ttone=\"outline-red\"\n\t\t\t\t\t\t\tonClick={() => setDialog(\"discard\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ContextRail.Section>\n\t\t\t\t) : null}\n\t\t\t\t<ContextRail.Section id=\"about\" icon={<Info size={16} />} label={t(\"changeSet.rail.about\")}>\n\t\t\t\t\t{isOpen ? (\n\t\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\t\tkeepWhenEmpty\n\t\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\t\treadiness.isError\n\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.unknownReadiness\")\n\t\t\t\t\t\t\t\t\t: blockerCount === undefined\n\t\t\t\t\t\t\t\t\t\t? \"…\"\n\t\t\t\t\t\t\t\t\t\t: blockerCount === 0\n\t\t\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.ready\")\n\t\t\t\t\t\t\t\t\t\t\t: blockerCount\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlabel={\n\t\t\t\t\t\t\t\tblockerCount\n\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.blockers\", { count: blockerCount })\n\t\t\t\t\t\t\t\t\t: t(\"changeSet.rail.readiness\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\t\tvalue={t(`changeSets.state.${fresh.state}`)}\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.state\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\tkeepWhenEmpty\n\t\t\t\t\t\tvalue={railStatus?.name ?? t(\"changeSet.rail.noStatus\")}\n\t\t\t\t\t\tlabel={t(\"changeSet.rail.status\")}\n\t\t\t\t\t\tmuted={!railStatus}\n\t\t\t\t\t/>\n\t\t\t\t\t<Stack gap=\"0\" mt=\"2\">\n\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t\t{t(\"changeSet.rail.source\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t<Text fontSize=\"sm\">\n\t\t\t\t\t\t\t{fresh.source\n\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\tdate: fresh.source.date,\n\t\t\t\t\t\t\t\t\t\treference: fresh.source.reference,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: t(\"changeSet.rail.noSource\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Stack>\n\t\t\t\t</ContextRail.Section>\n\t\t\t</ContextRail>\n\t\t) : null,\n\t);\n\n\tconst changeSet = baseline;\n\tif (!changeSet) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\"), to: paths.changeSets }]}\n\t\t\t\ttitle={query.isError ? t(\"changeSet.unavailable\") : t(\"changeSet.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\ttitle={notFound ? t(\"changeSet.notFound\") : t(\"changeSet.loadError\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\tconst changed = dirtyTabs.length;\n\tconst status = statuses.labelOf(changeSet.status);\n\tconst selectTab = (next: Tab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params, { replace: true });\n\t};\n\tconst contents = fresh ?? changeSet;\n\t/** A blocker's Content, opened where it is fixed: the Branch its Chain's row opens. */\n\tconst openContent = (contentId: string) => {\n\t\tconst chain = contents.chains.find((c) => c.contentId === contentId);\n\t\tif (!chain) return;\n\t\tcloseDialog();\n\t\tonOpenBranch({ changeSetId: contents.id, contentId, branchId: branchToOpen(chain) });\n\t};\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"changeSets.title\"), to: paths.changeSets },\n\t\t\t\t{ label: changeSet.name },\n\t\t\t]}\n\t\t\ttitle={changeSet.name}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t<TypeBadge\n\t\t\t\t\t\tname={t(`changeSets.state.${changeSet.state}`)}\n\t\t\t\t\t\tcolorPalette={changeSet.state === \"open\" ? \"blue\" : \"gray\"}\n\t\t\t\t\t/>\n\t\t\t\t\t{status ? <StatusBadge label={status.name} color={status.color ?? \"gray\"} /> : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\tdisabled={changed === 0}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void saveAll()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"changeSet.save\") : t(\"changeSet.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => selectTab(e.value as Tab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(`changeSet.tabs.${each}`)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{refusal ? <RefusalAlert refusal={refusal} labelOf={statuses.labelOf} /> : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"changeSet.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t{tab === \"general\" ? (\n\t\t\t\t\t<ChangeSetGeneralTab client={client} changeSet={changeSet} statuses={statuses} />\n\t\t\t\t) : null}\n\t\t\t</FormProvider>\n\t\t\t{tab === \"contents\" ? (\n\t\t\t\t<ChangeSetContentsTab changeSet={contents} onOpenBranch={onOpenBranch} />\n\t\t\t) : null}\n\t\t\t{tab === \"releases\" ? (\n\t\t\t\t<ChangeSetReleasesTab changeSet={contents} blockers={readiness.data?.blockers ?? []} />\n\t\t\t) : null}\n\t\t\t{tab === \"checks\" ? (\n\t\t\t\t<ChangeSetChecksTab\n\t\t\t\t\tstandings={standings.data ?? []}\n\t\t\t\t\tloading={standings.isPending}\n\t\t\t\t\tfailed={standings.isError}\n\t\t\t\t\tcanRecord={contents.state === \"open\"}\n\t\t\t\t\tonRecord={openRecord}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<PublishReviewModal\n\t\t\t\topen={dialog === \"publish\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSet={contents}\n\t\t\t\tcheckName={checkName}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonPublished={published}\n\t\t\t\tonReviewed={reviewed}\n\t\t\t\tonOpenContent={openContent}\n\t\t\t/>\n\t\t\t<UpdateFromMainModal\n\t\t\t\topen={dialog === \"update\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={updateFromMain}\n\t\t\t/>\n\t\t\t<DiscardChangeSetModal\n\t\t\t\topen={dialog === \"discard\"}\n\t\t\t\tname={contents.name}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={discard}\n\t\t\t/>\n\t\t\t<RecordCheckResultModal\n\t\t\t\topen={dialog === \"record\"}\n\t\t\t\tstanding={recording}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonSubmit={record}\n\t\t\t/>\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"changeSet.leave.title\")}\n\t\t\t\tmessage={t(\"changeSet.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"changeSet.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"changeSet.leave.cancel\")}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n\nfunction RefusalAlert({\n\trefusal,\n\tlabelOf,\n}: {\n\trefusal: Refusal;\n\tlabelOf: (slug: string) => { name: string } | undefined;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst name = (slug: string) => labelOf(slug)?.name ?? t(\"changeSet.general.noStatus\");\n\tswitch (refusal.kind) {\n\t\tcase \"transition\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(refusal.guarded ? \"changeSet.refused.guarded\" : \"changeSet.refused.transition\", {\n\t\t\t\t\t\tfrom: name(refusal.from),\n\t\t\t\t\t\tto: name(refusal.to),\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t{refusal.reason}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"staleStatus\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\ttitle={t(\"changeSet.refused.staleStatus\", { current: name(refusal.current) })}\n\t\t\t\t/>\n\t\t\t);\n\t\tcase \"unavailable\":\n\t\t\treturn <Alert status=\"warning\" title={t(\"changeSet.refused.unavailable\")} />;\n\t\tcase \"closed\":\n\t\t\treturn <Alert status=\"error\" title={t(\"changeSet.refused.closed\")} />;\n\t\tcase \"invalid\":\n\t\t\treturn (\n\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.refused.invalid\")}>\n\t\t\t\t\t{refusal.message}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn <Alert status=\"error\" title={t(\"changeSet.refused.failed\")} />;\n\t}\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tDataTable,\n\tDateCell,\n\tStatusBadgeCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, NativeSelect, Stack } from \"@knkcs/anker/primitives\";\nimport { IndexPageTemplate } from \"@knkcs/anker/templates\";\nimport { keepPreviousData, useInfiniteQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FolderGit2, Plus } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, ChangeSetState, StatusSource } from \"../types\";\nimport { CreateChangeSetModal } from \"./create-change-set-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype ChangeSetRow = ChangeSet & Record<string, unknown>;\n\nconst STATES: ChangeSetState[] = [\"open\", \"published\", \"discarded\"];\n/** The toolbar's \"me\" filter, distinct from any user id. */\nconst ME = \"@me\";\n/** Change Sets per page; \"Show more\" asks for the next. */\nconst PAGE_SIZE = 50;\n\nexport interface ChangeSetsIndexProps {\n\tclient: ContenthubClient;\n\t/**\n\t * statushub's labels for the status column. Without it the column shows\n\t * the bare slug (ADR 0020).\n\t */\n\tstatusSource?: StatusSource;\n\t/** Host navigation to a Change Set's page: a row's click, and a new one once created. */\n\tonOpenChangeSet: (changeSetId: string) => void;\n}\n\n/**\n * The workspace's Change Sets, newest first, narrowed by state and by who\n * is assigned (spec #56, story 101), created from the header in a Modal\n * (anker: no inline create form above a DataTable). Creating one opens its\n * page, where the work happens.\n */\nexport function ChangeSetsIndex({ client, statusSource, onOpenChangeSet }: ChangeSetsIndexProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst { userId, members } = useHostIdentity();\n\tconst statuses = useChangeSetStatuses(statusSource);\n\tconst [creating, setCreating] = useState(false);\n\t// Open work is what an editor comes here for.\n\tconst [state, setState] = useState<ChangeSetState | \"\">(\"open\");\n\tconst [assignee, setAssignee] = useState(\"\");\n\n\tconst filter = useMemo(\n\t\t() => ({\n\t\t\tstate: state || undefined,\n\t\t\tassigneeId: assignee === ME ? userId : assignee || undefined,\n\t\t}),\n\t\t[state, assignee, userId],\n\t);\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.changeSetList(filter),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listChangeSets({ ...filter, pageSize: PAGE_SIZE, pageToken: pageParam }),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t\t// A filter change keeps the rows on screen until the new ones arrive.\n\t\tplaceholderData: keepPreviousData,\n\t});\n\tconst changeSets = useMemo(\n\t\t() => query.data?.pages.flatMap((page) => page.changeSets) ?? [],\n\t\t[query.data],\n\t);\n\n\t// An assignee who is no longer a member is still shown, by id.\n\tconst nameOf = useCallback((id: string) => members.byId(id)?.displayName ?? id, [members]);\n\n\tconst columns = useMemo<ColumnDef<ChangeSetRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"changeSets.columns.name\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst source = row.original.source;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\t\tsource\n\t\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", { date: source.date, reference: source.reference })\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"state\",\n\t\t\t\theader: t(\"changeSets.columns.state\"),\n\t\t\t\tcell: ({ row }) => <StatusBadgeCell value={t(`changeSets.state.${row.original.state}`)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"status\",\n\t\t\t\theader: t(\"changeSets.columns.status\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst label = statuses.labelOf(row.original.status);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\t\tvalue={label?.name ?? null}\n\t\t\t\t\t\t\tcolorMap={label?.color ? { [label.name]: label.color } : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"assignees\",\n\t\t\t\theader: t(\"changeSets.columns.assignees\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.assigneeIds.map(nameOf).join(\", \") || null}\n\t\t\t\t\t\tmaxLength={60}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"created\",\n\t\t\t\theader: t(\"changeSets.columns.created\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t],\n\t\t[t, statuses, nameOf],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setCreating(true)}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"changeSets.create\")}\n\t\t</Button>\n\t);\n\n\treturn (\n\t\t<IndexPageTemplate\n\t\t\ttitle={t(\"changeSets.title\")}\n\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\") }]}\n\t\t\tactions={createButton}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Filters>\n\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label={t(\"changeSets.filter.state\")}\n\t\t\t\t\t\t\tvalue={state}\n\t\t\t\t\t\t\tonChange={(e) => setState(e.target.value as ChangeSetState | \"\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<option value=\"\">{t(\"changeSets.filter.anyState\")}</option>\n\t\t\t\t\t\t\t{STATES.map((s) => (\n\t\t\t\t\t\t\t\t<option key={s} value={s}>\n\t\t\t\t\t\t\t\t\t{t(`changeSets.state.${s}`)}\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label={t(\"changeSets.filter.assignee\")}\n\t\t\t\t\t\t\tvalue={assignee}\n\t\t\t\t\t\t\tonChange={(e) => setAssignee(e.target.value)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<option value=\"\">{t(\"changeSets.filter.anyone\")}</option>\n\t\t\t\t\t\t\t<option value={ME}>{t(\"changeSets.filter.me\")}</option>\n\t\t\t\t\t\t\t{members\n\t\t\t\t\t\t\t\t.list()\n\t\t\t\t\t\t\t\t.filter((m) => m.userId !== userId)\n\t\t\t\t\t\t\t\t.map((m) => (\n\t\t\t\t\t\t\t\t\t<option key={m.userId} value={m.userId}>\n\t\t\t\t\t\t\t\t\t\t{m.displayName}\n\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t</Toolbar.Filters>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<Toolbar.Count>\n\t\t\t\t\t\t\t{t(\"changeSets.count\", { count: changeSets.length })}\n\t\t\t\t\t\t\t{query.hasNextPage ? \"+\" : \"\"}\n\t\t\t\t\t\t</Toolbar.Count>\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{query.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSets.loadError\")} mx=\"8\" mt=\"4\" />\n\t\t\t\t) : null}\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={changeSets as ChangeSetRow[]}\n\t\t\t\t\tloading={query.isLoading}\n\t\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\t\tonRowClick={(row) => onOpenChangeSet(row.id)}\n\t\t\t\t\tvariant=\"hoverable\"\n\t\t\t\t\temptyState={\n\t\t\t\t\t\t<EmptyState\n\t\t\t\t\t\t\ticon={<FolderGit2 size={32} />}\n\t\t\t\t\t\t\theader={t(\"changeSets.empty\")}\n\t\t\t\t\t\t\tdescription={t(\"changeSets.emptyHint\")}\n\t\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t\t{query.hasNextPage ? (\n\t\t\t\t\t<HStack justify=\"center\" pb=\"4\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tloading={query.isFetchingNextPage}\n\t\t\t\t\t\t\tonClick={() => void query.fetchNextPage()}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"changeSets.more\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t\t{/* Rendered by the screen, never inside the reported header action:\n\t\t\t a host draws that action outside these providers (anker). */}\n\t\t\t<CreateChangeSetModal\n\t\t\t\topen={creating}\n\t\t\t\tonClose={() => setCreating(false)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tconst created = await client.createChangeSet(input);\n\t\t\t\t\tsetCreating(false);\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\t\t\tonOpenChangeSet(created.id);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</IndexPageTemplate>\n\t);\n}\n\nChangeSetsIndex.displayName = \"ChangeSetsIndex\";\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentAttributes } from \"../types\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nexport interface ArchiveContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** The Content was archived: its attributes now. */\n\tonArchived: (attributes: ContentAttributes) => void;\n}\n\n/**\n * Archive's confirmation (spec #56, story 92): archiving puts the Content\n * aside, out of the Library, every picker and editing, so it asks first.\n * Its Releases stay readable and every pin to them keeps resolving (ADR\n * 0015), and Unarchive brings it back.\n */\nexport function ArchiveContentModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tonArchived,\n}: ArchiveContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [busy, setBusy] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (open) setRefusal(null);\n\t}, [open]);\n\n\tasync function confirm() {\n\t\tsetBusy(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tonArchived(await client.archiveContent(contentId));\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"sm\"\n\t\t\theader={t(\"content.archive.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"content.archive.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t<Text>{t(\"content.archive.message\")}</Text>\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Link, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { Link as RouterLink } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubSettingsPath, useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentAttributes, ContentBlock } from \"../types\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-block-content\";\n\ntype BlockValues = { blockReasonId: string | null; allowedUserIds: string[] };\n\nexport interface BlockContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** The Block it has, which a new one replaces; absent while it has none. */\n\tcurrent?: ContentBlock;\n\t/** The Content was blocked: its attributes now. */\n\tonBlocked: (attributes: ContentAttributes) => void;\n}\n\n/**\n * Block (spec #56, story 92; CONTEXT.md, Block): one of the workspace's\n * Block Reasons and who may still edit it. Blocking a blocked Content\n * replaces its Block. Like filing, it is no save and writes no Revision.\n */\nexport function BlockContentModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tcurrent,\n\tonBlocked,\n}: BlockContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst reasons = useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t\tenabled: open,\n\t});\n\tconst empty = useMemo<BlockValues>(\n\t\t() => ({\n\t\t\tblockReasonId: current?.blockReasonId ?? null,\n\t\t\tallowedUserIds: [...(current?.allowedUserIds ?? [])],\n\t\t}),\n\t\t[current],\n\t);\n\tconst methods = useForm<BlockValues>({ defaultValues: empty });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(empty);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods, empty]);\n\n\tconst reasonOptions = useMemo<BaseOption[]>(\n\t\t() => (reasons.data ?? []).map((r) => ({ id: r.id, label: r.name })),\n\t\t[reasons.data],\n\t);\n\tconst userOptions = useMemo<BaseOption[]>(\n\t\t() => members.list().map((m) => ({ id: m.userId, label: m.displayName })),\n\t\t[members],\n\t);\n\tconst noReasons = reasons.isSuccess && reasons.data.length === 0;\n\tconst paths = useContenthubPaths();\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tif (!values.blockReasonId) {\n\t\t\tmethods.setError(\"blockReasonId\", { message: t(\"content.block.reasonRequired\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tonBlocked(\n\t\t\t\tawait client.blockContent({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tblockReasonId: values.blockReasonId,\n\t\t\t\t\tallowedUserIds: values.allowedUserIds,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.block.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\tform={FORM_ID}\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tloading={submitting}\n\t\t\t\t\t\tdisabled={noReasons}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"content.block.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{noReasons ? (\n\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"content.block.noReasons\")}>\n\t\t\t\t\t\t\t\t<Link asChild>\n\t\t\t\t\t\t\t\t\t<RouterLink to={contenthubSettingsPath(paths, \"block-reasons\")}>\n\t\t\t\t\t\t\t\t\t\t{t(\"content.block.openBlockReasons\")}\n\t\t\t\t\t\t\t\t\t</RouterLink>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</Alert>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<BlockValues>\n\t\t\t\t\t\t\tname=\"blockReasonId\"\n\t\t\t\t\t\t\tlabel={t(\"content.block.reason\")}\n\t\t\t\t\t\t\thelperText={t(\"content.block.reasonHelp\")}\n\t\t\t\t\t\t\toptions={reasonOptions}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<BaseSelectField<BlockValues>\n\t\t\t\t\t\t\tname=\"allowedUserIds\"\n\t\t\t\t\t\t\tlabel={t(\"content.block.allowed\")}\n\t\t\t\t\t\t\thelperText={t(\"content.block.allowedHelp\")}\n\t\t\t\t\t\t\toptions={userOptions}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DateCell, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useInfiniteQuery, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { History } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, CompareBase, Content, FieldChange, Revision } from \"../types\";\nimport { valueText } from \"./content-data-tab\";\n\ntype RevisionRow = Revision & Record<string, unknown>;\ntype ChangeRow = FieldChange & Record<string, unknown>;\n\n/** Revisions read at once; a Content with a longer history shows more on request. */\nconst REVISIONS_PAGE = 100;\n\n/** Every Change Set with a Chain on the Content, whatever its state. */\nexport function useContentChangeSets(client: ContenthubClient, contentId: string) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.contentChangeSets(contentId),\n\t\tqueryFn: () => client.listChangeSets({ contentId, pageSize: 200 }),\n\t});\n}\n\n/**\n * The Revisions tab (spec #56, story 90): who wrote what, when and why,\n * newest first, and how a chosen Revision differs from the one it was built\n * on (Compare). A published Content lists every Revision on every Branch;\n * Content born in an open Change Set, which versionkit can't list by Item\n * until it is published, lists its Branch's (#65). Revisions written in a\n * Change Set since discarded stay in history, and are marked so.\n */\nexport function ContentRevisionsTab({\n\tclient,\n\tcontent,\n\tpublished,\n}: {\n\tclient: ContenthubClient;\n\tcontent: Content;\n\t/** Whether it has a Main Branch, which a first Revision is compared against. */\n\tpublished: boolean;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst target = useMemo(\n\t\t() =>\n\t\t\tpublished || !content.branchId ? { contentId: content.id } : { branchId: content.branchId },\n\t\t[published, content.branchId, content.id],\n\t);\n\tconst revisions = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.contentRevisions(content.id, target),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listRevisions({ target, pageSize: REVISIONS_PAGE, pageToken: pageParam }),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t});\n\tconst rows = useMemo(\n\t\t() => (revisions.data?.pages ?? []).flatMap((p) => p.revisions) as RevisionRow[],\n\t\t[revisions.data],\n\t);\n\tconst changeSets = useContentChangeSets(client, content.id);\n\tconst [selected, setSelected] = useState<Revision | null>(null);\n\n\tconst changeSetOf = useCallback(\n\t\t(id: string): ChangeSet | undefined => changeSets.data?.changeSets.find((cs) => cs.id === id),\n\t\t[changeSets.data],\n\t);\n\n\tconst columns = useMemo<ColumnDef<RevisionRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"revision\",\n\t\t\t\theader: t(\"content.revisions.columns.revision\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.id} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"written\",\n\t\t\t\theader: t(\"content.revisions.columns.written\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"author\",\n\t\t\t\theader: t(\"content.revisions.columns.author\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={members.byId(row.original.author)?.displayName ?? row.original.author}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"cause\",\n\t\t\t\theader: t(\"content.revisions.columns.cause\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.revisions.cause.${row.original.cause}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"changeSet\",\n\t\t\t\theader: t(\"content.revisions.columns.changeSet\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst cs = changeSetOf(row.original.changeSetId);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={cs?.name ?? row.original.changeSetId}\n\t\t\t\t\t\t\tsubText={cs?.state === \"discarded\" ? t(\"content.revisions.discarded\") : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[t, members, changeSetOf],\n\t);\n\n\tif (revisions.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.revisions.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!revisions.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={rows}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\tvariant=\"hoverable\"\n\t\t\t\tonRowClick={(row) => setSelected(row)}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState icon={<History size={32} />} header={t(\"content.revisions.empty\")} />\n\t\t\t\t}\n\t\t\t/>\n\t\t\t{revisions.hasNextPage ? (\n\t\t\t\t<Box px=\"8\" py=\"3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tloading={revisions.isFetchingNextPage}\n\t\t\t\t\t\tonClick={() => void revisions.fetchNextPage()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"library.more\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</Box>\n\t\t\t) : null}\n\t\t\t{selected ? (\n\t\t\t\t<RevisionComparison\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontentId={content.id}\n\t\t\t\t\trevision={selected}\n\t\t\t\t\tpublished={published}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<Box px=\"8\" py=\"4\">\n\t\t\t\t\t<Alert status=\"info\" title={t(\"content.revisions.pickToCompare\")} />\n\t\t\t\t</Box>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * Compare: how a Revision differs from the one it was built on, or for a\n * Content's first Revision from Main's head. It only displays; it never\n * decides a merge.\n */\nfunction RevisionComparison({\n\tclient,\n\tcontentId,\n\trevision,\n\tpublished,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\trevision: Revision;\n\tpublished: boolean;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst base: CompareBase | null = revision.parentId\n\t\t? { kind: \"revision\", revisionId: revision.parentId }\n\t\t: published\n\t\t\t? { kind: \"main_head\" }\n\t\t\t: null;\n\tconst comparison = useQuery({\n\t\tqueryKey: contenthubKeys.contentCompare(contentId, revision.id, base ?? {}),\n\t\tqueryFn: () => client.compare({ revisionId: revision.id, base: base as CompareBase }),\n\t\tenabled: base !== null,\n\t});\n\tconst columns = useMemo<ColumnDef<ChangeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"field\",\n\t\t\t\theader: t(\"content.compare.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.compare.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.compare.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"before\",\n\t\t\t\theader: t(\"content.compare.columns.before\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.before)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"after\",\n\t\t\t\theader: t(\"content.compare.columns.after\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.after)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">\n\t\t\t\t\t{base?.kind === \"revision\"\n\t\t\t\t\t\t? t(\"content.compare.titleParent\", { revision: revision.id, base: base.revisionId })\n\t\t\t\t\t\t: base?.kind === \"main_head\"\n\t\t\t\t\t\t\t? t(\"content.compare.titleMain\", { revision: revision.id })\n\t\t\t\t\t\t\t: t(\"content.compare.title\", { revision: revision.id })}\n\t\t\t\t</Heading>\n\t\t\t</Box>\n\t\t\t{base === null ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"info\" title={t(\"content.compare.nothing\")} />\n\t\t\t\t</Box>\n\t\t\t) : comparison.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.compare.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : !comparison.data ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={comparison.data.changes as ChangeRow[]}\n\t\t\t\t\tgetRowId={(row) => row.path}\n\t\t\t\t\temptyState={<EmptyState header={t(\"content.compare.same\")} />}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { CountCell, DataTable, DateCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { GitBranch } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet } from \"../types\";\nimport { useContentChangeSets } from \"./content-revisions-tab\";\n\ntype ChangeSetRow = ChangeSet & Record<string, unknown>;\n\n/**\n * The Change Sets tab (spec #56, story 90): the open Change Sets with a\n * Chain on this Content, newest first: the work in progress on it. A table,\n * so flush.\n */\nexport function ContentChangeSetsTab({\n\tclient,\n\tcontentId,\n\tonOpenChangeSet,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Host navigation to a Change Set's page; without it, rows don't open. */\n\tonOpenChangeSet?: (changeSetId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst query = useContentChangeSets(client, contentId);\n\tconst open = useMemo(\n\t\t() => (query.data?.changeSets ?? []).filter((cs) => cs.state === \"open\") as ChangeSetRow[],\n\t\t[query.data],\n\t);\n\tconst columns = useMemo<ColumnDef<ChangeSetRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"changeSets.columns.name\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\trow.original.source\n\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\tdate: row.original.source.date,\n\t\t\t\t\t\t\t\t\t\treference: row.original.source.reference,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"assignees\",\n\t\t\t\theader: t(\"changeSet.general.assignees\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<CountCell\n\t\t\t\t\t\tvalue={row.original.assigneeIds}\n\t\t\t\t\t\tsingular={t(\"content.changeSets.assignee\")}\n\t\t\t\t\t\tplural={t(\"content.changeSets.assignees\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"created\",\n\t\t\t\theader: t(\"content.changeSets.opened\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\tif (query.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.changeSets.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!query.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={open}\n\t\t\tgetRowId={(row) => row.id}\n\t\t\tvariant={onOpenChangeSet ? \"hoverable\" : undefined}\n\t\t\tonRowClick={onOpenChangeSet ? (row) => onOpenChangeSet(row.id) : undefined}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<GitBranch size={32} />}\n\t\t\t\t\theader={t(\"content.changeSets.empty\")}\n\t\t\t\t\tdescription={t(\"content.changeSets.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Card } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Box, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection, ContentAttributes } from \"../types\";\n\n/** The Filing tab's draft: a Content's unversioned attributes that its page changes. */\nexport interface FilingValues {\n\tcollectionIds: string[];\n\tassigneeIds: string[];\n}\n\nexport function filingValuesOf(a: ContentAttributes): FilingValues {\n\treturn { collectionIds: [...a.collectionIds], assigneeIds: [...a.assigneeIds] };\n}\n\n/** A Collection by its path from the root, \"Laws / BGB\", so two of one name are told apart. */\nfunction pathOf(c: Collection, all: Collection[]): string {\n\tconst names = [c.name];\n\tconst seen = new Set([c.id]);\n\tlet parent = all.find((p) => p.id === c.parentId);\n\twhile (parent && !seen.has(parent.id)) {\n\t\tnames.unshift(parent.name);\n\t\tseen.add(parent.id);\n\t\tparent = all.find((p) => p.id === parent?.parentId);\n\t}\n\treturn names.join(\" / \");\n}\n\n/**\n * The Filing tab (spec #56, story 91): the Collections a Content is filed\n * in and who maintains it. Unversioned attributes (ADR 0015): the header's\n * Save sets them, and never writes a Revision. The draft is the page's\n * form, held above the tab, so it survives switching tabs.\n */\nexport function ContentFilingTab({\n\tclient,\n\tattributes,\n}: {\n\tclient: ContenthubClient;\n\tattributes: ContentAttributes;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst collections = useQuery({\n\t\tqueryKey: contenthubKeys.collections(),\n\t\tqueryFn: () => client.listCollections(),\n\t});\n\t// A Collection the reader can't see (restricted, ADR 0017) stays listed by\n\t// id, so saving never unfiles it by accident.\n\tconst collectionOptions = useMemo<BaseOption[]>(() => {\n\t\tconst all = collections.data ?? [];\n\t\tconst known = all\n\t\t\t.map((c) => ({ id: c.id, label: pathOf(c, all) }))\n\t\t\t.sort((a, b) => a.label.localeCompare(b.label));\n\t\tconst unknown = attributes.collectionIds\n\t\t\t.filter((id) => !all.some((c) => c.id === id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [collections.data, attributes.collectionIds]);\n\tconst assigneeOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = members.list().map((m) => ({ id: m.userId, label: m.displayName }));\n\t\tconst unknown = attributes.assigneeIds\n\t\t\t.filter((id) => !members.byId(id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [members, attributes.assigneeIds]);\n\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Card title={t(\"content.filing.title\")}>\n\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t<BaseSelectField<FilingValues>\n\t\t\t\t\t\tname=\"collectionIds\"\n\t\t\t\t\t\tlabel={t(\"content.filing.collections\")}\n\t\t\t\t\t\thelperText={t(\"content.filing.collectionsHelp\")}\n\t\t\t\t\t\toptions={collectionOptions}\n\t\t\t\t\t\tisMulti\n\t\t\t\t\t\tplaceholder={t(\"content.filing.nowhere\")}\n\t\t\t\t\t/>\n\t\t\t\t\t<BaseSelectField<FilingValues>\n\t\t\t\t\t\tname=\"assigneeIds\"\n\t\t\t\t\t\tlabel={t(\"content.filing.assignees\")}\n\t\t\t\t\t\thelperText={t(\"content.filing.assigneesHelp\")}\n\t\t\t\t\t\toptions={assigneeOptions}\n\t\t\t\t\t\tisMulti\n\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t/>\n\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t{t(\"content.filing.notASave\")}\n\t\t\t\t\t</Text>\n\t\t\t\t</Stack>\n\t\t\t</Card>\n\t\t</Box>\n\t);\n}\n","import { ContextRail, DescriptionList } from \"@knkcs/anker/components\";\nimport {\n\tArchive,\n\tArchiveRestore,\n\tBan,\n\tCopy,\n\tFileX,\n\tLock,\n\tLockOpen,\n\tPencilLine,\n} from \"lucide-react\";\n\n/** One of the rail's actions; absent from `ContentRailProps.actions` when it isn't offered. */\nexport type ContentRailAction =\n\t| \"startEditing\"\n\t| \"openBranch\"\n\t| \"duplicate\"\n\t| \"repeal\"\n\t| \"withdraw\"\n\t| \"block\"\n\t| \"unblock\"\n\t| \"archive\"\n\t| \"unarchive\";\n\nconst ICONS: Record<ContentRailAction, typeof Copy> = {\n\tstartEditing: PencilLine,\n\topenBranch: PencilLine,\n\tduplicate: Copy,\n\trepeal: FileX,\n\twithdraw: Ban,\n\tblock: Lock,\n\tunblock: LockOpen,\n\tarchive: Archive,\n\tunarchive: ArchiveRestore,\n};\n\nexport interface ContentRailProps {\n\ttitle: string;\n\t/** Every string the rail shows, translated by the screen. */\n\tlabels: {\n\t\teyebrow: string;\n\t\tactions: string;\n\t\tabout: string;\n\t\tblueprint: string;\n\t\tinForce: string;\n\t\tblock: string;\n\t\tarchived: string;\n\t\taction: Record<ContentRailAction, string>;\n\t};\n\t/** The actions offered, in the order shown. */\n\tactions: ContentRailAction[];\n\tonAction: (action: ContentRailAction) => void;\n\tabout: {\n\t\tblueprint: string;\n\t\tinForce: string;\n\t\tblock: string;\n\t\t/** Absent while it is not Archived. */\n\t\tarchived?: string;\n\t};\n}\n\n/**\n * The Content page's rail (anker ADR 0004): what one does to the Content in\n * Actions, the facts at a glance in About. It is reported to the host and\n * drawn away from the screen's providers, so it reads no context of the\n * screen's: every string arrives translated and every action is a callback\n * that sets screen state, the screen rendering the dialog.\n */\nexport function ContentRail({ title, labels, actions, onAction, about }: ContentRailProps) {\n\treturn (\n\t\t<ContextRail storageKey=\"contenthub-content-rail\">\n\t\t\t<ContextRail.Header eyebrow={labels.eyebrow} title={title} />\n\t\t\t<ContextRail.Section id=\"actions\" label={labels.actions}>\n\t\t\t\t{actions.map((action) => {\n\t\t\t\t\tconst Icon = ICONS[action];\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tkey={action}\n\t\t\t\t\t\t\tlabel={labels.action[action]}\n\t\t\t\t\t\t\ticon={<Icon size={16} />}\n\t\t\t\t\t\t\ttone={action === \"archive\" ? \"outline-red\" : \"default\"}\n\t\t\t\t\t\t\tonClick={() => onAction(action)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ContextRail.Section>\n\t\t\t<ContextRail.Section id=\"about\" label={labels.about}>\n\t\t\t\t<DescriptionList>\n\t\t\t\t\t<DescriptionList.Row label={labels.blueprint}>{about.blueprint}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.inForce}>{about.inForce}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.block}>{about.block}</DescriptionList.Row>\n\t\t\t\t\t{about.archived ? (\n\t\t\t\t\t\t<DescriptionList.Row label={labels.archived}>{about.archived}</DescriptionList.Row>\n\t\t\t\t\t) : null}\n\t\t\t\t</DescriptionList>\n\t\t\t</ContextRail.Section>\n\t\t</ContextRail>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useInfiniteQuery, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Content, Edge, OutdatedPin, Referrer } from \"../types\";\n\ntype EdgeRow = Edge & Record<string, unknown>;\ntype ReferrerRow = Referrer & Record<string, unknown>;\ntype PinRow = OutdatedPin & Record<string, unknown>;\n\n/** Referrers read at once; a Content cited more often shows more on request. */\nconst REFERRERS_PAGE = 100;\n\n/** What an edge points at: a Content, an Asset or a Blueprint Release, by id. */\nfunction targetOf(edge: Edge): string {\n\treturn edge.targetContentId || edge.targetAssetId || edge.targetBlueprintReleaseId;\n}\n\n/** A table's place on the tab: a heading, then its rows, its spinner or its failure. */\nfunction Section<T>({\n\ttitle,\n\tquery,\n\tchildren,\n}: {\n\ttitle: string;\n\t/** What a query read: whether it failed, and its data once read. */\n\tquery: { isError: boolean; data: T | undefined };\n\tchildren: (data: T) => ReactNode;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{title}</Heading>\n\t\t\t</Box>\n\t\t\t{query.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.references.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : query.data === undefined ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\tchildren(query.data)\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * The References tab (spec #56, story 90): the Content Graph around this\n * Content (ADR 0009). Its outgoing edges at the Revision shown; the edges\n * pointing at it from Releases In Force today and from open Change Sets'\n * Branch heads; and its pins that are outdated today, which only a save\n * re-pins, never contenthub by itself (#79). Tables, so flush.\n */\nexport function ContentReferencesTab({\n\tclient,\n\tcontent,\n\tonOpenContent,\n}: {\n\tclient: ContenthubClient;\n\tcontent: Content;\n\t/** Host navigation to another Content's page; without it, rows don't open. */\n\tonOpenContent?: (contentId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst outgoing = useQuery({\n\t\tqueryKey: contenthubKeys.contentReferences(content.id, content.revisionId),\n\t\tqueryFn: () => client.listReferences({ contentId: content.id, revisionId: content.revisionId }),\n\t});\n\tconst referrerPages = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.contentReferrers(content.id),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listReferrers({\n\t\t\t\tcontentId: content.id,\n\t\t\t\tincludeOpenChangeSets: true,\n\t\t\t\tpageSize: REFERRERS_PAGE,\n\t\t\t\tpageToken: pageParam,\n\t\t\t}),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t});\n\t// The pages read so far, as one list, so the section reads it as any other.\n\tconst referrers = {\n\t\tisError: referrerPages.isError,\n\t\tdata: referrerPages.data?.pages.flatMap((page) => page.referrers),\n\t};\n\tconst pinSource = content.branchId\n\t\t? { branchId: content.branchId }\n\t\t: { revisionId: content.revisionId };\n\tconst pins = useQuery({\n\t\tqueryKey: contenthubKeys.contentOutdatedPins(content.id, pinSource),\n\t\tqueryFn: () => client.listOutdatedPins(pinSource),\n\t});\n\n\tconst kindColumn = useMemo<ColumnDef<{ edge: Edge } & Record<string, unknown>, unknown>>(\n\t\t() => ({\n\t\t\tid: \"kind\",\n\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\tcell: ({ row }) => (\n\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.edge.kind}`)} />\n\t\t\t),\n\t\t}),\n\t\t[t],\n\t);\n\tconst pathColumn = useMemo<ColumnDef<{ edge: Edge } & Record<string, unknown>, unknown>>(\n\t\t() => ({\n\t\t\tid: \"path\",\n\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.path || \"—\"} />,\n\t\t}),\n\t\t[t],\n\t);\n\n\tconst outgoingColumns = useMemo<ColumnDef<EdgeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.pinReleaseId || t(\"content.references.followsInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst referrerColumns = useMemo<ColumnDef<ReferrerRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"source\",\n\t\t\t\theader: t(\"content.references.columns.source\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.sourceContentId} />,\n\t\t\t},\n\t\t\tkindColumn as ColumnDef<ReferrerRow, unknown>,\n\t\t\tpathColumn as ColumnDef<ReferrerRow, unknown>,\n\t\t\t{\n\t\t\t\tid: \"foundIn\",\n\t\t\t\theader: t(\"content.references.columns.foundIn\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.releaseId\n\t\t\t\t\t\t\t\t? t(\"content.references.inRelease\", { release: row.original.releaseId })\n\t\t\t\t\t\t\t\t: t(\"content.references.inChangeSet\", { changeSet: row.original.changeSetId })\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, kindColumn, pathColumn],\n\t);\n\tconst pinColumns = useMemo<ColumnDef<PinRow, unknown>[]>(\n\t\t() => [\n\t\t\tpathColumn as ColumnDef<PinRow, unknown>,\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original.edge)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.pinReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.references.columns.inForceNow\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={row.original.inForceReleaseId || t(\"content.references.gap\")} />\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, pathColumn],\n\t);\n\n\tconst openTarget = onOpenContent\n\t\t? (contentId: string) => {\n\t\t\t\tif (contentId) onOpenContent(contentId);\n\t\t\t}\n\t\t: undefined;\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Section title={t(\"content.references.outgoing\")} query={outgoing}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={outgoingColumns}\n\t\t\t\t\t\tdata={data as EdgeRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.path}:${index}`}\n\t\t\t\t\t\tvariant={openTarget ? \"hoverable\" : undefined}\n\t\t\t\t\t\tonRowClick={openTarget ? (row) => openTarget(row.targetContentId) : undefined}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutgoing\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t<Section title={t(\"content.references.referrers\")} query={referrers}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={referrerColumns}\n\t\t\t\t\t\tdata={data as ReferrerRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.sourceContentId}:${row.edge.path}:${index}`}\n\t\t\t\t\t\tvariant={openTarget ? \"hoverable\" : undefined}\n\t\t\t\t\t\tonRowClick={openTarget ? (row) => openTarget(row.edge.sourceContentId) : undefined}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noReferrers\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t{referrerPages.hasNextPage ? (\n\t\t\t\t<Box px=\"8\" py=\"3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tloading={referrerPages.isFetchingNextPage}\n\t\t\t\t\t\tonClick={() => void referrerPages.fetchNextPage()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"library.more\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</Box>\n\t\t\t) : null}\n\t\t\t<Section title={t(\"content.references.outdated\")} query={pins}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={pinColumns}\n\t\t\t\t\t\tdata={data as PinRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutdated\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t</Stack>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tBooleanCell,\n\tDataTable,\n\tDateCell,\n\tNumberCell,\n\tSlugCell,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { CalendarClock } from \"lucide-react\";\nimport { useCallback, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { localToday, releaseInForceOn } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useOpenChangeSets } from \"../common/use-open-change-sets\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedRelease, TimelineEntry, ValidityPeriod } from \"../types\";\n\ntype EntryRow = TimelineEntry & Record<string, unknown>;\ntype PlannedRow = { changeSetId: string; plannedRelease: PlannedRelease } & Record<string, unknown>;\n\n/** A Validity Period as \"first – last\", an open end as \"first –\"; undated Content has none. */\nexport function periodText(t: TFunction, period: ValidityPeriod | undefined): string {\n\tif (!period) return t(\"content.releases.undated\");\n\treturn period.lastDay\n\t\t? t(\"content.releases.period\", { first: period.firstDay, last: period.lastDay })\n\t\t: t(\"content.releases.openPeriod\", { first: period.firstDay });\n}\n\n/** The Content's Timeline, read once for the Releases tab and the rail's About and Actions. */\nexport function useContentTimeline(client: ContenthubClient, contentId: string) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.contentTimeline(contentId),\n\t\tqueryFn: () => client.getTimeline(contentId),\n\t});\n}\n\n/**\n * The Releases tab (spec #56, story 90): the Timeline as known now, the\n * Release In Force today marked, and below it the Planned Releases of open\n * Change Sets, which may join it when they are published. Tables, so flush.\n */\nexport function ContentReleasesTab({\n\tclient,\n\tcontentId,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst timeline = useContentTimeline(client, contentId);\n\tconst openChangeSets = useOpenChangeSets(client);\n\tconst inForce = releaseInForceOn(timeline.data?.entries ?? [], localToday());\n\tconst changeSetName = useCallback(\n\t\t(id: string) => openChangeSets.data?.changeSets.find((cs) => cs.id === id)?.name ?? id,\n\t\t[openChangeSets.data],\n\t);\n\n\tconst entryColumns = useMemo<ColumnDef<EntryRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"ordinal\",\n\t\t\t\theader: t(\"content.releases.columns.ordinal\"),\n\t\t\t\tcell: ({ row }) => <NumberCell value={row.original.ordinal} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"content.releases.columns.release\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.releaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.releases.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"content.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(t, row.original.validityPeriod)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"published\",\n\t\t\t\theader: t(\"content.releases.columns.published\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.publishTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.releases.columns.inForce\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.releaseId === inForce?.releaseId}\n\t\t\t\t\t\ttrueLabel={t(\"content.releases.inForceToday\")}\n\t\t\t\t\t\tfalseLabel={t(\"content.releases.notInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, inForce?.releaseId],\n\t);\n\n\tconst plannedColumns = useMemo<ColumnDef<PlannedRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"changeSet\",\n\t\t\t\theader: t(\"content.releases.columns.changeSet\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={changeSetName(row.original.changeSetId)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={t(`content.releases.kind.${row.original.plannedRelease.kind}`)}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"content.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={periodText(t, row.original.plannedRelease.validityPeriod)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"proposed\",\n\t\t\t\theader: t(\"content.releases.columns.proposed\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.plannedRelease.proposed}\n\t\t\t\t\t\ttrueLabel={t(\"content.releases.proposed\")}\n\t\t\t\t\t\tfalseLabel={t(\"content.releases.planned\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, changeSetName],\n\t);\n\n\tif (timeline.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.releases.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!timeline.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={entryColumns}\n\t\t\t\tdata={timeline.data.entries as EntryRow[]}\n\t\t\t\tgetRowId={(row) => row.releaseId}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarClock size={32} />}\n\t\t\t\t\t\theader={t(\"content.releases.empty\")}\n\t\t\t\t\t\tdescription={t(\"content.releases.emptyHint\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{t(\"content.releases.plannedTitle\")}</Heading>\n\t\t\t</Box>\n\t\t\t<DataTable\n\t\t\t\tcolumns={plannedColumns}\n\t\t\t\tdata={timeline.data.plannedReleases as PlannedRow[]}\n\t\t\t\tgetRowId={(row) => row.plannedRelease.id}\n\t\t\t\temptyState={<EmptyState header={t(\"content.releases.noPlanned\")} />}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-duplicate-content\";\nconst EMPTY: ChangeSetChoiceValues = { changeSetId: NEW_CHANGE_SET, changeSetName: \"\" };\n\nexport interface DuplicateContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\t/** The Revision the copy takes its data from: the one the page shows. */\n\trevisionId: string;\n\t/** The copy was created: open its Branch in the Branch editor. */\n\tonCreated: (target: OpenBranchTarget) => void;\n}\n\n/**\n * Duplicate (spec #56, story 92): a new Content in a Change Set picked or\n * opened here, whose first Revision copies the shown Revision's data and\n * pins its Blueprint Release (CreateContent's copy_from). The copy is new\n * Content, with no history of its own; it exists only in the Change Set\n * until it is published.\n *\n * A new Change Set is opened before the copy is created. If the copy is then\n * refused, the form switches to that Change Set, so trying again never opens\n * a second one.\n */\nexport function DuplicateContentModal({\n\topen,\n\tonClose,\n\tclient,\n\trevisionId,\n\tonCreated,\n}: DuplicateContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<ChangeSetChoiceValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tlet target = values.changeSetId as string;\n\t\ttry {\n\t\t\tif (target === NEW_CHANGE_SET) {\n\t\t\t\tconst created = await client.createChangeSet({ name: values.changeSetName.trim() });\n\t\t\t\ttarget = created.id;\n\t\t\t\tmethods.setValue(\"changeSetId\", target);\n\t\t\t}\n\t\t\tconst copy = await client.createContent({\n\t\t\t\tchangeSetId: target,\n\t\t\t\tblueprintReleaseId: \"\",\n\t\t\t\tcopyFrom: { revisionId },\n\t\t\t});\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contents() });\n\t\t\tonCreated({ changeSetId: target, contentId: copy.id, branchId: copy.branchId });\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.duplicate.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"content.duplicate.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t{t(\"content.duplicate.hint\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t<ChangeSetChoiceFields<ChangeSetChoiceValues>\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\thelperText={t(\"content.duplicate.changeSetHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedEnd } from \"../types\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-end-force\";\n\ntype EndValues = ChangeSetChoiceValues & { lastDay: string };\nconst EMPTY: EndValues = { changeSetId: NEW_CHANGE_SET, changeSetName: \"\", lastDay: \"\" };\n\nexport interface EndForceModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Dated Content is Repealed on a last day; undated Content is Withdrawn. */\n\tdated: boolean;\n}\n\n/**\n * Repeal or Withdraw (spec #56, story 92): plans the Release ending the\n * Content's force in a Change Set picked or opened here; Publish cuts it.\n * The referrers the gap will strand come back as a warning, never a refusal\n * (ADR 0009), and the dialog stays open to show them.\n */\nexport function EndForceModal({ open, onClose, client, contentId, dated }: EndForceModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<EndValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [planned, setPlanned] = useState<PlannedEnd | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst kind = dated ? \"repeal\" : \"withdraw\";\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t\tsetPlanned(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tif (dated && !DAY.test(values.lastDay)) {\n\t\t\tmethods.setError(\"lastDay\", { message: t(\"content.endForce.lastDayRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tlet target = values.changeSetId as string;\n\t\ttry {\n\t\t\tif (target === NEW_CHANGE_SET) {\n\t\t\t\tconst created = await client.createChangeSet({ name: values.changeSetName.trim() });\n\t\t\t\ttarget = created.id;\n\t\t\t\tmethods.setValue(\"changeSetId\", target);\n\t\t\t}\n\t\t\tconst result = dated\n\t\t\t\t? await client.planRepeal({ changeSetId: target, contentId, lastDay: values.lastDay })\n\t\t\t\t: await client.planWithdrawal({ changeSetId: target, contentId });\n\t\t\tsetPlanned(result);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentTimeline(contentId) });\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(`content.endForce.${kind}.title`)}\n\t\t\tfooter={\n\t\t\t\tplanned ? (\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"content.endForce.done\")}\n\t\t\t\t\t</Button>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t\t{t(`content.endForce.${kind}.submit`)}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t{planned ? (\n\t\t\t\t<Stack gap=\"3\">\n\t\t\t\t\t<Alert status=\"success\" title={t(`content.endForce.${kind}.planned`)} />\n\t\t\t\t\t{planned.gapReferrers.length > 0 ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\ttitle={t(\"content.endForce.gapReferrers\", { count: planned.gapReferrers.length })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{planned.gapReferrers\n\t\t\t\t\t\t\t\t.map((g) => `${g.edge.sourceContentId} (${g.edge.path || g.releaseId})`)\n\t\t\t\t\t\t\t\t.join(\", \")}\n\t\t\t\t\t\t</Alert>\n\t\t\t\t\t) : null}\n\t\t\t\t</Stack>\n\t\t\t) : (\n\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(`content.endForce.${kind}.hint`)}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<ChangeSetChoiceFields<EndValues>\n\t\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\t\thelperText={t(\"content.endForce.changeSetHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t\t<InputField<EndValues>\n\t\t\t\t\t\t\t\t\tname=\"lastDay\"\n\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"content.endForce.lastDay\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"content.endForce.lastDayHelp\")}\n\t\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</form>\n\t\t\t\t</FormProvider>\n\t\t\t)}\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { DescriptionList, Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-start-editing\";\n\ntype StartValues = ChangeSetChoiceValues & { effectiveOn: string };\n\nexport interface StartEditingModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Dated Content's Chain takes the date its change takes effect; undated Content's none. */\n\tdated: boolean;\n\t/** The Chain was started: open its Branch in the Branch editor. */\n\tonStarted: (target: OpenBranchTarget) => void;\n}\n\n/**\n * Start editing (spec #56, story 92; ADR 0015's one-off edit): a Change Set\n * picked or opened here, and for Dated Content the effective date, then\n * StartEditing, which starts the Chain and opens a new Change Set in one\n * transaction, so a refusal leaves nothing behind. With an open Change Set\n * and a date, PreviewChain shows what the Chain would fork from first.\n */\nexport function StartEditingModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tdated,\n\tonStarted,\n}: StartEditingModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<StartValues>({\n\t\tdefaultValues: { changeSetId: NEW_CHANGE_SET, changeSetName: \"\", effectiveOn: \"\" },\n\t});\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst changeSetId = useWatch({ control: methods.control, name: \"changeSetId\" });\n\tconst effectiveOn = useWatch({ control: methods.control, name: \"effectiveOn\" });\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ changeSetId: NEW_CHANGE_SET, changeSetName: \"\", effectiveOn: \"\" });\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst canPreview =\n\t\topen && dated && !!changeSetId && changeSetId !== NEW_CHANGE_SET && DAY.test(effectiveOn);\n\tconst preview = useQuery({\n\t\tqueryKey: [...contenthubKeys.content(contentId), \"preview\", changeSetId, effectiveOn],\n\t\tqueryFn: () =>\n\t\t\tclient.previewChain({ changeSetId: changeSetId as string, contentId, effectiveOn }),\n\t\tenabled: canPreview,\n\t});\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values, true);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tif (dated && !DAY.test(values.effectiveOn)) {\n\t\t\tmethods.setError(\"effectiveOn\", { message: t(\"content.startEditing.dateRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tconst isNew = values.changeSetId === NEW_CHANGE_SET;\n\t\ttry {\n\t\t\tconst started = await client.startEditing({\n\t\t\t\tcontentId,\n\t\t\t\tchangeSetId: isNew ? undefined : (values.changeSetId as string),\n\t\t\t\teffectiveOn: dated ? values.effectiveOn : undefined,\n\t\t\t\tchangeSetName: isNew ? values.changeSetName.trim() : undefined,\n\t\t\t});\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\tonStarted({\n\t\t\t\tchangeSetId: started.changeSet.id,\n\t\t\t\tcontentId,\n\t\t\t\tbranchId: started.content.branchId,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.startEditing.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"content.startEditing.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<ChangeSetChoiceFields<StartValues>\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\thelperText={t(\"content.startEditing.changeSetHelp\")}\n\t\t\t\t\t\t\tnameHelperText={t(\"content.startEditing.nameHelp\")}\n\t\t\t\t\t\t\tnameOptional\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t<InputField<StartValues>\n\t\t\t\t\t\t\t\tname=\"effectiveOn\"\n\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\tlabel={t(\"content.startEditing.effectiveOn\")}\n\t\t\t\t\t\t\t\thelperText={t(\"content.startEditing.effectiveOnHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data ? (\n\t\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.forksFrom\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.forkReleaseId || t(\"content.startEditing.forksFromMain\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.carriesForward\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.carryForwardReleaseIds.length}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.cutsInto\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.cutIntoReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data && preview.data.coveredReleaseIds.length > 0 ? (\n\t\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\t\ttitle={t(\"content.startEditing.covers\", {\n\t\t\t\t\t\t\t\t\treleases: preview.data.coveredReleaseIds.join(\", \"),\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { useHostIdentity, usePageRail } from \"@knkcs/anker/host\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Save } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { useBlueprintSource } from \"../common/blueprint-source\";\nimport { inForceOnOrAfter, localToday, releaseInForceOn } from \"../common/in-force\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlueprintSource, ContentAttributes, ContentDetail } from \"../types\";\nimport { ArchiveContentModal } from \"./archive-content-modal\";\nimport { BlockContentModal } from \"./block-content-modal\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { ContentChangeSetsTab } from \"./content-change-sets-tab\";\nimport { ContentDataTab } from \"./content-data-tab\";\nimport { ContentFilingTab, type FilingValues, filingValuesOf } from \"./content-filing-tab\";\nimport { contentLabel, type OpenContentTarget } from \"./content-library\";\nimport { ContentRail, type ContentRailAction } from \"./content-rail\";\nimport { ContentReferencesTab } from \"./content-references-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\nimport { ContentReleasesTab, periodText, useContentTimeline } from \"./content-releases-tab\";\nimport { ContentRevisionsTab } from \"./content-revisions-tab\";\nimport { DuplicateContentModal } from \"./duplicate-content-modal\";\nimport { EndForceModal } from \"./end-force-modal\";\nimport { StartEditingModal } from \"./start-editing-modal\";\n\ntype Tab = \"data\" | \"releases\" | \"revisions\" | \"references\" | \"changeSets\" | \"filing\";\nconst TABS: Tab[] = [\"data\", \"releases\", \"revisions\", \"references\", \"changeSets\", \"filing\"];\nconst NO_FILING: FilingValues = { collectionIds: [], assigneeIds: [] };\n\n/** A dialog the rail opened, which the screen renders. */\ntype Dialog = \"startEditing\" | \"duplicate\" | \"endForce\" | \"block\" | \"archive\" | null;\n\nexport interface ContentPageProps {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/**\n\t * The Change Set to read the Content in: one a Library row was read in.\n\t * Content born in an open Change Set exists only there, so its page needs\n\t * it; a published Content's page reads Main without it.\n\t */\n\tchangeSetId?: string;\n\t/**\n\t * Overrides where About reads the Blueprint's name. Absent, it reads\n\t * contenthub's own `BlueprintCatalogService` through `client` (#238);\n\t * a name it can't find falls back to the Release's own name, or the id.\n\t */\n\tblueprintSource?: BlueprintSource;\n\t/** Host navigation to the Branch editor: after Start editing or Duplicate, or a born Content's Branch. */\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n\t/** Host navigation to another Content's page, from the References tab. */\n\tonOpenContent?: (target: OpenContentTarget) => void;\n\t/** Host navigation to a Change Set's page, from the Change Sets tab. */\n\tonOpenChangeSet?: (changeSetId: string) => void;\n}\n\n/**\n * A Content's page (spec #56, stories 89–92): every angle on one Content in\n * tabs, the header's one Save for its Filing, and the rail's Actions and\n * About (anker ADR 0004). Its data is read-only here; it is edited in a\n * Branch, which Start editing opens.\n *\n * The draft registry is keyed by the Content (and the Change Set it is read\n * in), so moving to another starts clean.\n */\nexport function ContentPage(props: ContentPageProps) {\n\treturn (\n\t\t<TabDirtyProvider key={`${props.contentId}@${props.changeSetId ?? \"\"}`}>\n\t\t\t<ContentScreen {...props} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\nContentPage.displayName = \"ContentPage\";\n\n/** The same ids, in any order: neither Collections nor assignees mean anything by order here. */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n\treturn a.length === b.length && a.every((id) => b.includes(id));\n}\n\nfunction ContentScreen({\n\tclient,\n\tcontentId,\n\tchangeSetId,\n\tblueprintSource,\n\tonOpenBranch,\n\tonOpenContent,\n\tonOpenChangeSet,\n}: ContentPageProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst source = useBlueprintSource(client, blueprintSource);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { members } = useHostIdentity();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\") as Tab | null;\n\tconst tab: Tab = tabParam && TABS.includes(tabParam) ? tabParam : \"data\";\n\n\tconst readKey = useMemo(\n\t\t() => contenthubKeys.contentRead(contentId, changeSetId ?? \"\"),\n\t\t[contentId, changeSetId],\n\t);\n\tconst query = useQuery({\n\t\tqueryKey: readKey,\n\t\tqueryFn: () => client.getContent({ id: contentId, changeSetId }),\n\t});\n\tconst detail = query.data;\n\tconst timeline = useContentTimeline(client, contentId);\n\tconst blueprintName = useQuery({\n\t\tqueryKey: contenthubKeys.blueprintNames(detail ? [detail.content.blueprintId] : []),\n\t\tqueryFn: () => source.getBlueprints([detail?.content.blueprintId ?? \"\"]),\n\t\tenabled: !!detail,\n\t});\n\tconst blockReasons = useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t\tenabled: !!detail?.attributes.block,\n\t});\n\n\t// The Filing draft, held above the tab so it outlives the tab's mount\n\t// (anker ADR 0004). It follows every read while it is untouched, so a\n\t// colleague's filing shows up and a later Save never puts back what the\n\t// page first saw; once edited, it keeps the editor's draft.\n\tconst methods = useForm<FilingValues>({ defaultValues: NO_FILING });\n\tconst baseline = useRef<FilingValues | null>(null);\n\tuseEffect(() => {\n\t\tif (detail && (baseline.current === null || !methods.formState.isDirty)) {\n\t\t\tbaseline.current = filingValuesOf(detail.attributes);\n\t\t\tmethods.reset(baseline.current);\n\t\t}\n\t}, [detail, methods]);\n\tconst filingDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(\"filing\", filingDirty), [filingDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [saved, setSaved] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [dialog, setDialog] = useState<Dialog>(null);\n\tuseEffect(() => {\n\t\tif (filingDirty) setSaved(false);\n\t}, [filingDirty]);\n\n\t/** The attributes a write answered with, laid into the read so every tab sees them. */\n\tconst applyAttributes = useCallback(\n\t\t(attributes: ContentAttributes) => {\n\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (old) =>\n\t\t\t\told ? { ...old, attributes } : old,\n\t\t\t);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t},\n\t\t[queryClient, readKey],\n\t);\n\n\t/**\n\t * Persists the Filing draft: the attribute setters only, one per changed\n\t * attribute. Filing writes no Revision and needs no Change Set (ADR\n\t * 0015). A refusal stops there, and what wasn't saved stays in\n\t * the draft.\n\t */\n\tconst saveAll = useCallback(async () => {\n\t\tconst base = baseline.current;\n\t\tif (!base) return;\n\t\tconst draft = methods.getValues();\n\t\tconst next = { ...base };\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tif (!sameIds(draft.collectionIds, base.collectionIds)) {\n\t\t\t\tnext.collectionIds = await client.setContentCollections({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tcollectionIds: draft.collectionIds,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!sameIds(draft.assigneeIds, base.assigneeIds)) {\n\t\t\t\tconst attributes = await client.setContentAssignees({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tassigneeIds: draft.assigneeIds,\n\t\t\t\t});\n\t\t\t\tnext.assigneeIds = attributes.assigneeIds;\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tbaseline.current = next;\n\t\t\tmethods.reset(next);\n\t\t\tfor (const key of [\"collectionIds\", \"assigneeIds\"] as const) {\n\t\t\t\tif (!sameIds(draft[key], next[key]))\n\t\t\t\t\tmethods.setValue(key, draft[key], { shouldDirty: true });\n\t\t\t}\n\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (old) =>\n\t\t\t\told ? { ...old, attributes: { ...old.attributes, ...next } } : old,\n\t\t\t);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [client, contentId, methods, queryClient, readKey, t]);\n\n\t/** A rail action that writes at once, with no dialog: Unblock and Unarchive. */\n\tconst writeNow = useCallback(\n\t\tasync (write: () => Promise<ContentAttributes>) => {\n\t\t\tsetRefusal(null);\n\t\t\ttry {\n\t\t\t\tapplyAttributes(await write());\n\t\t\t} catch (err) {\n\t\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t\t}\n\t\t},\n\t\t[applyAttributes, t],\n\t);\n\n\tconst entries = timeline.data?.entries ?? [];\n\tconst today = localToday();\n\tconst content = detail?.content;\n\tconst attributes = detail?.attributes;\n\t// Read on Main, it is published; read in a Change Set, only its Timeline\n\t// says so, so until that arrives the page claims neither.\n\tconst publishedKnown = !!content && (!content.changeSetId || timeline.isSuccess);\n\tconst published = !!content && (!content.changeSetId || entries.length > 0);\n\tconst dated = detail?.blueprintRelease?.dated ?? entries.some((e) => e.validityPeriod);\n\tconst archived = !!attributes?.archiveTime;\n\tconst live = inForceOnOrAfter(entries, today);\n\n\tconst actions = useMemo<ContentRailAction[]>(() => {\n\t\tif (!content || !attributes) return [];\n\t\tconst list: ContentRailAction[] = [];\n\t\tif (publishedKnown && !published) list.push(\"openBranch\");\n\t\telse if (published && !archived) list.push(\"startEditing\");\n\t\tlist.push(\"duplicate\");\n\t\tif (published && !archived && timeline.isSuccess && live) {\n\t\t\tlist.push(dated ? \"repeal\" : \"withdraw\");\n\t\t}\n\t\tlist.push(attributes.block ? \"unblock\" : \"block\");\n\t\tif (archived) list.push(\"unarchive\");\n\t\t// Archive is offered only where ArchiveContent allows it: published,\n\t\t// with nothing In Force today or later (ADR 0015).\n\t\telse if (published && timeline.isSuccess && !live) list.push(\"archive\");\n\t\treturn list;\n\t}, [content, attributes, publishedKnown, published, archived, timeline.isSuccess, live, dated]);\n\n\tconst onAction = useCallback(\n\t\t(action: ContentRailAction) => {\n\t\t\tif (!content) return;\n\t\t\tswitch (action) {\n\t\t\t\tcase \"openBranch\":\n\t\t\t\t\tonOpenBranch({\n\t\t\t\t\t\tchangeSetId: content.changeSetId,\n\t\t\t\t\t\tcontentId: content.id,\n\t\t\t\t\t\tbranchId: content.branchId,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\tcase \"startEditing\":\n\t\t\t\t\tsetDialog(\"startEditing\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"duplicate\":\n\t\t\t\t\tsetDialog(\"duplicate\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"repeal\":\n\t\t\t\tcase \"withdraw\":\n\t\t\t\t\tsetDialog(\"endForce\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"block\":\n\t\t\t\t\tsetDialog(\"block\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"archive\":\n\t\t\t\t\tsetDialog(\"archive\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"unblock\":\n\t\t\t\t\tvoid writeNow(() => client.unblockContent(content.id));\n\t\t\t\t\treturn;\n\t\t\t\tcase \"unarchive\":\n\t\t\t\t\tvoid writeNow(() => client.unarchiveContent(content.id));\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t},\n\t\t[client, content, onOpenBranch, writeNow],\n\t);\n\n\tconst title = content ? contentLabel(content.data) || content.id : \"\";\n\tconst inForce = releaseInForceOn(entries, today);\n\tconst blockReason = blockReasons.data?.find((r) => r.id === attributes?.block?.blockReasonId);\n\tconst blockedBy = attributes?.block\n\t\t? (members.byId(attributes.block.blockedBy)?.displayName ?? attributes.block.blockedBy)\n\t\t: \"\";\n\tconst railLabels = useMemo(\n\t\t() => ({\n\t\t\teyebrow: t(\"content.rail.eyebrow\"),\n\t\t\tactions: t(\"content.rail.actions\"),\n\t\t\tabout: t(\"content.rail.about\"),\n\t\t\tblueprint: t(\"content.rail.blueprint\"),\n\t\t\tinForce: t(\"content.rail.inForce\"),\n\t\t\tblock: t(\"content.rail.block\"),\n\t\t\tarchived: t(\"content.rail.archived\"),\n\t\t\taction: {\n\t\t\t\tstartEditing: t(\"content.actions.startEditing\"),\n\t\t\t\topenBranch: t(\"content.actions.openBranch\"),\n\t\t\t\tduplicate: t(\"content.actions.duplicate\"),\n\t\t\t\trepeal: t(\"content.actions.repeal\"),\n\t\t\t\twithdraw: t(\"content.actions.withdraw\"),\n\t\t\t\tblock: t(\"content.actions.block\"),\n\t\t\t\tunblock: t(\"content.actions.unblock\"),\n\t\t\t\tarchive: t(\"content.actions.archive\"),\n\t\t\t\tunarchive: t(\"content.actions.unarchive\"),\n\t\t\t},\n\t\t}),\n\t\t[t],\n\t);\n\tconst about = useMemo(\n\t\t() => ({\n\t\t\tblueprint:\n\t\t\t\tblueprintName.data?.[0]?.name ||\n\t\t\t\tdetail?.blueprintRelease?.displayName ||\n\t\t\t\tdetail?.content.blueprintId ||\n\t\t\t\t\"\",\n\t\t\tinForce: !timeline.isSuccess\n\t\t\t\t? \"…\"\n\t\t\t\t: inForce\n\t\t\t\t\t? t(\"content.rail.inForceRelease\", {\n\t\t\t\t\t\t\tordinal: inForce.ordinal,\n\t\t\t\t\t\t\tperiod: periodText(t, inForce.validityPeriod),\n\t\t\t\t\t\t})\n\t\t\t\t\t: t(\"content.rail.noneInForce\"),\n\t\t\tblock: attributes?.block\n\t\t\t\t? t(\"content.rail.blockedBy\", {\n\t\t\t\t\t\treason: blockReason?.name ?? attributes.block.blockReasonId,\n\t\t\t\t\t\twho: blockedBy,\n\t\t\t\t\t})\n\t\t\t\t: t(\"content.rail.notBlocked\"),\n\t\t\tarchived: attributes?.archiveTime\n\t\t\t\t? new Date(attributes.archiveTime).toLocaleDateString()\n\t\t\t\t: undefined,\n\t\t}),\n\t\t[\n\t\t\tblueprintName.data,\n\t\t\tdetail,\n\t\t\ttimeline.isSuccess,\n\t\t\tinForce,\n\t\t\tattributes,\n\t\t\tblockReason,\n\t\t\tblockedBy,\n\t\t\tt,\n\t\t],\n\t);\n\tconst rail = useMemo(\n\t\t() =>\n\t\t\tcontent ? (\n\t\t\t\t<ContentRail\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tlabels={railLabels}\n\t\t\t\t\tactions={actions}\n\t\t\t\t\tonAction={onAction}\n\t\t\t\t\tabout={about}\n\t\t\t\t/>\n\t\t\t) : null,\n\t\t[content, title, railLabels, actions, onAction, about],\n\t);\n\tusePageRail(rail);\n\n\tif (!detail || !content || !attributes) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"library.title\"), to: paths.contents }]}\n\t\t\t\ttitle={query.isError ? t(\"content.unavailable\") : t(\"content.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\ttitle={notFound ? t(\"content.notFound\") : t(\"content.loadError\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\tconst changed = dirtyTabs.length;\n\tconst selectTab = (next: Tab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params, { replace: true });\n\t};\n\tconst closeDialog = () => setDialog(null);\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[{ label: t(\"library.title\"), to: paths.contents }, { label: title }]}\n\t\t\ttitle={title}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t{!publishedKnown || published ? null : (\n\t\t\t\t\t\t<TypeBadge name={t(\"content.badges.born\")} colorPalette=\"blue\" />\n\t\t\t\t\t)}\n\t\t\t\t\t{attributes.block ? (\n\t\t\t\t\t\t<TypeBadge name={t(\"content.badges.blocked\")} colorPalette=\"orange\" />\n\t\t\t\t\t) : null}\n\t\t\t\t\t{archived ? <TypeBadge name={t(\"content.badges.archived\")} colorPalette=\"gray\" /> : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\tdisabled={changed === 0}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void saveAll()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"changeSet.save\") : t(\"changeSet.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => selectTab(e.value as Tab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(`content.tabs.${each}`)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"content.filing.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t{tab === \"data\" ? <ContentDataTab detail={detail} /> : null}\n\t\t\t{tab === \"releases\" ? <ContentReleasesTab client={client} contentId={contentId} /> : null}\n\t\t\t{tab === \"revisions\" ? (\n\t\t\t\tpublishedKnown ? (\n\t\t\t\t\t<ContentRevisionsTab client={client} content={content} published={published} />\n\t\t\t\t) : (\n\t\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t</Box>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t\t{tab === \"references\" ? (\n\t\t\t\t<ContentReferencesTab\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontent={content}\n\t\t\t\t\t// Content born in this Change Set exists only in it, so a\n\t\t\t\t\t// Reference read here opens there.\n\t\t\t\t\tonOpenContent={\n\t\t\t\t\t\tonOpenContent\n\t\t\t\t\t\t\t? (id) =>\n\t\t\t\t\t\t\t\t\tonOpenContent({ contentId: id, changeSetId: content.changeSetId || undefined })\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{tab === \"changeSets\" ? (\n\t\t\t\t<ContentChangeSetsTab\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontentId={contentId}\n\t\t\t\t\tonOpenChangeSet={onOpenChangeSet}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t{tab === \"filing\" ? <ContentFilingTab client={client} attributes={attributes} /> : null}\n\t\t\t</FormProvider>\n\t\t\t<StartEditingModal\n\t\t\t\topen={dialog === \"startEditing\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tdated={dated}\n\t\t\t\tonStarted={(target) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tonOpenBranch(target);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<DuplicateContentModal\n\t\t\t\topen={dialog === \"duplicate\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\trevisionId={content.revisionId}\n\t\t\t\tonCreated={(target) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tonOpenBranch(target);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<EndForceModal\n\t\t\t\topen={dialog === \"endForce\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tdated={dated}\n\t\t\t/>\n\t\t\t<BlockContentModal\n\t\t\t\topen={dialog === \"block\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tcurrent={attributes.block}\n\t\t\t\tonBlocked={(next) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tapplyAttributes(next);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ArchiveContentModal\n\t\t\t\topen={dialog === \"archive\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tonArchived={(next) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tapplyAttributes(next);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"changeSet.leave.title\")}\n\t\t\t\tmessage={t(\"changeSet.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"changeSet.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"changeSet.leave.cancel\")}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tAccessDeniedError,\n\ttype ContenthubClient,\n\tInvalidInputError,\n\tRestrictionUnavailableError,\n} from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection, CollectionAccessLevel, CollectionGrant } from \"../types\";\n\ninterface GrantValues {\n\tuserId: string | null;\n\tlevel: GrantLevel | null;\n}\n\n/** What a grant gives: the owner's level comes from restricting, never from a grant. */\ntype GrantLevel = Exclude<CollectionAccessLevel, \"owner\">;\n\nconst EMPTY: GrantValues = { userId: null, level: \"viewer\" };\n\nconst LEVEL_KEYS: Record<CollectionAccessLevel, string> = {\n\towner: \"collections.access.levels.owner\",\n\teditor: \"collections.access.levels.editor\",\n\tviewer: \"collections.access.levels.viewer\",\n};\n\nexport interface CollectionAccessModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Restricted Collection whose grants are managed; null while closed. */\n\tcollection: Collection | null;\n\tonClose: () => void;\n\t/** Workspace mode refused it: the tab then says so and offers restriction no more. */\n\tonRestrictionUnavailable: () => void;\n}\n\n/**\n * Who may see a Restricted Collection's Content (ADR 0017): its owner, who\n * restricted it and is never granted, and each grantee as viewer or editor.\n * A grant replaces what the grantee held, so changing someone's level is\n * granting them again. Grantees are the host's members\n * (`useHostIdentity().members`, ADR 0020); granting oneself is the admin's\n * break-glass, announced to the owner like any grant (ADR 0017's 2026-10-03\n * amendment), so the picker offers it and says so.\n *\n * Only the owner or a workspace admin reads the roster: anyone else is told\n * that rather than shown an empty one.\n */\nexport function CollectionAccessModal({\n\topen,\n\tclient,\n\tcollection,\n\tonClose,\n\tonRestrictionUnavailable,\n}: CollectionAccessModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { userId: me, members } = useHostIdentity();\n\tconst queryClient = useQueryClient();\n\tconst id = collection?.id ?? \"\";\n\tconst grants = useQuery({\n\t\tqueryKey: contenthubKeys.collectionGrants(id),\n\t\tqueryFn: () => client.listCollectionGrants(id),\n\t\tenabled: open && id !== \"\",\n\t});\n\tconst methods = useForm<GrantValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst picked = methods.watch(\"userId\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst unavailable = grants.error instanceof RestrictionUnavailableError;\n\tuseEffect(() => {\n\t\tif (unavailable) onRestrictionUnavailable();\n\t}, [unavailable, onRestrictionUnavailable]);\n\n\tconst nameOf = (userId: string) => {\n\t\tconst name = members.byId(userId)?.displayName || userId;\n\t\treturn userId === me ? t(\"collections.access.you\", { name }) : name;\n\t};\n\tconst roster = grants.data ?? [];\n\tconst owner = roster.find((g) => g.level === \"owner\");\n\tconst granted = roster.filter((g) => g.level !== \"owner\");\n\n\t// Every member but the owner, who is never granted: someone granted\n\t// already stays offered, since granting them again changes their level.\n\tconst candidates = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\tmembers\n\t\t\t\t.list()\n\t\t\t\t.filter((m) => m.userId !== owner?.userId)\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.userId,\n\t\t\t\t\tlabel:\n\t\t\t\t\t\tm.userId === me\n\t\t\t\t\t\t\t? t(\"collections.access.you\", { name: m.displayName || m.userId })\n\t\t\t\t\t\t\t: m.displayName || m.userId,\n\t\t\t\t})),\n\t\t[members, owner, me, t],\n\t);\n\tconst levels = useMemo<BaseOption[]>(\n\t\t() => [\n\t\t\t{ id: \"viewer\", label: t(LEVEL_KEYS.viewer) },\n\t\t\t{ id: \"editor\", label: t(LEVEL_KEYS.editor) },\n\t\t],\n\t\t[t],\n\t);\n\n\tconst refused = (err: unknown) => {\n\t\tif (err instanceof RestrictionUnavailableError) {\n\t\t\tonRestrictionUnavailable();\n\t\t\tsetRefusal(t(\"collections.workspaceMode.title\"));\n\t\t} else if (err instanceof AccessDeniedError) {\n\t\t\tsetRefusal(t(\"collections.access.denied\"));\n\t\t} else if (err instanceof InvalidInputError) {\n\t\t\tsetRefusal(err.message);\n\t\t} else {\n\t\t\tsetRefusal(t(\"collections.access.failed\"));\n\t\t}\n\t};\n\tconst refresh = () =>\n\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.collectionGrants(id) });\n\n\tconst grant = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tif (!values.userId) {\n\t\t\tmethods.setError(\"userId\", { message: t(\"collections.access.personRequired\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait client.grantCollectionAccess({\n\t\t\t\tcollectionId: id,\n\t\t\t\tuserId: values.userId,\n\t\t\t\tlevel: values.level ?? \"viewer\",\n\t\t\t});\n\t\t\tmethods.reset(EMPTY);\n\t\t\tawait refresh();\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t}\n\t});\n\n\tconst revoke = async (g: CollectionGrant) => {\n\t\tsetRefusal(null);\n\t\tsetBusy(true);\n\t\ttry {\n\t\t\tawait client.revokeCollectionAccess({ collectionId: id, userId: g.userId });\n\t\t\tawait refresh();\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst loadError =\n\t\tgrants.error instanceof AccessDeniedError\n\t\t\t? t(\"collections.access.denied\")\n\t\t\t: unavailable\n\t\t\t\t? t(\"collections.workspaceMode.title\")\n\t\t\t\t: grants.isError\n\t\t\t\t\t? t(\"collections.access.loadError\")\n\t\t\t\t\t: null;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"collections.access.title\", { name: collection?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"collections.access.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t{loadError ? null : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tform=\"contenthub-collection-grant\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\t\tloading={methods.formState.isSubmitting}\n\t\t\t\t\t\t\tdisabled={!grants.isSuccess}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"collections.access.grant\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"collections.access.intro\")}\n\t\t\t\t</Text>\n\t\t\t\t{grants.isLoading ? <Spinner size=\"sm\" /> : null}\n\t\t\t\t{loadError ? <Alert status=\"error\" title={loadError} /> : null}\n\t\t\t\t{grants.isSuccess ? (\n\t\t\t\t\t<Stack gap=\"2\" aria-label={t(\"collections.access.roster\")} role=\"list\">\n\t\t\t\t\t\t{owner ? (\n\t\t\t\t\t\t\t<HStack role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(owner.userId)}</Text>\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t{t(LEVEL_KEYS.owner)}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{granted.map((g) => (\n\t\t\t\t\t\t\t<HStack key={g.userId} role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(g.userId)}</Text>\n\t\t\t\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t\t{t(LEVEL_KEYS[g.level])}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"collections.access.revokeOf\", { name: nameOf(g.userId) })}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void revoke(g)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{t(\"collections.access.revoke\")}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{granted.length === 0 ? (\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"collections.access.nobody\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t\t{grants.isSuccess ? (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\t\t\tnoValidate\n\t\t\t\t\t\t\tid=\"contenthub-collection-grant\"\n\t\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tvoid grant();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t<BaseSelectField<GrantValues>\n\t\t\t\t\t\t\t\t\tname=\"userId\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"collections.access.person\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"collections.access.personHelp\")}\n\t\t\t\t\t\t\t\t\toptions={candidates}\n\t\t\t\t\t\t\t\t\tplaceholder={t(\"collections.access.personPlaceholder\")}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<BaseSelectField<GrantValues>\n\t\t\t\t\t\t\t\t\tname=\"level\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"collections.access.level\")}\n\t\t\t\t\t\t\t\t\toptions={levels}\n\t\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{picked && picked === me ? (\n\t\t\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"collections.access.breakGlass\")} />\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</FormProvider>\n\t\t\t\t) : null}\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, SwitchField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tCOLLECTION_NAME_MAX,\n\tInvalidInputError,\n\tNameTakenError,\n\tRestrictionUnavailableError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection } from \"../types\";\nimport { collectionPath } from \"./collection-tree\";\n\n/** The parent picker's stand-in for the root, which has no id. */\nconst ROOT = \"__root__\";\n\n/** Each Collection as a place to put something: its path from the root. */\nexport function placeOptions(\n\tcollections: Collection[],\n\trootLabel: string,\n\texcept?: (c: Collection) => boolean,\n): BaseOption[] {\n\treturn [\n\t\t{ id: ROOT, label: rootLabel },\n\t\t...collections\n\t\t\t.filter((c) => !except?.(c))\n\t\t\t.map((c) => ({\n\t\t\t\tid: c.id,\n\t\t\t\tlabel: collectionPath(c.id, collections)\n\t\t\t\t\t.map((each) => each.name)\n\t\t\t\t\t.join(\" / \"),\n\t\t\t}))\n\t\t\t.sort((a, b) => a.label.localeCompare(b.label)),\n\t];\n}\n\n/** True for `id` and every Collection under it: where it can't move. */\nexport function isWithin(id: string, c: Collection, collections: Collection[]): boolean {\n\treturn collectionPath(c.id, collections).some((each) => each.id === id);\n}\n\ninterface NameValues {\n\tname: string;\n\tparent: string | null;\n\trestricted: boolean;\n}\n\nexport interface CollectionFormModalProps {\n\topen: boolean;\n\t/** A new Collection, or a rename of `collection`. */\n\tmode: \"create\" | \"rename\";\n\t/** The Collection renamed; ignored on create. */\n\tcollection: Collection | null;\n\t/** Every Collection, for the parent picker. */\n\tcollections: Collection[];\n\t/** Offer creating it restricted: false once workspace mode refused a restriction. */\n\tcanRestrict: boolean;\n\tonClose: () => void;\n\t/**\n\t * Sends it. A `NameTakenError` lands on the name, an `InvalidInputError`\n\t * or `RestrictionUnavailableError` above the form.\n\t */\n\tonSubmit: (input: { name: string; parentId: string; restricted: boolean }) => Promise<void>;\n}\n\n/**\n * Names a new Collection and where it sits (and whether it starts\n * Restricted, so its Content is never briefly open, ADR 0017), or renames\n * one. The service's name rule is checked first: trimmed, not blank, at most\n * 200 characters, one line.\n */\nexport function CollectionFormModal({\n\topen,\n\tmode,\n\tcollection,\n\tcollections,\n\tcanRestrict,\n\tonClose,\n\tonSubmit,\n}: CollectionFormModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst formId = `contenthub-collection-${mode}`;\n\tconst initial = useMemo<NameValues>(\n\t\t() => ({\n\t\t\tname: mode === \"rename\" ? (collection?.name ?? \"\") : \"\",\n\t\t\tparent: ROOT,\n\t\t\trestricted: false,\n\t\t}),\n\t\t[mode, collection],\n\t);\n\tconst methods = useForm<NameValues>({ defaultValues: initial });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(initial);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, initial, methods]);\n\n\tconst parents = useMemo(() => placeOptions(collections, t(\"collections.root\")), [collections, t]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst name = values.name.trim();\n\t\tif (name === \"\") {\n\t\t\tmethods.setError(\"name\", { message: t(\"collections.form.nameRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tif ([...name].length > COLLECTION_NAME_MAX) {\n\t\t\tmethods.setError(\"name\", {\n\t\t\t\tmessage: t(\"collections.form.nameTooLong\", { max: COLLECTION_NAME_MAX }),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\tif (/[\\u0000-\\u001f\\u007f]/.test(name)) {\n\t\t\tmethods.setError(\"name\", { message: t(\"collections.form.oneLine\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait onSubmit({\n\t\t\t\tname,\n\t\t\t\tparentId: !values.parent || values.parent === ROOT ? \"\" : values.parent,\n\t\t\t\trestricted: canRestrict && values.restricted,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"collections.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof RestrictionUnavailableError) {\n\t\t\t\tsetRefusal(t(\"collections.workspaceMode.title\"));\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"collections.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\n\t\t\t\tmode === \"create\" ? \"collections.form.createTitle\" : \"collections.form.renameTitle\",\n\t\t\t)}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={formId} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\n\t\t\t\t\t\t\tmode === \"create\" ? \"collections.form.createSubmit\" : \"collections.form.renameSubmit\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid={formId}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<NameValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"collections.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"collections.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{mode === \"create\" ? (\n\t\t\t\t\t\t\t<BaseSelectField<NameValues>\n\t\t\t\t\t\t\t\tname=\"parent\"\n\t\t\t\t\t\t\t\tlabel={t(\"collections.form.parent\")}\n\t\t\t\t\t\t\t\toptions={parents}\n\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{mode === \"create\" && canRestrict ? (\n\t\t\t\t\t\t\t<SwitchField<NameValues>\n\t\t\t\t\t\t\t\tname=\"restricted\"\n\t\t\t\t\t\t\t\tlabel={t(\"collections.form.restrictedLabel\")}\n\t\t\t\t\t\t\t\thelperText={t(\"collections.form.restrictedHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n\ninterface MoveValues {\n\tparent: string | null;\n}\n\nexport interface MoveCollectionModalProps {\n\topen: boolean;\n\tcollection: Collection | null;\n\tcollections: Collection[];\n\tonClose: () => void;\n\t/** Sends the move; \"\" for the root. Refusals show above the form. */\n\tonSubmit: (parentId: string) => Promise<void>;\n}\n\n/**\n * Moves a Collection, with everything under it, to the root or under\n * another. It offers no place under itself, which the service would refuse\n * as a cycle.\n */\nexport function MoveCollectionModal({\n\topen,\n\tcollection,\n\tcollections,\n\tonClose,\n\tonSubmit,\n}: MoveCollectionModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst initial = useMemo<MoveValues>(\n\t\t() => ({ parent: collection?.parentId ? collection.parentId : ROOT }),\n\t\t[collection],\n\t);\n\tconst methods = useForm<MoveValues>({ defaultValues: initial });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(initial);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, initial, methods]);\n\n\tconst places = useMemo(\n\t\t() =>\n\t\t\tplaceOptions(collections, t(\"collections.root\"), (c) =>\n\t\t\t\tcollection ? isWithin(collection.id, c, collections) : false,\n\t\t\t),\n\t\t[collections, collection, t],\n\t);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onSubmit(!values.parent || values.parent === ROOT ? \"\" : values.parent);\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\t// A move sends no name, so the refusal names none: the moved one's own.\n\t\t\t\tsetRefusal(\n\t\t\t\t\tt(\"collections.form.nameTaken\", { name: err.takenName || (collection?.name ?? \"\") }),\n\t\t\t\t);\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"collections.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"collections.move.title\", { name: collection?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\tform=\"contenthub-collection-move\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tloading={submitting}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"collections.move.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid=\"contenthub-collection-move\"\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<BaseSelectField<MoveValues>\n\t\t\t\t\t\t\tname=\"parent\"\n\t\t\t\t\t\t\tlabel={t(\"collections.move.parent\")}\n\t\t\t\t\t\t\thelperText={t(\"collections.move.parentHelp\")}\n\t\t\t\t\t\t\toptions={places}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tDataTable,\n\tMenuCell,\n\tStatusBadgeCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FolderInput, FolderTree, Lock, LockOpen, Pencil, Plus, Trash2, Users } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, RestrictionUnavailableError } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection } from \"../types\";\nimport { CollectionAccessModal } from \"./collection-access-modal\";\nimport { CollectionFormModal, MoveCollectionModal } from \"./collection-modals\";\nimport { collectionPath } from \"./collection-tree\";\nimport { ConfirmModal } from \"./confirm-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype CollectionRow = Collection & Record<string, unknown>;\n\n/** The tree depth first, siblings in the service's order (by name). */\nfunction treeOrder(collections: Collection[]): CollectionRow[] {\n\tconst children = new Map<string, Collection[]>();\n\tconst ids = new Set(collections.map((c) => c.id));\n\tfor (const c of collections) {\n\t\t// A parent the caller can't see would orphan its children: show them at the root.\n\t\tconst parent = ids.has(c.parentId) ? c.parentId : \"\";\n\t\tchildren.set(parent, [...(children.get(parent) ?? []), c]);\n\t}\n\tconst out: CollectionRow[] = [];\n\tconst seen = new Set<string>();\n\tconst walk = (parent: string) => {\n\t\tfor (const c of children.get(parent) ?? []) {\n\t\t\tif (seen.has(c.id)) continue;\n\t\t\tseen.add(c.id);\n\t\t\tout.push({ ...c });\n\t\t\twalk(c.id);\n\t\t}\n\t};\n\twalk(\"\");\n\treturn out;\n}\n\ntype Confirming = { kind: \"restrict\" | \"unrestrict\" | \"remove\"; collection: Collection };\n\nexport interface CollectionsTabProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * The workspace's Collection tree as an admin manages it (ADR 0017; spec\n * #56, stories 64, 65, 67 and 107): a flush table in tree order, each row\n * named with the path above it; create from the tab's Toolbar; rename, move,\n * restrict or open again, manage access and remove from each row.\n *\n * Restricting and opening again are both confirmed: restricting makes the\n * admin its owner and hides its Content from everyone not granted, and\n * opening it again discloses that Content to every viewer and drops its\n * grants, so it is sent with the disclosure acknowledged only from the\n * confirmation. In `authz.mode: workspace` contenthub refuses every\n * restriction; no RPC says which mode runs, so the tab learns it from the\n * first refusal and then says so instead of offering restriction.\n */\nexport function CollectionsTab({ client }: CollectionsTabProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst [creating, setCreating] = useState(false);\n\tconst [renaming, setRenaming] = useState<Collection | null>(null);\n\tconst [moving, setMoving] = useState<Collection | null>(null);\n\tconst [confirming, setConfirming] = useState<Confirming | null>(null);\n\tconst [managing, setManaging] = useState<Collection | null>(null);\n\tconst [restrictionUnavailable, setRestrictionUnavailable] = useState(false);\n\tconst markUnavailable = useCallback(() => setRestrictionUnavailable(true), []);\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.collections(),\n\t\tqueryFn: () => client.listCollections(),\n\t});\n\tconst collections = query.data ?? [];\n\tconst rows = useMemo(() => treeOrder(collections), [collections]);\n\t// Filing and the Library read the tree, and a removal unfiles Content.\n\tconst refresh = () =>\n\t\tPromise.all([\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.collections() }),\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.contents() }),\n\t\t]);\n\n\t/** Runs a write, learning workspace mode from its refusal before passing it on. */\n\tconst learning = async <T,>(write: () => Promise<T>): Promise<T> => {\n\t\ttry {\n\t\t\treturn await write();\n\t\t} catch (err) {\n\t\t\tif (err instanceof RestrictionUnavailableError) markUnavailable();\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst columns = useMemo<ColumnDef<CollectionRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"collections.columns.name\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst above = collectionPath(row.original.parentId, collections);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\t\tabove.length > 0\n\t\t\t\t\t\t\t\t\t? t(\"collections.inPath\", { path: above.map((c) => c.name).join(\" / \") })\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"access\",\n\t\t\t\theader: t(\"collections.columns.access\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(row.original.restricted ? \"collections.restricted\" : \"collections.open\")}\n\t\t\t\t\t\tcolorMap={{ [t(\"collections.restricted\")]: \"orange\" }}\n\t\t\t\t\t\ticon={row.original.restricted ? <Lock size={12} /> : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"collections.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst c = row.original;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<MenuCell\n\t\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t\t{ label: t(\"collections.rename\"), icon: Pencil, onClick: () => setRenaming(c) },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: t(\"collections.moveAction\"),\n\t\t\t\t\t\t\t\t\ticon: FolderInput,\n\t\t\t\t\t\t\t\t\tonClick: () => setMoving(c),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t...(c.restricted\n\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.manageAccess\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: Users,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled: restrictionUnavailable,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setManaging(c),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.unrestrict\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: LockOpen,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"unrestrict\", collection: c }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.restrict\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: Lock,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled: restrictionUnavailable,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"restrict\", collection: c }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: t(\"collections.remove\"),\n\t\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"remove\", collection: c }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[t, collections, restrictionUnavailable],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setCreating(true)}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"collections.create\")}\n\t\t</Button>\n\t);\n\n\tconst target = confirming?.collection;\n\tconst confirmText = {\n\t\trestrict: {\n\t\t\ttitle: t(\"collections.restrictDialog.title\"),\n\t\t\tmessage: t(\"collections.restrictDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.restrictDialog.confirm\"),\n\t\t\tfailed: t(\"collections.restrictDialog.failed\"),\n\t\t},\n\t\tunrestrict: {\n\t\t\ttitle: t(\"collections.unrestrictDialog.title\"),\n\t\t\tmessage: t(\"collections.unrestrictDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.unrestrictDialog.confirm\"),\n\t\t\tfailed: t(\"collections.unrestrictDialog.failed\"),\n\t\t},\n\t\tremove: {\n\t\t\ttitle: t(\"collections.removeDialog.title\"),\n\t\t\tmessage: t(\"collections.removeDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.removeDialog.confirm\"),\n\t\t\tfailed: t(\"collections.removeDialog.failed\"),\n\t\t},\n\t}[confirming?.kind ?? \"remove\"];\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Toolbar>\n\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t<Toolbar.Count>{t(\"collections.count\", { count: collections.length })}</Toolbar.Count>\n\t\t\t\t\t{createButton}\n\t\t\t\t</Toolbar.Right>\n\t\t\t</Toolbar>\n\t\t\t{restrictionUnavailable ? (\n\t\t\t\t<Alert status=\"info\" title={t(\"collections.workspaceMode.title\")} mx=\"8\" my=\"4\">\n\t\t\t\t\t{t(\"collections.workspaceMode.description\")}\n\t\t\t\t</Alert>\n\t\t\t) : null}\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"collections.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={rows}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<FolderTree size={32} />}\n\t\t\t\t\t\theader={t(\"collections.empty\")}\n\t\t\t\t\t\tdescription={t(\"collections.emptyHint\")}\n\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<CollectionFormModal\n\t\t\t\topen={creating}\n\t\t\t\tmode=\"create\"\n\t\t\t\tcollection={null}\n\t\t\t\tcollections={collections}\n\t\t\t\tcanRestrict={!restrictionUnavailable}\n\t\t\t\tonClose={() => setCreating(false)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tawait learning(() => client.createCollection(input));\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetCreating(false);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<CollectionFormModal\n\t\t\t\topen={renaming !== null}\n\t\t\t\tmode=\"rename\"\n\t\t\t\tcollection={renaming}\n\t\t\t\tcollections={collections}\n\t\t\t\tcanRestrict={false}\n\t\t\t\tonClose={() => setRenaming(null)}\n\t\t\t\tonSubmit={async ({ name }) => {\n\t\t\t\t\tif (!renaming) return;\n\t\t\t\t\tawait client.renameCollection({ id: renaming.id, name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRenaming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<MoveCollectionModal\n\t\t\t\topen={moving !== null}\n\t\t\t\tcollection={moving}\n\t\t\t\tcollections={collections}\n\t\t\t\tonClose={() => setMoving(null)}\n\t\t\t\tonSubmit={async (parentId) => {\n\t\t\t\t\tif (!moving) return;\n\t\t\t\t\tawait client.moveCollection({ id: moving.id, parentId });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetMoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={confirming !== null}\n\t\t\t\ttitle={confirmText.title}\n\t\t\t\tmessage={confirmText.message}\n\t\t\t\tconfirmLabel={confirmText.confirm}\n\t\t\t\tdanger={confirming?.kind !== \"restrict\"}\n\t\t\t\tfailedMessage={confirmText.failed}\n\t\t\t\tonClose={() => setConfirming(null)}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!confirming) return;\n\t\t\t\t\tconst { kind, collection } = confirming;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (kind === \"remove\") {\n\t\t\t\t\t\t\tawait client.removeCollection({ id: collection.id });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tawait learning(() =>\n\t\t\t\t\t\t\t\tclient.setCollectionRestricted({\n\t\t\t\t\t\t\t\t\tid: collection.id,\n\t\t\t\t\t\t\t\t\trestricted: kind === \"restrict\",\n\t\t\t\t\t\t\t\t\t// Sent only from here: the admin has just read what it discloses.\n\t\t\t\t\t\t\t\t\tacknowledgeDisclosure: kind === \"unrestrict\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Workspace mode refused a restriction: the tab now says why, so the\n\t\t\t\t\t\t// dialog has nothing to add. Any other refusal is shown in the dialog.\n\t\t\t\t\t\tif (kind === \"restrict\" && err instanceof RestrictionUnavailableError) {\n\t\t\t\t\t\t\tsetConfirming(null);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetConfirming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<CollectionAccessModal\n\t\t\t\topen={managing !== null}\n\t\t\t\tclient={client}\n\t\t\t\tcollection={managing}\n\t\t\t\tonClose={() => setManaging(null)}\n\t\t\t\tonRestrictionUnavailable={markUnavailable}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, SwitchField, TextareaField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tBLUEPRINT_ACCESSOR_MAX,\n\tInvalidInputError,\n\tNameTakenError,\n\tREQUIRED_CHECK_NAME_MAX,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckScope, RequiredCheck, RequiredCheckInput } from \"../types\";\n\nconst FORM_ID = \"contenthub-required-check\";\n\n/** Each scope's label key, for the picker and the table alike. */\nexport const SCOPE_LABELS: Record<CheckScope, string> = {\n\tbranch: \"requiredChecks.scope.branch\",\n\tchange_set: \"requiredChecks.scope.change_set\",\n};\n\ninterface CheckValues {\n\tname: string;\n\tscope: CheckScope | null;\n\teveryBlueprint: boolean;\n\t/** One Blueprint accessor per line. */\n\taccessors: string;\n\tindependent: boolean;\n}\n\nfunction valuesOf(check: RequiredCheck | null): CheckValues {\n\treturn {\n\t\tname: check?.name ?? \"\",\n\t\tscope: check?.scope ?? null,\n\t\teveryBlueprint: (check?.blueprintAccessors.length ?? 0) === 0,\n\t\taccessors: (check?.blueprintAccessors ?? []).join(\"\\n\"),\n\t\tindependent: check?.independent ?? false,\n\t};\n}\n\n/** The accessors a textarea holds: one a line, blank lines dropped. */\nconst accessorsOf = (text: string) =>\n\ttext\n\t\t.split(\"\\n\")\n\t\t.map((a) => a.trim())\n\t\t.filter((a) => a !== \"\");\n\nexport interface RequiredCheckModalProps {\n\topen: boolean;\n\t/** The check to edit; null to declare a new one. */\n\tcheck: RequiredCheck | null;\n\tonClose: () => void;\n\t/**\n\t * Sends the check. A `NameTakenError` lands on the name, an\n\t * `InvalidInputError` above the form with the service's guidance.\n\t */\n\tonSubmit: (input: RequiredCheckInput) => Promise<void>;\n}\n\n/**\n * Declares or edits a Required Check (ADR 0014; spec #56, story 39): its\n * name, its scope, the Blueprints it applies to by accessor or every one,\n * and whether it is independent. The form checks the service's rules first\n * (internal/workspaceconfig), so most mistakes are said before a request.\n *\n * Who may record it is said, not edited here: contenthub grants `recorder` to\n * every member when a check is created (ADR 0017's 2026-10-03 amendment),\n * and the tab's RequiredCheckRecordersModal narrows it.\n */\nexport function RequiredCheckModal({ open, check, onClose, onSubmit }: RequiredCheckModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst methods = useForm<CheckValues>({ defaultValues: valuesOf(check) });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst everyBlueprint = methods.watch(\"everyBlueprint\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(valuesOf(check));\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, check, methods]);\n\n\tconst scopeOptions = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\t(Object.keys(SCOPE_LABELS) as CheckScope[]).map((id) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: t(SCOPE_LABELS[id]),\n\t\t\t})),\n\t\t[t],\n\t);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst name = values.name.trim();\n\t\tlet valid = true;\n\t\tconst fail = (field: keyof CheckValues, message: string) => {\n\t\t\tmethods.setError(field, { message });\n\t\t\tvalid = false;\n\t\t};\n\t\tif (name === \"\") fail(\"name\", t(\"requiredChecks.form.nameRequired\"));\n\t\telse if ([...name].length > REQUIRED_CHECK_NAME_MAX) {\n\t\t\tfail(\"name\", t(\"requiredChecks.form.nameTooLong\", { max: REQUIRED_CHECK_NAME_MAX }));\n\t\t}\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\telse if (/[\\u0000-\\u001f\\u007f]/.test(name)) fail(\"name\", t(\"requiredChecks.form.oneLine\"));\n\t\tif (!values.scope) fail(\"scope\", t(\"requiredChecks.form.scopeRequired\"));\n\t\tconst accessors = values.everyBlueprint ? [] : accessorsOf(values.accessors);\n\t\tif (!values.everyBlueprint && accessors.length === 0) {\n\t\t\tfail(\"accessors\", t(\"requiredChecks.form.accessorsRequired\"));\n\t\t} else if (accessors.some((a) => [...a].length > BLUEPRINT_ACCESSOR_MAX)) {\n\t\t\tfail(\"accessors\", t(\"requiredChecks.form.accessorTooLong\", { max: BLUEPRINT_ACCESSOR_MAX }));\n\t\t}\n\t\tif (!valid || !values.scope) return;\n\t\ttry {\n\t\t\tawait onSubmit({\n\t\t\t\tname,\n\t\t\t\tscope: values.scope,\n\t\t\t\tblueprintAccessors: [...new Set(accessors)],\n\t\t\t\tindependent: values.independent,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"requiredChecks.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"requiredChecks.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(check ? \"requiredChecks.form.editTitle\" : \"requiredChecks.form.createTitle\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(check ? \"requiredChecks.form.editSubmit\" : \"requiredChecks.form.createSubmit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<CheckValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<BaseSelectField<CheckValues>\n\t\t\t\t\t\t\tname=\"scope\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.scope\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.scopeHelp\")}\n\t\t\t\t\t\t\toptions={scopeOptions}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<SwitchField<CheckValues>\n\t\t\t\t\t\t\tname=\"everyBlueprint\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.everyBlueprint\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{everyBlueprint ? null : (\n\t\t\t\t\t\t\t<TextareaField<CheckValues>\n\t\t\t\t\t\t\t\tname=\"accessors\"\n\t\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.accessors\")}\n\t\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.accessorsHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<SwitchField<CheckValues>\n\t\t\t\t\t\t\tname=\"independent\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.independentLabel\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.independentHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Stack gap=\"1\">\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\">\n\t\t\t\t\t\t\t\t{t(\"requiredChecks.form.recorders\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"requiredChecks.form.recordersHelp\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tAccessDeniedError,\n\ttype ContenthubClient,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n} from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { RecorderGrant, RequiredCheck } from \"../types\";\n\ninterface AddValues {\n\tuserId: string | null;\n}\n\nconst EMPTY: AddValues = { userId: null };\n\n/** Don't ask again what the service refused for good: the mode, or the caller's rights. */\nexport function retryRecorders(failures: number, err: unknown): boolean {\n\treturn (\n\t\t!(err instanceof GuardianModeRequiredError || err instanceof AccessDeniedError) && failures < 3\n\t);\n}\n\nexport interface RequiredCheckRecordersModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Required Check whose recorders are managed; null while closed. */\n\tcheck: RequiredCheck | null;\n\tonClose: () => void;\n\t/** Workspace mode refused it: the tab then says so and offers the editor no more. */\n\tonGuardianModeRequired: () => void;\n}\n\n/**\n * Who records a Required Check's results (ADR 0017's 2026-10-03 amendment):\n * every member of the workspace until an admin narrows it to named people.\n * Narrowing is adding the people, then removing every member; restoring is\n * adding every member back. People are the host's members\n * (`useHostIdentity().members`, ADR 0020), as for a Restricted Collection's\n * grants (CollectionAccessModal). An admin records a check only when\n * granted, so adding oneself is break-glass, announced like any grant, and\n * the picker says so.\n *\n * In `authz.mode: workspace` every member records every check and contenthub\n * refuses to narrow it: the tab is told, and stops offering this.\n */\nexport function RequiredCheckRecordersModal({\n\topen,\n\tclient,\n\tcheck,\n\tonClose,\n\tonGuardianModeRequired,\n}: RequiredCheckRecordersModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { userId: me, members } = useHostIdentity();\n\tconst queryClient = useQueryClient();\n\tconst id = check?.id ?? \"\";\n\tconst recorders = useQuery({\n\t\tqueryKey: contenthubKeys.requiredCheckRecorders(id),\n\t\tqueryFn: () => client.listRequiredCheckRecorders(id),\n\t\tenabled: open && id !== \"\",\n\t\tretry: retryRecorders,\n\t});\n\tconst methods = useForm<AddValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst picked = methods.watch(\"userId\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst unavailable = recorders.error instanceof GuardianModeRequiredError;\n\tuseEffect(() => {\n\t\tif (unavailable) onGuardianModeRequired();\n\t}, [unavailable, onGuardianModeRequired]);\n\n\tconst nameOf = (userId: string) => {\n\t\tconst name = members.byId(userId)?.displayName || userId;\n\t\treturn userId === me ? t(\"requiredChecks.recorders.you\", { name }) : name;\n\t};\n\tconst everyMember = recorders.data?.everyMember ?? false;\n\tconst named = recorders.data?.userIds ?? [];\n\n\t// Every member not named already.\n\tconst candidates = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\tmembers\n\t\t\t\t.list()\n\t\t\t\t.filter((m) => !named.includes(m.userId))\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.userId,\n\t\t\t\t\tlabel:\n\t\t\t\t\t\tm.userId === me\n\t\t\t\t\t\t\t? t(\"requiredChecks.recorders.you\", { name: m.displayName || m.userId })\n\t\t\t\t\t\t\t: m.displayName || m.userId,\n\t\t\t\t})),\n\t\t[members, named, me, t],\n\t);\n\n\tconst refused = (err: unknown) => {\n\t\tif (err instanceof GuardianModeRequiredError) {\n\t\t\tonGuardianModeRequired();\n\t\t\tsetRefusal(t(\"requiredChecks.workspaceMode.title\"));\n\t\t} else if (err instanceof AccessDeniedError) {\n\t\t\tsetRefusal(t(\"requiredChecks.recorders.denied\"));\n\t\t} else if (err instanceof InvalidInputError) {\n\t\t\tsetRefusal(err.message);\n\t\t} else {\n\t\t\tsetRefusal(t(\"requiredChecks.recorders.failed\"));\n\t\t}\n\t};\n\tconst refresh = () =>\n\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.requiredCheckRecorders(id) });\n\n\tconst change = async (kind: \"grant\" | \"revoke\", recorder: RecorderGrant) => {\n\t\tsetRefusal(null);\n\t\tsetBusy(true);\n\t\ttry {\n\t\t\tconst input = { requiredCheckId: id, recorder };\n\t\t\tif (kind === \"grant\") await client.grantRequiredCheckRecorder(input);\n\t\t\telse await client.revokeRequiredCheckRecorder(input);\n\t\t\tawait refresh();\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst add = methods.handleSubmit(async (values) => {\n\t\tif (!values.userId) {\n\t\t\tmethods.setError(\"userId\", { message: t(\"requiredChecks.recorders.personRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tif (await change(\"grant\", { userId: values.userId })) methods.reset(EMPTY);\n\t});\n\n\tconst loadError =\n\t\trecorders.error instanceof AccessDeniedError\n\t\t\t? t(\"requiredChecks.recorders.denied\")\n\t\t\t: unavailable\n\t\t\t\t? t(\"requiredChecks.workspaceMode.title\")\n\t\t\t\t: recorders.isError\n\t\t\t\t\t? t(\"requiredChecks.recorders.loadError\")\n\t\t\t\t\t: null;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"requiredChecks.recorders.title\", { name: check?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"requiredChecks.recorders.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t{loadError ? null : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tform=\"contenthub-required-check-recorder\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\t\tloading={methods.formState.isSubmitting}\n\t\t\t\t\t\t\tdisabled={!recorders.isSuccess || busy}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.add\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"requiredChecks.recorders.intro\")}\n\t\t\t\t</Text>\n\t\t\t\t{recorders.isLoading ? <Spinner size=\"sm\" /> : null}\n\t\t\t\t{loadError ? <Alert status=\"error\" title={loadError} /> : null}\n\t\t\t\t{recorders.isSuccess ? (\n\t\t\t\t\t<Stack gap=\"2\" aria-label={t(\"requiredChecks.recorders.roster\")} role=\"list\">\n\t\t\t\t\t\t{everyMember ? (\n\t\t\t\t\t\t\t<HStack role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"requiredChecks.recorders.everyMember\")}</Text>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\taria-label={t(\"requiredChecks.recorders.removeOf\", {\n\t\t\t\t\t\t\t\t\t\tname: t(\"requiredChecks.recorders.everyMember\"),\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\tonClick={() => void change(\"revoke\", { everyMember: true })}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.remove\")}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{named.map((userId) => (\n\t\t\t\t\t\t\t<HStack key={userId} role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(userId)}</Text>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\taria-label={t(\"requiredChecks.recorders.removeOf\", { name: nameOf(userId) })}\n\t\t\t\t\t\t\t\t\tonClick={() => void change(\"revoke\", { userId })}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.remove\")}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess && !everyMember && named.length === 0 ? (\n\t\t\t\t\t<Alert status=\"warning\" title={t(\"requiredChecks.recorders.nobody\")} />\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess && !everyMember ? (\n\t\t\t\t\t<HStack>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => void change(\"grant\", { everyMember: true })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.restoreEveryMember\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess ? (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\t\t\tnoValidate\n\t\t\t\t\t\t\tid=\"contenthub-required-check-recorder\"\n\t\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tvoid add();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t<BaseSelectField<AddValues>\n\t\t\t\t\t\t\t\t\tname=\"userId\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"requiredChecks.recorders.person\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"requiredChecks.recorders.personHelp\")}\n\t\t\t\t\t\t\t\t\toptions={candidates}\n\t\t\t\t\t\t\t\t\tplaceholder={t(\"requiredChecks.recorders.personPlaceholder\")}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{picked && picked === me ? (\n\t\t\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"requiredChecks.recorders.breakGlass\")} />\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</FormProvider>\n\t\t\t\t) : null}\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tBooleanCell,\n\tDataTable,\n\tMenuCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { ListChecks, Pencil, Plus, Trash2, UserCheck } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, GuardianModeRequiredError } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { RequiredCheck } from \"../types\";\nimport { ConfirmModal } from \"./confirm-modal\";\nimport { RequiredCheckModal, SCOPE_LABELS } from \"./required-check-modal\";\nimport { RequiredCheckRecordersModal, retryRecorders } from \"./required-check-recorders-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype CheckRow = RequiredCheck & Record<string, unknown>;\n\nexport interface RequiredChecksTabProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * Who records one check, read from contenthub: every member, the people\n * named, or nobody. In workspace mode every member records and contenthub\n * says so by refusing the read, which the tab is told.\n */\nfunction RecordersCell({\n\tclient,\n\tcheckId,\n\tworkspaceMode,\n\tonGuardianModeRequired,\n}: {\n\tclient: ContenthubClient;\n\tcheckId: string;\n\tworkspaceMode: boolean;\n\tonGuardianModeRequired: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.requiredCheckRecorders(checkId),\n\t\tqueryFn: () => client.listRequiredCheckRecorders(checkId),\n\t\tenabled: !workspaceMode,\n\t\tretry: retryRecorders,\n\t});\n\tconst refused = query.error instanceof GuardianModeRequiredError;\n\tuseEffect(() => {\n\t\tif (refused) onGuardianModeRequired();\n\t}, [refused, onGuardianModeRequired]);\n\n\tlet value = \"\";\n\tif (workspaceMode || refused || query.data?.everyMember) value = t(\"requiredChecks.everyMember\");\n\telse if (query.data && query.data.userIds.length === 0) value = t(\"requiredChecks.nobody\");\n\telse if (query.data) {\n\t\tvalue = query.data.userIds.map((u) => members.byId(u)?.displayName || u).join(\", \");\n\t} else if (query.isError) value = t(\"requiredChecks.recordersUnknown\");\n\treturn <TruncatedTextCell value={value} />;\n}\n\n/**\n * The workspace's Required Checks (ADR 0014), a settings tab: a flush table,\n * declared and edited in a Modal opened from the tab's Toolbar (anker: no\n * inline create form above a DataTable; a tab's add goes in its Toolbar).\n * Every change is read back, so the table shows what contenthub holds.\n *\n * Who records each check is narrowed from its row (ADR 0017's 2026-10-03\n * amendment). In `authz.mode: workspace` every member records every check\n * and contenthub refuses to narrow it, with a typed refusal: the tab learns\n * the mode from the first one, says so, and offers no recorders editor.\n */\nexport function RequiredChecksTab({ client }: RequiredChecksTabProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\t// null: closed; \"new\": declaring one; a check: editing it.\n\tconst [editing, setEditing] = useState<RequiredCheck | \"new\" | null>(null);\n\tconst [removing, setRemoving] = useState<RequiredCheck | null>(null);\n\tconst [narrowing, setNarrowing] = useState<RequiredCheck | null>(null);\n\tconst [workspaceMode, setWorkspaceMode] = useState(false);\n\tconst markWorkspaceMode = useCallback(() => {\n\t\tsetWorkspaceMode(true);\n\t\tsetNarrowing(null);\n\t}, []);\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.requiredChecks(),\n\t\tqueryFn: () => client.listRequiredChecks(),\n\t});\n\tconst checks = query.data ?? [];\n\t// The Change Set pages read which checks apply, so they ask again too.\n\tconst refresh = () =>\n\t\tPromise.all([\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.requiredChecks() }),\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() }),\n\t\t]);\n\n\tconst columns = useMemo<ColumnDef<CheckRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"requiredChecks.columns.name\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={row.original.name} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"scope\",\n\t\t\t\theader: t(\"requiredChecks.columns.scope\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={t(SCOPE_LABELS[row.original.scope])} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"blueprints\",\n\t\t\t\theader: t(\"requiredChecks.columns.blueprints\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.blueprintAccessors.length === 0\n\t\t\t\t\t\t\t\t? t(\"requiredChecks.everyBlueprint\")\n\t\t\t\t\t\t\t\t: row.original.blueprintAccessors.join(\", \")\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"independent\",\n\t\t\t\theader: t(\"requiredChecks.columns.independent\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.independent}\n\t\t\t\t\t\ttrueLabel={t(\"requiredChecks.yes\")}\n\t\t\t\t\t\tfalseLabel={t(\"requiredChecks.no\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"recorders\",\n\t\t\t\theader: t(\"requiredChecks.columns.recorders\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<RecordersCell\n\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\tcheckId={row.original.id}\n\t\t\t\t\t\tworkspaceMode={workspaceMode}\n\t\t\t\t\t\tonGuardianModeRequired={markWorkspaceMode}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"requiredChecks.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<MenuCell\n\t\t\t\t\t\tmenuThreshold={2}\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.edit\"),\n\t\t\t\t\t\t\t\ticon: Pencil,\n\t\t\t\t\t\t\t\tonClick: () => setEditing(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t// Not offered in workspace mode: nothing narrows it there.\n\t\t\t\t\t\t\t...(workspaceMode\n\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.manageRecorders\"),\n\t\t\t\t\t\t\t\t\t\t\ticon: UserCheck,\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => setNarrowing(row.original),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.remove\"),\n\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\tonClick: () => setRemoving(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, client, workspaceMode, markWorkspaceMode],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setEditing(\"new\")}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"requiredChecks.create\")}\n\t\t</Button>\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Toolbar>\n\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t<Toolbar.Count>{t(\"requiredChecks.count\", { count: checks.length })}</Toolbar.Count>\n\t\t\t\t\t{createButton}\n\t\t\t\t</Toolbar.Right>\n\t\t\t</Toolbar>\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"requiredChecks.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t{workspaceMode ? (\n\t\t\t\t<Alert status=\"info\" title={t(\"requiredChecks.workspaceMode.title\")} mx=\"8\" my=\"4\">\n\t\t\t\t\t{t(\"requiredChecks.workspaceMode.description\")}\n\t\t\t\t</Alert>\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={checks as CheckRow[]}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<ListChecks size={32} />}\n\t\t\t\t\t\theader={t(\"requiredChecks.empty\")}\n\t\t\t\t\t\tdescription={t(\"requiredChecks.emptyHint\")}\n\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<RequiredCheckModal\n\t\t\t\topen={editing !== null}\n\t\t\t\tcheck={editing === \"new\" ? null : editing}\n\t\t\t\tonClose={() => setEditing(null)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tif (editing === \"new\") await client.createRequiredCheck(input);\n\t\t\t\t\telse if (editing) await client.updateRequiredCheck({ id: editing.id, ...input });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetEditing(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<RequiredCheckRecordersModal\n\t\t\t\topen={narrowing !== null}\n\t\t\t\tclient={client}\n\t\t\t\tcheck={narrowing}\n\t\t\t\tonClose={() => setNarrowing(null)}\n\t\t\t\tonGuardianModeRequired={markWorkspaceMode}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={removing !== null}\n\t\t\t\ttitle={t(\"requiredChecks.removeDialog.title\")}\n\t\t\t\tmessage={t(\"requiredChecks.removeDialog.message\", { name: removing?.name ?? \"\" })}\n\t\t\t\tconfirmLabel={t(\"requiredChecks.removeDialog.confirm\")}\n\t\t\t\tdanger\n\t\t\t\tfailedMessage={t(\"requiredChecks.removeDialog.failed\")}\n\t\t\t\tonClose={() => setRemoving(null)}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!removing) return;\n\t\t\t\t\tawait client.deleteRequiredCheck({ id: removing.id });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRemoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import { Tabs } from \"@knkcs/anker/primitives\";\nimport { SettingsPageTemplate } from \"@knkcs/anker/templates\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { type ContenthubSettingsTab, useContenthubPaths } from \"../common/paths\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport { BlockReasonsTab } from \"./block-reasons-settings\";\nimport { CollectionsTab } from \"./collections-tab\";\nimport { RequiredChecksTab } from \"./required-checks-tab\";\n\nconst TABS: ContenthubSettingsTab[] = [\"required-checks\", \"block-reasons\", \"collections\"];\nconst TAB_LABELS: Record<ContenthubSettingsTab, string> = {\n\t\"required-checks\": \"settings.tabs.requiredChecks\",\n\t\"block-reasons\": \"settings.tabs.blockReasons\",\n\tcollections: \"settings.tabs.collections\",\n};\n\nexport interface ContenthubSettingsProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * contenthub's workspace configuration in one settings page (spec #56, story\n * 107): Required Checks, Block Reasons and the Collection tree with its\n * restriction and grants, each a tab chosen by `?tab=` so a host links\n * straight to one.\n *\n * Every tab is a flush DataTable whose rows are changed through Modals, so\n * the body is unpadded (`bodyPadding=\"none\"`, anker's rule for table tabs)\n * and there is no header Save: nothing here is a draft. Only the active tab\n * is mounted (nav-link tabs), so no two tabs' Modals or queries live at once.\n */\nexport function ContenthubSettings({ client }: ContenthubSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst asked = searchParams.get(\"tab\") as ContenthubSettingsTab | null;\n\tconst tab: ContenthubSettingsTab = asked && TABS.includes(asked) ? asked : \"required-checks\";\n\n\tconst select = (next: ContenthubSettingsTab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params);\n\t};\n\n\treturn (\n\t\t<SettingsPageTemplate\n\t\t\ttitle={t(\"settings.title\")}\n\t\t\tsubtitle={t(\"settings.subtitle\")}\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"settings.section\"), to: paths.settings },\n\t\t\t\t{ label: t(\"settings.title\") },\n\t\t\t]}\n\t\t\tbodyPadding=\"none\"\n\t\t\tmaxBodyWidth=\"full\"\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => select(e.value as ContenthubSettingsTab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(TAB_LABELS[each])}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{tab === \"required-checks\" ? <RequiredChecksTab client={client} /> : null}\n\t\t\t{tab === \"block-reasons\" ? <BlockReasonsTab client={client} /> : null}\n\t\t\t{tab === \"collections\" ? <CollectionsTab client={client} /> : null}\n\t\t</SettingsPageTemplate>\n\t);\n}\n\nContenthubSettings.displayName = \"ContenthubSettings\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ProtoChangeSetState","ProtoBranchKind","ProtoReleaseKind","ProtoCheckOutcome","ProtoCheckScope","ProtoCollectionAccessLevel","ProtoRevisionCause","ProtoEdgeKind","ProtoFieldChangeKind","ProtoPendingMergeReason","ProtoMergeSide","BranchContentFields","periodText","periodText","ICONS","targetOf","Section","ConnectCode","RefusalAlert","_Fragment","_Fragment","periodText","_Fragment","periodText","EMPTY","FORM_ID","TABS","sameIds","ConnectCode","FORM_ID","RouterLink","FORM_ID","EMPTY","FORM_ID","EMPTY","FORM_ID","TABS","ConnectCode","EMPTY","StaleHeadError","RestrictionUnavailableError","REQUIRED_CHECK_NAME_MAX","StatusTransitionRefusedError","WithheldWorkError","SOURCE_REFERENCE_MAX","InvalidInputError","PublishRefusedError","ContentArchivedError","localToday","CoversReleaseError","BLOCK_REASON_NAME_MAX","CHANGE_SET_NAME_MAX","CHECK_NOTE_MAX","CheckResultDeniedError","inForceOnOrAfter","StaleStatusError","ServiceUnavailableError","BLUEPRINT_ACCESSOR_MAX","CONTENT_SEARCH_MAX","releaseInForceOn","COLLECTION_NAME_MAX","DAY","AccessDeniedError","headsOf","BlockReasonNameTakenError","ContentBlockedError","NameTakenError","GuardianModeRequiredError","ContentRefusedError","NEW_CHANGE_SET","collectionPath","CONTENTHUB_UI_NS","contenthubTranslations","ChangeSetChoiceFields","useOpenChangeSets","contenthubKeys","ContentLibrary","changeSetChoiceIssue","i18nResources","contentLabel","CreateChangeSetModal","COLLECTION_PARAM","useBlueprintSource","usePageRail$1","Link$1","file_contenthub_v1_workspace_config","file_google_protobuf_struct","file_google_protobuf_timestamp","GuardianModeRequiredSchema","RefusalSchema","CheckScope","\"UNSPECIFIED\"","\"BRANCH\"","\"CHANGE_SET\"","WorkspaceConfigService","BlueprintCatalogService","fileDesc","file_contenthub_v1_content_graph","EdgeKind","\"REFERENCE\"","\"TOC\"","\"INCLUDE\"","\"EXCLUDE\"","\"REPLACE\"","\"ANNOTATE\"","\"LINK\"","\"FOOTNOTE\"","\"ANCHOR\"","\"MEDIA\"","\"BLUEPRINT\"","file_contenthub_v1_release","PublishBlockerSchema","ReleaseKind","\"REVISION\"","\"DATE_ONLY\"","\"REPEAL\"","\"WITHDRAWAL\"","file_contenthub_v1_release_read","ReleaseService","file_contenthub_v1_graph_warnings","file_contenthub_v1_merge","PendingMergeReason","\"CONFLICT\"","\"INVALID\"","MergeSide","\"OURS\"","\"THEIRS\"","file_contenthub_v1_planning","CoversReleaseSchema","file_contenthub_v1_change_set","StaleHeadSchema","ChangeSetClosedSchema","WithheldWorkSchema","StaleStatusSchema","StatusTransitionRefusedSchema","ViolationSchema","ChangeSetState","\"OPEN\"","\"PUBLISHED\"","\"DISCARDED\"","BranchKind","\"EDITORIAL\"","\"CARRY_FORWARD\"","CheckOutcome","\"PASSED\"","\"FAILED\"","\"WAIVED\"","ChangeSetService","file_contenthub_v1_collection","CollectionAccessLevel","\"VIEWER\"","\"EDITOR\"","\"OWNER\"","CollectionService","file_contenthub_v1_revision","RevisionCause","\"CREATE\"","\"SAVE\"","\"MERGE\"","\"RESOLVE\"","\"UPGRADE\"","FieldChangeKind","\"ADDED\"","\"REMOVED\"","\"CHANGED\"","file_contenthub_v1_content","ContentBlockedSchema","ContentArchivedSchema","ContentService","iso","ts","timestampDate","catalogReleaseFromProto","r","v","catalogRead","call","err","ce","ConnectError","Code","blockReasonFromProto","STATE_FROM_PROTO","STATE_TO_PROTO","stateFromProto","state","changeSetFromProto","cs","chain","b","plannedReleaseFromProto","KIND_FROM_PROTO","periodFromProto","p","pr","releaseFromProto","blockerFromProto","pendingFromProto","jsonOf","toJson","ValueSchema","mergeFieldFromProto","f","planRefusal","covers","saveRefusal","changeSetId","struct","values","OUTCOME_FROM_PROTO","OUTCOME_TO_PROTO","checkResultFromProto","requiredCheckFromProto","c","collectionFromProto","SCOPE_TO_PROTO","LEVEL_FROM_PROTO","COLLECTION_RESTRICTION","settingsRefusal","name","guardianMode","recorderToProto","settingsWrite","contentFromProto","attributesFromProto","a","resolvedReleaseFromBytes","bytes","doc","fields","parts","timelineEntryFromProto","requiredPlannedRelease","CAUSES","revisionFromProto","EDGE_KINDS","edgeFromProto","plannedEndFromProto","res","g","editRefusal","blocked","archived","changeSetRefusal","attributeWrite","contentRefusal","reasons","refused","stale","closed","id","ChangeSetClosedError","blockers","moved","changeSetWrite","nameRefusal","createConnectContenthubClient","transport","options","createConnectTransport","config","createClient","changeSets","contents","collections","releases","catalog","input","updateMask","idempotencyKey","dependsOnId","chainId","st","outcome","recorder","level","view","copyFrom","data","fieldMask","branchId","target","pageSize","pageToken","base","kinds","revisionId","includeOpenChangeSets","effectiveOn","changeSetName","releaseSpec","supersedesReleaseIds","resolutions","fromJson","row","contentId","validOn","STANDALONE_CONTENTHUB_PATHS","contenthubSettingsPath","tab","paths","PathsContext","createContext","ContenthubPathsProvider","useContenthubPaths","useContext","BlockReasonNameModal","useTranslation","formId","mode","schema","useMemo","z","t","methods","useForm","zodResolver","initialName","failed","setFailed","useState","submitting","open","submit","onSubmit","Modal","HStack","Button","onClose","FormProvider","Stack","InputField","Alert","RemoveBlockReasonModal","reason","shown","setShown","removing","setRemoving","confirm","onConfirm","Text","useBlockReasons","useQuery","client","CreateBlockReasonButton","Plus","label","BlockReasonsBody","queryClient","useQueryClient","renaming","setRenaming","query","refresh","columns","TruncatedTextCell","DateCell","MenuCell","Pencil","Trash2","toolbar","DataTable","EmptyState","Lock","onCreatingChange","creating","BlockReasonsCount","count","Toolbar","BlockReasonsTab","setCreating","BlockReasonsSettings","IndexPageTemplate","isAnswer","newIdempotencyKey","what","useAttemptKey","attempt","useRef","useCallback","json","asked","ContentDataFields","lazy","valueText","value","plainRows","declared","known","rest","k","ContentDataTab","detail","labels","Box","content","blueprintRelease","Suspense","Spinner","Card","DescriptionList","BranchCompareTab","born","against","compareBase","comparison","headRevisionId","SlugCell","onCompareBase","BranchContentFields$1","BranchContentTab","release","record","BranchContentFields","periodText$2","planIssues","dated","issues","BranchReleaseTab","ctx","planning","useWatch","firstDay","lastDay","published","timeline","releaseOptions","canPreview","preview","proposals","changeSet","readOnly","BaseSelectField","Heading","CalendarPlus","contentRefusalText","BranchUpdateModal","setOutcome","failure","setFailure","running","setRunning","settle","run","keyFor","stopped","merged","onResolve","ResolveMergeModal","resolveKey","abortKey","pending","busy","setBusy","pm","nameOf","accessor","path","resolve","undecided","choices","i","request","onDone","abort","RadioGroupField","PreviewModal","defaultDay","day","valid","AppendBranchModal","after","ICONS$1","GitMerge","Wrench","GitCompare","Eye","GitPullRequestArrow","BranchRail","ContextRail","actions","Zap","Icon","action","onAction","Info","about","targetOf$1","edge","Section$1","title","children","BranchReferencesTab","outgoing","pins","outgoingColumns","pinColumns","index","ConfirmModal","message","confirmLabel","danger","failedMessage","refusal","setRefusal","withoutRequired","clear","out","key","CONTENT","RELEASE","COMPARE","BRANCH_EDITOR_TABS","BranchEditor","BranchEditorFrame","props","TabDirtyProvider","BranchScreen","kitLoad","loadKit","m","useFormKit","kit","setKit","useEffect","live","loaded","sameJSON","canonical","x","y","changedFields","baseline","draft","formPath","part","planValuesOf","planned","branch","settleForm","form","sent","useTabDirty","searchParams","setSearchParams","useSearchParams","tabParam","tabs","each","readKey","changeSetKey","setRecord","head","contentKey","releaseKey","resolverRef","context","seeded","setSeeded","planForm","specResolverRef","specForm","setPlanned","releaseSeeded","setReleaseSeeded","seed","defaults","specFields","plan","contentDirty","setTabDirty","releaseDirty","saving","setSaving","saved","setSaved","changed","dirtyTabs","setCompareBase","dialog","setDialog","closeDialog","dropKey","selectTab","params","current","next","saveContent","mask","snapshot","parsed","saveRelease","validityPeriod","sentPlan","spec","result","save","doContent","doRelease","planSnapshot","issue","contentSaved","reload","fresh","headMoved","pendingMerge","railActions","offered","onRailAction","notFound","DetailPageTemplate","otherBranch","active","lastEditorial","TypeBadge","Save","Tabs","RefusalAlert$1","ids","UnsavedChangesGuard","appended","onOpenBranch","onDeleted","savedFirst","reloading","onReload","RotateCcw","onSupersede","NO_STATUSES","useChangeSetStatuses","statuses","source","labelOf","slug","s","available","failureOf","summaryOf","UpdateFromMainModal","Fragment","DiscardChangeSetModal","subjectText","standingKey","ChangeSetChecksTab","useHostIdentity","standingLabel","latest","members","StatusBadgeCell","canRecord","ActionCell","ClipboardCheck","onRecord","loading","standings","ListChecks","branchToOpen","ChangeSetContentsTab","CountCell","BooleanCell","FileText","generalValuesOf","DEPENDENCY_CANDIDATES","ChangeSetGeneralTab","statusOptions","o","assigneeOptions","unknown","searchDependencies","q","resolveDependencies","createdBy","status","LookupSelectField","periodText$1","period","coveredRows","rows","ChangeSetReleasesTab","originText","covered","coveredColumns","CalendarRange","KNOWN","blockerMessage","checkName","FIXED_IN_EDITOR","PublishBlockerList","onOpenContent","PublishReviewModal","reviewed","setReviewed","stage","setStage","publishing","setPublishing","session","review","heads","answer","onReviewed","publish","previous","contentOf","ready","Send","refusalKey","EMPTY$4","FORM_ID$5","OUTCOMES","RecordCheckResultModal","standing","TextareaField","TABS$2","GENERAL","NO_VALUES","ChangeSetPage","ChangeSetEditor","sameIds$1","trimmed","updateMaskOf","was","statusSource","setBaseline","generalDirty","updateKeyFor","settleUpdateKey","saveAll","wanted","isOpen","freshHeads","readiness","checkNames","names","recording","setRecording","refreshReview","adopt","kept","onPublished","updateFromMain","discard","onDiscarded","openRecord","blockerCount","railStatus","openContent","StatusBadge","RefusalAlert","STATES","ME","PAGE_SIZE","ChangeSetsIndex","setState","assignee","setAssignee","filter","userId","useInfiniteQuery","pageParam","last","keepPreviousData","page","createButton","NativeSelect","onOpenChangeSet","FolderGit2","created","ArchiveContentModal","FORM_ID$4","BlockContentModal","empty","reasonOptions","userOptions","noReasons","Link","REVISIONS_PAGE","useContentChangeSets","ContentRevisionsTab","revisions","selected","setSelected","changeSetOf","History","RevisionComparison","revision","ContentChangeSetsTab","GitBranch","filingValuesOf","pathOf","seen","parent","all","ContentFilingTab","collectionOptions","attributes","ICONS","PencilLine","Copy","FileX","Ban","LockOpen","Archive","ArchiveRestore","ContentRail","REFERRERS_PAGE","targetOf","Section","ContentReferencesTab","referrerPages","referrers","pinSource","kindColumn","pathColumn","referrerColumns","openTarget","periodText","useContentTimeline","ContentReleasesTab","openChangeSets","inForce","entryColumns","NumberCell","plannedColumns","CalendarClock","FORM_ID$3","EMPTY$3","DuplicateContentModal","copy","onCreated","FORM_ID$2","EMPTY$2","EndForceModal","kind","FORM_ID$1","StartEditingModal","isNew","started","onStarted","TABS$1","NO_FILING","ContentPage","ContentScreen","sameIds","blueprintSource","blueprintName","blockReasons","filingDirty","applyAttributes","old","writeNow","write","entries","today","publishedKnown","list","blockReason","blockedBy","railLabels","rail","EMPTY$1","LEVEL_KEYS","CollectionAccessModal","me","collection","grants","picked","unavailable","onRestrictionUnavailable","roster","owner","granted","candidates","levels","grant","revoke","loadError","ROOT","placeOptions","rootLabel","except","isWithin","CollectionFormModal","initial","parents","canRestrict","SwitchField","MoveCollectionModal","places","treeOrder","walk","CollectionsTab","moving","setMoving","confirming","setConfirming","managing","setManaging","restrictionUnavailable","setRestrictionUnavailable","markUnavailable","learning","above","FolderInput","Users","confirmText","FolderTree","FORM_ID","SCOPE_LABELS","valuesOf","check","accessorsOf","text","RequiredCheckModal","everyBlueprint","scopeOptions","fail","field","accessors","EMPTY","retryRecorders","failures","RequiredCheckRecordersModal","recorders","onGuardianModeRequired","everyMember","named","change","add","RecordersCell","checkId","workspaceMode","u","RequiredChecksTab","editing","setEditing","narrowing","setNarrowing","setWorkspaceMode","markWorkspaceMode","checks","UserCheck","TABS","TAB_LABELS","ContenthubSettings","select","SettingsPageTemplate"],"sources":["../../../gen/ts/contenthub/v1/workspace_config_pb.ts","../../../gen/ts/contenthub/v1/blueprint_catalog_pb.ts","../../../gen/ts/contenthub/v1/content_graph_pb.ts","../../../gen/ts/contenthub/v1/release_pb.ts","../../../gen/ts/contenthub/v1/release_read_pb.ts","../../../gen/ts/contenthub/v1/graph_warnings_pb.ts","../../../gen/ts/contenthub/v1/merge_pb.ts","../../../gen/ts/contenthub/v1/planning_pb.ts","../../../gen/ts/contenthub/v1/change_set_pb.ts","../../../gen/ts/contenthub/v1/collection_pb.ts","../../../gen/ts/contenthub/v1/revision_pb.ts","../../../gen/ts/contenthub/v1/content_pb.ts","../src/client/connect-contenthub-client.ts","../src/common/paths.tsx","../src/screens/block-reason-name-modal.tsx","../src/screens/remove-block-reason-modal.tsx","../src/screens/block-reasons-settings.tsx","../src/common/idempotency.ts","../src/screens/content-data-tab.tsx","../src/screens/branch-compare-tab.tsx","../src/screens/branch-content-tab.tsx","../src/screens/branch-release-tab.tsx","../src/screens/content-refusal.ts","../src/screens/branch-dialogs.tsx","../src/screens/branch-rail.tsx","../src/screens/branch-references-tab.tsx","../src/screens/confirm-modal.tsx","../src/screens/required-fields.ts","../src/screens/branch-editor.tsx","../src/common/use-change-set-statuses.ts","../src/screens/change-set-action-modals.tsx","../src/screens/change-set-checks-tab.tsx","../src/screens/change-set-contents-tab.tsx","../src/screens/change-set-general-tab.tsx","../src/screens/change-set-releases-tab.tsx","../src/screens/publish-blockers.tsx","../src/screens/publish-review-modal.tsx","../src/screens/record-check-result-modal.tsx","../src/screens/change-set-page.tsx","../src/screens/change-sets-index.tsx","../src/screens/archive-content-modal.tsx","../src/screens/block-content-modal.tsx","../src/screens/content-revisions-tab.tsx","../src/screens/content-change-sets-tab.tsx","../src/screens/content-filing-tab.tsx","../src/screens/content-rail.tsx","../src/screens/content-references-tab.tsx","../src/screens/content-releases-tab.tsx","../src/screens/duplicate-content-modal.tsx","../src/screens/end-force-modal.tsx","../src/screens/start-editing-modal.tsx","../src/screens/content-page.tsx","../src/screens/collection-access-modal.tsx","../src/screens/collection-modals.tsx","../src/screens/collections-tab.tsx","../src/screens/required-check-modal.tsx","../src/screens/required-check-recorders-modal.tsx","../src/screens/required-checks-tab.tsx","../src/screens/contenthub-settings.tsx"],"sourcesContent":["// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/workspace_config.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/workspace_config.proto.\n */\nexport const file_contenthub_v1_workspace_config: GenFile = /*@__PURE__*/\n fileDesc(\"CiRjb250ZW50aHViL3YxL3dvcmtzcGFjZV9jb25maWcucHJvdG8SDWNvbnRlbnRodWIudjEiiQEKC0Jsb2NrUmVhc29uEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSLwoLY3JlYXRlX3RpbWUYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC3VwZGF0ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIoChhDcmVhdGVCbG9ja1JlYXNvblJlcXVlc3QSDAoEbmFtZRgBIAEoCSJNChlDcmVhdGVCbG9ja1JlYXNvblJlc3BvbnNlEjAKDGJsb2NrX3JlYXNvbhgBIAEoCzIaLmNvbnRlbnRodWIudjEuQmxvY2tSZWFzb24iGQoXTGlzdEJsb2NrUmVhc29uc1JlcXVlc3QiTQoYTGlzdEJsb2NrUmVhc29uc1Jlc3BvbnNlEjEKDWJsb2NrX3JlYXNvbnMYASADKAsyGi5jb250ZW50aHViLnYxLkJsb2NrUmVhc29uIjQKGFJlbmFtZUJsb2NrUmVhc29uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJIk0KGVJlbmFtZUJsb2NrUmVhc29uUmVzcG9uc2USMAoMYmxvY2tfcmVhc29uGAEgASgLMhouY29udGVudGh1Yi52MS5CbG9ja1JlYXNvbiImChhEZWxldGVCbG9ja1JlYXNvblJlcXVlc3QSCgoCaWQYASABKAkiGwoZRGVsZXRlQmxvY2tSZWFzb25SZXNwb25zZSLnAQoNUmVxdWlyZWRDaGVjaxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEigKBXNjb3BlGAMgASgOMhkuY29udGVudGh1Yi52MS5DaGVja1Njb3BlEhsKE2JsdWVwcmludF9hY2Nlc3NvcnMYBCADKAkSEwoLaW5kZXBlbmRlbnQYBSABKAgSLwoLY3JlYXRlX3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC3VwZGF0ZV90aW1lGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKGAQoaQ3JlYXRlUmVxdWlyZWRDaGVja1JlcXVlc3QSDAoEbmFtZRgBIAEoCRIoCgVzY29wZRgCIAEoDjIZLmNvbnRlbnRodWIudjEuQ2hlY2tTY29wZRIbChNibHVlcHJpbnRfYWNjZXNzb3JzGAMgAygJEhMKC2luZGVwZW5kZW50GAQgASgIIlMKG0NyZWF0ZVJlcXVpcmVkQ2hlY2tSZXNwb25zZRI0Cg5yZXF1aXJlZF9jaGVjaxgBIAEoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayIbChlMaXN0UmVxdWlyZWRDaGVja3NSZXF1ZXN0IlMKGkxpc3RSZXF1aXJlZENoZWNrc1Jlc3BvbnNlEjUKD3JlcXVpcmVkX2NoZWNrcxgBIAMoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayKSAQoaVXBkYXRlUmVxdWlyZWRDaGVja1JlcXVlc3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIoCgVzY29wZRgDIAEoDjIZLmNvbnRlbnRodWIudjEuQ2hlY2tTY29wZRIbChNibHVlcHJpbnRfYWNjZXNzb3JzGAQgAygJEhMKC2luZGVwZW5kZW50GAUgASgIIlMKG1VwZGF0ZVJlcXVpcmVkQ2hlY2tSZXNwb25zZRI0Cg5yZXF1aXJlZF9jaGVjaxgBIAEoCzIcLmNvbnRlbnRodWIudjEuUmVxdWlyZWRDaGVjayIoChpEZWxldGVSZXF1aXJlZENoZWNrUmVxdWVzdBIKCgJpZBgBIAEoCSIdChtEZWxldGVSZXF1aXJlZENoZWNrUmVzcG9uc2UiQQoIUmVjb3JkZXISEQoHdXNlcl9pZBgBIAEoCUgAEhYKDGV2ZXJ5X21lbWJlchgCIAEoCEgAQgoKCHJlY29yZGVyIj4KIUxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzUmVxdWVzdBIZChFyZXF1aXJlZF9jaGVja19pZBgBIAEoCSJMCiJMaXN0UmVxdWlyZWRDaGVja1JlY29yZGVyc1Jlc3BvbnNlEhQKDGV2ZXJ5X21lbWJlchgBIAEoCBIQCgh1c2VyX2lkcxgCIAMoCSJpCiFHcmFudFJlcXVpcmVkQ2hlY2tSZWNvcmRlclJlcXVlc3QSGQoRcmVxdWlyZWRfY2hlY2tfaWQYASABKAkSKQoIcmVjb3JkZXIYAiABKAsyFy5jb250ZW50aHViLnYxLlJlY29yZGVyIiQKIkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UiagoiUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVxdWVzdBIZChFyZXF1aXJlZF9jaGVja19pZBgBIAEoCRIpCghyZWNvcmRlchgCIAEoCzIXLmNvbnRlbnRodWIudjEuUmVjb3JkZXIiJQojUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UiJwoUR3VhcmRpYW5Nb2RlUmVxdWlyZWQSDwoHZmVhdHVyZRgBIAEoCSI4ChxDaGVja0JsdWVwcmludFJlbGVhc2VSZXF1ZXN0EhgKEHJlc29sdmVkX3JlbGVhc2UYASABKAwiSQodQ2hlY2tCbHVlcHJpbnRSZWxlYXNlUmVzcG9uc2USKAoIcmVmdXNhbHMYASADKAsyFi5jb250ZW50aHViLnYxLlJlZnVzYWwiXgoHUmVmdXNhbBIOCgZzb3VyY2UYASABKAkSDAoEY29kZRgCIAEoCRIMCgRwYXRoGAMgASgJEicKBnBhcmFtcxgEIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QqXQoKQ2hlY2tTY29wZRIbChdDSEVDS19TQ09QRV9VTlNQRUNJRklFRBAAEhYKEkNIRUNLX1NDT1BFX0JSQU5DSBABEhoKFkNIRUNLX1NDT1BFX0NIQU5HRV9TRVQQAjLtCgoWV29ya3NwYWNlQ29uZmlnU2VydmljZRJmChFDcmVhdGVCbG9ja1JlYXNvbhInLmNvbnRlbnRodWIudjEuQ3JlYXRlQmxvY2tSZWFzb25SZXF1ZXN0GiguY29udGVudGh1Yi52MS5DcmVhdGVCbG9ja1JlYXNvblJlc3BvbnNlEmMKEExpc3RCbG9ja1JlYXNvbnMSJi5jb250ZW50aHViLnYxLkxpc3RCbG9ja1JlYXNvbnNSZXF1ZXN0GicuY29udGVudGh1Yi52MS5MaXN0QmxvY2tSZWFzb25zUmVzcG9uc2USZgoRUmVuYW1lQmxvY2tSZWFzb24SJy5jb250ZW50aHViLnYxLlJlbmFtZUJsb2NrUmVhc29uUmVxdWVzdBooLmNvbnRlbnRodWIudjEuUmVuYW1lQmxvY2tSZWFzb25SZXNwb25zZRJmChFEZWxldGVCbG9ja1JlYXNvbhInLmNvbnRlbnRodWIudjEuRGVsZXRlQmxvY2tSZWFzb25SZXF1ZXN0GiguY29udGVudGh1Yi52MS5EZWxldGVCbG9ja1JlYXNvblJlc3BvbnNlEmwKE0NyZWF0ZVJlcXVpcmVkQ2hlY2sSKS5jb250ZW50aHViLnYxLkNyZWF0ZVJlcXVpcmVkQ2hlY2tSZXF1ZXN0GiouY29udGVudGh1Yi52MS5DcmVhdGVSZXF1aXJlZENoZWNrUmVzcG9uc2USaQoSTGlzdFJlcXVpcmVkQ2hlY2tzEiguY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja3NSZXF1ZXN0GikuY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja3NSZXNwb25zZRJsChNVcGRhdGVSZXF1aXJlZENoZWNrEikuY29udGVudGh1Yi52MS5VcGRhdGVSZXF1aXJlZENoZWNrUmVxdWVzdBoqLmNvbnRlbnRodWIudjEuVXBkYXRlUmVxdWlyZWRDaGVja1Jlc3BvbnNlEmwKE0RlbGV0ZVJlcXVpcmVkQ2hlY2sSKS5jb250ZW50aHViLnYxLkRlbGV0ZVJlcXVpcmVkQ2hlY2tSZXF1ZXN0GiouY29udGVudGh1Yi52MS5EZWxldGVSZXF1aXJlZENoZWNrUmVzcG9uc2USgQEKGkxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzEjAuY29udGVudGh1Yi52MS5MaXN0UmVxdWlyZWRDaGVja1JlY29yZGVyc1JlcXVlc3QaMS5jb250ZW50aHViLnYxLkxpc3RSZXF1aXJlZENoZWNrUmVjb3JkZXJzUmVzcG9uc2USgQEKGkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyEjAuY29udGVudGh1Yi52MS5HcmFudFJlcXVpcmVkQ2hlY2tSZWNvcmRlclJlcXVlc3QaMS5jb250ZW50aHViLnYxLkdyYW50UmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UShAEKG1Jldm9rZVJlcXVpcmVkQ2hlY2tSZWNvcmRlchIxLmNvbnRlbnRodWIudjEuUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVxdWVzdBoyLmNvbnRlbnRodWIudjEuUmV2b2tlUmVxdWlyZWRDaGVja1JlY29yZGVyUmVzcG9uc2UScgoVQ2hlY2tCbHVlcHJpbnRSZWxlYXNlEisuY29udGVudGh1Yi52MS5DaGVja0JsdWVwcmludFJlbGVhc2VSZXF1ZXN0GiwuY29udGVudGh1Yi52MS5DaGVja0JsdWVwcmludFJlbGVhc2VSZXNwb25zZUI8WjpnaXRodWIuY29tL2tua2NzL2NvbnRlbnRodWIvZ2VuL2NvbnRlbnRodWIvdjE7Y29udGVudGh1YnYxYgZwcm90bzM\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * BlockReason is one of a workspace's own reasons a Content may be blocked,\n * such as \"being revised by the author\" (CONTEXT.md). It is configuration, not\n * versioned.\n *\n * @generated from message contenthub.v1.BlockReason\n */\nexport type BlockReason = Message<\"contenthub.v1.BlockReason\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 3;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 4;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.BlockReason.\n * Use `create(BlockReasonSchema)` to create a new message.\n */\nexport const BlockReasonSchema: GenMessage<BlockReason> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 0);\n\n/**\n * @generated from message contenthub.v1.CreateBlockReasonRequest\n */\nexport type CreateBlockReasonRequest = Message<\"contenthub.v1.CreateBlockReasonRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, and no other Block Reason\n * of the workspace may have it. Surrounding whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateBlockReasonRequest.\n * Use `create(CreateBlockReasonRequestSchema)` to create a new message.\n */\nexport const CreateBlockReasonRequestSchema: GenMessage<CreateBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 1);\n\n/**\n * @generated from message contenthub.v1.CreateBlockReasonResponse\n */\nexport type CreateBlockReasonResponse = Message<\"contenthub.v1.CreateBlockReasonResponse\"> & {\n /**\n * @generated from field: contenthub.v1.BlockReason block_reason = 1;\n */\n blockReason?: BlockReason | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateBlockReasonResponse.\n * Use `create(CreateBlockReasonResponseSchema)` to create a new message.\n */\nexport const CreateBlockReasonResponseSchema: GenMessage<CreateBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 2);\n\n/**\n * @generated from message contenthub.v1.ListBlockReasonsRequest\n */\nexport type ListBlockReasonsRequest = Message<\"contenthub.v1.ListBlockReasonsRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListBlockReasonsRequest.\n * Use `create(ListBlockReasonsRequestSchema)` to create a new message.\n */\nexport const ListBlockReasonsRequestSchema: GenMessage<ListBlockReasonsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 3);\n\n/**\n * @generated from message contenthub.v1.ListBlockReasonsResponse\n */\nexport type ListBlockReasonsResponse = Message<\"contenthub.v1.ListBlockReasonsResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.BlockReason block_reasons = 1;\n */\n blockReasons: BlockReason[];\n};\n\n/**\n * Describes the message contenthub.v1.ListBlockReasonsResponse.\n * Use `create(ListBlockReasonsResponseSchema)` to create a new message.\n */\nexport const ListBlockReasonsResponseSchema: GenMessage<ListBlockReasonsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 4);\n\n/**\n * @generated from message contenthub.v1.RenameBlockReasonRequest\n */\nexport type RenameBlockReasonRequest = Message<\"contenthub.v1.RenameBlockReasonRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The new name, under the rules of CreateBlockReasonRequest.name.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.RenameBlockReasonRequest.\n * Use `create(RenameBlockReasonRequestSchema)` to create a new message.\n */\nexport const RenameBlockReasonRequestSchema: GenMessage<RenameBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 5);\n\n/**\n * @generated from message contenthub.v1.RenameBlockReasonResponse\n */\nexport type RenameBlockReasonResponse = Message<\"contenthub.v1.RenameBlockReasonResponse\"> & {\n /**\n * @generated from field: contenthub.v1.BlockReason block_reason = 1;\n */\n blockReason?: BlockReason | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RenameBlockReasonResponse.\n * Use `create(RenameBlockReasonResponseSchema)` to create a new message.\n */\nexport const RenameBlockReasonResponseSchema: GenMessage<RenameBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 6);\n\n/**\n * @generated from message contenthub.v1.DeleteBlockReasonRequest\n */\nexport type DeleteBlockReasonRequest = Message<\"contenthub.v1.DeleteBlockReasonRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.DeleteBlockReasonRequest.\n * Use `create(DeleteBlockReasonRequestSchema)` to create a new message.\n */\nexport const DeleteBlockReasonRequestSchema: GenMessage<DeleteBlockReasonRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 7);\n\n/**\n * @generated from message contenthub.v1.DeleteBlockReasonResponse\n */\nexport type DeleteBlockReasonResponse = Message<\"contenthub.v1.DeleteBlockReasonResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.DeleteBlockReasonResponse.\n * Use `create(DeleteBlockReasonResponseSchema)` to create a new message.\n */\nexport const DeleteBlockReasonResponseSchema: GenMessage<DeleteBlockReasonResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 8);\n\n/**\n * RequiredCheck is a condition the workspace requires to have passed before\n * Publish, such as a lawyer's approval or a print round trip (CONTEXT.md).\n * It is configuration, never released and not versioned.\n *\n * @generated from message contenthub.v1.RequiredCheck\n */\nexport type RequiredCheck = Message<\"contenthub.v1.RequiredCheck\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: contenthub.v1.CheckScope scope = 3;\n */\n scope: CheckScope;\n\n /**\n * The accessors of the Blueprints whose Content it applies to, sorted;\n * empty means every Blueprint.\n *\n * @generated from field: repeated string blueprint_accessors = 4;\n */\n blueprintAccessors: string[];\n\n /**\n * When set, passed and waived are refused from anyone who authored a\n * Revision on the Branches the result covers; failed is accepted from\n * anyone.\n *\n * @generated from field: bool independent = 5;\n */\n independent: boolean;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 7;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RequiredCheck.\n * Use `create(RequiredCheckSchema)` to create a new message.\n */\nexport const RequiredCheckSchema: GenMessage<RequiredCheck> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 9);\n\n/**\n * @generated from message contenthub.v1.CreateRequiredCheckRequest\n */\nexport type CreateRequiredCheckRequest = Message<\"contenthub.v1.CreateRequiredCheckRequest\"> & {\n /**\n * Required: not blank, one line, at most 200 characters, and no other\n * Required Check of the workspace may have it. Surrounding whitespace is\n * trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.CheckScope scope = 2;\n */\n scope: CheckScope;\n\n /**\n * Blueprint accessors; empty means every Blueprint. Duplicates are\n * dropped.\n *\n * @generated from field: repeated string blueprint_accessors = 3;\n */\n blueprintAccessors: string[];\n\n /**\n * @generated from field: bool independent = 4;\n */\n independent: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CreateRequiredCheckRequest.\n * Use `create(CreateRequiredCheckRequestSchema)` to create a new message.\n */\nexport const CreateRequiredCheckRequestSchema: GenMessage<CreateRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 10);\n\n/**\n * @generated from message contenthub.v1.CreateRequiredCheckResponse\n */\nexport type CreateRequiredCheckResponse = Message<\"contenthub.v1.CreateRequiredCheckResponse\"> & {\n /**\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateRequiredCheckResponse.\n * Use `create(CreateRequiredCheckResponseSchema)` to create a new message.\n */\nexport const CreateRequiredCheckResponseSchema: GenMessage<CreateRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 11);\n\n/**\n * @generated from message contenthub.v1.ListRequiredChecksRequest\n */\nexport type ListRequiredChecksRequest = Message<\"contenthub.v1.ListRequiredChecksRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredChecksRequest.\n * Use `create(ListRequiredChecksRequestSchema)` to create a new message.\n */\nexport const ListRequiredChecksRequestSchema: GenMessage<ListRequiredChecksRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 12);\n\n/**\n * @generated from message contenthub.v1.ListRequiredChecksResponse\n */\nexport type ListRequiredChecksResponse = Message<\"contenthub.v1.ListRequiredChecksResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.RequiredCheck required_checks = 1;\n */\n requiredChecks: RequiredCheck[];\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredChecksResponse.\n * Use `create(ListRequiredChecksResponseSchema)` to create a new message.\n */\nexport const ListRequiredChecksResponseSchema: GenMessage<ListRequiredChecksResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 13);\n\n/**\n * @generated from message contenthub.v1.UpdateRequiredCheckRequest\n */\nexport type UpdateRequiredCheckRequest = Message<\"contenthub.v1.UpdateRequiredCheckRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Every field is replaced, under the rules of CreateRequiredCheckRequest.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * @generated from field: contenthub.v1.CheckScope scope = 3;\n */\n scope: CheckScope;\n\n /**\n * @generated from field: repeated string blueprint_accessors = 4;\n */\n blueprintAccessors: string[];\n\n /**\n * @generated from field: bool independent = 5;\n */\n independent: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateRequiredCheckRequest.\n * Use `create(UpdateRequiredCheckRequestSchema)` to create a new message.\n */\nexport const UpdateRequiredCheckRequestSchema: GenMessage<UpdateRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 14);\n\n/**\n * @generated from message contenthub.v1.UpdateRequiredCheckResponse\n */\nexport type UpdateRequiredCheckResponse = Message<\"contenthub.v1.UpdateRequiredCheckResponse\"> & {\n /**\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateRequiredCheckResponse.\n * Use `create(UpdateRequiredCheckResponseSchema)` to create a new message.\n */\nexport const UpdateRequiredCheckResponseSchema: GenMessage<UpdateRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 15);\n\n/**\n * @generated from message contenthub.v1.DeleteRequiredCheckRequest\n */\nexport type DeleteRequiredCheckRequest = Message<\"contenthub.v1.DeleteRequiredCheckRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.DeleteRequiredCheckRequest.\n * Use `create(DeleteRequiredCheckRequestSchema)` to create a new message.\n */\nexport const DeleteRequiredCheckRequestSchema: GenMessage<DeleteRequiredCheckRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 16);\n\n/**\n * @generated from message contenthub.v1.DeleteRequiredCheckResponse\n */\nexport type DeleteRequiredCheckResponse = Message<\"contenthub.v1.DeleteRequiredCheckResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.DeleteRequiredCheckResponse.\n * Use `create(DeleteRequiredCheckResponseSchema)` to create a new message.\n */\nexport const DeleteRequiredCheckResponseSchema: GenMessage<DeleteRequiredCheckResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 17);\n\n/**\n * Recorder is who a recorder grant names: one user, or every member of the\n * workspace (`core/workspace:<W>#member`).\n *\n * @generated from message contenthub.v1.Recorder\n */\nexport type Recorder = Message<\"contenthub.v1.Recorder\"> & {\n /**\n * @generated from oneof contenthub.v1.Recorder.recorder\n */\n recorder: {\n /**\n * An odon user id, a member of the workspace.\n *\n * @generated from field: string user_id = 1;\n */\n value: string;\n case: \"userId\";\n } | {\n /**\n * Every member of the workspace, now and later; only true is meaningful.\n *\n * @generated from field: bool every_member = 2;\n */\n value: boolean;\n case: \"everyMember\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.Recorder.\n * Use `create(RecorderSchema)` to create a new message.\n */\nexport const RecorderSchema: GenMessage<Recorder> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 18);\n\n/**\n * @generated from message contenthub.v1.ListRequiredCheckRecordersRequest\n */\nexport type ListRequiredCheckRecordersRequest = Message<\"contenthub.v1.ListRequiredCheckRecordersRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredCheckRecordersRequest.\n * Use `create(ListRequiredCheckRecordersRequestSchema)` to create a new message.\n */\nexport const ListRequiredCheckRecordersRequestSchema: GenMessage<ListRequiredCheckRecordersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 19);\n\n/**\n * @generated from message contenthub.v1.ListRequiredCheckRecordersResponse\n */\nexport type ListRequiredCheckRecordersResponse = Message<\"contenthub.v1.ListRequiredCheckRecordersResponse\"> & {\n /**\n * Whether every member of the workspace records the check.\n *\n * @generated from field: bool every_member = 1;\n */\n everyMember: boolean;\n\n /**\n * The users granted by name, sorted. Unpaginated: bounded by the\n * workspace's members.\n *\n * @generated from field: repeated string user_ids = 2;\n */\n userIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ListRequiredCheckRecordersResponse.\n * Use `create(ListRequiredCheckRecordersResponseSchema)` to create a new message.\n */\nexport const ListRequiredCheckRecordersResponseSchema: GenMessage<ListRequiredCheckRecordersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 20);\n\n/**\n * @generated from message contenthub.v1.GrantRequiredCheckRecorderRequest\n */\nexport type GrantRequiredCheckRecorderRequest = Message<\"contenthub.v1.GrantRequiredCheckRecorderRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.Recorder recorder = 2;\n */\n recorder?: Recorder | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GrantRequiredCheckRecorderRequest.\n * Use `create(GrantRequiredCheckRecorderRequestSchema)` to create a new message.\n */\nexport const GrantRequiredCheckRecorderRequestSchema: GenMessage<GrantRequiredCheckRecorderRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 21);\n\n/**\n * @generated from message contenthub.v1.GrantRequiredCheckRecorderResponse\n */\nexport type GrantRequiredCheckRecorderResponse = Message<\"contenthub.v1.GrantRequiredCheckRecorderResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.GrantRequiredCheckRecorderResponse.\n * Use `create(GrantRequiredCheckRecorderResponseSchema)` to create a new message.\n */\nexport const GrantRequiredCheckRecorderResponseSchema: GenMessage<GrantRequiredCheckRecorderResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 22);\n\n/**\n * @generated from message contenthub.v1.RevokeRequiredCheckRecorderRequest\n */\nexport type RevokeRequiredCheckRecorderRequest = Message<\"contenthub.v1.RevokeRequiredCheckRecorderRequest\"> & {\n /**\n * @generated from field: string required_check_id = 1;\n */\n requiredCheckId: string;\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.Recorder recorder = 2;\n */\n recorder?: Recorder | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RevokeRequiredCheckRecorderRequest.\n * Use `create(RevokeRequiredCheckRecorderRequestSchema)` to create a new message.\n */\nexport const RevokeRequiredCheckRecorderRequestSchema: GenMessage<RevokeRequiredCheckRecorderRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 23);\n\n/**\n * @generated from message contenthub.v1.RevokeRequiredCheckRecorderResponse\n */\nexport type RevokeRequiredCheckRecorderResponse = Message<\"contenthub.v1.RevokeRequiredCheckRecorderResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.RevokeRequiredCheckRecorderResponse.\n * Use `create(RevokeRequiredCheckRecorderResponseSchema)` to create a new message.\n */\nexport const RevokeRequiredCheckRecorderResponseSchema: GenMessage<RevokeRequiredCheckRecorderResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 24);\n\n/**\n * GuardianModeRequired is the detail of a FailedPrecondition refusal of what\n * only `authz.mode: guardian` can hold (ADR 0017): in workspace mode every\n * member records any Required Check, so who records one can't be narrowed,\n * and no Collection can be restricted, since nothing could enforce it.\n * A client reads it as \"this workspace runs in workspace mode\" and stops\n * offering the feature.\n *\n * @generated from message contenthub.v1.GuardianModeRequired\n */\nexport type GuardianModeRequired = Message<\"contenthub.v1.GuardianModeRequired\"> & {\n /**\n * What was refused: \"required_check_recorders\" (who records a Required\n * Check) or \"collection_restriction\" (restricting a Collection and its\n * grants).\n *\n * @generated from field: string feature = 1;\n */\n feature: string;\n};\n\n/**\n * Describes the message contenthub.v1.GuardianModeRequired.\n * Use `create(GuardianModeRequiredSchema)` to create a new message.\n */\nexport const GuardianModeRequiredSchema: GenMessage<GuardianModeRequired> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 25);\n\n/**\n * @generated from message contenthub.v1.CheckBlueprintReleaseRequest\n */\nexport type CheckBlueprintReleaseRequest = Message<\"contenthub.v1.CheckBlueprintReleaseRequest\"> & {\n /**\n * The Resolved Release document, byte for byte as blueprinthub stores and\n * serves it. The workspace comes from the token.\n *\n * @generated from field: bytes resolved_release = 1;\n */\n resolvedRelease: Uint8Array;\n};\n\n/**\n * Describes the message contenthub.v1.CheckBlueprintReleaseRequest.\n * Use `create(CheckBlueprintReleaseRequestSchema)` to create a new message.\n */\nexport const CheckBlueprintReleaseRequestSchema: GenMessage<CheckBlueprintReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 26);\n\n/**\n * @generated from message contenthub.v1.CheckBlueprintReleaseResponse\n */\nexport type CheckBlueprintReleaseResponse = Message<\"contenthub.v1.CheckBlueprintReleaseResponse\"> & {\n /**\n * Every reason contenthub refuses the Release; empty means accepted.\n *\n * @generated from field: repeated contenthub.v1.Refusal refusals = 1;\n */\n refusals: Refusal[];\n};\n\n/**\n * Describes the message contenthub.v1.CheckBlueprintReleaseResponse.\n * Use `create(CheckBlueprintReleaseResponseSchema)` to create a new message.\n */\nexport const CheckBlueprintReleaseResponseSchema: GenMessage<CheckBlueprintReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 27);\n\n/**\n * Refusal is one reason contenthub can't load a Resolved Release.\n *\n * @generated from message contenthub.v1.Refusal\n */\nexport type Refusal = Message<\"contenthub.v1.Refusal\"> & {\n /**\n * Whose rule refused it: \"format\" (the envelope), \"fieldkit\", \"knkeditor\"\n * or \"contenthub\" (contenthub's own policy).\n *\n * @generated from field: string source = 1;\n */\n source: string;\n\n /**\n * The refusing module's own data-contract code, unchanged: format's\n * \"format_too_new\", fieldkit's \"unknown_field_type\", knkeditor's\n * \"unknown-node\", contenthub's \"localizable_unsupported\".\n *\n * @generated from field: string code = 2;\n */\n code: string;\n\n /**\n * A /-separated location in the Resolved Release document, such as\n * \"/spec/fields/title/settings/max\" or \"/spec/parts/text_type/<id>/nodes/x\".\n * Below spec.fields, segments are Field accessors as fieldkit names them,\n * not list indexes. \"\" is the document itself.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * Detail a message may interpolate, as the module gave it; empty when the\n * code says everything.\n *\n * @generated from field: google.protobuf.Struct params = 4;\n */\n params?: JsonObject | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Refusal.\n * Use `create(RefusalSchema)` to create a new message.\n */\nexport const RefusalSchema: GenMessage<Refusal> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_workspace_config, 28);\n\n/**\n * CheckScope is what one Check Result of a Required Check is about (ADR\n * 0014).\n *\n * @generated from enum contenthub.v1.CheckScope\n */\nexport enum CheckScope {\n /**\n * @generated from enum value: CHECK_SCOPE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Each Branch of covered Content in a Change Set, and each of its Planned\n * Releases that has no Branch (date-only, Repeal, Withdrawal), needs a\n * result of its own, against its head.\n *\n * @generated from enum value: CHECK_SCOPE_BRANCH = 1;\n */\n BRANCH = 1,\n\n /**\n * A Change Set containing any covered Content needs one result, against\n * every head in it: each Branch's, and the Revision each Branch-less\n * Planned Release re-pins.\n *\n * @generated from enum value: CHECK_SCOPE_CHANGE_SET = 2;\n */\n CHANGE_SET = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.CheckScope.\n */\nexport const CheckScopeSchema: GenEnum<CheckScope> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_workspace_config, 0);\n\n/**\n * WorkspaceConfigService holds contenthub's own per-workspace configuration\n * (ADR 0015): its Block Reasons and its Required Checks, and\n * CheckBlueprintRelease, blueprinthub's question before it cuts a Release.\n * The workspace's time zone is not here: it is the workspace's in odon\n * (ADR 0021), and contenthub only keeps a copy.\n *\n * Every RPC acts on the caller's workspace, which comes from the token's\n * active workspace and never from a request field: no message here names a\n * workspace. Reads need `viewer`, writes `admin` (ADR 0017).\n *\n * @generated from service contenthub.v1.WorkspaceConfigService\n */\nexport const WorkspaceConfigService: GenService<{\n /**\n * CreateBlockReason adds a Block Reason. Names are unique in a workspace.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CreateBlockReason\n */\n createBlockReason: {\n methodKind: \"unary\";\n input: typeof CreateBlockReasonRequestSchema;\n output: typeof CreateBlockReasonResponseSchema;\n },\n /**\n * ListBlockReasons returns every Block Reason of the workspace, by name. A\n * workspace keeps a handful, so the list is not paged.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListBlockReasons\n */\n listBlockReasons: {\n methodKind: \"unary\";\n input: typeof ListBlockReasonsRequestSchema;\n output: typeof ListBlockReasonsResponseSchema;\n },\n /**\n * RenameBlockReason changes a Block Reason's name; its id stays.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.RenameBlockReason\n */\n renameBlockReason: {\n methodKind: \"unary\";\n input: typeof RenameBlockReasonRequestSchema;\n output: typeof RenameBlockReasonResponseSchema;\n },\n /**\n * DeleteBlockReason removes a Block Reason.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.DeleteBlockReason\n */\n deleteBlockReason: {\n methodKind: \"unary\";\n input: typeof DeleteBlockReasonRequestSchema;\n output: typeof DeleteBlockReasonResponseSchema;\n },\n /**\n * CreateRequiredCheck declares a Required Check (ADR 0014). Names are\n * unique in a workspace. It gates every open Change Set at once: Publish\n * reads the checks as declared at that moment.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CreateRequiredCheck\n */\n createRequiredCheck: {\n methodKind: \"unary\";\n input: typeof CreateRequiredCheckRequestSchema;\n output: typeof CreateRequiredCheckResponseSchema;\n },\n /**\n * ListRequiredChecks returns every Required Check of the workspace, by\n * name. A workspace keeps a handful, so the list is not paged.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListRequiredChecks\n */\n listRequiredChecks: {\n methodKind: \"unary\";\n input: typeof ListRequiredChecksRequestSchema;\n output: typeof ListRequiredChecksResponseSchema;\n },\n /**\n * UpdateRequiredCheck replaces a Required Check's name, scope, Blueprints\n * and independent flag; its id stays. Results recorded under another scope\n * stop counting.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.UpdateRequiredCheck\n */\n updateRequiredCheck: {\n methodKind: \"unary\";\n input: typeof UpdateRequiredCheckRequestSchema;\n output: typeof UpdateRequiredCheckResponseSchema;\n },\n /**\n * DeleteRequiredCheck removes a Required Check: it stops gating every open\n * Change Set. Its results are kept, and count for nothing.\n * Its recorders' grants go with it.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.DeleteRequiredCheck\n */\n deleteRequiredCheck: {\n methodKind: \"unary\";\n input: typeof DeleteRequiredCheckRequestSchema;\n output: typeof DeleteRequiredCheckResponseSchema;\n },\n /**\n * ListRequiredCheckRecorders reads who records a Required Check's results\n * (ADR 0017's 2026-10-03 amendment): every member of the workspace, named\n * people, or both while an admin narrows it. A new check starts with every\n * member. Only `admin` reads it, as only `admin` changes it.\n *\n * In `authz.mode: workspace` any member records any check, so there is\n * nothing to read or narrow: all three recorder RPCs are FailedPrecondition\n * with a GuardianModeRequired detail.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.ListRequiredCheckRecorders\n */\n listRequiredCheckRecorders: {\n methodKind: \"unary\";\n input: typeof ListRequiredCheckRecordersRequestSchema;\n output: typeof ListRequiredCheckRecordersResponseSchema;\n },\n /**\n * GrantRequiredCheckRecorder makes a member of the workspace, or every\n * member, a recorder of a Required Check; `admin` only. A grantee who is\n * not a member is InvalidArgument. An admin records only what they are\n * granted, so granting oneself is their break-glass, announced like any\n * grant. Granting what is granted already succeeds. It publishes\n * contenthub.required_check.recorder_granted.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.GrantRequiredCheckRecorder\n */\n grantRequiredCheckRecorder: {\n methodKind: \"unary\";\n input: typeof GrantRequiredCheckRecorderRequestSchema;\n output: typeof GrantRequiredCheckRecorderResponseSchema;\n },\n /**\n * RevokeRequiredCheckRecorder takes recorder from a user, or from every\n * member (narrowing the check to the people granted by name); `admin`\n * only. Revoking what isn't granted succeeds. Revoking the last recorder is\n * allowed: Publish then waits on the check until someone is granted. It\n * publishes contenthub.required_check.recorder_revoked.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.RevokeRequiredCheckRecorder\n */\n revokeRequiredCheckRecorder: {\n methodKind: \"unary\";\n input: typeof RevokeRequiredCheckRecorderRequestSchema;\n output: typeof RevokeRequiredCheckRecorderResponseSchema;\n },\n /**\n * CheckBlueprintRelease says whether contenthub can load a Resolved Release\n * (blueprinthub ADR 0004, contenthub#51). blueprinthub's CutRelease asks it\n * before it commits, forwarding its caller's token, and cuts nothing that\n * is refused.\n *\n * The check validates fully, with contenthub's own modules, and compares\n * no versions: (1) the envelope decodes strictly, in a format contenthub\n * knows; (2) spec.fields and release_spec pass fieldkit's publishing\n * catalogue with contenthub's policy, a release_spec refusal's path under\n * /release_spec; (3) every Text Type part passes knkeditor's resolved check\n * and needs no newer vocabulary; (4) every TI Set part has fieldkit's\n * minimum shape and no code twice (duplicate_code, naming the Set and the\n * code). A catalogue or vocabulary stated newer than contenthub's is\n * information, not a refusal: only what the Release uses counts.\n *\n * Refusals are a successful response. An error means contenthub gave no\n * answer, and is what blueprinthub retries. It has no side effects, so\n * `viewer` is enough, and it answers well inside blueprinthub's 10-second\n * deadline. Loading a Blueprint Release, and pinning one, run the same\n * check.\n *\n * @generated from rpc contenthub.v1.WorkspaceConfigService.CheckBlueprintRelease\n */\n checkBlueprintRelease: {\n methodKind: \"unary\";\n input: typeof CheckBlueprintReleaseRequestSchema;\n output: typeof CheckBlueprintReleaseResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_workspace_config, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/blueprint_catalog.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Refusal } from \"./workspace_config_pb\";\nimport { file_contenthub_v1_workspace_config } from \"./workspace_config_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/blueprint_catalog.proto.\n */\nexport const file_contenthub_v1_blueprint_catalog: GenFile = /*@__PURE__*/\n fileDesc(\"CiVjb250ZW50aHViL3YxL2JsdWVwcmludF9jYXRhbG9nLnByb3RvEg1jb250ZW50aHViLnYxIj4KEENhdGFsb2dCbHVlcHJpbnQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIQCghhY2Nlc3NvchgDIAEoCSJPChdTZWFyY2hCbHVlcHJpbnRzUmVxdWVzdBINCgVxdWVyeRgBIAEoCRIRCglwYWdlX3NpemUYAiABKAUSEgoKcGFnZV90b2tlbhgDIAEoCSJoChhTZWFyY2hCbHVlcHJpbnRzUmVzcG9uc2USMwoKYmx1ZXByaW50cxgBIAMoCzIfLmNvbnRlbnRodWIudjEuQ2F0YWxvZ0JsdWVwcmludBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkirgEKDkNhdGFsb2dSZWxlYXNlEgoKAmlkGAEgASgJEhQKDGJsdWVwcmludF9pZBgCIAEoCRIMCgRuYW1lGAMgASgJEjAKDHJlbGVhc2VfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASEAoIYWNjZXB0ZWQYBSABKAgSKAoIcmVmdXNhbHMYBiADKAsyFi5jb250ZW50aHViLnYxLlJlZnVzYWwiNAocTGlzdEJsdWVwcmludFJlbGVhc2VzUmVxdWVzdBIUCgxibHVlcHJpbnRfaWQYASABKAkiUAodTGlzdEJsdWVwcmludFJlbGVhc2VzUmVzcG9uc2USLwoIcmVsZWFzZXMYASADKAsyHS5jb250ZW50aHViLnYxLkNhdGFsb2dSZWxlYXNlIiMKFEdldEJsdWVwcmludHNSZXF1ZXN0EgsKA2lkcxgBIAMoCSJMChVHZXRCbHVlcHJpbnRzUmVzcG9uc2USMwoKYmx1ZXByaW50cxgBIAMoCzIfLmNvbnRlbnRodWIudjEuQ2F0YWxvZ0JsdWVwcmludDLOAgoXQmx1ZXByaW50Q2F0YWxvZ1NlcnZpY2USYwoQU2VhcmNoQmx1ZXByaW50cxImLmNvbnRlbnRodWIudjEuU2VhcmNoQmx1ZXByaW50c1JlcXVlc3QaJy5jb250ZW50aHViLnYxLlNlYXJjaEJsdWVwcmludHNSZXNwb25zZRJyChVMaXN0Qmx1ZXByaW50UmVsZWFzZXMSKy5jb250ZW50aHViLnYxLkxpc3RCbHVlcHJpbnRSZWxlYXNlc1JlcXVlc3QaLC5jb250ZW50aHViLnYxLkxpc3RCbHVlcHJpbnRSZWxlYXNlc1Jlc3BvbnNlEloKDUdldEJsdWVwcmludHMSIy5jb250ZW50aHViLnYxLkdldEJsdWVwcmludHNSZXF1ZXN0GiQuY29udGVudGh1Yi52MS5HZXRCbHVlcHJpbnRzUmVzcG9uc2VCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_contenthub_v1_workspace_config, file_google_protobuf_timestamp]);\n\n/**\n * CatalogBlueprint is a Blueprint as New Content offers it.\n *\n * @generated from message contenthub.v1.CatalogBlueprint\n */\nexport type CatalogBlueprint = Message<\"contenthub.v1.CatalogBlueprint\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * What editors call it: the head Revision's name, or the accessor when it\n * has none.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The accessor, unique in the workspace for good.\n *\n * @generated from field: string accessor = 3;\n */\n accessor: string;\n};\n\n/**\n * Describes the message contenthub.v1.CatalogBlueprint.\n * Use `create(CatalogBlueprintSchema)` to create a new message.\n */\nexport const CatalogBlueprintSchema: GenMessage<CatalogBlueprint> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 0);\n\n/**\n * @generated from message contenthub.v1.SearchBlueprintsRequest\n */\nexport type SearchBlueprintsRequest = Message<\"contenthub.v1.SearchBlueprintsRequest\"> & {\n /**\n * Only Blueprints whose accessor or name contains this text, ignoring\n * case. Empty means every one.\n *\n * @generated from field: string query = 1;\n */\n query: string;\n\n /**\n * At most this many Blueprints; 0 is blueprinthub's default. A page can\n * hold fewer and still not be the last.\n *\n * @generated from field: int32 page_size = 2;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 3;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.SearchBlueprintsRequest.\n * Use `create(SearchBlueprintsRequestSchema)` to create a new message.\n */\nexport const SearchBlueprintsRequestSchema: GenMessage<SearchBlueprintsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 1);\n\n/**\n * @generated from message contenthub.v1.SearchBlueprintsResponse\n */\nexport type SearchBlueprintsResponse = Message<\"contenthub.v1.SearchBlueprintsResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.CatalogBlueprint blueprints = 1;\n */\n blueprints: CatalogBlueprint[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.SearchBlueprintsResponse.\n * Use `create(SearchBlueprintsResponseSchema)` to create a new message.\n */\nexport const SearchBlueprintsResponseSchema: GenMessage<SearchBlueprintsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 2);\n\n/**\n * CatalogRelease is a Blueprint Release and whether Content can pin it.\n *\n * @generated from message contenthub.v1.CatalogRelease\n */\nexport type CatalogRelease = Message<\"contenthub.v1.CatalogRelease\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string blueprint_id = 2;\n */\n blueprintId: string;\n\n /**\n * The name given when it was cut, such as \"2026-10\".\n *\n * @generated from field: string name = 3;\n */\n name: string;\n\n /**\n * When it was cut.\n *\n * @generated from field: google.protobuf.Timestamp release_time = 4;\n */\n releaseTime?: Timestamp | undefined;\n\n /**\n * Whether contenthub loads it. A refused Release can't be pinned.\n *\n * @generated from field: bool accepted = 5;\n */\n accepted: boolean;\n\n /**\n * Why it is refused, as CheckBlueprintRelease would answer for it; empty\n * when accepted.\n *\n * @generated from field: repeated contenthub.v1.Refusal refusals = 6;\n */\n refusals: Refusal[];\n};\n\n/**\n * Describes the message contenthub.v1.CatalogRelease.\n * Use `create(CatalogReleaseSchema)` to create a new message.\n */\nexport const CatalogReleaseSchema: GenMessage<CatalogRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 3);\n\n/**\n * @generated from message contenthub.v1.ListBlueprintReleasesRequest\n */\nexport type ListBlueprintReleasesRequest = Message<\"contenthub.v1.ListBlueprintReleasesRequest\"> & {\n /**\n * @generated from field: string blueprint_id = 1;\n */\n blueprintId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListBlueprintReleasesRequest.\n * Use `create(ListBlueprintReleasesRequestSchema)` to create a new message.\n */\nexport const ListBlueprintReleasesRequestSchema: GenMessage<ListBlueprintReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 4);\n\n/**\n * @generated from message contenthub.v1.ListBlueprintReleasesResponse\n */\nexport type ListBlueprintReleasesResponse = Message<\"contenthub.v1.ListBlueprintReleasesResponse\"> & {\n /**\n * Newest first. Empty while none has been cut, or for a Blueprint the\n * caller's workspace doesn't have.\n *\n * @generated from field: repeated contenthub.v1.CatalogRelease releases = 1;\n */\n releases: CatalogRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.ListBlueprintReleasesResponse.\n * Use `create(ListBlueprintReleasesResponseSchema)` to create a new message.\n */\nexport const ListBlueprintReleasesResponseSchema: GenMessage<ListBlueprintReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 5);\n\n/**\n * @generated from message contenthub.v1.GetBlueprintsRequest\n */\nexport type GetBlueprintsRequest = Message<\"contenthub.v1.GetBlueprintsRequest\"> & {\n /**\n * At most 1000, as blueprinthub's id filter takes them; more is\n * InvalidArgument. Empty answers none, never every Blueprint.\n *\n * @generated from field: repeated string ids = 1;\n */\n ids: string[];\n};\n\n/**\n * Describes the message contenthub.v1.GetBlueprintsRequest.\n * Use `create(GetBlueprintsRequestSchema)` to create a new message.\n */\nexport const GetBlueprintsRequestSchema: GenMessage<GetBlueprintsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 6);\n\n/**\n * @generated from message contenthub.v1.GetBlueprintsResponse\n */\nexport type GetBlueprintsResponse = Message<\"contenthub.v1.GetBlueprintsResponse\"> & {\n /**\n * Ordered by accessor. Only the ids found: an unknown id, or one of\n * another workspace, has no entry.\n *\n * @generated from field: repeated contenthub.v1.CatalogBlueprint blueprints = 1;\n */\n blueprints: CatalogBlueprint[];\n};\n\n/**\n * Describes the message contenthub.v1.GetBlueprintsResponse.\n * Use `create(GetBlueprintsResponseSchema)` to create a new message.\n */\nexport const GetBlueprintsResponseSchema: GenMessage<GetBlueprintsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_blueprint_catalog, 7);\n\n/**\n * BlueprintCatalogService answers which Blueprints and Blueprint Releases\n * Content can be made from (#238, ADR 0020 as amended). blueprinthub is\n * contenthub's direct dependency, not a port a host fills: contenthub reads\n * the workspace's Blueprints from it with the caller's token (ADR 0017) and\n * says of each Release whether it loads, with the same check that runs when\n * Content pins it. A host mounting contenthub's screens therefore needs no\n * connection to blueprinthub of its own.\n *\n * The workspace comes from the token's active workspace, never a request\n * field. Every RPC is a read and needs `viewer`. blueprinthub giving no answer\n * is Unavailable (or the code it failed with); a Release contenthub refuses\n * is data, not an error.\n *\n * @generated from service contenthub.v1.BlueprintCatalogService\n */\nexport const BlueprintCatalogService: GenService<{\n /**\n * SearchBlueprints returns a page of the workspace's content Blueprints\n * that Content can be made from: of kind content, not archived, with at\n * least one Release. Ordered and paged as blueprinthub lists them, by\n * accessor.\n *\n * @generated from rpc contenthub.v1.BlueprintCatalogService.SearchBlueprints\n */\n searchBlueprints: {\n methodKind: \"unary\";\n input: typeof SearchBlueprintsRequestSchema;\n output: typeof SearchBlueprintsResponseSchema;\n },\n /**\n * ListBlueprintReleases returns every Release of a Blueprint, newest\n * first, each saying whether contenthub accepts it. Each answer is the\n * Blueprint Release cache's: an accepted Release is loaded into the cache\n * as a pin would load it, so a later pin costs no fetch.\n *\n * @generated from rpc contenthub.v1.BlueprintCatalogService.ListBlueprintReleases\n */\n listBlueprintReleases: {\n methodKind: \"unary\";\n input: typeof ListBlueprintReleasesRequestSchema;\n output: typeof ListBlueprintReleasesResponseSchema;\n },\n /**\n * GetBlueprints names the Blueprints of these ids, archived ones and ones\n * without a Release included, so existing Content stays readable after its\n * Blueprint is retired (#241). Of any kind. An unknown id, or one of\n * another workspace, is left out, never an error.\n *\n * @generated from rpc contenthub.v1.BlueprintCatalogService.GetBlueprints\n */\n getBlueprints: {\n methodKind: \"unary\";\n input: typeof GetBlueprintsRequestSchema;\n output: typeof GetBlueprintsResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_blueprint_catalog, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/content_graph.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/content_graph.proto.\n */\nexport const file_contenthub_v1_content_graph: GenFile = /*@__PURE__*/\n fileDesc(\"CiFjb250ZW50aHViL3YxL2NvbnRlbnRfZ3JhcGgucHJvdG8SDWNvbnRlbnRodWIudjEitwIKBEVkZ2USGQoRc291cmNlX2NvbnRlbnRfaWQYASABKAkSGgoSc291cmNlX3JldmlzaW9uX2lkGAIgASgJEgwKBHBhdGgYAyABKAkSJQoEa2luZBgEIAEoDjIXLmNvbnRlbnRodWIudjEuRWRnZUtpbmQSGQoRdGFyZ2V0X2NvbnRlbnRfaWQYBSABKAkSFQoNdGFyZ2V0X2FuY2hvchgGIAEoCRIXCg90YXJnZXRfYXNzZXRfaWQYByABKAkSIwobdGFyZ2V0X2JsdWVwcmludF9yZWxlYXNlX2lkGAggASgJEhYKDnBpbl9yZWxlYXNlX2lkGAkgASgJEhMKC3BhcmVudF9wYXRoGAogASgJEhQKDGhhc19wb3NpdGlvbhgLIAEoCBIQCghwb3NpdGlvbhgMIAEoBSJLCglJbkZvcmNlQXQSEAoIdmFsaWRfb24YASABKAkSLAoIa25vd25fYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIsYBChVMaXN0UmVmZXJlbmNlc1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIVCgtyZXZpc2lvbl9pZBgCIAEoCUgAEhQKCnJlbGVhc2VfaWQYAyABKAlIABIvCgtpbl9mb3JjZV9hdBgEIAEoCzIYLmNvbnRlbnRodWIudjEuSW5Gb3JjZUF0SAASJgoFa2luZHMYBSADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kEg0KBWRlcHRoGAYgASgFQgQKAmF0IkYKFkxpc3RSZWZlcmVuY2VzUmVzcG9uc2USLAoKcmVmZXJlbmNlcxgBIAMoCzIYLmNvbnRlbnRodWIudjEuUmVmZXJlbmNlIlgKCVJlZmVyZW5jZRIhCgRlZGdlGAEgASgLMhMuY29udGVudGh1Yi52MS5FZGdlEg0KBWRlcHRoGAIgASgFEhkKEXNvdXJjZV9yZWxlYXNlX2lkGAMgASgJItEBChRMaXN0UmVmZXJyZXJzUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEg4KBmFuY2hvchgCIAEoCRImCgVraW5kcxgDIAMoDjIXLmNvbnRlbnRodWIudjEuRWRnZUtpbmQSJAoCYXQYBCABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIgChhpbmNsdWRlX29wZW5fY2hhbmdlX3NldHMYBSABKAgSEQoJcGFnZV9zaXplGAYgASgFEhIKCnBhZ2VfdG9rZW4YByABKAkiXAoVTGlzdFJlZmVycmVyc1Jlc3BvbnNlEioKCXJlZmVycmVycxgBIAMoCzIXLmNvbnRlbnRodWIudjEuUmVmZXJyZXISFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJImsKCFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCRIVCg1jaGFuZ2Vfc2V0X2lkGAMgASgJEhEKCWJyYW5jaF9pZBgEIAEoCSqeAgoIRWRnZUtpbmQSGQoVRURHRV9LSU5EX1VOU1BFQ0lGSUVEEAASFwoTRURHRV9LSU5EX1JFRkVSRU5DRRABEhEKDUVER0VfS0lORF9UT0MQAhIVChFFREdFX0tJTkRfSU5DTFVERRADEhUKEUVER0VfS0lORF9FWENMVURFEAQSFQoRRURHRV9LSU5EX1JFUExBQ0UQBRIWChJFREdFX0tJTkRfQU5OT1RBVEUQBhISCg5FREdFX0tJTkRfTElOSxAHEhYKEkVER0VfS0lORF9GT09UTk9URRAIEhQKEEVER0VfS0lORF9BTkNIT1IQCRITCg9FREdFX0tJTkRfTUVESUEQChIXChNFREdFX0tJTkRfQkxVRVBSSU5UEAtCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_timestamp]);\n\n/**\n * Edge is one edge of one Revision.\n *\n * @generated from message contenthub.v1.Edge\n */\nexport type Edge = Message<\"contenthub.v1.Edge\"> & {\n /**\n * The Content and Revision holding the edge.\n *\n * @generated from field: string source_content_id = 1;\n */\n sourceContentId: string;\n\n /**\n * @generated from field: string source_revision_id = 2;\n */\n sourceRevisionId: string;\n\n /**\n * fieldkit's Path of the value the edge comes from, each row as its _id\n * (\"/sections/r1/image\"); empty for the blueprint edge.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * @generated from field: contenthub.v1.EdgeKind kind = 4;\n */\n kind: EdgeKind;\n\n /**\n * What it points at: exactly one of target_content_id, target_asset_id and\n * target_blueprint_release_id is set.\n *\n * @generated from field: string target_content_id = 5;\n */\n targetContentId: string;\n\n /**\n * The Anchor (a node id) a link names inside target_content_id.\n *\n * @generated from field: string target_anchor = 6;\n */\n targetAnchor: string;\n\n /**\n * @generated from field: string target_asset_id = 7;\n */\n targetAssetId: string;\n\n /**\n * @generated from field: string target_blueprint_release_id = 8;\n */\n targetBlueprintReleaseId: string;\n\n /**\n * The Release of target_content_id the edge is pinned to; empty when it\n * follows the Release In Force.\n *\n * @generated from field: string pin_release_id = 9;\n */\n pinReleaseId: string;\n\n /**\n * For a node of a reference tree (the TOC Field's above all): the Path of\n * its parent node, empty at the top of the tree, and its index among its\n * siblings. has_position is false for an edge that is no tree node.\n *\n * @generated from field: string parent_path = 10;\n */\n parentPath: string;\n\n /**\n * @generated from field: bool has_position = 11;\n */\n hasPosition: boolean;\n\n /**\n * @generated from field: int32 position = 12;\n */\n position: number;\n};\n\n/**\n * Describes the message contenthub.v1.Edge.\n * Use `create(EdgeSchema)` to create a new message.\n */\nexport const EdgeSchema: GenMessage<Edge> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 0);\n\n/**\n * InForceAt is a date and a moment to read In Force at (CONTEXT.md).\n *\n * @generated from message contenthub.v1.InForceAt\n */\nexport type InForceAt = Message<\"contenthub.v1.InForceAt\"> & {\n /**\n * The day, as YYYY-MM-DD in the workspace's time zone; empty for today.\n *\n * @generated from field: string valid_on = 1;\n */\n validOn: string;\n\n /**\n * The moment the state was known at; unset for now.\n *\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.InForceAt.\n * Use `create(InForceAtSchema)` to create a new message.\n */\nexport const InForceAtSchema: GenMessage<InForceAt> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 1);\n\n/**\n * @generated from message contenthub.v1.ListReferencesRequest\n */\nexport type ListReferencesRequest = Message<\"contenthub.v1.ListReferencesRequest\"> & {\n /**\n * The Content whose outgoing edges to read.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Which of its Revisions: one by id, the one a Release pins, or the one\n * its Release In Force pins. Exactly one is required.\n *\n * @generated from oneof contenthub.v1.ListReferencesRequest.at\n */\n at: {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | {\n /**\n * @generated from field: string release_id = 3;\n */\n value: string;\n case: \"releaseId\";\n } | {\n /**\n * @generated from field: contenthub.v1.InForceAt in_force_at = 4;\n */\n value: InForceAt;\n case: \"inForceAt\";\n } | { case: undefined; value?: undefined };\n\n /**\n * Only edges of these kinds, at every depth; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 5;\n */\n kinds: EdgeKind[];\n\n /**\n * How far to follow edges into the Content they point at: 1 (0 means 1)\n * reads the Revision's own edges, 2 also those of each target, and so on,\n * at most 8. With kinds [TOC] it reads a TOC subtree.\n *\n * A target is read at the Release an edge pins, or else at its Release In\n * Force: at in_force_at; for release_id, on the first day of that\n * Release's Validity Period (for undated Content, the day of its Publish\n * Time) as known now; for revision_id, today as known now. A target\n * already on the way there is not entered again. A footnote edge is\n * listed but not followed: a Footnote Body is read at its citer's Release\n * coordinates, never at these (ADR 0009 as amended).\n *\n * @generated from field: int32 depth = 6;\n */\n depth: number;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferencesRequest.\n * Use `create(ListReferencesRequestSchema)` to create a new message.\n */\nexport const ListReferencesRequestSchema: GenMessage<ListReferencesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 2);\n\n/**\n * @generated from message contenthub.v1.ListReferencesResponse\n */\nexport type ListReferencesResponse = Message<\"contenthub.v1.ListReferencesResponse\"> & {\n /**\n * In walk order: the Revision's own edges in their order, each followed by\n * the edges of its target.\n *\n * @generated from field: repeated contenthub.v1.Reference references = 1;\n */\n references: Reference[];\n};\n\n/**\n * Describes the message contenthub.v1.ListReferencesResponse.\n * Use `create(ListReferencesResponseSchema)` to create a new message.\n */\nexport const ListReferencesResponseSchema: GenMessage<ListReferencesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 3);\n\n/**\n * Reference is one edge ListReferences reached.\n *\n * @generated from message contenthub.v1.Reference\n */\nexport type Reference = Message<\"contenthub.v1.Reference\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * 1 for the Revision's own edges, 2 for its targets' edges, and so on.\n *\n * @generated from field: int32 depth = 2;\n */\n depth: number;\n\n /**\n * The Release of edge.source_content_id it was read at: the Release\n * named, or In Force, or that an edge pinned; empty for the edges of a\n * Revision read by its id.\n *\n * @generated from field: string source_release_id = 3;\n */\n sourceReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Reference.\n * Use `create(ReferenceSchema)` to create a new message.\n */\nexport const ReferenceSchema: GenMessage<Reference> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 4);\n\n/**\n * @generated from message contenthub.v1.ListReferrersRequest\n */\nexport type ListReferrersRequest = Message<\"contenthub.v1.ListReferrersRequest\"> & {\n /**\n * The Content pointed at.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only edges naming this Anchor inside it; empty for every edge to the\n * Content, Anchor or not.\n *\n * @generated from field: string anchor = 2;\n */\n anchor: string;\n\n /**\n * Only edges of these kinds; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 3;\n */\n kinds: EdgeKind[];\n\n /**\n * Releases In Force at this date and moment are searched; unset is today,\n * as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 4;\n */\n at?: InForceAt | undefined;\n\n /**\n * Also search the head of every Branch of every open Change Set.\n *\n * @generated from field: bool include_open_change_sets = 5;\n */\n includeOpenChangeSets: boolean;\n\n /**\n * 0 means 100; above 1000 reads as 1000.\n *\n * @generated from field: int32 page_size = 6;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page, asked with the same other\n * fields; empty for the first.\n *\n * @generated from field: string page_token = 7;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferrersRequest.\n * Use `create(ListReferrersRequestSchema)` to create a new message.\n */\nexport const ListReferrersRequestSchema: GenMessage<ListReferrersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 5);\n\n/**\n * @generated from message contenthub.v1.ListReferrersResponse\n */\nexport type ListReferrersResponse = Message<\"contenthub.v1.ListReferrersResponse\"> & {\n /**\n * Those found in Releases first, then those in open Change Sets, each\n * ordered by the referring Content (in a Change Set, then by Change Set\n * and Branch) and its edge order. A page leaves out the referrers the\n * caller may not see without coming up short for them.\n *\n * @generated from field: repeated contenthub.v1.Referrer referrers = 1;\n */\n referrers: Referrer[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListReferrersResponse.\n * Use `create(ListReferrersResponseSchema)` to create a new message.\n */\nexport const ListReferrersResponseSchema: GenMessage<ListReferrersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 6);\n\n/**\n * Referrer is one incoming edge, and where it was found.\n *\n * @generated from message contenthub.v1.Referrer\n */\nexport type Referrer = Message<\"contenthub.v1.Referrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release In Force that pins edge.source_revision_id; empty when\n * found in a Change Set.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * The open Change Set and Branch whose head is edge.source_revision_id;\n * empty when found in a Release.\n *\n * @generated from field: string change_set_id = 3;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Referrer.\n * Use `create(ReferrerSchema)` to create a new message.\n */\nexport const ReferrerSchema: GenMessage<Referrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content_graph, 7);\n\n/**\n * EdgeKind is what an edge is, and which kind of value it comes from.\n *\n * @generated from enum contenthub.v1.EdgeKind\n */\nexport enum EdgeKind {\n /**\n * @generated from enum value: EDGE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * From a reference field.\n *\n * @generated from enum value: EDGE_KIND_REFERENCE = 1;\n */\n REFERENCE = 1,\n\n /**\n * From the Blueprint's TOC Field: the Content's children.\n *\n * @generated from enum value: EDGE_KIND_TOC = 2;\n */\n TOC = 2,\n\n /**\n * From a Title's manipulation tree (and EXCLUDE also from a\n * reference_filter).\n *\n * @generated from enum value: EDGE_KIND_INCLUDE = 3;\n */\n INCLUDE = 3,\n\n /**\n * @generated from enum value: EDGE_KIND_EXCLUDE = 4;\n */\n EXCLUDE = 4,\n\n /**\n * @generated from enum value: EDGE_KIND_REPLACE = 5;\n */\n REPLACE = 5,\n\n /**\n * @generated from enum value: EDGE_KIND_ANNOTATE = 6;\n */\n ANNOTATE = 6,\n\n /**\n * From a content link in rich text, with an optional Anchor. An internal\n * link names a node in the same document and is no edge.\n *\n * @generated from enum value: EDGE_KIND_LINK = 7;\n */\n LINK = 7,\n\n /**\n * From a footnote in rich text, to the Content holding its body.\n *\n * @generated from enum value: EDGE_KIND_FOOTNOTE = 8;\n */\n FOOTNOTE = 8,\n\n /**\n * From a typesetting instruction, to the node it is anchored at.\n *\n * @generated from enum value: EDGE_KIND_ANCHOR = 9;\n */\n ANCHOR = 9,\n\n /**\n * From a media field or an image in rich text, to a mediahub Asset.\n *\n * @generated from enum value: EDGE_KIND_MEDIA = 10;\n */\n MEDIA = 10,\n\n /**\n * To the Blueprint Release the Revision pins.\n *\n * @generated from enum value: EDGE_KIND_BLUEPRINT = 11;\n */\n BLUEPRINT = 11,\n}\n\n/**\n * Describes the enum contenthub.v1.EdgeKind.\n */\nexport const EdgeKindSchema: GenEnum<EdgeKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_content_graph, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/release.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/release.proto.\n */\nexport const file_contenthub_v1_release: GenFile = /*@__PURE__*/\n fileDesc(\"Chtjb250ZW50aHViL3YxL3JlbGVhc2UucHJvdG8SDWNvbnRlbnRodWIudjEiNQoOVmFsaWRpdHlQZXJpb2QSEQoJZmlyc3RfZGF5GAEgASgJEhAKCGxhc3RfZGF5GAIgASgJIu0CCg5QbGFubmVkUmVsZWFzZRIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEigKBGtpbmQYAyABKA4yGi5jb250ZW50aHViLnYxLlJlbGVhc2VLaW5kEhEKCWJyYW5jaF9pZBgEIAEoCRITCgtyZXZpc2lvbl9pZBgFIAEoCRI2Cg92YWxpZGl0eV9wZXJpb2QYBiABKAsyHS5jb250ZW50aHViLnYxLlZhbGlkaXR5UGVyaW9kEi0KDHJlbGVhc2Vfc3BlYxgHIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSHgoWc3VwZXJzZWRlc19yZWxlYXNlX2lkcxgIIAMoCRIQCghwcm9wb3NlZBgJIAEoCBIfChdwcm9wb3NlZF9mb3JfcmVsZWFzZV9pZBgKIAEoCRIdChVzcGxpdF9mcm9tX3JlbGVhc2VfaWQYCyABKAkSEAoId2l0aGhlbGQYDCABKAgiJAoNUmVsZWFzZUlkTGlzdBITCgtyZWxlYXNlX2lkcxgBIAMoCSLhAgoHUmVsZWFzZRIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEigKBGtpbmQYAyABKA4yGi5jb250ZW50aHViLnYxLlJlbGVhc2VLaW5kEhEKCWJyYW5jaF9pZBgEIAEoCRITCgtyZXZpc2lvbl9pZBgFIAEoCRIcChRibHVlcHJpbnRfcmVsZWFzZV9pZBgGIAEoCRINCgVmaXJzdBgHIAEoCBIeChZzdXBlcnNlZGVzX3JlbGVhc2VfaWRzGAggAygJEjYKD3ZhbGlkaXR5X3BlcmlvZBgJIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSLQoMcmVsZWFzZV9zcGVjGAogASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIwCgxwdWJsaXNoX3RpbWUYCyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIu4CCg5QdWJsaXNoQmxvY2tlchIMCgRjb2RlGAEgASgJEhIKCmNvbnRlbnRfaWQYAiABKAkSEQoJYnJhbmNoX2lkGAMgASgJEhgKEGV4cGVjdGVkX2hlYWRfaWQYBCABKAkSFwoPY3VycmVudF9oZWFkX2lkGAUgASgJEhIKCnJlbGVhc2VfaWQYBiABKAkSGwoTb3ZlcmxhcHNfcmVsZWFzZV9pZBgHIAEoCRIgChhkZXBlbmRlbmN5X2NoYW5nZV9zZXRfaWQYCCABKAkSDAoEcGF0aBgJIAEoCRIZChF0YXJnZXRfY29udGVudF9pZBgKIAEoCRIQCghhc3NldF9pZBgLIAEoCRIaChJwYXJlbnRfY29udGVudF9pZHMYDCADKAkSGQoRcmVxdWlyZWRfY2hlY2tfaWQYDSABKAkSGgoSY292ZXJlZF9yZWxlYXNlX2lkGA4gASgJEhMKC3JldmlzaW9uX2lkGA8gASgJKpgBCgtSZWxlYXNlS2luZBIcChhSRUxFQVNFX0tJTkRfVU5TUEVDSUZJRUQQABIZChVSRUxFQVNFX0tJTkRfUkVWSVNJT04QARIaChZSRUxFQVNFX0tJTkRfREFURV9PTkxZEAISFwoTUkVMRUFTRV9LSU5EX1JFUEVBTBADEhsKF1JFTEVBU0VfS0lORF9XSVRIRFJBV0FMEARCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * ValidityPeriod is the span of calendar days a Release of Dated Content is\n * In Force (CONTEXT.md): a first day, and a last day if one is known, both\n * included, as days of the workspace's time zone. Releases of undated Content\n * carry none.\n *\n * @generated from message contenthub.v1.ValidityPeriod\n */\nexport type ValidityPeriod = Message<\"contenthub.v1.ValidityPeriod\"> & {\n /**\n * The first day, as YYYY-MM-DD.\n *\n * @generated from field: string first_day = 1;\n */\n firstDay: string;\n\n /**\n * The last day, as YYYY-MM-DD; empty for an open end. A planned open end\n * stays open until Publish, which ends it the day before the next later\n * Release In Force then starts.\n *\n * @generated from field: string last_day = 2;\n */\n lastDay: string;\n};\n\n/**\n * Describes the message contenthub.v1.ValidityPeriod.\n * Use `create(ValidityPeriodSchema)` to create a new message.\n */\nexport const ValidityPeriodSchema: GenMessage<ValidityPeriod> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 0);\n\n/**\n * PlannedRelease is a Release a Change Set will cut when it is published,\n * with its Validity Period and Release Spec values set and reviewable\n * beforehand (CONTEXT.md). Its id is the Release's id from the moment it is\n * planned.\n *\n * @generated from message contenthub.v1.PlannedRelease\n */\nexport type PlannedRelease = Message<\"contenthub.v1.PlannedRelease\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The editorial Branch whose head at Publish it pins; empty for a\n * Branch-less kind.\n *\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n\n /**\n * The Revision a Branch-less kind re-pins; empty for a Branch's Release.\n *\n * @generated from field: string revision_id = 5;\n */\n revisionId: string;\n\n /**\n * Absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 6;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Its Release Spec values, keyed by the Release Spec Field's accessor.\n *\n * @generated from field: google.protobuf.Struct release_spec = 7;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Releases it will Supersede.\n *\n * @generated from field: repeated string supersedes_release_ids = 8;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Whether the Change Set proposed it, to end proposed_for_release_id, a\n * Release a planned Validity Period cuts into.\n *\n * @generated from field: bool proposed = 9;\n */\n proposed: boolean;\n\n /**\n * @generated from field: string proposed_for_release_id = 10;\n */\n proposedForReleaseId: string;\n\n /**\n * For a proposed tail, the Release it was split from: a Validity Period\n * planned strictly inside that Release proposes a cut ending it the day\n * before and this tail, which resumes its wording the day after that\n * Validity Period and supersedes nothing.\n *\n * @generated from field: string split_from_release_id = 11;\n */\n splitFromReleaseId: string;\n\n /**\n * For the proposal of a Carry-forward link, whether a plan of the Change\n * Set supersedes the Release it carries (a Repeal reaching it, say), so\n * that Publish doesn't cut it.\n *\n * @generated from field: bool withheld = 12;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.PlannedRelease.\n * Use `create(PlannedReleaseSchema)` to create a new message.\n */\nexport const PlannedReleaseSchema: GenMessage<PlannedRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 1);\n\n/**\n * ReleaseIdList is a list of Release ids that can be told apart from none\n * given.\n *\n * @generated from message contenthub.v1.ReleaseIdList\n */\nexport type ReleaseIdList = Message<\"contenthub.v1.ReleaseIdList\"> & {\n /**\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseIdList.\n * Use `create(ReleaseIdListSchema)` to create a new message.\n */\nexport const ReleaseIdListSchema: GenMessage<ReleaseIdList> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 2);\n\n/**\n * Release is one Release a Publish cut: immutable, pinning one Revision.\n *\n * @generated from message contenthub.v1.Release\n */\nexport type Release = Message<\"contenthub.v1.Release\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The editorial Branch whose head it pins; empty for a Withdrawal.\n *\n * @generated from field: string branch_id = 4;\n */\n branchId: string;\n\n /**\n * The Revision it pins, and the Blueprint Release that Revision pins.\n *\n * @generated from field: string revision_id = 5;\n */\n revisionId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 6;\n */\n blueprintReleaseId: string;\n\n /**\n * Whether it is the Content's first Release: the moment the Content\n * exists outside its Change Set.\n *\n * @generated from field: bool first = 7;\n */\n first: boolean;\n\n /**\n * The Releases it Supersedes from its Publish Time on.\n *\n * @generated from field: repeated string supersedes_release_ids = 8;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Its Validity Period, an open end resolved as Publish resolved it;\n * absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 9;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 10;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Its Publish Time; absent in ValidatePublish's would-be outcome, since a\n * Publish Time is stamped only when the Publish writes.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 11;\n */\n publishTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Release.\n * Use `create(ReleaseSchema)` to create a new message.\n */\nexport const ReleaseSchema: GenMessage<Release> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 3);\n\n/**\n * PublishBlocker is one reason a Publish is refused, or would be. Publish\n * lists every one at once, as FailedPrecondition details, and\n * ValidatePublish returns them, so the editor fixes everything in one pass\n * (ADR 0015). Which ids are set depends on the code.\n *\n * @generated from message contenthub.v1.PublishBlocker\n */\nexport type PublishBlocker = Message<\"contenthub.v1.PublishBlocker\"> & {\n /**\n * The reason. versionkit's, as it names them: moved_head,\n * unplanned_branch, several_branches, behind_base, superseded_release,\n * overlapping_periods, covers_release, pending_merge, nothing_in_force,\n * withdrawal_with_chain, dated_changed, unpublished_dependency or\n * discarded_dependency. contenthub's Content Graph's (ADR 0009):\n * dangling_pin (a pin naming a Release that won't exist),\n * second_toc_parent (a Content in the TOC of two Contents on the\n * resulting Main heads), missing_asset (a media edge to an Asset\n * mediahub says doesn't exist) and media_unavailable (mediahub refused\n * the caller's token, as for an org that doesn't license it, so no Asset\n * could be checked; once per Publish, naming nothing, and never beside a\n * missing_asset). contenthub's Required Checks' (ADR\n * 0014): outstanding_check (a check that applies lacks a latest passed\n * or waived result on the reviewed heads; for a Branch-scope check, on\n * branch_id's head or on the Revision Planned Release release_id\n * re-pins). contenthub's unversioned attributes' (ADR 0015):\n * blocked_content (a Content the Publish changes is blocked, and its\n * Block doesn't allow the caller) and archived_content (a Content the\n * Publish changes is Archived). contenthub's Footnote Bodies' (ADR 0009\n * as amended), each\n * against the resulting Main heads: footnote_body_citers (Footnote Body\n * content_id cited by more than one Content), footnote_body_edge (an\n * edge of another kind than footnote, a link with an Anchor say, from\n * content_id into Footnote Body target_content_id), footnote_body_alone\n * (Footnote Body content_id released without any of its citers),\n * footnote_body_born_elsewhere (a footnote of content_id into\n * target_content_id, which wasn't born in this Change Set) and\n * footnote_body_not_ended (Footnote Body content_id, which its citer\n * leaves, or ends, and which can't be Repealed or withdrawn with it).\n * contenthub's check of the released values (decision D1 of #176):\n * missing_required_field (a required Field left empty, at path, in\n * revision_id, a Revision of content_id the Publish releases; a save\n * allows it, Publish doesn't).\n *\n * @generated from field: string code = 1;\n */\n code: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 3;\n */\n branchId: string;\n\n /**\n * For moved_head, the head the caller reviewed (empty for a Branch the\n * reviewed heads left out) and the head now (empty for a reviewed Branch\n * that isn't the Change Set's). For behind_base, the upstream Revision\n * the Branch last took in and the upstream's head now.\n *\n * @generated from field: string expected_head_id = 4;\n */\n expectedHeadId: string;\n\n /**\n * @generated from field: string current_head_id = 5;\n */\n currentHeadId: string;\n\n /**\n * For superseded_release, the Release superseded already; for\n * overlapping_periods, the Release to cut and the one it overlaps; for\n * covers_release, the Planned Release whose Validity Period covers\n * covered_release_id; for dangling_pin, the Release the pin names.\n *\n * @generated from field: string release_id = 6;\n */\n releaseId: string;\n\n /**\n * @generated from field: string overlaps_release_id = 7;\n */\n overlapsReleaseId: string;\n\n /**\n * For unpublished_dependency and discarded_dependency, the Change Set\n * depended on.\n *\n * @generated from field: string dependency_change_set_id = 8;\n */\n dependencyChangeSetId: string;\n\n /**\n * For dangling_pin, missing_asset, footnote_body_edge and\n * footnote_body_born_elsewhere, fieldkit's Path of the value in\n * content_id's head the edge comes from. For missing_required_field,\n * fieldkit's Path of the empty Field.\n *\n * @generated from field: string path = 9;\n */\n path: string;\n\n /**\n * For dangling_pin, the Content the pin points at; release_id is the\n * Release it names. For footnote_body_edge and\n * footnote_body_born_elsewhere, the Footnote Body.\n *\n * @generated from field: string target_content_id = 10;\n */\n targetContentId: string;\n\n /**\n * For missing_asset, the Asset.\n *\n * @generated from field: string asset_id = 11;\n */\n assetId: string;\n\n /**\n * For second_toc_parent, every Content whose TOC holds content_id on\n * the resulting Main heads, ordered by id. For footnote_body_citers and\n * footnote_body_alone, every Content citing Footnote Body content_id,\n * ordered by id; for footnote_body_not_ended, the citer that left or\n * ended it.\n *\n * @generated from field: repeated string parent_content_ids = 12;\n */\n parentContentIds: string[];\n\n /**\n * For outstanding_check, the Required Check.\n *\n * @generated from field: string required_check_id = 13;\n */\n requiredCheckId: string;\n\n /**\n * For covers_release, the published Release whose Validity Period\n * release_id's covers entirely: one another Change Set published after\n * this one was planned, or one a Repeal reaches. Publish never re-plans;\n * a replan in the Change Set supersedes it, or changes the dates.\n *\n * @generated from field: string covered_release_id = 14;\n */\n coveredReleaseId: string;\n\n /**\n * For missing_required_field, the Revision that leaves the Field empty:\n * a head the Publish releases.\n *\n * @generated from field: string revision_id = 15;\n */\n revisionId: string;\n};\n\n/**\n * Describes the message contenthub.v1.PublishBlocker.\n * Use `create(PublishBlockerSchema)` to create a new message.\n */\nexport const PublishBlockerSchema: GenMessage<PublishBlocker> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release, 4);\n\n/**\n * ReleaseKind says how a Release came to be (ADR 0016).\n *\n * @generated from enum contenthub.v1.ReleaseKind\n */\nexport enum ReleaseKind {\n /**\n * @generated from enum value: RELEASE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Cut of an editorial Branch's head.\n *\n * @generated from enum value: RELEASE_KIND_REVISION = 1;\n */\n REVISION = 1,\n\n /**\n * Re-pins an existing Release's Revision with a corrected Validity Period.\n *\n * @generated from enum value: RELEASE_KIND_DATE_ONLY = 2;\n */\n DATE_ONLY = 2,\n\n /**\n * Ends a Dated Content's force, leaving a gap.\n *\n * @generated from enum value: RELEASE_KIND_REPEAL = 3;\n */\n REPEAL = 3,\n\n /**\n * Ends an undated Content's force.\n *\n * @generated from enum value: RELEASE_KIND_WITHDRAWAL = 4;\n */\n WITHDRAWAL = 4,\n}\n\n/**\n * Describes the enum contenthub.v1.ReleaseKind.\n */\nexport const ReleaseKindSchema: GenEnum<ReleaseKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_release, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/release_read.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Edge, EdgeKind, InForceAt } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { PlannedRelease, ReleaseKind, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/release_read.proto.\n */\nexport const file_contenthub_v1_release_read: GenFile = /*@__PURE__*/\n fileDesc(\"CiBjb250ZW50aHViL3YxL3JlbGVhc2VfcmVhZC5wcm90bxINY29udGVudGh1Yi52MSKqBAoPUmVsZWFzZWRDb250ZW50EhIKCnJlbGVhc2VfaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIoCgRraW5kGAMgASgOMhouY29udGVudGh1Yi52MS5SZWxlYXNlS2luZBITCgtyZXZpc2lvbl9pZBgEIAEoCRIUCgxibHVlcHJpbnRfaWQYBSABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYBiABKAkSDQoFZmlyc3QYByABKAgSNgoPdmFsaWRpdHlfcGVyaW9kGAggASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYCSABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKDHB1Ymxpc2hfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASIAoYc3VwZXJzZWRlZF9ieV9yZWxlYXNlX2lkGAsgASgJEjIKDnN1cGVyc2VkZV90aW1lGAwgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIPCgdwbGFubmVkGA0gASgIEiUKBGRhdGEYDiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjQKCnJlZmVyZW5jZXMYDyADKAsyIC5jb250ZW50aHViLnYxLlJlc29sdmVkUmVmZXJlbmNlEhAKCHdpdGhoZWxkGBAgASgIIoYBChFSZXNvbHZlZFJlZmVyZW5jZRIhCgRlZGdlGAEgASgLMhMuY29udGVudGh1Yi52MS5FZGdlEg0KBWRlcHRoGAIgASgFEhkKEXNvdXJjZV9yZWxlYXNlX2lkGAMgASgJEhIKCnJlbGVhc2VfaWQYBCABKAkSEAoId2l0aGhlbGQYBSABKAgiRAoLUmVsZWFzZVJlYWQSDQoFZGVwdGgYASABKAUSJgoFa2luZHMYAiADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kIqoBChJMaXN0SW5Gb3JjZVJlcXVlc3QSJAoCYXQYASABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIdChVwcmV2aWV3X2NoYW5nZV9zZXRfaWQYAiABKAkSKAoEcmVhZBgDIAEoCzIaLmNvbnRlbnRodWIudjEuUmVsZWFzZVJlYWQSEQoJcGFnZV9zaXplGAQgASgFEhIKCnBhZ2VfdG9rZW4YBSABKAkilAEKE0xpc3RJbkZvcmNlUmVzcG9uc2USMAoIY29udGVudHMYASADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudBIyCgpyZWZlcmVuY2VkGAIgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQSFwoPbmV4dF9wYWdlX3Rva2VuGAMgASgJIpcBChFHZXRJbkZvcmNlUmVxdWVzdBITCgtjb250ZW50X2lkcxgBIAMoCRIkCgJhdBgCIAEoCzIYLmNvbnRlbnRodWIudjEuSW5Gb3JjZUF0Eh0KFXByZXZpZXdfY2hhbmdlX3NldF9pZBgDIAEoCRIoCgRyZWFkGAQgASgLMhouY29udGVudGh1Yi52MS5SZWxlYXNlUmVhZCJ6ChJHZXRJbkZvcmNlUmVzcG9uc2USMAoIY29udGVudHMYASADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudBIyCgpyZWZlcmVuY2VkGAIgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQihwEKIFJlbGVhc2VTZXJ2aWNlR2V0UmVsZWFzZXNSZXF1ZXN0EhMKC3JlbGVhc2VfaWRzGAEgAygJEiQKAmF0GAIgASgLMhguY29udGVudGh1Yi52MS5JbkZvcmNlQXQSKAoEcmVhZBgDIAEoCzIaLmNvbnRlbnRodWIudjEuUmVsZWFzZVJlYWQiiQEKIVJlbGVhc2VTZXJ2aWNlR2V0UmVsZWFzZXNSZXNwb25zZRIwCghyZWxlYXNlcxgBIAMoCzIeLmNvbnRlbnRodWIudjEuUmVsZWFzZWRDb250ZW50EjIKCnJlZmVyZW5jZWQYAiADKAsyHi5jb250ZW50aHViLnYxLlJlbGVhc2VkQ29udGVudCJkCiBSZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEiwKCGtub3duX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJSCiFSZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVzcG9uc2USLQoHZW50cmllcxgBIAMoCzIcLmNvbnRlbnRodWIudjEuVGltZWxpbmVFbnRyeSK5AgoNVGltZWxpbmVFbnRyeRIPCgdvcmRpbmFsGAEgASgFEhIKCnJlbGVhc2VfaWQYAiABKAkSKAoEa2luZBgDIAEoDjIaLmNvbnRlbnRodWIudjEuUmVsZWFzZUtpbmQSEwoLcmV2aXNpb25faWQYBCABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYBSABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAYgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYByABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjAKDHB1Ymxpc2hfdGltZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDQoFZmlyc3QYCSABKAgivQEKIlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIOCgZhbmNob3IYAiABKAkSJgoFa2luZHMYAyADKA4yFy5jb250ZW50aHViLnYxLkVkZ2VLaW5kEiQKAmF0GAQgASgLMhguY29udGVudGh1Yi52MS5JbkZvcmNlQXQSEQoJcGFnZV9zaXplGAUgASgFEhIKCnBhZ2VfdG9rZW4YBiABKAkicgojUmVsZWFzZVNlcnZpY2VMaXN0UmVmZXJyZXJzUmVzcG9uc2USMgoJcmVmZXJyZXJzGAEgAygLMh8uY29udGVudGh1Yi52MS5SZWxlYXNlZFJlZmVycmVyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSJJChBSZWxlYXNlZFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCSJ5ChJHZXRSZWxlYXNlc1JlcXVlc3QSEwoLcmVsZWFzZV9pZHMYASADKAkSJAoCYXQYAiABKAsyGC5jb250ZW50aHViLnYxLkluRm9yY2VBdBIoCgRyZWFkGAMgASgLMhouY29udGVudGh1Yi52MS5SZWxlYXNlUmVhZCJ7ChNHZXRSZWxlYXNlc1Jlc3BvbnNlEjAKCHJlbGVhc2VzGAEgAygLMh4uY29udGVudGh1Yi52MS5SZWxlYXNlZENvbnRlbnQSMgoKcmVmZXJlbmNlZBgCIAMoCzIeLmNvbnRlbnRodWIudjEuUmVsZWFzZWRDb250ZW50IlYKEkdldFRpbWVsaW5lUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEiwKCGtub3duX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKGAQoTR2V0VGltZWxpbmVSZXNwb25zZRItCgdlbnRyaWVzGAEgAygLMhwuY29udGVudGh1Yi52MS5UaW1lbGluZUVudHJ5EkAKEHBsYW5uZWRfcmVsZWFzZXMYAiADKAsyJi5jb250ZW50aHViLnYxLkNoYW5nZVNldFBsYW5uZWRSZWxlYXNlImgKF0NoYW5nZVNldFBsYW5uZWRSZWxlYXNlEhUKDWNoYW5nZV9zZXRfaWQYASABKAkSNgoPcGxhbm5lZF9yZWxlYXNlGAIgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZTKVBAoOUmVsZWFzZVNlcnZpY2USVAoLTGlzdEluRm9yY2USIS5jb250ZW50aHViLnYxLkxpc3RJbkZvcmNlUmVxdWVzdBoiLmNvbnRlbnRodWIudjEuTGlzdEluRm9yY2VSZXNwb25zZRJRCgpHZXRJbkZvcmNlEiAuY29udGVudGh1Yi52MS5HZXRJbkZvcmNlUmVxdWVzdBohLmNvbnRlbnRodWIudjEuR2V0SW5Gb3JjZVJlc3BvbnNlEnAKC0dldFJlbGVhc2VzEi8uY29udGVudGh1Yi52MS5SZWxlYXNlU2VydmljZUdldFJlbGVhc2VzUmVxdWVzdBowLmNvbnRlbnRodWIudjEuUmVsZWFzZVNlcnZpY2VHZXRSZWxlYXNlc1Jlc3BvbnNlEnAKC0dldFRpbWVsaW5lEi8uY29udGVudGh1Yi52MS5SZWxlYXNlU2VydmljZUdldFRpbWVsaW5lUmVxdWVzdBowLmNvbnRlbnRodWIudjEuUmVsZWFzZVNlcnZpY2VHZXRUaW1lbGluZVJlc3BvbnNlEnYKDUxpc3RSZWZlcnJlcnMSMS5jb250ZW50aHViLnYxLlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1JlcXVlc3QaMi5jb250ZW50aHViLnYxLlJlbGVhc2VTZXJ2aWNlTGlzdFJlZmVycmVyc1Jlc3BvbnNlQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_contenthub_v1_content_graph, file_contenthub_v1_release, file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * ReleasedContent is one Release, with the data of the Revision it pins.\n *\n * @generated from message contenthub.v1.ReleasedContent\n */\nexport type ReleasedContent = Message<\"contenthub.v1.ReleasedContent\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * The Revision the Release pins; in a Preview's planned row, the Branch\n * head it would pin if published now.\n *\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * The Blueprint, and the Blueprint Release the Revision pins.\n *\n * @generated from field: string blueprint_id = 5;\n */\n blueprintId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 6;\n */\n blueprintReleaseId: string;\n\n /**\n * Whether it is the Content's first Release.\n *\n * @generated from field: bool first = 7;\n */\n first: boolean;\n\n /**\n * Absent for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 8;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 9;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Its Publish Time; for a planned row, the earliest the next Publish\n * could get.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 10;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * The Release that supersedes it, and that one's Publish Time, as known at\n * the read's known_at; empty while it isn't superseded then.\n *\n * @generated from field: string superseded_by_release_id = 11;\n */\n supersededByReleaseId: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp supersede_time = 12;\n */\n supersedeTime?: Timestamp | undefined;\n\n /**\n * Whether it is a Preview's Planned Release, read as if published now.\n *\n * @generated from field: bool planned = 13;\n */\n planned: boolean;\n\n /**\n * The Revision's data, a JSON object keyed by field accessor.\n *\n * @generated from field: google.protobuf.Struct data = 14;\n */\n data?: JsonObject | undefined;\n\n /**\n * Its References, resolved to the depth asked for, in walk order: each\n * edge followed by the edges of the Release it resolved to.\n *\n * @generated from field: repeated contenthub.v1.ResolvedReference references = 15;\n */\n references: ResolvedReference[];\n\n /**\n * In a Preview, whether this Content is Restricted (ADR 0017) and the\n * caller is not granted on it: the row is then its Release In Force\n * without the Preview, and what the Change Set does to it is withheld.\n *\n * @generated from field: bool withheld = 16;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.ReleasedContent.\n * Use `create(ReleasedContentSchema)` to create a new message.\n */\nexport const ReleasedContentSchema: GenMessage<ReleasedContent> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 0);\n\n/**\n * ResolvedReference is one edge from a Release's Revision to another Content,\n * and the Release of that Content it resolves to at the read's coordinates.\n *\n * @generated from message contenthub.v1.ResolvedReference\n */\nexport type ResolvedReference = Message<\"contenthub.v1.ResolvedReference\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * 1 for the Release's own edges, 2 for those of the Release an edge\n * resolved to, and so on.\n *\n * @generated from field: int32 depth = 2;\n */\n depth: number;\n\n /**\n * The Release whose Revision holds the edge.\n *\n * @generated from field: string source_release_id = 3;\n */\n sourceReleaseId: string;\n\n /**\n * The Release of edge.target_content_id it resolves to: the one the edge\n * pins, or else the one In Force at the read's coordinates. Empty when\n * none is In Force then, and for a footnote, whose Footnote Body is read\n * at its citer's Release coordinates (ADR 0009 as amended).\n *\n * @generated from field: string release_id = 4;\n */\n releaseId: string;\n\n /**\n * In a Preview, whether the target is Restricted Content the Preview\n * changes and the caller is not granted on (ADR 0017): it resolves to\n * edge.target_content_id and nothing more, release_id is empty, and the\n * walk does not go through it.\n *\n * @generated from field: bool withheld = 5;\n */\n withheld: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.ResolvedReference.\n * Use `create(ResolvedReferenceSchema)` to create a new message.\n */\nexport const ResolvedReferenceSchema: GenMessage<ResolvedReference> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 1);\n\n/**\n * ReleaseRead is how deep a read resolves References, and which.\n *\n * @generated from message contenthub.v1.ReleaseRead\n */\nexport type ReleaseRead = Message<\"contenthub.v1.ReleaseRead\"> & {\n /**\n * 0 resolves none; 1 resolves each Release's own References; 2 also those\n * of the Releases they resolve to; and so on, at most 8. A Content\n * already on the way is not entered again.\n *\n * @generated from field: int32 depth = 1;\n */\n depth: number;\n\n /**\n * Only References of these kinds, at every depth; empty for every kind\n * that points at Content.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 2;\n */\n kinds: EdgeKind[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseRead.\n * Use `create(ReleaseReadSchema)` to create a new message.\n */\nexport const ReleaseReadSchema: GenMessage<ReleaseRead> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 2);\n\n/**\n * @generated from message contenthub.v1.ListInForceRequest\n */\nexport type ListInForceRequest = Message<\"contenthub.v1.ListInForceRequest\"> & {\n /**\n * The date and moment to read at; unset is today, as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 1;\n */\n at?: InForceAt | undefined;\n\n /**\n * An open Change Set to Preview: it, and the open Change Sets it depends\n * on, read as if published now. User tokens only; an API key is\n * PermissionDenied.\n *\n * @generated from field: string preview_change_set_id = 2;\n */\n previewChangeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 4;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 5;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListInForceRequest.\n * Use `create(ListInForceRequestSchema)` to create a new message.\n */\nexport const ListInForceRequestSchema: GenMessage<ListInForceRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 3);\n\n/**\n * @generated from message contenthub.v1.ListInForceResponse\n */\nexport type ListInForceResponse = Message<\"contenthub.v1.ListInForceResponse\"> & {\n /**\n * By Content id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent contents = 1;\n */\n contents: ReleasedContent[];\n\n /**\n * The Releases References resolved to that aren't in contents, each once,\n * by Release id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 3;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListInForceResponse.\n * Use `create(ListInForceResponseSchema)` to create a new message.\n */\nexport const ListInForceResponseSchema: GenMessage<ListInForceResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 4);\n\n/**\n * @generated from message contenthub.v1.GetInForceRequest\n */\nexport type GetInForceRequest = Message<\"contenthub.v1.GetInForceRequest\"> & {\n /**\n * At most 200.\n *\n * @generated from field: repeated string content_ids = 1;\n */\n contentIds: string[];\n\n /**\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * As ListInForceRequest.preview_change_set_id.\n *\n * @generated from field: string preview_change_set_id = 3;\n */\n previewChangeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 4;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetInForceRequest.\n * Use `create(GetInForceRequestSchema)` to create a new message.\n */\nexport const GetInForceRequestSchema: GenMessage<GetInForceRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 5);\n\n/**\n * @generated from message contenthub.v1.GetInForceResponse\n */\nexport type GetInForceResponse = Message<\"contenthub.v1.GetInForceResponse\"> & {\n /**\n * By Content id.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent contents = 1;\n */\n contents: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.GetInForceResponse.\n * Use `create(GetInForceResponseSchema)` to create a new message.\n */\nexport const GetInForceResponseSchema: GenMessage<GetInForceResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 6);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetReleasesRequest\n */\nexport type ReleaseServiceGetReleasesRequest = Message<\"contenthub.v1.ReleaseServiceGetReleasesRequest\"> & {\n /**\n * At most 200. An id that isn't a Release of the workspace is NotFound.\n *\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n\n /**\n * Where unpinned References resolve and supersede marks are read. Unset,\n * each Release's References resolve on the first day of its Validity\n * Period (for undated Content, the day of its Publish Time), as known now\n * (ADR 0009); a known_at alone keeps those days.\n *\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetReleasesRequest.\n * Use `create(ReleaseServiceGetReleasesRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceGetReleasesRequestSchema: GenMessage<ReleaseServiceGetReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 7);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetReleasesResponse\n */\nexport type ReleaseServiceGetReleasesResponse = Message<\"contenthub.v1.ReleaseServiceGetReleasesResponse\"> & {\n /**\n * In the order asked.\n *\n * @generated from field: repeated contenthub.v1.ReleasedContent releases = 1;\n */\n releases: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetReleasesResponse.\n * Use `create(ReleaseServiceGetReleasesResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceGetReleasesResponseSchema: GenMessage<ReleaseServiceGetReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 8);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetTimelineRequest\n */\nexport type ReleaseServiceGetTimelineRequest = Message<\"contenthub.v1.ReleaseServiceGetTimelineRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The moment to read it as known at; unset for now.\n *\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetTimelineRequest.\n * Use `create(ReleaseServiceGetTimelineRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceGetTimelineRequestSchema: GenMessage<ReleaseServiceGetTimelineRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 9);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceGetTimelineResponse\n */\nexport type ReleaseServiceGetTimelineResponse = Message<\"contenthub.v1.ReleaseServiceGetTimelineResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.TimelineEntry entries = 1;\n */\n entries: TimelineEntry[];\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceGetTimelineResponse.\n * Use `create(ReleaseServiceGetTimelineResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceGetTimelineResponseSchema: GenMessage<ReleaseServiceGetTimelineResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 10);\n\n/**\n * TimelineEntry is one Release of a Timeline, without its data.\n *\n * @generated from message contenthub.v1.TimelineEntry\n */\nexport type TimelineEntry = Message<\"contenthub.v1.TimelineEntry\"> & {\n /**\n * Its place in the Timeline, from 1.\n *\n * @generated from field: int32 ordinal = 1;\n */\n ordinal: number;\n\n /**\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * @generated from field: contenthub.v1.ReleaseKind kind = 3;\n */\n kind: ReleaseKind;\n\n /**\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 5;\n */\n blueprintReleaseId: string;\n\n /**\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 6;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * @generated from field: google.protobuf.Struct release_spec = 7;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp publish_time = 8;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * @generated from field: bool first = 9;\n */\n first: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.TimelineEntry.\n * Use `create(TimelineEntrySchema)` to create a new message.\n */\nexport const TimelineEntrySchema: GenMessage<TimelineEntry> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 11);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceListReferrersRequest\n */\nexport type ReleaseServiceListReferrersRequest = Message<\"contenthub.v1.ReleaseServiceListReferrersRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only edges naming this Anchor; empty for every edge to the Content.\n *\n * @generated from field: string anchor = 2;\n */\n anchor: string;\n\n /**\n * Only edges of these kinds; empty for all.\n *\n * @generated from field: repeated contenthub.v1.EdgeKind kinds = 3;\n */\n kinds: EdgeKind[];\n\n /**\n * Unset is today, as known now.\n *\n * @generated from field: contenthub.v1.InForceAt at = 4;\n */\n at?: InForceAt | undefined;\n\n /**\n * As ListReferrersRequest.page_size: 0 means 100; above 1000 reads as\n * 1000.\n *\n * @generated from field: int32 page_size = 5;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page, asked with the same other\n * fields; empty for the first.\n *\n * @generated from field: string page_token = 6;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceListReferrersRequest.\n * Use `create(ReleaseServiceListReferrersRequestSchema)` to create a new message.\n */\nexport const ReleaseServiceListReferrersRequestSchema: GenMessage<ReleaseServiceListReferrersRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 12);\n\n/**\n * @generated from message contenthub.v1.ReleaseServiceListReferrersResponse\n */\nexport type ReleaseServiceListReferrersResponse = Message<\"contenthub.v1.ReleaseServiceListReferrersResponse\"> & {\n /**\n * Ordered by the referring Content and its edge order.\n *\n * @generated from field: repeated contenthub.v1.ReleasedReferrer referrers = 1;\n */\n referrers: ReleasedReferrer[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleaseServiceListReferrersResponse.\n * Use `create(ReleaseServiceListReferrersResponseSchema)` to create a new message.\n */\nexport const ReleaseServiceListReferrersResponseSchema: GenMessage<ReleaseServiceListReferrersResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 13);\n\n/**\n * ReleasedReferrer is one incoming edge, and the Release In Force whose\n * Revision holds it.\n *\n * @generated from message contenthub.v1.ReleasedReferrer\n */\nexport type ReleasedReferrer = Message<\"contenthub.v1.ReleasedReferrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ReleasedReferrer.\n * Use `create(ReleasedReferrerSchema)` to create a new message.\n */\nexport const ReleasedReferrerSchema: GenMessage<ReleasedReferrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 14);\n\n/**\n * @generated from message contenthub.v1.GetReleasesRequest\n */\nexport type GetReleasesRequest = Message<\"contenthub.v1.GetReleasesRequest\"> & {\n /**\n * As ReleaseServiceGetReleasesRequest.\n *\n * @generated from field: repeated string release_ids = 1;\n */\n releaseIds: string[];\n\n /**\n * @generated from field: contenthub.v1.InForceAt at = 2;\n */\n at?: InForceAt | undefined;\n\n /**\n * @generated from field: contenthub.v1.ReleaseRead read = 3;\n */\n read?: ReleaseRead | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetReleasesRequest.\n * Use `create(GetReleasesRequestSchema)` to create a new message.\n */\nexport const GetReleasesRequestSchema: GenMessage<GetReleasesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 15);\n\n/**\n * @generated from message contenthub.v1.GetReleasesResponse\n */\nexport type GetReleasesResponse = Message<\"contenthub.v1.GetReleasesResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent releases = 1;\n */\n releases: ReleasedContent[];\n\n /**\n * @generated from field: repeated contenthub.v1.ReleasedContent referenced = 2;\n */\n referenced: ReleasedContent[];\n};\n\n/**\n * Describes the message contenthub.v1.GetReleasesResponse.\n * Use `create(GetReleasesResponseSchema)` to create a new message.\n */\nexport const GetReleasesResponseSchema: GenMessage<GetReleasesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 16);\n\n/**\n * @generated from message contenthub.v1.GetTimelineRequest\n */\nexport type GetTimelineRequest = Message<\"contenthub.v1.GetTimelineRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp known_at = 2;\n */\n knownAt?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetTimelineRequest.\n * Use `create(GetTimelineRequestSchema)` to create a new message.\n */\nexport const GetTimelineRequestSchema: GenMessage<GetTimelineRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 17);\n\n/**\n * @generated from message contenthub.v1.GetTimelineResponse\n */\nexport type GetTimelineResponse = Message<\"contenthub.v1.GetTimelineResponse\"> & {\n /**\n * @generated from field: repeated contenthub.v1.TimelineEntry entries = 1;\n */\n entries: TimelineEntry[];\n\n /**\n * The Planned Releases of the Content in open Change Sets, by Change Set\n * and in the order they were planned: what may join the Timeline.\n *\n * @generated from field: repeated contenthub.v1.ChangeSetPlannedRelease planned_releases = 2;\n */\n plannedReleases: ChangeSetPlannedRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.GetTimelineResponse.\n * Use `create(GetTimelineResponseSchema)` to create a new message.\n */\nexport const GetTimelineResponseSchema: GenMessage<GetTimelineResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 18);\n\n/**\n * ChangeSetPlannedRelease is a Planned Release and the open Change Set whose\n * Publish would cut it.\n *\n * @generated from message contenthub.v1.ChangeSetPlannedRelease\n */\nexport type ChangeSetPlannedRelease = Message<\"contenthub.v1.ChangeSetPlannedRelease\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 2;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSetPlannedRelease.\n * Use `create(ChangeSetPlannedReleaseSchema)` to create a new message.\n */\nexport const ChangeSetPlannedReleaseSchema: GenMessage<ChangeSetPlannedRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_release_read, 19);\n\n/**\n * ReleaseService is the read path for template, export, flows and API keys\n * (ADR 0015): released data at (valid_on, known_at), with References resolved\n * at the same coordinates. Its responses never contain a Branch, or a\n * Revision that no Release pins, apart from a Preview's rows, which are\n * marked planned.\n *\n * Every RPC acts in the caller's workspace, from the token, and needs\n * `viewer` (ADR 0017). preview_change_set is accepted from user tokens only:\n * an API key never Previews (ADR 0006).\n *\n * @generated from service contenthub.v1.ReleaseService\n */\nexport const ReleaseService: GenService<{\n /**\n * ListInForce lists the Release In Force of every Content, one page at a\n * time, by Content id.\n *\n * @generated from rpc contenthub.v1.ReleaseService.ListInForce\n */\n listInForce: {\n methodKind: \"unary\";\n input: typeof ListInForceRequestSchema;\n output: typeof ListInForceResponseSchema;\n },\n /**\n * GetInForce reads the Release In Force of each Content named. A Content\n * with none In Force then (a gap, before its first Release, or unknown) is\n * left out.\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetInForce\n */\n getInForce: {\n methodKind: \"unary\";\n input: typeof GetInForceRequestSchema;\n output: typeof GetInForceResponseSchema;\n },\n /**\n * GetReleases reads Releases by id, superseded ones included and marked.\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetReleases\n */\n getReleases: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceGetReleasesRequestSchema;\n output: typeof ReleaseServiceGetReleasesResponseSchema;\n },\n /**\n * GetTimeline reads a Content's Timeline (CONTEXT.md).\n *\n * @generated from rpc contenthub.v1.ReleaseService.GetTimeline\n */\n getTimeline: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceGetTimelineRequestSchema;\n output: typeof ReleaseServiceGetTimelineResponseSchema;\n },\n /**\n * ListReferrers reads the edges pointing at a Content, or at an Anchor in\n * it, from the Releases In Force at a date and moment.\n *\n * @generated from rpc contenthub.v1.ReleaseService.ListReferrers\n */\n listReferrers: {\n methodKind: \"unary\";\n input: typeof ReleaseServiceListReferrersRequestSchema;\n output: typeof ReleaseServiceListReferrersResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_release_read, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/graph_warnings.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Edge } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { TimelineEntry } from \"./release_read_pb\";\nimport { file_contenthub_v1_release_read } from \"./release_read_pb\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/graph_warnings.proto.\n */\nexport const file_contenthub_v1_graph_warnings: GenFile = /*@__PURE__*/\n fileDesc(\"CiJjb250ZW50aHViL3YxL2dyYXBoX3dhcm5pbmdzLnByb3RvEg1jb250ZW50aHViLnYxImEKF0xpc3RPdXRkYXRlZFBpbnNSZXF1ZXN0EhMKCWJyYW5jaF9pZBgBIAEoCUgAEhUKC3JldmlzaW9uX2lkGAIgASgJSAASEAoIdmFsaWRfb24YAyABKAlCCAoGc291cmNlIkQKGExpc3RPdXRkYXRlZFBpbnNSZXNwb25zZRIoCgRwaW5zGAEgAygLMhouY29udGVudGh1Yi52MS5PdXRkYXRlZFBpbiKhAQoLT3V0ZGF0ZWRQaW4SIQoEZWRnZRgBIAEoCzITLmNvbnRlbnRodWIudjEuRWRnZRIgChhzdXBlcnNlZGVkX2J5X3JlbGVhc2VfaWQYAiABKAkSGwoTaW5fZm9yY2VfcmVsZWFzZV9pZBgDIAEoCRIwCgpjYW5kaWRhdGVzGAQgAygLMhwuY29udGVudGh1Yi52MS5UaW1lbGluZUVudHJ5IkQKC0dhcFJlZmVycmVyEiEKBGVkZ2UYASABKAsyEy5jb250ZW50aHViLnYxLkVkZ2USEgoKcmVsZWFzZV9pZBgCIAEoCSJ0Cg5QdWJsaXNoV2FybmluZxIMCgRjb2RlGAEgASgJEhIKCmNvbnRlbnRfaWQYAiABKAkSEgoKcmVsZWFzZV9pZBgDIAEoCRIsCghyZWZlcnJlchgEIAEoCzIaLmNvbnRlbnRodWIudjEuR2FwUmVmZXJyZXJCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_contenthub_v1_content_graph, file_contenthub_v1_release_read]);\n\n/**\n * @generated from message contenthub.v1.ListOutdatedPinsRequest\n */\nexport type ListOutdatedPinsRequest = Message<\"contenthub.v1.ListOutdatedPinsRequest\"> & {\n /**\n * Whose pins: the head of a Branch, or one Revision. Exactly one is\n * required.\n *\n * @generated from oneof contenthub.v1.ListOutdatedPinsRequest.source\n */\n source: {\n /**\n * @generated from field: string branch_id = 1;\n */\n value: string;\n case: \"branchId\";\n } | {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | { case: undefined; value?: undefined };\n\n /**\n * The day each pin is compared with its target's Release In Force, as\n * YYYY-MM-DD in the workspace's time zone; empty for today. In Force is\n * read as known now.\n *\n * @generated from field: string valid_on = 3;\n */\n validOn: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListOutdatedPinsRequest.\n * Use `create(ListOutdatedPinsRequestSchema)` to create a new message.\n */\nexport const ListOutdatedPinsRequestSchema: GenMessage<ListOutdatedPinsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 0);\n\n/**\n * @generated from message contenthub.v1.ListOutdatedPinsResponse\n */\nexport type ListOutdatedPinsResponse = Message<\"contenthub.v1.ListOutdatedPinsResponse\"> & {\n /**\n * In the Revision's edge order.\n *\n * @generated from field: repeated contenthub.v1.OutdatedPin pins = 1;\n */\n pins: OutdatedPin[];\n};\n\n/**\n * Describes the message contenthub.v1.ListOutdatedPinsResponse.\n * Use `create(ListOutdatedPinsResponseSchema)` to create a new message.\n */\nexport const ListOutdatedPinsResponseSchema: GenMessage<ListOutdatedPinsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 1);\n\n/**\n * OutdatedPin is a pinned edge whose Release is superseded, or is not the\n * one In Force on valid_on. A pin to a Planned Release is never outdated: it\n * names the newest wording there is.\n *\n * @generated from message contenthub.v1.OutdatedPin\n */\nexport type OutdatedPin = Message<\"contenthub.v1.OutdatedPin\"> & {\n /**\n * The edge; pin_release_id is the Release it pins.\n *\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release that supersedes the pinned one, as known now; empty if\n * none.\n *\n * @generated from field: string superseded_by_release_id = 2;\n */\n supersededByReleaseId: string;\n\n /**\n * The target's Release In Force on valid_on; empty in a gap.\n *\n * @generated from field: string in_force_release_id = 3;\n */\n inForceReleaseId: string;\n\n /**\n * The target's Timeline as known now: the Releases to re-pin to, in\n * order, as GetTimeline lists them: superseded Releases are never among\n * them, while a Repeal or Withdrawal is, so that the gap it leaves shows.\n *\n * @generated from field: repeated contenthub.v1.TimelineEntry candidates = 4;\n */\n candidates: TimelineEntry[];\n};\n\n/**\n * Describes the message contenthub.v1.OutdatedPin.\n * Use `create(OutdatedPinSchema)` to create a new message.\n */\nexport const OutdatedPinSchema: GenMessage<OutdatedPin> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 2);\n\n/**\n * GapReferrer is an unpinned edge that a Repeal or Withdrawal will leave\n * pointing at a gap: it is held by a Release In Force, with the Change Set\n * published, on the first day without the Content (the day after a Repeal's\n * last day, today for a Withdrawal) or on today if that is later, each day\n * counting only while the Content has nothing In Force on it. A pinned edge\n * keeps resolving, and a footnote resolves at its citer's coordinates, so\n * neither is ever one. Branch heads of other open Change Sets are not read.\n *\n * @generated from message contenthub.v1.GapReferrer\n */\nexport type GapReferrer = Message<\"contenthub.v1.GapReferrer\"> & {\n /**\n * @generated from field: contenthub.v1.Edge edge = 1;\n */\n edge?: Edge | undefined;\n\n /**\n * The Release of edge.source_content_id holding the edge: a Planned\n * Release of the Change Set where it is one.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GapReferrer.\n * Use `create(GapReferrerSchema)` to create a new message.\n */\nexport const GapReferrerSchema: GenMessage<GapReferrer> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 3);\n\n/**\n * PublishWarning is advice ValidatePublish gives: it never blocks Publish.\n *\n * @generated from message contenthub.v1.PublishWarning\n */\nexport type PublishWarning = Message<\"contenthub.v1.PublishWarning\"> & {\n /**\n * \"gap_referrer\": referrer is left with a gap by the Repeal or Withdrawal\n * release_id of content_id.\n *\n * @generated from field: string code = 1;\n */\n code: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string release_id = 3;\n */\n releaseId: string;\n\n /**\n * @generated from field: contenthub.v1.GapReferrer referrer = 4;\n */\n referrer?: GapReferrer | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PublishWarning.\n * Use `create(PublishWarningSchema)` to create a new message.\n */\nexport const PublishWarningSchema: GenMessage<PublishWarning> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_graph_warnings, 4);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/merge.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp, Value } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/merge.proto.\n */\nexport const file_contenthub_v1_merge: GenFile = /*@__PURE__*/\n fileDesc(\"Chljb250ZW50aHViL3YxL21lcmdlLnByb3RvEg1jb250ZW50aHViLnYxIrICCgxQZW5kaW5nTWVyZ2USEQoJYnJhbmNoX2lkGAEgASgJEhAKCGNoYWluX2lkGAIgASgJEhIKCmNvbnRlbnRfaWQYAyABKAkSFQoNY2hhbmdlX3NldF9pZBgEIAEoCRIYChBiYXNlX3JldmlzaW9uX2lkGAUgASgJEhgKEG91cnNfcmV2aXNpb25faWQYBiABKAkSGgoSdGhlaXJzX3JldmlzaW9uX2lkGAcgASgJEjEKBnJlYXNvbhgIIAEoDjIhLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlUmVhc29uEg0KBXBhdGhzGAkgAygJEg8KB2NhcnJpZWQYCiABKAgSLwoLY3JlYXRlX3RpbWUYCyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIqYBCgpNZXJnZUZpZWxkEgwKBHBhdGgYASABKAkSFgoOY29uZmxpY3RfcGF0aHMYAiADKAkSJAoEYmFzZRgDIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRIkCgRvdXJzGAQgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEiYKBnRoZWlycxgFIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSJ8Cg9GaWVsZFJlc29sdXRpb24SDAoEcGF0aBgBIAEoCRIoCgRzaWRlGAIgASgOMhguY29udGVudGh1Yi52MS5NZXJnZVNpZGVIABInCgV2YWx1ZRgDIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZUgAQggKBmNob2ljZSp/ChJQZW5kaW5nTWVyZ2VSZWFzb24SJAogUEVORElOR19NRVJHRV9SRUFTT05fVU5TUEVDSUZJRUQQABIhCh1QRU5ESU5HX01FUkdFX1JFQVNPTl9DT05GTElDVBABEiAKHFBFTkRJTkdfTUVSR0VfUkVBU09OX0lOVkFMSUQQAipTCglNZXJnZVNpZGUSGgoWTUVSR0VfU0lERV9VTlNQRUNJRklFRBAAEhMKD01FUkdFX1NJREVfT1VSUxABEhUKEU1FUkdFX1NJREVfVEhFSVJTEAJCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * PendingMerge is a merge on a Branch that stopped (CONTEXT.md, Conflict):\n * Update from Main stores one on a Branch whose merge has Conflicts, or is\n * clean but fails the Blueprint Release it would pin. It stays until it is\n * resolved (ResolveMerge) or aborted (AbortMerge); until then saves on the\n * Branch and Publish are refused, and later updates leave the Branch alone.\n *\n * @generated from message contenthub.v1.PendingMerge\n */\nexport type PendingMerge = Message<\"contenthub.v1.PendingMerge\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * @generated from field: string content_id = 3;\n */\n contentId: string;\n\n /**\n * @generated from field: string change_set_id = 4;\n */\n changeSetId: string;\n\n /**\n * The merge's three Revisions: what the Branch last took in (base), its\n * head (ours, still its head while the merge is pending) and what it was\n * merging (theirs: Main's head, a dependency's Branch head, the link before\n * it, or the Release a link carries).\n *\n * @generated from field: string base_revision_id = 5;\n */\n baseRevisionId: string;\n\n /**\n * @generated from field: string ours_revision_id = 6;\n */\n oursRevisionId: string;\n\n /**\n * @generated from field: string theirs_revision_id = 7;\n */\n theirsRevisionId: string;\n\n /**\n * @generated from field: contenthub.v1.PendingMergeReason reason = 8;\n */\n reason: PendingMergeReason;\n\n /**\n * Where it stopped: the conflicting field paths (an accessor, or an\n * accessor and a path within the field such as \"rows/r1\") for a conflict;\n * the paths the Blueprint Release refuses (\"/\" and an accessor, and\n * deeper) for invalid data. Never empty.\n *\n * @generated from field: repeated string paths = 9;\n */\n paths: string[];\n\n /**\n * Whether theirs is what a Chain link on Dated Content carries, rather\n * than its upstream Branch's head.\n *\n * @generated from field: bool carried = 10;\n */\n carried: boolean;\n\n /**\n * When Update from Main stored it.\n *\n * @generated from field: google.protobuf.Timestamp create_time = 11;\n */\n createTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PendingMerge.\n * Use `create(PendingMergeSchema)` to create a new message.\n */\nexport const PendingMergeSchema: GenMessage<PendingMerge> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 0);\n\n/**\n * MergeField is one field a resolution must decide: a field both sides\n * changed in ways that don't merge, or one whose merged value the Blueprint\n * Release refuses.\n *\n * @generated from message contenthub.v1.MergeField\n */\nexport type MergeField = Message<\"contenthub.v1.MergeField\"> & {\n /**\n * \"/\" and the field's accessor, as a Violation spells it.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * The Pending Merge's paths within this field.\n *\n * @generated from field: repeated string conflict_paths = 2;\n */\n conflictPaths: string[];\n\n /**\n * The field's value in base, ours and theirs; unset on a side that doesn't\n * hold the field.\n *\n * @generated from field: google.protobuf.Value base = 3;\n */\n base?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value ours = 4;\n */\n ours?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value theirs = 5;\n */\n theirs?: Value | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.MergeField.\n * Use `create(MergeFieldSchema)` to create a new message.\n */\nexport const MergeFieldSchema: GenMessage<MergeField> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 1);\n\n/**\n * FieldResolution decides one MergeField: one side's value (its absence\n * included, when that side doesn't hold the field), or a value the editor\n * wrote.\n *\n * @generated from message contenthub.v1.FieldResolution\n */\nexport type FieldResolution = Message<\"contenthub.v1.FieldResolution\"> & {\n /**\n * The MergeField's path.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from oneof contenthub.v1.FieldResolution.choice\n */\n choice: {\n /**\n * @generated from field: contenthub.v1.MergeSide side = 2;\n */\n value: MergeSide;\n case: \"side\";\n } | {\n /**\n * @generated from field: google.protobuf.Value value = 3;\n */\n value: Value;\n case: \"value\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.FieldResolution.\n * Use `create(FieldResolutionSchema)` to create a new message.\n */\nexport const FieldResolutionSchema: GenMessage<FieldResolution> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_merge, 2);\n\n/**\n * PendingMergeReason is why Update from Main stored a Pending Merge.\n *\n * @generated from enum contenthub.v1.PendingMergeReason\n */\nexport enum PendingMergeReason {\n /**\n * @generated from enum value: PENDING_MERGE_REASON_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Both sides changed fields in ways that don't merge.\n *\n * @generated from enum value: PENDING_MERGE_REASON_CONFLICT = 1;\n */\n CONFLICT = 1,\n\n /**\n * The merge was clean, but its data fails the Blueprint Release it would\n * pin.\n *\n * @generated from enum value: PENDING_MERGE_REASON_INVALID = 2;\n */\n INVALID = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.PendingMergeReason.\n */\nexport const PendingMergeReasonSchema: GenEnum<PendingMergeReason> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_merge, 0);\n\n/**\n * MergeSide is a side of a Pending Merge whose value a resolution takes.\n *\n * @generated from enum contenthub.v1.MergeSide\n */\nexport enum MergeSide {\n /**\n * @generated from enum value: MERGE_SIDE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * The Branch's head.\n *\n * @generated from enum value: MERGE_SIDE_OURS = 1;\n */\n OURS = 1,\n\n /**\n * What the Branch was merging.\n *\n * @generated from enum value: MERGE_SIDE_THEIRS = 2;\n */\n THEIRS = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.MergeSide.\n */\nexport const MergeSideSchema: GenEnum<MergeSide> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_merge, 1);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/planning.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { GapReferrer } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { PlannedRelease, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/planning.proto.\n */\nexport const file_contenthub_v1_planning: GenFile = /*@__PURE__*/\n fileDesc(\"Chxjb250ZW50aHViL3YxL3BsYW5uaW5nLnByb3RvEg1jb250ZW50aHViLnYxIpgBChpQbGFuRGF0ZU9ubHlSZWxlYXNlUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhIKCnJlbGVhc2VfaWQYAiABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAMgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiVQobUGxhbkRhdGVPbmx5UmVsZWFzZVJlc3BvbnNlEjYKD3BsYW5uZWRfcmVsZWFzZRgBIAEoCzIdLmNvbnRlbnRodWIudjEuUGxhbm5lZFJlbGVhc2UiaQoRUGxhblJlcGVhbFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhAKCGxhc3RfZGF5GAMgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgEIAEoCSJ/ChJQbGFuUmVwZWFsUmVzcG9uc2USNgoPcGxhbm5lZF9yZWxlYXNlGAEgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZRIxCg1nYXBfcmVmZXJyZXJzGAIgAygLMhouY29udGVudGh1Yi52MS5HYXBSZWZlcnJlciJbChVQbGFuV2l0aGRyYXdhbFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSKDAQoWUGxhbldpdGhkcmF3YWxSZXNwb25zZRI2Cg9wbGFubmVkX3JlbGVhc2UYASABKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlEjEKDWdhcF9yZWZlcnJlcnMYAiADKAsyGi5jb250ZW50aHViLnYxLkdhcFJlZmVycmVyImcKGURyb3BQbGFubmVkUmVsZWFzZVJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIaChJwbGFubmVkX3JlbGVhc2VfaWQYAiABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIlUKGkRyb3BQbGFubmVkUmVsZWFzZVJlc3BvbnNlEjcKEHBsYW5uZWRfcmVsZWFzZXMYASADKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlIkAKDUNvdmVyc1JlbGVhc2USEgoKY29udGVudF9pZBgBIAEoCRIbChNjb3ZlcmVkX3JlbGVhc2VfaWRzGAIgAygJQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_contenthub_v1_graph_warnings, file_contenthub_v1_release]);\n\n/**\n * @generated from message contenthub.v1.PlanDateOnlyReleaseRequest\n */\nexport type PlanDateOnlyReleaseRequest = Message<\"contenthub.v1.PlanDateOnlyReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Release of Dated Content to re-pin and supersede.\n *\n * @generated from field: string release_id = 2;\n */\n releaseId: string;\n\n /**\n * Required: the corrected Validity Period.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanDateOnlyReleaseRequest.\n * Use `create(PlanDateOnlyReleaseRequestSchema)` to create a new message.\n */\nexport const PlanDateOnlyReleaseRequestSchema: GenMessage<PlanDateOnlyReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 0);\n\n/**\n * @generated from message contenthub.v1.PlanDateOnlyReleaseResponse\n */\nexport type PlanDateOnlyReleaseResponse = Message<\"contenthub.v1.PlanDateOnlyReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PlanDateOnlyReleaseResponse.\n * Use `create(PlanDateOnlyReleaseResponseSchema)` to create a new message.\n */\nexport const PlanDateOnlyReleaseResponseSchema: GenMessage<PlanDateOnlyReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 1);\n\n/**\n * @generated from message contenthub.v1.PlanRepealRequest\n */\nexport type PlanRepealRequest = Message<\"contenthub.v1.PlanRepealRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Dated Content to repeal.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Required: the last day it is In Force, as YYYY-MM-DD.\n *\n * @generated from field: string last_day = 3;\n */\n lastDay: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanRepealRequest.\n * Use `create(PlanRepealRequestSchema)` to create a new message.\n */\nexport const PlanRepealRequestSchema: GenMessage<PlanRepealRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 2);\n\n/**\n * @generated from message contenthub.v1.PlanRepealResponse\n */\nexport type PlanRepealResponse = Message<\"contenthub.v1.PlanRepealResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n\n /**\n * A warning, never a refusal: the referrers it will leave with a gap\n * once the Change Set is published (ADR 0009).\n *\n * @generated from field: repeated contenthub.v1.GapReferrer gap_referrers = 2;\n */\n gapReferrers: GapReferrer[];\n};\n\n/**\n * Describes the message contenthub.v1.PlanRepealResponse.\n * Use `create(PlanRepealResponseSchema)` to create a new message.\n */\nexport const PlanRepealResponseSchema: GenMessage<PlanRepealResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 3);\n\n/**\n * @generated from message contenthub.v1.PlanWithdrawalRequest\n */\nexport type PlanWithdrawalRequest = Message<\"contenthub.v1.PlanWithdrawalRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The undated Content to withdraw.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanWithdrawalRequest.\n * Use `create(PlanWithdrawalRequestSchema)` to create a new message.\n */\nexport const PlanWithdrawalRequestSchema: GenMessage<PlanWithdrawalRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 4);\n\n/**\n * @generated from message contenthub.v1.PlanWithdrawalResponse\n */\nexport type PlanWithdrawalResponse = Message<\"contenthub.v1.PlanWithdrawalResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n\n /**\n * A warning, never a refusal: the referrers it will leave with a gap\n * once the Change Set is published (ADR 0009).\n *\n * @generated from field: repeated contenthub.v1.GapReferrer gap_referrers = 2;\n */\n gapReferrers: GapReferrer[];\n};\n\n/**\n * Describes the message contenthub.v1.PlanWithdrawalResponse.\n * Use `create(PlanWithdrawalResponseSchema)` to create a new message.\n */\nexport const PlanWithdrawalResponseSchema: GenMessage<PlanWithdrawalResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 5);\n\n/**\n * @generated from message contenthub.v1.DropPlannedReleaseRequest\n */\nexport type DropPlannedReleaseRequest = Message<\"contenthub.v1.DropPlannedReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string planned_release_id = 2;\n */\n plannedReleaseId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DropPlannedReleaseRequest.\n * Use `create(DropPlannedReleaseRequestSchema)` to create a new message.\n */\nexport const DropPlannedReleaseRequestSchema: GenMessage<DropPlannedReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 6);\n\n/**\n * @generated from message contenthub.v1.DropPlannedReleaseResponse\n */\nexport type DropPlannedReleaseResponse = Message<\"contenthub.v1.DropPlannedReleaseResponse\"> & {\n /**\n * The Change Set's Planned Releases left, proposals recomputed.\n *\n * @generated from field: repeated contenthub.v1.PlannedRelease planned_releases = 1;\n */\n plannedReleases: PlannedRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.DropPlannedReleaseResponse.\n * Use `create(DropPlannedReleaseResponseSchema)` to create a new message.\n */\nexport const DropPlannedReleaseResponseSchema: GenMessage<DropPlannedReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 7);\n\n/**\n * CoversRelease is the detail of a FailedPrecondition plan whose Validity\n * Period would cover other Releases of the Content entirely: nothing is\n * planned. Supersede them (drop them, if they are planned) or change the\n * dates.\n *\n * @generated from message contenthub.v1.CoversRelease\n */\nexport type CoversRelease = Message<\"contenthub.v1.CoversRelease\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The Releases covered, by first day.\n *\n * @generated from field: repeated string covered_release_ids = 2;\n */\n coveredReleaseIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.CoversRelease.\n * Use `create(CoversReleaseSchema)` to create a new message.\n */\nexport const CoversReleaseSchema: GenMessage<CoversRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_planning, 8);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/change_set.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { PublishWarning } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { FieldResolution, MergeField, PendingMerge } from \"./merge_pb\";\nimport { file_contenthub_v1_merge } from \"./merge_pb\";\nimport type { DropPlannedReleaseRequestSchema, DropPlannedReleaseResponseSchema, PlanDateOnlyReleaseRequestSchema, PlanDateOnlyReleaseResponseSchema, PlanRepealRequestSchema, PlanRepealResponseSchema, PlanWithdrawalRequestSchema, PlanWithdrawalResponseSchema } from \"./planning_pb\";\nimport { file_contenthub_v1_planning } from \"./planning_pb\";\nimport type { PlannedRelease, PublishBlocker, Release, ReleaseIdList, ValidityPeriod } from \"./release_pb\";\nimport { file_contenthub_v1_release } from \"./release_pb\";\nimport type { RequiredCheck } from \"./workspace_config_pb\";\nimport { file_contenthub_v1_workspace_config } from \"./workspace_config_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { JsonObject, Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/change_set.proto.\n */\nexport const file_contenthub_v1_change_set: GenFile = /*@__PURE__*/\n fileDesc(\"Ch5jb250ZW50aHViL3YxL2NoYW5nZV9zZXQucHJvdG8SDWNvbnRlbnRodWIudjEiKQoGU291cmNlEgwKBGRhdGUYASABKAkSEQoJcmVmZXJlbmNlGAIgASgJIpcDCglDaGFuZ2VTZXQSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIlCgZzb3VyY2UYAyABKAsyFS5jb250ZW50aHViLnYxLlNvdXJjZRIsCgVzdGF0ZRgEIAEoDjIdLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0U3RhdGUSEgoKY3JlYXRlZF9ieRgFIAEoCRIvCgtjcmVhdGVfdGltZRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKY2xvc2VfdGltZRgHIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJAoGY2hhaW5zGAggAygLMhQuY29udGVudGh1Yi52MS5DaGFpbhIhChlkZXBlbmRzX29uX2NoYW5nZV9zZXRfaWRzGAkgAygJEjcKEHBsYW5uZWRfcmVsZWFzZXMYCiADKAsyHS5jb250ZW50aHViLnYxLlBsYW5uZWRSZWxlYXNlEg4KBnN0YXR1cxgLIAEoCRIUCgxhc3NpZ25lZV9pZHMYDCADKAkiXgoFQ2hhaW4SCgoCaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIMCgRib3JuGAMgASgIEicKCGJyYW5jaGVzGAQgAygLMhUuY29udGVudGh1Yi52MS5CcmFuY2gitgEKBkJyYW5jaBIKCgJpZBgBIAEoCRIQCghwb3NpdGlvbhgCIAEoBRInCgRraW5kGAMgASgOMhkuY29udGVudGh1Yi52MS5CcmFuY2hLaW5kEhgKEGhlYWRfcmV2aXNpb25faWQYBCABKAkSFAoMZWZmZWN0aXZlX29uGAUgASgJEhoKEmNhcnJpZWRfcmVsZWFzZV9pZBgGIAEoCRIZChFoYXNfcGVuZGluZ19tZXJnZRgHIAEoCCJmChZDcmVhdGVDaGFuZ2VTZXRSZXF1ZXN0EgwKBG5hbWUYASABKAkSJQoGc291cmNlGAIgASgLMhUuY29udGVudGh1Yi52MS5Tb3VyY2USFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIkcKF0NyZWF0ZUNoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCIhChNHZXRDaGFuZ2VTZXRSZXF1ZXN0EgoKAmlkGAEgASgJIkQKFEdldENoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCKhAQoWVXBkYXRlQ2hhbmdlU2V0UmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEiUKBnNvdXJjZRgDIAEoCzIVLmNvbnRlbnRodWIudjEuU291cmNlEi0KC3VwZGF0ZV9tYXNrGAQgASgLMhguY29udGVudGh1Yi52MS5GaWVsZE1hc2sSFwoPaWRlbXBvdGVuY3lfa2V5GAUgASgJIkcKF1VwZGF0ZUNoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCI+ChdEaXNjYXJkQ2hhbmdlU2V0UmVxdWVzdBIKCgJpZBgBIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAiABKAkiSAoYRGlzY2FyZENoYW5nZVNldFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCJ0ChlTZXRDaGFuZ2VTZXRTdGF0dXNSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSFwoPZXhwZWN0ZWRfc3RhdHVzGAIgASgJEg4KBnN0YXR1cxgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiSgoaU2V0Q2hhbmdlU2V0U3RhdHVzUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0ImQKHFNldENoYW5nZVNldEFzc2lnbmVlc1JlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIUCgxhc3NpZ25lZV9pZHMYAiADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIk0KHVNldENoYW5nZVNldEFzc2lnbmVlc1Jlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCJBCghDb3B5RnJvbRIUCgpyZWxlYXNlX2lkGAEgASgJSAASFQoLcmV2aXNpb25faWQYAiABKAlIAEIICgZzb3VyY2Ui4wEKFENyZWF0ZUNvbnRlbnRSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEgoKY29udGVudF9pZBgCIAEoCRIcChRibHVlcHJpbnRfcmVsZWFzZV9pZBgDIAEoCRIlCgRkYXRhGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIqCgljb3B5X2Zyb20YBSABKAsyFy5jb250ZW50aHViLnYxLkNvcHlGcm9tEhYKDmNvbGxlY3Rpb25faWRzGAYgAygJEhcKD2lkZW1wb3RlbmN5X2tleRgHIAEoCSJAChVDcmVhdGVDb250ZW50UmVzcG9uc2USJwoHY29udGVudBgBIAEoCzIWLmNvbnRlbnRodWIudjEuQ29udGVudCIbCglGaWVsZE1hc2sSDgoGZmllbGRzGAEgAygJIrABChNTYXZlUmV2aXNpb25SZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAIgASgJEiUKBGRhdGEYAyABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EiwKCmZpZWxkX21hc2sYBCABKAsyGC5jb250ZW50aHViLnYxLkZpZWxkTWFzaxIXCg9pZGVtcG90ZW5jeV9rZXkYBSABKAkiPwoUU2F2ZVJldmlzaW9uUmVzcG9uc2USJwoHY29udGVudBgBIAEoCzIWLmNvbnRlbnRodWIudjEuQ29udGVudCL9AQoHQ29udGVudBIKCgJpZBgBIAEoCRIUCgxibHVlcHJpbnRfaWQYAiABKAkSHAoUYmx1ZXByaW50X3JlbGVhc2VfaWQYAyABKAkSEwoLcmV2aXNpb25faWQYBCABKAkSJQoEZGF0YRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSFQoNY2hhbmdlX3NldF9pZBgGIAEoCRIRCglicmFuY2hfaWQYByABKAkSOAoUcmV2aXNpb25fY3JlYXRlX3RpbWUYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhIKCnJlbGVhc2VfaWQYCSABKAkijgEKE1ByZXZpZXdDaGFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRI2Cg92YWxpZGl0eV9wZXJpb2QYBCABKAsyHS5jb250ZW50aHViLnYxLlZhbGlkaXR5UGVyaW9kIkQKFFByZXZpZXdDaGFpblJlc3BvbnNlEiwKB3ByZXZpZXcYASABKAsyGy5jb250ZW50aHViLnYxLkNoYWluUHJldmlldyKUAgoMQ2hhaW5QcmV2aWV3EhcKD2ZvcmtfcmVsZWFzZV9pZBgBIAEoCRIhChljYXJyeV9mb3J3YXJkX3JlbGVhc2VfaWRzGAIgAygJEhMKC21lcmdlc19tYWluGAMgASgIEjYKD3ZhbGlkaXR5X3BlcmlvZBgEIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSKAoIY3V0X2ludG8YBSADKAsyFi5jb250ZW50aHViLnYxLkN1dEludG8SGwoTY292ZXJlZF9yZWxlYXNlX2lkcxgGIAMoCRI0CgpzdXBlcnNlZGVkGAcgAygLMiAuY29udGVudGh1Yi52MS5TdXBlcnNlZGVkUmVsZWFzZSKIAQoHQ3V0SW50bxISCgpyZWxlYXNlX2lkGAEgASgJEg8KB3BsYW5uZWQYAiABKAgSKwoEa2VwdBgDIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSKwoEdGFpbBgEIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QiRgoRU3VwZXJzZWRlZFJlbGVhc2USEgoKcmVsZWFzZV9pZBgBIAEoCRIdChVieV9wbGFubmVkX3JlbGVhc2VfaWQYAiABKAkibQoRU3RhcnRDaGFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkibQoSU3RhcnRDaGFpblJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBIQCghjaGFpbl9pZBgCIAEoCRIXCg9mb3JrX3JlbGVhc2VfaWQYAyABKAkibQoTQXBwZW5kQnJhbmNoUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhAKCGNoYWluX2lkGAIgASgJEhQKDGVmZmVjdGl2ZV9vbhgDIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBCABKAkiVwoUQXBwZW5kQnJhbmNoUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EhEKCWJyYW5jaF9pZBgCIAEoCSJUChBEcm9wQ2hhaW5SZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEAoIY2hhaW5faWQYAiABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAMgASgJIkEKEURyb3BDaGFpblJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldCKIAQoTU3RhcnRFZGl0aW5nUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEhUKDWNoYW5nZV9zZXRfaWQYAiABKAkSFAoMZWZmZWN0aXZlX29uGAMgASgJEhcKD2NoYW5nZV9zZXRfbmFtZRgEIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBSABKAkihgEKFFN0YXJ0RWRpdGluZ1Jlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBInCgdjb250ZW50GAIgASgLMhYuY29udGVudGh1Yi52MS5Db250ZW50EhcKD2ZvcmtfcmVsZWFzZV9pZBgDIAEoCSJZChVVcGRhdGVGcm9tTWFpblJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIQCghjaGFpbl9pZBgCIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAyABKAki2gEKFlVwZGF0ZUZyb21NYWluUmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EhkKEW1lcmdlZF9icmFuY2hfaWRzGAIgAygJEi8KCmNvbmZsaWN0ZWQYAyADKAsyGy5jb250ZW50aHViLnYxLlBlbmRpbmdNZXJnZRIsCgdwZW5kaW5nGAQgAygLMhsuY29udGVudGh1Yi52MS5QZW5kaW5nTWVyZ2USGAoQZW5kZWRfYnJhbmNoX2lkcxgFIAMoCSIrChZHZXRQZW5kaW5nTWVyZ2VSZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCSK/AQoXR2V0UGVuZGluZ01lcmdlUmVzcG9uc2USMgoNcGVuZGluZ19tZXJnZRgBIAEoCzIbLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAIgASgJEikKBmZpZWxkcxgDIAMoCzIZLmNvbnRlbnRodWIudjEuTWVyZ2VGaWVsZBInCgZtZXJnZWQYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0IpABChNSZXNvbHZlTWVyZ2VSZXF1ZXN0EhEKCWJyYW5jaF9pZBgBIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAIgASgJEjMKC3Jlc29sdXRpb25zGAMgAygLMh4uY29udGVudGh1Yi52MS5GaWVsZFJlc29sdXRpb24SFwoPaWRlbXBvdGVuY3lfa2V5GAQgASgJIj8KFFJlc29sdmVNZXJnZVJlc3BvbnNlEicKB2NvbnRlbnQYASABKAsyFi5jb250ZW50aHViLnYxLkNvbnRlbnQiPwoRQWJvcnRNZXJnZVJlcXVlc3QSEQoJYnJhbmNoX2lkGAEgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgCIAEoCSJCChJBYm9ydE1lcmdlUmVzcG9uc2USLAoHYWJvcnRlZBgBIAEoCzIbLmNvbnRlbnRodWIudjEuUGVuZGluZ01lcmdlImgKFEFkZERlcGVuZGVuY3lSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSIAoYZGVwZW5kc19vbl9jaGFuZ2Vfc2V0X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJFChVBZGREZXBlbmRlbmN5UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0ImsKF1JlbW92ZURlcGVuZGVuY3lSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSIAoYZGVwZW5kc19vbl9jaGFuZ2Vfc2V0X2lkGAIgASgJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJIChhSZW1vdmVEZXBlbmRlbmN5UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0It4BChJQbGFuUmVsZWFzZVJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIRCglicmFuY2hfaWQYAiABKAkSNgoPdmFsaWRpdHlfcGVyaW9kGAMgASgLMh0uY29udGVudGh1Yi52MS5WYWxpZGl0eVBlcmlvZBItCgxyZWxlYXNlX3NwZWMYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0Eh4KFnN1cGVyc2VkZXNfcmVsZWFzZV9pZHMYBSADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAYgASgJIk0KE1BsYW5SZWxlYXNlUmVzcG9uc2USNgoPcGxhbm5lZF9yZWxlYXNlGAEgASgLMh0uY29udGVudGh1Yi52MS5QbGFubmVkUmVsZWFzZSKCAgobVXBkYXRlUGxhbm5lZFJlbGVhc2VSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSGgoScGxhbm5lZF9yZWxlYXNlX2lkGAIgASgJEjYKD3ZhbGlkaXR5X3BlcmlvZBgDIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSLQoMcmVsZWFzZV9zcGVjGAQgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdBIwCgpzdXBlcnNlZGVzGAUgASgLMhwuY29udGVudGh1Yi52MS5SZWxlYXNlSWRMaXN0EhcKD2lkZW1wb3RlbmN5X2tleRgGIAEoCSJWChxVcGRhdGVQbGFubmVkUmVsZWFzZVJlc3BvbnNlEjYKD3BsYW5uZWRfcmVsZWFzZRgBIAEoCzIdLmNvbnRlbnRodWIudjEuUGxhbm5lZFJlbGVhc2UiPQoNVXBncmFkZVRhcmdldBISCgpjb250ZW50X2lkGAEgASgJEhgKEGV4cGVjdGVkX2hlYWRfaWQYAiABKAki+gEKFVVwZ3JhZGVDb250ZW50UmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAIgASgJEi4KCGNvbnRlbnRzGAMgAygLMhwuY29udGVudGh1Yi52MS5VcGdyYWRlVGFyZ2V0EhkKEWFsbF9waW5uaW5nX29sZGVyGAQgASgIEhMKC2Ryb3BfZmllbGRzGAUgAygJEjMKDGZpcnN0X3BlcmlvZBgGIAEoCzIdLmNvbnRlbnRodWIudjEuVmFsaWRpdHlQZXJpb2QSFwoPaWRlbXBvdGVuY3lfa2V5GAcgASgJInAKFlVwZ3JhZGVDb250ZW50UmVzcG9uc2USLAoKY2hhbmdlX3NldBgBIAEoCzIYLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0EigKCGNvbnRlbnRzGAIgAygLMhYuY29udGVudGh1Yi52MS5Db250ZW50IpICChhSZWNvcmRDaGVja1Jlc3VsdFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIZChFyZXF1aXJlZF9jaGVja19pZBgCIAEoCRJBCgVoZWFkcxgDIAMoCzIyLmNvbnRlbnRodWIudjEuUmVjb3JkQ2hlY2tSZXN1bHRSZXF1ZXN0LkhlYWRzRW50cnkSLAoHb3V0Y29tZRgEIAEoDjIbLmNvbnRlbnRodWIudjEuQ2hlY2tPdXRjb21lEgwKBG5vdGUYBSABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAYgASgJGiwKCkhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJNChlSZWNvcmRDaGVja1Jlc3VsdFJlc3BvbnNlEjAKDGNoZWNrX3Jlc3VsdBgBIAEoCzIaLmNvbnRlbnRodWIudjEuQ2hlY2tSZXN1bHQisQIKC0NoZWNrUmVzdWx0EgoKAmlkGAEgASgJEhUKDWNoYW5nZV9zZXRfaWQYAiABKAkSGQoRcmVxdWlyZWRfY2hlY2tfaWQYAyABKAkSNAoFaGVhZHMYBCADKAsyJS5jb250ZW50aHViLnYxLkNoZWNrUmVzdWx0LkhlYWRzRW50cnkSLAoHb3V0Y29tZRgFIAEoDjIbLmNvbnRlbnRodWIudjEuQ2hlY2tPdXRjb21lEgwKBG5vdGUYBiABKAkSEwoLcmVjb3JkZWRfYnkYByABKAkSLwoLcmVjb3JkX3RpbWUYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGiwKCkhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIwChdMaXN0Q2hlY2tSZXN1bHRzUmVxdWVzdBIVCg1jaGFuZ2Vfc2V0X2lkGAEgASgJIksKGExpc3RDaGVja1Jlc3VsdHNSZXNwb25zZRIvCglzdGFuZGluZ3MYASADKAsyHC5jb250ZW50aHViLnYxLkNoZWNrU3RhbmRpbmciswIKDUNoZWNrU3RhbmRpbmcSNAoOcmVxdWlyZWRfY2hlY2sYASABKAsyHC5jb250ZW50aHViLnYxLlJlcXVpcmVkQ2hlY2sSEgoKY29udGVudF9pZBgCIAEoCRIRCglicmFuY2hfaWQYAyABKAkSEgoKcmVsZWFzZV9pZBgEIAEoCRI2CgVoZWFkcxgFIAMoCzInLmNvbnRlbnRodWIudjEuQ2hlY2tTdGFuZGluZy5IZWFkc0VudHJ5EisKB3Jlc3VsdHMYBiADKAsyGi5jb250ZW50aHViLnYxLkNoZWNrUmVzdWx0Eg0KBXN0YWxlGAcgASgIEg8KB2NsZWFyZWQYCCABKAgaLAoKSGVhZHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrcBChZWYWxpZGF0ZVB1Ymxpc2hSZXF1ZXN0EhUKDWNoYW5nZV9zZXRfaWQYASABKAkSUAoOcmV2aWV3ZWRfaGVhZHMYAiADKAsyOC5jb250ZW50aHViLnYxLlZhbGlkYXRlUHVibGlzaFJlcXVlc3QuUmV2aWV3ZWRIZWFkc0VudHJ5GjQKElJldmlld2VkSGVhZHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrgBChdWYWxpZGF0ZVB1Ymxpc2hSZXNwb25zZRIvCghibG9ja2VycxgBIAMoCzIdLmNvbnRlbnRodWIudjEuUHVibGlzaEJsb2NrZXISKAoIcmVsZWFzZXMYAiADKAsyFi5jb250ZW50aHViLnYxLlJlbGVhc2USEQoJcHVibGlzaGVkGAMgASgIEi8KCHdhcm5pbmdzGAQgAygLMh0uY29udGVudGh1Yi52MS5QdWJsaXNoV2FybmluZyLAAQoOUHVibGlzaFJlcXVlc3QSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRJICg5yZXZpZXdlZF9oZWFkcxgCIAMoCzIwLmNvbnRlbnRodWIudjEuUHVibGlzaFJlcXVlc3QuUmV2aWV3ZWRIZWFkc0VudHJ5EhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCRo0ChJSZXZpZXdlZEhlYWRzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASKbAQoPUHVibGlzaFJlc3BvbnNlEiwKCmNoYW5nZV9zZXQYASABKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBIwCgxwdWJsaXNoX3RpbWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEigKCHJlbGVhc2VzGAMgAygLMhYuY29udGVudGh1Yi52MS5SZWxlYXNlImUKCVN0YWxlSGVhZBISCgpjb250ZW50X2lkGAEgASgJEhEKCWJyYW5jaF9pZBgCIAEoCRIYChBleHBlY3RlZF9oZWFkX2lkGAMgASgJEhcKD2N1cnJlbnRfaGVhZF9pZBgEIAEoCSJWCg9DaGFuZ2VTZXRDbG9zZWQSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIsCgVzdGF0ZRgCIAEoDjIdLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0U3RhdGUiJQoMV2l0aGhlbGRXb3JrEhUKDWNoYW5nZV9zZXRfaWQYASABKAkiVQoLU3RhbGVTdGF0dXMSFQoNY2hhbmdlX3NldF9pZBgBIAEoCRIXCg9leHBlY3RlZF9zdGF0dXMYAiABKAkSFgoOY3VycmVudF9zdGF0dXMYAyABKAkihQEKF1N0YXR1c1RyYW5zaXRpb25SZWZ1c2VkEhUKDWNoYW5nZV9zZXRfaWQYASABKAkSEwoLZnJvbV9zdGF0dXMYAiABKAkSEQoJdG9fc3RhdHVzGAMgASgJEg4KBnJlYXNvbhgEIAEoCRIbChNyZXF1aXJlc19wZXJtaXNzaW9uGAUgASgIIpABCglWaW9sYXRpb24SDgoGc291cmNlGAEgASgJEgwKBGNvZGUYAiABKAkSDAoEcGF0aBgDIAEoCRInCgZwYXJhbXMYBCABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EhIKCmNvbnRlbnRfaWQYBSABKAkSGgoScGxhbm5lZF9yZWxlYXNlX2lkGAYgASgJKo0BCg5DaGFuZ2VTZXRTdGF0ZRIgChxDSEFOR0VfU0VUX1NUQVRFX1VOU1BFQ0lGSUVEEAASGQoVQ0hBTkdFX1NFVF9TVEFURV9PUEVOEAESHgoaQ0hBTkdFX1NFVF9TVEFURV9QVUJMSVNIRUQQAhIeChpDSEFOR0VfU0VUX1NUQVRFX0RJU0NBUkRFRBADKmMKCkJyYW5jaEtpbmQSGwoXQlJBTkNIX0tJTkRfVU5TUEVDSUZJRUQQABIZChVCUkFOQ0hfS0lORF9FRElUT1JJQUwQARIdChlCUkFOQ0hfS0lORF9DQVJSWV9GT1JXQVJEEAIqewoMQ2hlY2tPdXRjb21lEh0KGUNIRUNLX09VVENPTUVfVU5TUEVDSUZJRUQQABIYChRDSEVDS19PVVRDT01FX1BBU1NFRBABEhgKFENIRUNLX09VVENPTUVfRkFJTEVEEAISGAoUQ0hFQ0tfT1VUQ09NRV9XQUlWRUQQAzKuFgoQQ2hhbmdlU2V0U2VydmljZRJgCg9DcmVhdGVDaGFuZ2VTZXQSJS5jb250ZW50aHViLnYxLkNyZWF0ZUNoYW5nZVNldFJlcXVlc3QaJi5jb250ZW50aHViLnYxLkNyZWF0ZUNoYW5nZVNldFJlc3BvbnNlElcKDEdldENoYW5nZVNldBIiLmNvbnRlbnRodWIudjEuR2V0Q2hhbmdlU2V0UmVxdWVzdBojLmNvbnRlbnRodWIudjEuR2V0Q2hhbmdlU2V0UmVzcG9uc2USYAoPVXBkYXRlQ2hhbmdlU2V0EiUuY29udGVudGh1Yi52MS5VcGRhdGVDaGFuZ2VTZXRSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5VcGRhdGVDaGFuZ2VTZXRSZXNwb25zZRJjChBEaXNjYXJkQ2hhbmdlU2V0EiYuY29udGVudGh1Yi52MS5EaXNjYXJkQ2hhbmdlU2V0UmVxdWVzdBonLmNvbnRlbnRodWIudjEuRGlzY2FyZENoYW5nZVNldFJlc3BvbnNlEmkKElNldENoYW5nZVNldFN0YXR1cxIoLmNvbnRlbnRodWIudjEuU2V0Q2hhbmdlU2V0U3RhdHVzUmVxdWVzdBopLmNvbnRlbnRodWIudjEuU2V0Q2hhbmdlU2V0U3RhdHVzUmVzcG9uc2UScgoVU2V0Q2hhbmdlU2V0QXNzaWduZWVzEisuY29udGVudGh1Yi52MS5TZXRDaGFuZ2VTZXRBc3NpZ25lZXNSZXF1ZXN0GiwuY29udGVudGh1Yi52MS5TZXRDaGFuZ2VTZXRBc3NpZ25lZXNSZXNwb25zZRJaCg1DcmVhdGVDb250ZW50EiMuY29udGVudGh1Yi52MS5DcmVhdGVDb250ZW50UmVxdWVzdBokLmNvbnRlbnRodWIudjEuQ3JlYXRlQ29udGVudFJlc3BvbnNlElcKDFNhdmVSZXZpc2lvbhIiLmNvbnRlbnRodWIudjEuU2F2ZVJldmlzaW9uUmVxdWVzdBojLmNvbnRlbnRodWIudjEuU2F2ZVJldmlzaW9uUmVzcG9uc2USVwoMUHJldmlld0NoYWluEiIuY29udGVudGh1Yi52MS5QcmV2aWV3Q2hhaW5SZXF1ZXN0GiMuY29udGVudGh1Yi52MS5QcmV2aWV3Q2hhaW5SZXNwb25zZRJRCgpTdGFydENoYWluEiAuY29udGVudGh1Yi52MS5TdGFydENoYWluUmVxdWVzdBohLmNvbnRlbnRodWIudjEuU3RhcnRDaGFpblJlc3BvbnNlElcKDEFwcGVuZEJyYW5jaBIiLmNvbnRlbnRodWIudjEuQXBwZW5kQnJhbmNoUmVxdWVzdBojLmNvbnRlbnRodWIudjEuQXBwZW5kQnJhbmNoUmVzcG9uc2USTgoJRHJvcENoYWluEh8uY29udGVudGh1Yi52MS5Ecm9wQ2hhaW5SZXF1ZXN0GiAuY29udGVudGh1Yi52MS5Ecm9wQ2hhaW5SZXNwb25zZRJXCgxTdGFydEVkaXRpbmcSIi5jb250ZW50aHViLnYxLlN0YXJ0RWRpdGluZ1JlcXVlc3QaIy5jb250ZW50aHViLnYxLlN0YXJ0RWRpdGluZ1Jlc3BvbnNlEl0KDlVwZGF0ZUZyb21NYWluEiQuY29udGVudGh1Yi52MS5VcGRhdGVGcm9tTWFpblJlcXVlc3QaJS5jb250ZW50aHViLnYxLlVwZGF0ZUZyb21NYWluUmVzcG9uc2USYAoPR2V0UGVuZGluZ01lcmdlEiUuY29udGVudGh1Yi52MS5HZXRQZW5kaW5nTWVyZ2VSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5HZXRQZW5kaW5nTWVyZ2VSZXNwb25zZRJXCgxSZXNvbHZlTWVyZ2USIi5jb250ZW50aHViLnYxLlJlc29sdmVNZXJnZVJlcXVlc3QaIy5jb250ZW50aHViLnYxLlJlc29sdmVNZXJnZVJlc3BvbnNlElEKCkFib3J0TWVyZ2USIC5jb250ZW50aHViLnYxLkFib3J0TWVyZ2VSZXF1ZXN0GiEuY29udGVudGh1Yi52MS5BYm9ydE1lcmdlUmVzcG9uc2USWgoNQWRkRGVwZW5kZW5jeRIjLmNvbnRlbnRodWIudjEuQWRkRGVwZW5kZW5jeVJlcXVlc3QaJC5jb250ZW50aHViLnYxLkFkZERlcGVuZGVuY3lSZXNwb25zZRJjChBSZW1vdmVEZXBlbmRlbmN5EiYuY29udGVudGh1Yi52MS5SZW1vdmVEZXBlbmRlbmN5UmVxdWVzdBonLmNvbnRlbnRodWIudjEuUmVtb3ZlRGVwZW5kZW5jeVJlc3BvbnNlElQKC1BsYW5SZWxlYXNlEiEuY29udGVudGh1Yi52MS5QbGFuUmVsZWFzZVJlcXVlc3QaIi5jb250ZW50aHViLnYxLlBsYW5SZWxlYXNlUmVzcG9uc2USbwoUVXBkYXRlUGxhbm5lZFJlbGVhc2USKi5jb250ZW50aHViLnYxLlVwZGF0ZVBsYW5uZWRSZWxlYXNlUmVxdWVzdBorLmNvbnRlbnRodWIudjEuVXBkYXRlUGxhbm5lZFJlbGVhc2VSZXNwb25zZRJsChNQbGFuRGF0ZU9ubHlSZWxlYXNlEikuY29udGVudGh1Yi52MS5QbGFuRGF0ZU9ubHlSZWxlYXNlUmVxdWVzdBoqLmNvbnRlbnRodWIudjEuUGxhbkRhdGVPbmx5UmVsZWFzZVJlc3BvbnNlElEKClBsYW5SZXBlYWwSIC5jb250ZW50aHViLnYxLlBsYW5SZXBlYWxSZXF1ZXN0GiEuY29udGVudGh1Yi52MS5QbGFuUmVwZWFsUmVzcG9uc2USXQoOUGxhbldpdGhkcmF3YWwSJC5jb250ZW50aHViLnYxLlBsYW5XaXRoZHJhd2FsUmVxdWVzdBolLmNvbnRlbnRodWIudjEuUGxhbldpdGhkcmF3YWxSZXNwb25zZRJpChJEcm9wUGxhbm5lZFJlbGVhc2USKC5jb250ZW50aHViLnYxLkRyb3BQbGFubmVkUmVsZWFzZVJlcXVlc3QaKS5jb250ZW50aHViLnYxLkRyb3BQbGFubmVkUmVsZWFzZVJlc3BvbnNlEl0KDlVwZ3JhZGVDb250ZW50EiQuY29udGVudGh1Yi52MS5VcGdyYWRlQ29udGVudFJlcXVlc3QaJS5jb250ZW50aHViLnYxLlVwZ3JhZGVDb250ZW50UmVzcG9uc2USZgoRUmVjb3JkQ2hlY2tSZXN1bHQSJy5jb250ZW50aHViLnYxLlJlY29yZENoZWNrUmVzdWx0UmVxdWVzdBooLmNvbnRlbnRodWIudjEuUmVjb3JkQ2hlY2tSZXN1bHRSZXNwb25zZRJjChBMaXN0Q2hlY2tSZXN1bHRzEiYuY29udGVudGh1Yi52MS5MaXN0Q2hlY2tSZXN1bHRzUmVxdWVzdBonLmNvbnRlbnRodWIudjEuTGlzdENoZWNrUmVzdWx0c1Jlc3BvbnNlEmAKD1ZhbGlkYXRlUHVibGlzaBIlLmNvbnRlbnRodWIudjEuVmFsaWRhdGVQdWJsaXNoUmVxdWVzdBomLmNvbnRlbnRodWIudjEuVmFsaWRhdGVQdWJsaXNoUmVzcG9uc2USSAoHUHVibGlzaBIdLmNvbnRlbnRodWIudjEuUHVibGlzaFJlcXVlc3QaHi5jb250ZW50aHViLnYxLlB1Ymxpc2hSZXNwb25zZUI8WjpnaXRodWIuY29tL2tua2NzL2NvbnRlbnRodWIvZ2VuL2NvbnRlbnRodWIvdjE7Y29udGVudGh1YnYxYgZwcm90bzM\", [file_contenthub_v1_graph_warnings, file_contenthub_v1_merge, file_contenthub_v1_planning, file_contenthub_v1_release, file_contenthub_v1_workspace_config, file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * Source is the publication that triggered a Change Set (CONTEXT.md), such\n * as 2026-09-20, \"BGBl. 2026 I Nr. 270\". Release Spec fields can be prefilled\n * from either part.\n *\n * @generated from message contenthub.v1.Source\n */\nexport type Source = Message<\"contenthub.v1.Source\"> & {\n /**\n * The day it was published, as YYYY-MM-DD.\n *\n * @generated from field: string date = 1;\n */\n date: string;\n\n /**\n * How it is cited. At most 500 characters, one line.\n *\n * @generated from field: string reference = 2;\n */\n reference: string;\n};\n\n/**\n * Describes the message contenthub.v1.Source.\n * Use `create(SourceSchema)` to create a new message.\n */\nexport const SourceSchema: GenMessage<Source> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 0);\n\n/**\n * ChangeSet is a Change Set as editors see it.\n *\n * @generated from message contenthub.v1.ChangeSet\n */\nexport type ChangeSet = Message<\"contenthub.v1.ChangeSet\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The Source it records; absent when it records none, as a one-off\n * correction does.\n *\n * @generated from field: contenthub.v1.Source source = 3;\n */\n source?: Source | undefined;\n\n /**\n * @generated from field: contenthub.v1.ChangeSetState state = 4;\n */\n state: ChangeSetState;\n\n /**\n * Who opened it: the token's subject.\n *\n * @generated from field: string created_by = 5;\n */\n createdBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * When it was published or discarded; absent while it is open.\n *\n * @generated from field: google.protobuf.Timestamp close_time = 7;\n */\n closeTime?: Timestamp | undefined;\n\n /**\n * Its Chains, in the order they were started. Empty in ListChangeSets, and\n * for a discarded Change Set: the Content born in it is gone.\n *\n * @generated from field: repeated contenthub.v1.Chain chains = 8;\n */\n chains: Chain[];\n\n /**\n * The Change Sets it depends on, whatever their state. Empty in\n * ListChangeSets.\n *\n * @generated from field: repeated string depends_on_change_set_ids = 9;\n */\n dependsOnChangeSetIds: string[];\n\n /**\n * Its Planned Releases, proposed ones included, in the order they were\n * planned. Empty in ListChangeSets.\n *\n * @generated from field: repeated contenthub.v1.PlannedRelease planned_releases = 10;\n */\n plannedReleases: PlannedRelease[];\n\n /**\n * The slug of its status in statushub's `contenthub/change_set` catalogue\n * (ADR 0014); empty for an unknown status, which a Change Set has until\n * someone first sets one. A slug the catalogue no longer holds is unknown\n * too. Frozen once the Change Set is closed.\n *\n * @generated from field: string status = 11;\n */\n status: string;\n\n /**\n * Who is working on it now: odon user ids, in the order they were set.\n *\n * @generated from field: repeated string assignee_ids = 12;\n */\n assigneeIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSet.\n * Use `create(ChangeSetSchema)` to create a new message.\n */\nexport const ChangeSetSchema: GenMessage<ChangeSet> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 1);\n\n/**\n * Chain is the ordered Branches of one Content inside a Change Set.\n *\n * @generated from message contenthub.v1.Chain\n */\nexport type Chain = Message<\"contenthub.v1.Chain\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * True when the Content was born in this Change Set, and so has no Main\n * Branch until it is published.\n *\n * @generated from field: bool born = 3;\n */\n born: boolean;\n\n /**\n * Its Branches, by position.\n *\n * @generated from field: repeated contenthub.v1.Branch branches = 4;\n */\n branches: Branch[];\n};\n\n/**\n * Describes the message contenthub.v1.Chain.\n * Use `create(ChainSchema)` to create a new message.\n */\nexport const ChainSchema: GenMessage<Chain> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 2);\n\n/**\n * Branch is one Branch of a Chain, with its head.\n *\n * @generated from message contenthub.v1.Branch\n */\nexport type Branch = Message<\"contenthub.v1.Branch\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Its place in its Chain, from 0.\n *\n * @generated from field: int32 position = 2;\n */\n position: number;\n\n /**\n * @generated from field: contenthub.v1.BranchKind kind = 3;\n */\n kind: BranchKind;\n\n /**\n * The Revision the Branch points at: what a save on it names as\n * expected_head_id.\n *\n * @generated from field: string head_revision_id = 4;\n */\n headRevisionId: string;\n\n /**\n * On a Chain on Dated Content, the date its change takes effect, as\n * YYYY-MM-DD: an editorial Branch's date, or the first day of the Release\n * a Carry-forward link carries. Empty on a final link merging Main's head\n * and on undated Content.\n *\n * @generated from field: string effective_on = 5;\n */\n effectiveOn: string;\n\n /**\n * On a Chain on Dated Content, the Release the Branch carries: the first\n * Branch's fork Release, or the later Release a Carry-forward link\n * carries. Empty where it carries Main's head or nothing.\n *\n * @generated from field: string carried_release_id = 6;\n */\n carriedReleaseId: string;\n\n /**\n * Whether a Pending Merge is stored on it, which GetPendingMerge reads.\n *\n * @generated from field: bool has_pending_merge = 7;\n */\n hasPendingMerge: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.Branch.\n * Use `create(BranchSchema)` to create a new message.\n */\nexport const BranchSchema: GenMessage<Branch> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 3);\n\n/**\n * @generated from message contenthub.v1.CreateChangeSetRequest\n */\nexport type CreateChangeSetRequest = Message<\"contenthub.v1.CreateChangeSetRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, one line. Surrounding\n * whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * The Source, when the Change Set has one. Both its date and its\n * reference are then required.\n *\n * @generated from field: contenthub.v1.Source source = 2;\n */\n source?: Source | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateChangeSetRequest.\n * Use `create(CreateChangeSetRequestSchema)` to create a new message.\n */\nexport const CreateChangeSetRequestSchema: GenMessage<CreateChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 4);\n\n/**\n * @generated from message contenthub.v1.CreateChangeSetResponse\n */\nexport type CreateChangeSetResponse = Message<\"contenthub.v1.CreateChangeSetResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateChangeSetResponse.\n * Use `create(CreateChangeSetResponseSchema)` to create a new message.\n */\nexport const CreateChangeSetResponseSchema: GenMessage<CreateChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 5);\n\n/**\n * @generated from message contenthub.v1.GetChangeSetRequest\n */\nexport type GetChangeSetRequest = Message<\"contenthub.v1.GetChangeSetRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetChangeSetRequest.\n * Use `create(GetChangeSetRequestSchema)` to create a new message.\n */\nexport const GetChangeSetRequestSchema: GenMessage<GetChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 6);\n\n/**\n * @generated from message contenthub.v1.GetChangeSetResponse\n */\nexport type GetChangeSetResponse = Message<\"contenthub.v1.GetChangeSetResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetChangeSetResponse.\n * Use `create(GetChangeSetResponseSchema)` to create a new message.\n */\nexport const GetChangeSetResponseSchema: GenMessage<GetChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 7);\n\n/**\n * @generated from message contenthub.v1.UpdateChangeSetRequest\n */\nexport type UpdateChangeSetRequest = Message<\"contenthub.v1.UpdateChangeSetRequest\"> & {\n /**\n * The Change Set to change.\n *\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The new name, when update_mask names `name`. Required then, as at\n * CreateChangeSet: not blank, at most 200 characters, one line.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The new Source, when update_mask names `source`: both its date and its\n * reference, or absent to clear it (AIP-134), as a one-off correction\n * records none.\n *\n * @generated from field: contenthub.v1.Source source = 3;\n */\n source?: Source | undefined;\n\n /**\n * Required, and naming at least one of `name` and `source`: what to\n * change. A field it doesn't name is left as it is, whatever the request\n * holds for it; any other name is InvalidArgument.\n *\n * @generated from field: contenthub.v1.FieldMask update_mask = 4;\n */\n updateMask?: FieldMask | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateChangeSetRequest.\n * Use `create(UpdateChangeSetRequestSchema)` to create a new message.\n */\nexport const UpdateChangeSetRequestSchema: GenMessage<UpdateChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 8);\n\n/**\n * @generated from message contenthub.v1.UpdateChangeSetResponse\n */\nexport type UpdateChangeSetResponse = Message<\"contenthub.v1.UpdateChangeSetResponse\"> & {\n /**\n * The Change Set, as GetChangeSet reads it after the change.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateChangeSetResponse.\n * Use `create(UpdateChangeSetResponseSchema)` to create a new message.\n */\nexport const UpdateChangeSetResponseSchema: GenMessage<UpdateChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 9);\n\n/**\n * @generated from message contenthub.v1.DiscardChangeSetRequest\n */\nexport type DiscardChangeSetRequest = Message<\"contenthub.v1.DiscardChangeSetRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DiscardChangeSetRequest.\n * Use `create(DiscardChangeSetRequestSchema)` to create a new message.\n */\nexport const DiscardChangeSetRequestSchema: GenMessage<DiscardChangeSetRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 10);\n\n/**\n * @generated from message contenthub.v1.DiscardChangeSetResponse\n */\nexport type DiscardChangeSetResponse = Message<\"contenthub.v1.DiscardChangeSetResponse\"> & {\n /**\n * The Change Set, discarded.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.DiscardChangeSetResponse.\n * Use `create(DiscardChangeSetResponseSchema)` to create a new message.\n */\nexport const DiscardChangeSetResponseSchema: GenMessage<DiscardChangeSetResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 11);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetStatusRequest\n */\nexport type SetChangeSetStatusRequest = Message<\"contenthub.v1.SetChangeSetStatusRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The status the caller last saw, exactly as ChangeSet.status read it:\n * empty when it read empty, and the slug itself when it read a slug the\n * catalogue no longer holds. Required in that sense: a move is made from\n * a status the caller saw, never from whatever it is now.\n *\n * @generated from field: string expected_status = 2;\n */\n expectedStatus: string;\n\n /**\n * The slug to move to. Required: there is no move to an unknown status.\n *\n * @generated from field: string status = 3;\n */\n status: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetStatusRequest.\n * Use `create(SetChangeSetStatusRequestSchema)` to create a new message.\n */\nexport const SetChangeSetStatusRequestSchema: GenMessage<SetChangeSetStatusRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 12);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetStatusResponse\n */\nexport type SetChangeSetStatusResponse = Message<\"contenthub.v1.SetChangeSetStatusResponse\"> & {\n /**\n * The Change Set, with its new status.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetStatusResponse.\n * Use `create(SetChangeSetStatusResponseSchema)` to create a new message.\n */\nexport const SetChangeSetStatusResponseSchema: GenMessage<SetChangeSetStatusResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 13);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetAssigneesRequest\n */\nexport type SetChangeSetAssigneesRequest = Message<\"contenthub.v1.SetChangeSetAssigneesRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The whole new set: odon user ids, each given once, at most 50. Empty\n * unassigns everyone.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetAssigneesRequest.\n * Use `create(SetChangeSetAssigneesRequestSchema)` to create a new message.\n */\nexport const SetChangeSetAssigneesRequestSchema: GenMessage<SetChangeSetAssigneesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 14);\n\n/**\n * @generated from message contenthub.v1.SetChangeSetAssigneesResponse\n */\nexport type SetChangeSetAssigneesResponse = Message<\"contenthub.v1.SetChangeSetAssigneesResponse\"> & {\n /**\n * The Change Set, with its assignees.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetChangeSetAssigneesResponse.\n * Use `create(SetChangeSetAssigneesResponseSchema)` to create a new message.\n */\nexport const SetChangeSetAssigneesResponseSchema: GenMessage<SetChangeSetAssigneesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 15);\n\n/**\n * CopyFrom names what new Content is a copy of: a Release, or a Revision,\n * of any Content of the workspace. The copy records it as its origin.\n *\n * @generated from message contenthub.v1.CopyFrom\n */\nexport type CopyFrom = Message<\"contenthub.v1.CopyFrom\"> & {\n /**\n * @generated from oneof contenthub.v1.CopyFrom.source\n */\n source: {\n /**\n * @generated from field: string release_id = 1;\n */\n value: string;\n case: \"releaseId\";\n } | {\n /**\n * @generated from field: string revision_id = 2;\n */\n value: string;\n case: \"revisionId\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.CopyFrom.\n * Use `create(CopyFromSchema)` to create a new message.\n */\nexport const CopyFromSchema: GenMessage<CopyFrom> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 16);\n\n/**\n * @generated from message contenthub.v1.CreateContentRequest\n */\nexport type CreateContentRequest = Message<\"contenthub.v1.CreateContentRequest\"> & {\n /**\n * The open Change Set to create the Content in.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Content's id, when the client reserved one (a KSUID it minted), so\n * that an import can write first Revisions that already reference each\n * other (ADR 0003). Empty mints one. An id already taken in the workspace\n * is AlreadyExists.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The Blueprint Release the Content pins: a Release of a content\n * Blueprint. With copy_from it may be left empty, to pin what the source\n * pins.\n *\n * @generated from field: string blueprint_release_id = 3;\n */\n blueprintReleaseId: string;\n\n /**\n * The first Revision's data, a JSON object keyed by field accessor. With\n * copy_from it may be left absent, to take the source's data unchanged;\n * given, it is the whole data, stored as given.\n *\n * @generated from field: google.protobuf.Struct data = 4;\n */\n data?: JsonObject | undefined;\n\n /**\n * What the Content is a copy of, if anything.\n *\n * @generated from field: contenthub.v1.CopyFrom copy_from = 5;\n */\n copyFrom?: CopyFrom | undefined;\n\n /**\n * The Collections to file the Content in as it is created, at most 100,\n * as SetContentCollections files it. Content created in a Restricted\n * Collection is never visible to anyone else, not even briefly (ADR\n * 0017); filing into a Restricted Collection needs `editor` on it. A copy\n * of a citer files its Footnote Bodies' copies in the same Collections.\n *\n * @generated from field: repeated string collection_ids = 6;\n */\n collectionIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 7;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.CreateContentRequest.\n * Use `create(CreateContentRequestSchema)` to create a new message.\n */\nexport const CreateContentRequestSchema: GenMessage<CreateContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 17);\n\n/**\n * @generated from message contenthub.v1.CreateContentResponse\n */\nexport type CreateContentResponse = Message<\"contenthub.v1.CreateContentResponse\"> & {\n /**\n * The Content, as GetContent reads it in the Change Set.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateContentResponse.\n * Use `create(CreateContentResponseSchema)` to create a new message.\n */\nexport const CreateContentResponseSchema: GenMessage<CreateContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 18);\n\n/**\n * FieldMask names the fields a partial write carries: a partial save's\n * Content fields, or the Change Set fields UpdateChangeSet changes.\n *\n * @generated from message contenthub.v1.FieldMask\n */\nexport type FieldMask = Message<\"contenthub.v1.FieldMask\"> & {\n /**\n * Top-level field accessors.\n *\n * @generated from field: repeated string fields = 1;\n */\n fields: string[];\n};\n\n/**\n * Describes the message contenthub.v1.FieldMask.\n * Use `create(FieldMaskSchema)` to create a new message.\n */\nexport const FieldMaskSchema: GenMessage<FieldMask> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 19);\n\n/**\n * @generated from message contenthub.v1.SaveRevisionRequest\n */\nexport type SaveRevisionRequest = Message<\"contenthub.v1.SaveRevisionRequest\"> & {\n /**\n * The Branch to save on.\n *\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * The head Revision the author edited. Required: a save that names no head\n * could silently overwrite someone else's.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n\n /**\n * The data. Without a field_mask it is the whole new Revision. With one,\n * it holds only the fields the mask names.\n *\n * @generated from field: google.protobuf.Struct data = 3;\n */\n data?: JsonObject | undefined;\n\n /**\n * Makes the save partial: the new Revision is the head's data with each\n * field the mask names replaced by its value in data, or removed when data\n * doesn't hold it. Every other field is carried over unchanged, so the new\n * Revision is still whole. A field in data that the mask doesn't name is\n * InvalidArgument.\n *\n * @generated from field: contenthub.v1.FieldMask field_mask = 4;\n */\n fieldMask?: FieldMask | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SaveRevisionRequest.\n * Use `create(SaveRevisionRequestSchema)` to create a new message.\n */\nexport const SaveRevisionRequestSchema: GenMessage<SaveRevisionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 20);\n\n/**\n * @generated from message contenthub.v1.SaveRevisionResponse\n */\nexport type SaveRevisionResponse = Message<\"contenthub.v1.SaveRevisionResponse\"> & {\n /**\n * The Content, as GetContent reads it in the Change Set: its data is the\n * saved Revision's.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SaveRevisionResponse.\n * Use `create(SaveRevisionResponseSchema)` to create a new message.\n */\nexport const SaveRevisionResponseSchema: GenMessage<SaveRevisionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 21);\n\n/**\n * Content is one Content as read at one Revision: in a Change Set, the head\n * of its Chain's last Branch; on Main, the head of its Main Branch.\n *\n * @generated from message contenthub.v1.Content\n */\nexport type Content = Message<\"contenthub.v1.Content\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Blueprint, and the Blueprint Release the Revision pins.\n *\n * @generated from field: string blueprint_id = 2;\n */\n blueprintId: string;\n\n /**\n * @generated from field: string blueprint_release_id = 3;\n */\n blueprintReleaseId: string;\n\n /**\n * The Revision read.\n *\n * @generated from field: string revision_id = 4;\n */\n revisionId: string;\n\n /**\n * Its data, a JSON object keyed by field accessor.\n *\n * @generated from field: google.protobuf.Struct data = 5;\n */\n data?: JsonObject | undefined;\n\n /**\n * The Change Set and Branch it was read on; empty when read on Main.\n *\n * @generated from field: string change_set_id = 6;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string branch_id = 7;\n */\n branchId: string;\n\n /**\n * When the Revision was written.\n *\n * @generated from field: google.protobuf.Timestamp revision_create_time = 8;\n */\n revisionCreateTime?: Timestamp | undefined;\n\n /**\n * The Release it was read at, in ListContents' In Force view; empty\n * elsewhere.\n *\n * @generated from field: string release_id = 9;\n */\n releaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Content.\n * Use `create(ContentSchema)` to create a new message.\n */\nexport const ContentSchema: GenMessage<Content> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 22);\n\n/**\n * @generated from message contenthub.v1.PreviewChainRequest\n */\nexport type PreviewChainRequest = Message<\"contenthub.v1.PreviewChainRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Content the Chain would start on.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * Required: the date the change takes effect, as YYYY-MM-DD.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * The period to preview against the Content's Releases; absent previews\n * one from effective_on, with an open end.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 4;\n */\n validityPeriod?: ValidityPeriod | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PreviewChainRequest.\n * Use `create(PreviewChainRequestSchema)` to create a new message.\n */\nexport const PreviewChainRequestSchema: GenMessage<PreviewChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 23);\n\n/**\n * @generated from message contenthub.v1.PreviewChainResponse\n */\nexport type PreviewChainResponse = Message<\"contenthub.v1.PreviewChainResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChainPreview preview = 1;\n */\n preview?: ChainPreview | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PreviewChainResponse.\n * Use `create(PreviewChainResponseSchema)` to create a new message.\n */\nexport const PreviewChainResponseSchema: GenMessage<PreviewChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 24);\n\n/**\n * ChainPreview is what a Chain would be and meet, as PreviewChain found it.\n *\n * @generated from message contenthub.v1.ChainPreview\n */\nexport type ChainPreview = Message<\"contenthub.v1.ChainPreview\"> & {\n /**\n * The Release the Chain would fork from: the Release In Force on the date\n * (in a Change Set with dependencies, possibly a dependency's Planned\n * Release, under the id it will be cut with). Empty in a gap, where it\n * forks from Main's head.\n *\n * @generated from field: string fork_release_id = 1;\n */\n forkReleaseId: string;\n\n /**\n * The later Releases In Force it would carry forward through, by date:\n * one Carry-forward link each.\n *\n * @generated from field: repeated string carry_forward_release_ids = 2;\n */\n carryForwardReleaseIds: string[];\n\n /**\n * Whether a final link would merge Main's head, which is not the last\n * Release's Revision.\n *\n * @generated from field: bool merges_main = 3;\n */\n mergesMain: boolean;\n\n /**\n * The period previewed, an open end resolved as Publish would resolve it\n * now.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 4;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * The Releases the period cuts into, by first day: planning it would\n * propose a date-only cut of each.\n *\n * @generated from field: repeated contenthub.v1.CutInto cut_into = 5;\n */\n cutInto: CutInto[];\n\n /**\n * The Releases the period covers entirely, by first day: planning it as\n * it is would be refused.\n *\n * @generated from field: repeated string covered_release_ids = 6;\n */\n coveredReleaseIds: string[];\n\n /**\n * The Releases of the Content that the Change Set's Planned Releases\n * supersede already, so the period meets none of them.\n *\n * @generated from field: repeated contenthub.v1.SupersededRelease superseded = 7;\n */\n superseded: SupersededRelease[];\n};\n\n/**\n * Describes the message contenthub.v1.ChainPreview.\n * Use `create(ChainPreviewSchema)` to create a new message.\n */\nexport const ChainPreviewSchema: GenMessage<ChainPreview> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 25);\n\n/**\n * CutInto is one Release a period cuts into.\n *\n * @generated from message contenthub.v1.CutInto\n */\nexport type CutInto = Message<\"contenthub.v1.CutInto\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * Whether it is a Planned Release (of this Change Set or of one it\n * depends on) rather than a published one.\n *\n * @generated from field: bool planned = 2;\n */\n planned: boolean;\n\n /**\n * What is left of its Validity Period: the period the proposed date-only\n * cut would give it.\n *\n * @generated from field: contenthub.v1.ValidityPeriod kept = 3;\n */\n kept?: ValidityPeriod | undefined;\n\n /**\n * When the period lies strictly inside it, the part after: a second\n * proposed cut resumes its wording then. Absent otherwise.\n *\n * @generated from field: contenthub.v1.ValidityPeriod tail = 4;\n */\n tail?: ValidityPeriod | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CutInto.\n * Use `create(CutIntoSchema)` to create a new message.\n */\nexport const CutIntoSchema: GenMessage<CutInto> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 26);\n\n/**\n * SupersededRelease is one Release a Planned Release supersedes.\n *\n * @generated from message contenthub.v1.SupersededRelease\n */\nexport type SupersededRelease = Message<\"contenthub.v1.SupersededRelease\"> & {\n /**\n * @generated from field: string release_id = 1;\n */\n releaseId: string;\n\n /**\n * @generated from field: string by_planned_release_id = 2;\n */\n byPlannedReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.SupersededRelease.\n * Use `create(SupersededReleaseSchema)` to create a new message.\n */\nexport const SupersededReleaseSchema: GenMessage<SupersededRelease> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 27);\n\n/**\n * @generated from message contenthub.v1.StartChainRequest\n */\nexport type StartChainRequest = Message<\"contenthub.v1.StartChainRequest\"> & {\n /**\n * The open Change Set to start the Chain in.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The published Content to change.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The date the change takes effect, as YYYY-MM-DD: required for Dated\n * Content, refused for undated Content.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartChainRequest.\n * Use `create(StartChainRequestSchema)` to create a new message.\n */\nexport const StartChainRequestSchema: GenMessage<StartChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 28);\n\n/**\n * @generated from message contenthub.v1.StartChainResponse\n */\nexport type StartChainResponse = Message<\"contenthub.v1.StartChainResponse\"> & {\n /**\n * The Change Set, with the new Chain.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * The Release the Chain forked from, as ChainPreview.fork_release_id;\n * empty for undated Content and in a gap.\n *\n * @generated from field: string fork_release_id = 3;\n */\n forkReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartChainResponse.\n * Use `create(StartChainResponseSchema)` to create a new message.\n */\nexport const StartChainResponseSchema: GenMessage<StartChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 29);\n\n/**\n * @generated from message contenthub.v1.AppendBranchRequest\n */\nexport type AppendBranchRequest = Message<\"contenthub.v1.AppendBranchRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Required: the date the new Branch's change takes effect, as\n * YYYY-MM-DD, after the Chain's last editorial Branch's.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AppendBranchRequest.\n * Use `create(AppendBranchRequestSchema)` to create a new message.\n */\nexport const AppendBranchRequestSchema: GenMessage<AppendBranchRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 30);\n\n/**\n * @generated from message contenthub.v1.AppendBranchResponse\n */\nexport type AppendBranchResponse = Message<\"contenthub.v1.AppendBranchResponse\"> & {\n /**\n * The Change Set, with the Chain re-laid.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The new editorial Branch.\n *\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.AppendBranchResponse.\n * Use `create(AppendBranchResponseSchema)` to create a new message.\n */\nexport const AppendBranchResponseSchema: GenMessage<AppendBranchResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 31);\n\n/**\n * @generated from message contenthub.v1.DropChainRequest\n */\nexport type DropChainRequest = Message<\"contenthub.v1.DropChainRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.DropChainRequest.\n * Use `create(DropChainRequestSchema)` to create a new message.\n */\nexport const DropChainRequestSchema: GenMessage<DropChainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 32);\n\n/**\n * @generated from message contenthub.v1.DropChainResponse\n */\nexport type DropChainResponse = Message<\"contenthub.v1.DropChainResponse\"> & {\n /**\n * The Change Set, without the Chain.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.DropChainResponse.\n * Use `create(DropChainResponseSchema)` to create a new message.\n */\nexport const DropChainResponseSchema: GenMessage<DropChainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 33);\n\n/**\n * @generated from message contenthub.v1.StartEditingRequest\n */\nexport type StartEditingRequest = Message<\"contenthub.v1.StartEditingRequest\"> & {\n /**\n * The published Content to change.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The open Change Set to start the Chain in; empty opens a new one.\n *\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n\n /**\n * As StartChainRequest.effective_on.\n *\n * @generated from field: string effective_on = 3;\n */\n effectiveOn: string;\n\n /**\n * The new Change Set's name, when change_set_id is empty: at most 200\n * characters, one line. Empty names it after the Content.\n *\n * @generated from field: string change_set_name = 4;\n */\n changeSetName: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 5;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartEditingRequest.\n * Use `create(StartEditingRequestSchema)` to create a new message.\n */\nexport const StartEditingRequestSchema: GenMessage<StartEditingRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 34);\n\n/**\n * @generated from message contenthub.v1.StartEditingResponse\n */\nexport type StartEditingResponse = Message<\"contenthub.v1.StartEditingResponse\"> & {\n /**\n * The Change Set the Chain was started in, new or given.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Content as read on the Branch to edit, the Chain's first: what a\n * save names as branch_id and expected_head_id.\n *\n * @generated from field: contenthub.v1.Content content = 2;\n */\n content?: Content | undefined;\n\n /**\n * As StartChainResponse.fork_release_id.\n *\n * @generated from field: string fork_release_id = 3;\n */\n forkReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StartEditingResponse.\n * Use `create(StartEditingResponseSchema)` to create a new message.\n */\nexport const StartEditingResponseSchema: GenMessage<StartEditingResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 35);\n\n/**\n * @generated from message contenthub.v1.UpdateFromMainRequest\n */\nexport type UpdateFromMainRequest = Message<\"contenthub.v1.UpdateFromMainRequest\"> & {\n /**\n * The open Change Set.\n *\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * One of its Chains to update alone; empty updates every Chain.\n *\n * @generated from field: string chain_id = 2;\n */\n chainId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdateFromMainRequest.\n * Use `create(UpdateFromMainRequestSchema)` to create a new message.\n */\nexport const UpdateFromMainRequestSchema: GenMessage<UpdateFromMainRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 36);\n\n/**\n * @generated from message contenthub.v1.UpdateFromMainResponse\n */\nexport type UpdateFromMainResponse = Message<\"contenthub.v1.UpdateFromMainResponse\"> & {\n /**\n * The Change Set as the update left it.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Branches whose heads moved to a merge Revision, by id.\n *\n * @generated from field: repeated string merged_branch_ids = 2;\n */\n mergedBranchIds: string[];\n\n /**\n * The Pending Merges this update stored, by Branch id.\n *\n * @generated from field: repeated contenthub.v1.PendingMerge conflicted = 3;\n */\n conflicted: PendingMerge[];\n\n /**\n * The Pending Merges stored before it, on Branches it left alone, by\n * Branch id: resolve or abort them, then update again.\n *\n * @generated from field: repeated contenthub.v1.PendingMerge pending = 4;\n */\n pending: PendingMerge[];\n\n /**\n * The Carry-forward links a re-lay took out of their Chains, because the\n * Release they carried no longer counts: their life ended, as with\n * DropChain.\n *\n * @generated from field: repeated string ended_branch_ids = 5;\n */\n endedBranchIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.UpdateFromMainResponse.\n * Use `create(UpdateFromMainResponseSchema)` to create a new message.\n */\nexport const UpdateFromMainResponseSchema: GenMessage<UpdateFromMainResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 37);\n\n/**\n * @generated from message contenthub.v1.GetPendingMergeRequest\n */\nexport type GetPendingMergeRequest = Message<\"contenthub.v1.GetPendingMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetPendingMergeRequest.\n * Use `create(GetPendingMergeRequestSchema)` to create a new message.\n */\nexport const GetPendingMergeRequestSchema: GenMessage<GetPendingMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 38);\n\n/**\n * @generated from message contenthub.v1.GetPendingMergeResponse\n */\nexport type GetPendingMergeResponse = Message<\"contenthub.v1.GetPendingMergeResponse\"> & {\n /**\n * The Pending Merge; unset, as is everything below, when the Branch has\n * none.\n *\n * @generated from field: contenthub.v1.PendingMerge pending_merge = 1;\n */\n pendingMerge?: PendingMerge | undefined;\n\n /**\n * The Blueprint Release a resolution pins: the newer of the two sides'.\n *\n * @generated from field: string blueprint_release_id = 2;\n */\n blueprintReleaseId: string;\n\n /**\n * The fields a resolution must decide, by path.\n *\n * @generated from field: repeated contenthub.v1.MergeField fields = 3;\n */\n fields: MergeField[];\n\n /**\n * The data a resolution starts from: every field but those in fields\n * merged, those at their base value.\n *\n * @generated from field: google.protobuf.Struct merged = 4;\n */\n merged?: JsonObject | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetPendingMergeResponse.\n * Use `create(GetPendingMergeResponseSchema)` to create a new message.\n */\nexport const GetPendingMergeResponseSchema: GenMessage<GetPendingMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 39);\n\n/**\n * @generated from message contenthub.v1.ResolveMergeRequest\n */\nexport type ResolveMergeRequest = Message<\"contenthub.v1.ResolveMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * The Branch's head, the Pending Merge's ours: required, as for a save.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n\n /**\n * One decision per field GetPendingMerge lists, no more.\n *\n * @generated from field: repeated contenthub.v1.FieldResolution resolutions = 3;\n */\n resolutions: FieldResolution[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.ResolveMergeRequest.\n * Use `create(ResolveMergeRequestSchema)` to create a new message.\n */\nexport const ResolveMergeRequestSchema: GenMessage<ResolveMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 40);\n\n/**\n * @generated from message contenthub.v1.ResolveMergeResponse\n */\nexport type ResolveMergeResponse = Message<\"contenthub.v1.ResolveMergeResponse\"> & {\n /**\n * The Content as read on the Branch: its data is the resolution's.\n *\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ResolveMergeResponse.\n * Use `create(ResolveMergeResponseSchema)` to create a new message.\n */\nexport const ResolveMergeResponseSchema: GenMessage<ResolveMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 41);\n\n/**\n * @generated from message contenthub.v1.AbortMergeRequest\n */\nexport type AbortMergeRequest = Message<\"contenthub.v1.AbortMergeRequest\"> & {\n /**\n * @generated from field: string branch_id = 1;\n */\n branchId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AbortMergeRequest.\n * Use `create(AbortMergeRequestSchema)` to create a new message.\n */\nexport const AbortMergeRequestSchema: GenMessage<AbortMergeRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 42);\n\n/**\n * @generated from message contenthub.v1.AbortMergeResponse\n */\nexport type AbortMergeResponse = Message<\"contenthub.v1.AbortMergeResponse\"> & {\n /**\n * The Pending Merge it dropped.\n *\n * @generated from field: contenthub.v1.PendingMerge aborted = 1;\n */\n aborted?: PendingMerge | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.AbortMergeResponse.\n * Use `create(AbortMergeResponseSchema)` to create a new message.\n */\nexport const AbortMergeResponseSchema: GenMessage<AbortMergeResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 43);\n\n/**\n * @generated from message contenthub.v1.AddDependencyRequest\n */\nexport type AddDependencyRequest = Message<\"contenthub.v1.AddDependencyRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The open Change Set it is to depend on.\n *\n * @generated from field: string depends_on_change_set_id = 2;\n */\n dependsOnChangeSetId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.AddDependencyRequest.\n * Use `create(AddDependencyRequestSchema)` to create a new message.\n */\nexport const AddDependencyRequestSchema: GenMessage<AddDependencyRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 44);\n\n/**\n * @generated from message contenthub.v1.AddDependencyResponse\n */\nexport type AddDependencyResponse = Message<\"contenthub.v1.AddDependencyResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.AddDependencyResponse.\n * Use `create(AddDependencyResponseSchema)` to create a new message.\n */\nexport const AddDependencyResponseSchema: GenMessage<AddDependencyResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 45);\n\n/**\n * @generated from message contenthub.v1.RemoveDependencyRequest\n */\nexport type RemoveDependencyRequest = Message<\"contenthub.v1.RemoveDependencyRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string depends_on_change_set_id = 2;\n */\n dependsOnChangeSetId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveDependencyRequest.\n * Use `create(RemoveDependencyRequestSchema)` to create a new message.\n */\nexport const RemoveDependencyRequestSchema: GenMessage<RemoveDependencyRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 46);\n\n/**\n * @generated from message contenthub.v1.RemoveDependencyResponse\n */\nexport type RemoveDependencyResponse = Message<\"contenthub.v1.RemoveDependencyResponse\"> & {\n /**\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveDependencyResponse.\n * Use `create(RemoveDependencyResponseSchema)` to create a new message.\n */\nexport const RemoveDependencyResponseSchema: GenMessage<RemoveDependencyResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 47);\n\n/**\n * @generated from message contenthub.v1.PlanReleaseRequest\n */\nexport type PlanReleaseRequest = Message<\"contenthub.v1.PlanReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The editorial Branch whose head at Publish the Release pins.\n *\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n\n /**\n * Required for Dated Content, refused for undated Content.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * Release Spec values, keyed by the Release Spec Field's accessor and\n * checked against the Release Spec of the Blueprint Release the Branch's\n * head pins.\n *\n * @generated from field: google.protobuf.Struct release_spec = 4;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * Releases of the Content the new Release will Supersede: a correction\n * names the Release it corrects. Superseding a Release the Validity\n * Period would cover is how a cover is resolved.\n *\n * @generated from field: repeated string supersedes_release_ids = 5;\n */\n supersedesReleaseIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PlanReleaseRequest.\n * Use `create(PlanReleaseRequestSchema)` to create a new message.\n */\nexport const PlanReleaseRequestSchema: GenMessage<PlanReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 48);\n\n/**\n * @generated from message contenthub.v1.PlanReleaseResponse\n */\nexport type PlanReleaseResponse = Message<\"contenthub.v1.PlanReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.PlanReleaseResponse.\n * Use `create(PlanReleaseResponseSchema)` to create a new message.\n */\nexport const PlanReleaseResponseSchema: GenMessage<PlanReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 49);\n\n/**\n * @generated from message contenthub.v1.UpdatePlannedReleaseRequest\n */\nexport type UpdatePlannedReleaseRequest = Message<\"contenthub.v1.UpdatePlannedReleaseRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string planned_release_id = 2;\n */\n plannedReleaseId: string;\n\n /**\n * The new Validity Period; absent keeps it.\n *\n * @generated from field: contenthub.v1.ValidityPeriod validity_period = 3;\n */\n validityPeriod?: ValidityPeriod | undefined;\n\n /**\n * The new Release Spec values, all of them; absent keeps them.\n *\n * @generated from field: google.protobuf.Struct release_spec = 4;\n */\n releaseSpec?: JsonObject | undefined;\n\n /**\n * The new list of Releases it supersedes, for a Release of a Branch's\n * head; absent keeps it, an empty list clears it.\n *\n * @generated from field: contenthub.v1.ReleaseIdList supersedes = 5;\n */\n supersedes?: ReleaseIdList | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpdatePlannedReleaseRequest.\n * Use `create(UpdatePlannedReleaseRequestSchema)` to create a new message.\n */\nexport const UpdatePlannedReleaseRequestSchema: GenMessage<UpdatePlannedReleaseRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 50);\n\n/**\n * @generated from message contenthub.v1.UpdatePlannedReleaseResponse\n */\nexport type UpdatePlannedReleaseResponse = Message<\"contenthub.v1.UpdatePlannedReleaseResponse\"> & {\n /**\n * @generated from field: contenthub.v1.PlannedRelease planned_release = 1;\n */\n plannedRelease?: PlannedRelease | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UpdatePlannedReleaseResponse.\n * Use `create(UpdatePlannedReleaseResponseSchema)` to create a new message.\n */\nexport const UpdatePlannedReleaseResponseSchema: GenMessage<UpdatePlannedReleaseResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 51);\n\n/**\n * UpgradeTarget is one Content an upgrade names, with the head the caller\n * saw: the head of the last Branch of its Chain in the Change Set.\n *\n * @generated from message contenthub.v1.UpgradeTarget\n */\nexport type UpgradeTarget = Message<\"contenthub.v1.UpgradeTarget\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Required: an upgrade that names no head could silently build on a save\n * the caller never saw.\n *\n * @generated from field: string expected_head_id = 2;\n */\n expectedHeadId: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeTarget.\n * Use `create(UpgradeTargetSchema)` to create a new message.\n */\nexport const UpgradeTargetSchema: GenMessage<UpgradeTarget> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 52);\n\n/**\n * @generated from message contenthub.v1.UpgradeContentRequest\n */\nexport type UpgradeContentRequest = Message<\"contenthub.v1.UpgradeContentRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The Blueprint Release to move to.\n *\n * @generated from field: string blueprint_release_id = 2;\n */\n blueprintReleaseId: string;\n\n /**\n * The Content to upgrade, each with the head the caller saw. Exactly one\n * of contents and all_pinning_older is given.\n *\n * @generated from field: repeated contenthub.v1.UpgradeTarget contents = 3;\n */\n contents: UpgradeTarget[];\n\n /**\n * Upgrades every Content of the Change Set whose Chain's last Branch pins\n * an older Release of the same Blueprint, at the heads it reads. None is\n * no change.\n *\n * @generated from field: bool all_pinning_older = 4;\n */\n allPinningOlder: boolean;\n\n /**\n * Top-level field accessors whose values the upgrade removes; every other\n * field is carried over unchanged.\n *\n * @generated from field: repeated string drop_fields = 5;\n */\n dropFields: string[];\n\n /**\n * The first Validity Period of Content the upgrade makes Dated: required\n * when blueprint_release_id is dated and a Content's current one isn't,\n * refused otherwise. A Blueprint never stops being dated, so an upgrade\n * from a dated Release to an undated one is FailedPrecondition.\n *\n * @generated from field: contenthub.v1.ValidityPeriod first_period = 6;\n */\n firstPeriod?: ValidityPeriod | undefined;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 7;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeContentRequest.\n * Use `create(UpgradeContentRequestSchema)` to create a new message.\n */\nexport const UpgradeContentRequestSchema: GenMessage<UpgradeContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 53);\n\n/**\n * @generated from message contenthub.v1.UpgradeContentResponse\n */\nexport type UpgradeContentResponse = Message<\"contenthub.v1.UpgradeContentResponse\"> & {\n /**\n * The Change Set with its Chains, at their new heads.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * Each upgraded Content as GetContent reads it in the Change Set, in the\n * order the request named them (by id for all_pinning_older).\n *\n * @generated from field: repeated contenthub.v1.Content contents = 2;\n */\n contents: Content[];\n};\n\n/**\n * Describes the message contenthub.v1.UpgradeContentResponse.\n * Use `create(UpgradeContentResponseSchema)` to create a new message.\n */\nexport const UpgradeContentResponseSchema: GenMessage<UpgradeContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 54);\n\n/**\n * @generated from message contenthub.v1.RecordCheckResultRequest\n */\nexport type RecordCheckResultRequest = Message<\"contenthub.v1.RecordCheckResultRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string required_check_id = 2;\n */\n requiredCheckId: string;\n\n /**\n * The heads the check saw, id to Revision id. For a Branch-scope check,\n * exactly one: a Branch id to its head, or a Branch-less Planned\n * Release's id to the Revision it re-pins. For a Change Set-scope check,\n * every head of the Change Set: each Branch's, and each Branch-less\n * Planned Release's.\n *\n * @generated from field: map<string, string> heads = 3;\n */\n heads: { [key: string]: string };\n\n /**\n * Required.\n *\n * @generated from field: contenthub.v1.CheckOutcome outcome = 4;\n */\n outcome: CheckOutcome;\n\n /**\n * Required for waived, saying why; optional otherwise. At most 2000\n * characters.\n *\n * @generated from field: string note = 5;\n */\n note: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 6;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.RecordCheckResultRequest.\n * Use `create(RecordCheckResultRequestSchema)` to create a new message.\n */\nexport const RecordCheckResultRequestSchema: GenMessage<RecordCheckResultRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 55);\n\n/**\n * @generated from message contenthub.v1.RecordCheckResultResponse\n */\nexport type RecordCheckResultResponse = Message<\"contenthub.v1.RecordCheckResultResponse\"> & {\n /**\n * @generated from field: contenthub.v1.CheckResult check_result = 1;\n */\n checkResult?: CheckResult | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RecordCheckResultResponse.\n * Use `create(RecordCheckResultResponseSchema)` to create a new message.\n */\nexport const RecordCheckResultResponseSchema: GenMessage<RecordCheckResultResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 56);\n\n/**\n * CheckResult is one recorded outcome of a Required Check (CONTEXT.md).\n *\n * @generated from message contenthub.v1.CheckResult\n */\nexport type CheckResult = Message<\"contenthub.v1.CheckResult\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string required_check_id = 3;\n */\n requiredCheckId: string;\n\n /**\n * @generated from field: map<string, string> heads = 4;\n */\n heads: { [key: string]: string };\n\n /**\n * @generated from field: contenthub.v1.CheckOutcome outcome = 5;\n */\n outcome: CheckOutcome;\n\n /**\n * @generated from field: string note = 6;\n */\n note: string;\n\n /**\n * The token's subject of whoever recorded it: a person, or a flow's\n * Run-as user.\n *\n * @generated from field: string recorded_by = 7;\n */\n recordedBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp record_time = 8;\n */\n recordTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CheckResult.\n * Use `create(CheckResultSchema)` to create a new message.\n */\nexport const CheckResultSchema: GenMessage<CheckResult> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 57);\n\n/**\n * @generated from message contenthub.v1.ListCheckResultsRequest\n */\nexport type ListCheckResultsRequest = Message<\"contenthub.v1.ListCheckResultsRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListCheckResultsRequest.\n * Use `create(ListCheckResultsRequestSchema)` to create a new message.\n */\nexport const ListCheckResultsRequestSchema: GenMessage<ListCheckResultsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 58);\n\n/**\n * @generated from message contenthub.v1.ListCheckResultsResponse\n */\nexport type ListCheckResultsResponse = Message<\"contenthub.v1.ListCheckResultsResponse\"> & {\n /**\n * By check name, then in the Change Set's order: Branches by Chain, then\n * Branch-less Planned Releases.\n *\n * @generated from field: repeated contenthub.v1.CheckStanding standings = 1;\n */\n standings: CheckStanding[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCheckResultsResponse.\n * Use `create(ListCheckResultsResponseSchema)` to create a new message.\n */\nexport const ListCheckResultsResponseSchema: GenMessage<ListCheckResultsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 59);\n\n/**\n * CheckStanding is where one Required Check stands on one thing it applies\n * to: a Branch or a Branch-less Planned Release for Branch scope, the whole\n * Change Set for Change Set scope.\n *\n * @generated from message contenthub.v1.CheckStanding\n */\nexport type CheckStanding = Message<\"contenthub.v1.CheckStanding\"> & {\n /**\n * The check, as declared now.\n *\n * @generated from field: contenthub.v1.RequiredCheck required_check = 1;\n */\n requiredCheck?: RequiredCheck | undefined;\n\n /**\n * For Branch scope, the Content and the Branch or the Branch-less Planned\n * Release the result is about; empty for Change Set scope.\n *\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 3;\n */\n branchId: string;\n\n /**\n * @generated from field: string release_id = 4;\n */\n releaseId: string;\n\n /**\n * What a result recorded now names, as RecordCheckResultRequest.heads.\n *\n * @generated from field: map<string, string> heads = 5;\n */\n heads: { [key: string]: string };\n\n /**\n * Every result on it, newest first: the first is the latest, the one that\n * counts.\n *\n * @generated from field: repeated contenthub.v1.CheckResult results = 6;\n */\n results: CheckResult[];\n\n /**\n * Whether the latest result names heads other than these.\n *\n * @generated from field: bool stale = 7;\n */\n stale: boolean;\n\n /**\n * Whether the latest result is passed or waived and not stale: no\n * outstanding_check blocker for it while the heads stay.\n *\n * @generated from field: bool cleared = 8;\n */\n cleared: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CheckStanding.\n * Use `create(CheckStandingSchema)` to create a new message.\n */\nexport const CheckStandingSchema: GenMessage<CheckStanding> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 60);\n\n/**\n * @generated from message contenthub.v1.ValidatePublishRequest\n */\nexport type ValidatePublishRequest = Message<\"contenthub.v1.ValidatePublishRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The heads the caller would publish, Branch id to head Revision id.\n *\n * @generated from field: map<string, string> reviewed_heads = 2;\n */\n reviewedHeads: { [key: string]: string };\n};\n\n/**\n * Describes the message contenthub.v1.ValidatePublishRequest.\n * Use `create(ValidatePublishRequestSchema)` to create a new message.\n */\nexport const ValidatePublishRequestSchema: GenMessage<ValidatePublishRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 61);\n\n/**\n * @generated from message contenthub.v1.ValidatePublishResponse\n */\nexport type ValidatePublishResponse = Message<\"contenthub.v1.ValidatePublishResponse\"> & {\n /**\n * Every blocker; none means a Publish with these heads would succeed now.\n *\n * @generated from field: repeated contenthub.v1.PublishBlocker blockers = 1;\n */\n blockers: PublishBlocker[];\n\n /**\n * The Releases the Publish would cut, without a Publish Time; for a\n * Change Set published already with these heads, the ones it cut.\n *\n * @generated from field: repeated contenthub.v1.Release releases = 2;\n */\n releases: Release[];\n\n /**\n * Whether the Change Set is published already with these heads: Publish\n * would return its stored outcome.\n *\n * @generated from field: bool published = 3;\n */\n published: boolean;\n\n /**\n * Advice that never blocks Publish: the referrers each Repeal or\n * Withdrawal will leave with a gap (ADR 0015). None for a Change Set\n * published already.\n *\n * @generated from field: repeated contenthub.v1.PublishWarning warnings = 4;\n */\n warnings: PublishWarning[];\n};\n\n/**\n * Describes the message contenthub.v1.ValidatePublishResponse.\n * Use `create(ValidatePublishResponseSchema)` to create a new message.\n */\nexport const ValidatePublishResponseSchema: GenMessage<ValidatePublishResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 62);\n\n/**\n * @generated from message contenthub.v1.PublishRequest\n */\nexport type PublishRequest = Message<\"contenthub.v1.PublishRequest\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * The heads the caller reviewed, Branch id to head Revision id: every\n * Branch of the Change Set, each at its current head.\n *\n * @generated from field: map<string, string> reviewed_heads = 2;\n */\n reviewedHeads: { [key: string]: string };\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.PublishRequest.\n * Use `create(PublishRequestSchema)` to create a new message.\n */\nexport const PublishRequestSchema: GenMessage<PublishRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 63);\n\n/**\n * @generated from message contenthub.v1.PublishResponse\n */\nexport type PublishResponse = Message<\"contenthub.v1.PublishResponse\"> & {\n /**\n * The Change Set, published.\n *\n * @generated from field: contenthub.v1.ChangeSet change_set = 1;\n */\n changeSet?: ChangeSet | undefined;\n\n /**\n * The Publish Time every Release carries.\n *\n * @generated from field: google.protobuf.Timestamp publish_time = 2;\n */\n publishTime?: Timestamp | undefined;\n\n /**\n * The Releases cut, under their planned ids.\n *\n * @generated from field: repeated contenthub.v1.Release releases = 3;\n */\n releases: Release[];\n};\n\n/**\n * Describes the message contenthub.v1.PublishResponse.\n * Use `create(PublishResponseSchema)` to create a new message.\n */\nexport const PublishResponseSchema: GenMessage<PublishResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 64);\n\n/**\n * StaleHead is the detail of an Aborted save: the head the save named has\n * moved. Apply the edit to current_head_id and save again.\n *\n * @generated from message contenthub.v1.StaleHead\n */\nexport type StaleHead = Message<\"contenthub.v1.StaleHead\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: string branch_id = 2;\n */\n branchId: string;\n\n /**\n * @generated from field: string expected_head_id = 3;\n */\n expectedHeadId: string;\n\n /**\n * @generated from field: string current_head_id = 4;\n */\n currentHeadId: string;\n};\n\n/**\n * Describes the message contenthub.v1.StaleHead.\n * Use `create(StaleHeadSchema)` to create a new message.\n */\nexport const StaleHeadSchema: GenMessage<StaleHead> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 65);\n\n/**\n * ChangeSetClosed is the detail of a FailedPrecondition write to a Change Set\n * that is published or discarded, and so closed for good.\n *\n * @generated from message contenthub.v1.ChangeSetClosed\n */\nexport type ChangeSetClosed = Message<\"contenthub.v1.ChangeSetClosed\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: contenthub.v1.ChangeSetState state = 2;\n */\n state: ChangeSetState;\n};\n\n/**\n * Describes the message contenthub.v1.ChangeSetClosed.\n * Use `create(ChangeSetClosedSchema)` to create a new message.\n */\nexport const ChangeSetClosedSchema: GenMessage<ChangeSetClosed> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 66);\n\n/**\n * WithheldWork is the detail of the PermissionDenied refusal of a call over\n * a whole Change Set (Publish and its dry run ValidatePublish,\n * DiscardChangeSet, UpdateFromMain without chain_id) to a caller who cannot\n * see every Content in it (ADR 0017). It names no Content: a client reads it as \"this Change\n * Set holds work you can't see\".\n *\n * @generated from message contenthub.v1.WithheldWork\n */\nexport type WithheldWork = Message<\"contenthub.v1.WithheldWork\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.WithheldWork.\n * Use `create(WithheldWorkSchema)` to create a new message.\n */\nexport const WithheldWorkSchema: GenMessage<WithheldWork> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 67);\n\n/**\n * StaleStatus is the detail of an Aborted SetChangeSetStatus: the status\n * moved since the caller saw it. Read current_status and choose again.\n *\n * @generated from message contenthub.v1.StaleStatus\n */\nexport type StaleStatus = Message<\"contenthub.v1.StaleStatus\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string expected_status = 2;\n */\n expectedStatus: string;\n\n /**\n * Empty for an unknown status.\n *\n * @generated from field: string current_status = 3;\n */\n currentStatus: string;\n};\n\n/**\n * Describes the message contenthub.v1.StaleStatus.\n * Use `create(StaleStatusSchema)` to create a new message.\n */\nexport const StaleStatusSchema: GenMessage<StaleStatus> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 68);\n\n/**\n * StatusTransitionRefused is the detail of a SetChangeSetStatus statushub\n * refused: the workspace's catalogue has no such move, or it is guarded.\n *\n * @generated from message contenthub.v1.StatusTransitionRefused\n */\nexport type StatusTransitionRefused = Message<\"contenthub.v1.StatusTransitionRefused\"> & {\n /**\n * @generated from field: string change_set_id = 1;\n */\n changeSetId: string;\n\n /**\n * @generated from field: string from_status = 2;\n */\n fromStatus: string;\n\n /**\n * @generated from field: string to_status = 3;\n */\n toStatus: string;\n\n /**\n * statushub's reason, as it gave it.\n *\n * @generated from field: string reason = 4;\n */\n reason: string;\n\n /**\n * True for a guarded move (PermissionDenied), which statushub refuses\n * while it runs without Guardian.\n *\n * @generated from field: bool requires_permission = 5;\n */\n requiresPermission: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.StatusTransitionRefused.\n * Use `create(StatusTransitionRefusedSchema)` to create a new message.\n */\nexport const StatusTransitionRefusedSchema: GenMessage<StatusTransitionRefused> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 69);\n\n/**\n * Violation is one detail of an InvalidArgument write: one reason its data\n * was refused, in the shape blueprinthub's Violation has.\n *\n * @generated from message contenthub.v1.Violation\n */\nexport type Violation = Message<\"contenthub.v1.Violation\"> & {\n /**\n * Whose rule it is: \"fieldkit\" (a code from fieldkit's data contract,\n * unchanged), \"knkeditor\" (a rich-text code of knkeditor's, unchanged) or\n * \"contenthub\" (contenthub's own). Until fieldkit enforces them\n * (knkCS/fieldkit#347), contenthub reports two fieldkit rules itself, with\n * the codes fieldkit will use: \"unknown_field\" at a key no Field declares,\n * and \"invalid_format\" at a date that isn't YYYY-MM-DD.\n *\n * @generated from field: string source = 1;\n */\n source: string;\n\n /**\n * The rule's own code, such as fieldkit's \"required\" or knkeditor's\n * \"unknown-node\".\n *\n * @generated from field: string code = 2;\n */\n code: string;\n\n /**\n * A /-separated location in the data, such as \"/title\" or\n * \"/body/content/0\"; \"\" is the data itself.\n *\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * Detail a message may interpolate; empty when the code says everything.\n *\n * @generated from field: google.protobuf.Struct params = 4;\n */\n params?: JsonObject | undefined;\n\n /**\n * The Content whose data or Release Spec values it is in, set where one\n * call checks several (UpgradeContent); empty elsewhere.\n *\n * @generated from field: string content_id = 5;\n */\n contentId: string;\n\n /**\n * The Planned Release whose Release Spec values it is in, set by\n * UpgradeContent, which checks them again against the new Blueprint\n * Release; empty when it is in the Content's data.\n *\n * @generated from field: string planned_release_id = 6;\n */\n plannedReleaseId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Violation.\n * Use `create(ViolationSchema)` to create a new message.\n */\nexport const ViolationSchema: GenMessage<Violation> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_change_set, 70);\n\n/**\n * ChangeSetState is where a Change Set is in its life: open, then published\n * or discarded, and closed for good after either.\n *\n * @generated from enum contenthub.v1.ChangeSetState\n */\nexport enum ChangeSetState {\n /**\n * @generated from enum value: CHANGE_SET_STATE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_OPEN = 1;\n */\n OPEN = 1,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_PUBLISHED = 2;\n */\n PUBLISHED = 2,\n\n /**\n * @generated from enum value: CHANGE_SET_STATE_DISCARDED = 3;\n */\n DISCARDED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.ChangeSetState.\n */\nexport const ChangeSetStateSchema: GenEnum<ChangeSetState> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 0);\n\n/**\n * BranchKind is what a Branch is for.\n *\n * @generated from enum contenthub.v1.BranchKind\n */\nexport enum BranchKind {\n /**\n * @generated from enum value: BRANCH_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * A Branch an editor works on.\n *\n * @generated from enum value: BRANCH_KIND_EDITORIAL = 1;\n */\n EDITORIAL = 1,\n\n /**\n * A Carry-forward link (CONTEXT.md).\n *\n * @generated from enum value: BRANCH_KIND_CARRY_FORWARD = 2;\n */\n CARRY_FORWARD = 2,\n}\n\n/**\n * Describes the enum contenthub.v1.BranchKind.\n */\nexport const BranchKindSchema: GenEnum<BranchKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 1);\n\n/**\n * CheckOutcome is what a Check Result says.\n *\n * @generated from enum contenthub.v1.CheckOutcome\n */\nexport enum CheckOutcome {\n /**\n * @generated from enum value: CHECK_OUTCOME_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: CHECK_OUTCOME_PASSED = 1;\n */\n PASSED = 1,\n\n /**\n * @generated from enum value: CHECK_OUTCOME_FAILED = 2;\n */\n FAILED = 2,\n\n /**\n * Waived, for the reason the note gives: the check gates no more on these\n * heads, as if passed.\n *\n * @generated from enum value: CHECK_OUTCOME_WAIVED = 3;\n */\n WAIVED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.CheckOutcome.\n */\nexport const CheckOutcomeSchema: GenEnum<CheckOutcome> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_change_set, 2);\n\n/**\n * ChangeSetService holds every write to history, and is the only service\n * whose requests name Branches or Revisions (ADR 0015). A Change Set is the\n * only path to a Release: Content is born inside one, edited on its Branches\n * and released when it is published (ADRs 0002, 0003).\n *\n * Every RPC acts in the caller's workspace, which comes from the token's\n * active workspace and never from a request field. Reads need `viewer`,\n * writes `editor` (ADR 0017).\n *\n * Every write that changes history announces it in its own transaction\n * (ADR 0016): contenthub.change_set.created, contenthub.change_set.updated,\n * contenthub.change_set.discarded, contenthub.change_set.status_changed,\n * contenthub.change_set.assignees_changed,\n * contenthub.change_set.updated_from_main and contenthub.branch.head_moved,\n * in contenthub.events.v1; Publish\n * announces contenthub.change_set.published, contenthub.content.released and\n * contenthub.content.in_force_changed.\n *\n * @generated from service contenthub.v1.ChangeSetService\n */\nexport const ChangeSetService: GenService<{\n /**\n * CreateChangeSet opens a Change Set, the container for the work one\n * publishing event triggers. It publishes contenthub.change_set.created.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.CreateChangeSet\n */\n createChangeSet: {\n methodKind: \"unary\";\n input: typeof CreateChangeSetRequestSchema;\n output: typeof CreateChangeSetResponseSchema;\n },\n /**\n * GetChangeSet returns a Change Set with its Chains, their Branches and\n * each Branch's head: the heads a save names as expected_head_id.\n *\n * A Change Set is visible to every viewer, but its Chains and Planned\n * Releases on Restricted Content are left out for a caller not granted on\n * that Content (ADR 0017), here and in every response that returns a\n * Change Set.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.GetChangeSet\n */\n getChangeSet: {\n methodKind: \"unary\";\n input: typeof GetChangeSetRequestSchema;\n output: typeof GetChangeSetResponseSchema;\n },\n /**\n * UpdateChangeSet changes an open Change Set's name and Source, as\n * update_mask says (#126): a gazette citation with a typo is corrected\n * before it travels into contenthub.change_set.published and every\n * Release. It publishes contenthub.change_set.updated, naming the fields\n * whose value changed; a write that changes nothing publishes nothing.\n *\n * The Source freezes at Publish: a published or discarded Change Set is\n * FailedPrecondition with a ChangeSetClosed detail, and nothing changes.\n * A Change Set's name and Source are its own, not its Content's, so a\n * caller who can't see some of its work may still correct them (ADR 0017).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdateChangeSet\n */\n updateChangeSet: {\n methodKind: \"unary\";\n input: typeof UpdateChangeSetRequestSchema;\n output: typeof UpdateChangeSetResponseSchema;\n },\n /**\n * DiscardChangeSet closes an open Change Set for good without publishing\n * it. Its Branches end, and Content born in it is gone from every read; the\n * Revisions written in it stay in history (ADR 0003). It publishes\n * contenthub.change_set.discarded. A Change Set that is already published\n * or discarded is FailedPrecondition, with a ChangeSetClosed detail.\n *\n * A caller who cannot see every Content in the Change Set is\n * PermissionDenied, as Publish refuses them, naming no Content (ADR 0017),\n * with a WithheldWork detail: nobody ends work they were never shown.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DiscardChangeSet\n */\n discardChangeSet: {\n methodKind: \"unary\";\n input: typeof DiscardChangeSetRequestSchema;\n output: typeof DiscardChangeSetResponseSchema;\n },\n /**\n * SetChangeSetStatus moves a Change Set's status label, a status of\n * statushub's `contenthub/change_set` catalogue (ADR 0014), and publishes\n * contenthub.change_set.status_changed. The label never gates Publish, and\n * contenthub never sets it itself: not at birth, where it is unset (an\n * unknown status), and not at Publish or discard, after which it is frozen.\n *\n * statushub decides whether the move is allowed, asked with the caller's\n * token. A move it refuses is FailedPrecondition, or PermissionDenied for a\n * guarded one, with a StatusTransitionRefused detail carrying its reason.\n * A move away from an unknown status is never validated, so a Change Set is\n * never stuck on a deleted status. A status not in the workspace's\n * catalogue is InvalidArgument. If the status is no longer expected_status,\n * nothing is written and the call is Aborted with a StaleStatus detail\n * naming the current one. A published or discarded Change Set is\n * FailedPrecondition with a ChangeSetClosed detail. While statushub can't\n * be reached the call is Unavailable: retry it unchanged.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SetChangeSetStatus\n */\n setChangeSetStatus: {\n methodKind: \"unary\";\n input: typeof SetChangeSetStatusRequestSchema;\n output: typeof SetChangeSetStatusResponseSchema;\n },\n /**\n * SetChangeSetAssignees replaces who is working on a Change Set now. It is\n * outside history (ADR 0015): no save, no Change Set state, and allowed\n * whatever the state. It publishes contenthub.change_set.assignees_changed\n * when the set changes, and nothing when it doesn't.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SetChangeSetAssignees\n */\n setChangeSetAssignees: {\n methodKind: \"unary\";\n input: typeof SetChangeSetAssigneesRequestSchema;\n output: typeof SetChangeSetAssigneesResponseSchema;\n },\n /**\n * CreateContent creates Content inside an open Change Set, on a Blueprint\n * Release it pins. The Content has one Chain of one Branch, whose head is\n * its first Revision, and exists only inside the Change Set until Publish\n * gives it a Main Branch. It publishes contenthub.branch.head_moved with\n * cause create (and copied_from, for a copy).\n *\n * The first Revision is validated like any save: data fieldkit or\n * knkeditor refuses against the Blueprint Release is InvalidArgument, with\n * one Violation detail per problem, but required Fields may be left empty\n * (empty data included) until Publish. A Blueprint Release contenthub can't\n * load is InvalidArgument with one Refusal detail per reason.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.CreateContent\n */\n createContent: {\n methodKind: \"unary\";\n input: typeof CreateContentRequestSchema;\n output: typeof CreateContentResponseSchema;\n },\n /**\n * SaveRevision writes a new immutable Revision on a Branch, on top of the\n * head the author edited (ADR 0003), against the Blueprint Release that\n * head pins.\n *\n * If the head has moved since, nothing is written and the call is Aborted\n * with a StaleHead detail naming the current head: load it, apply the edit\n * there, and save again. A value fieldkit or knkeditor refuses is\n * InvalidArgument with one Violation detail per problem, and nothing is\n * written. A required Field left empty is not refused: Publish is,\n * with a missing_required_field blocker, until it is filled. It\n * publishes contenthub.branch.head_moved with cause save.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.SaveRevision\n */\n saveRevision: {\n methodKind: \"unary\";\n input: typeof SaveRevisionRequestSchema;\n output: typeof SaveRevisionResponseSchema;\n },\n /**\n * PreviewChain is StartChain's dry run for Dated Content: what a Chain on\n * a published Content, effective on a date, would fork from (the Release\n * In Force then, or a Planned Release of a Change Set it depends on), the\n * later Releases it would carry forward through, whether a final link\n * would merge Main's head, and the Releases a period from that date would\n * cut into or cover entirely (ADR 0015). It refuses what StartChain would\n * refuse, so undated Content, whose Chain takes no date, is\n * InvalidArgument. It writes nothing and waits on nothing: a Publish in\n * between may change the answer.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PreviewChain\n */\n previewChain: {\n methodKind: \"unary\";\n input: typeof PreviewChainRequestSchema;\n output: typeof PreviewChainResponseSchema;\n },\n /**\n * StartChain starts a Chain on a published Content in an open Change Set,\n * so that editors can change it there (ADR 0002). Editors choose the date\n * the change takes effect, never a Branch or a Revision: on Dated Content\n * the Chain forks from the Release In Force on effective_on (in a Change\n * Set with dependencies, possibly a dependency's Planned Release), and when\n * that is behind Main's head the Chain gets a Carry-forward link for each\n * later Release In Force, and a final link merging Main's head where that\n * isn't the last Release's Revision. Undated Content takes no date: its\n * Chain is one Branch forked from Main's head.\n *\n * It writes no Revision: each Branch starts at a Revision that exists.\n * It publishes contenthub.branch.head_moved with cause start for each\n * Branch. A Content with a Chain in the Change Set already, or born in it,\n * is AlreadyExists; one with no Main Branch yet (born in another open\n * Change Set) is FailedPrecondition; a missing or wrongly given date is\n * InvalidArgument.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.StartChain\n */\n startChain: {\n methodKind: \"unary\";\n input: typeof StartChainRequestSchema;\n output: typeof StartChainResponseSchema;\n },\n /**\n * AppendBranch adds an editorial Branch to a Chain on Dated Content, for a\n * later date: one announcement amending a paragraph from 2027 and again\n * from 2028 is two stacked Branches, the second starting at the head of\n * the one before. The Chain is re-laid around it, so Carry-forward links\n * for Releases starting after the date build on the new Branch. A date\n * not after the Chain's last editorial Branch's is InvalidArgument; a\n * Chain without dates (undated Content, or Content born in the Change\n * Set) is FailedPrecondition. It publishes contenthub.branch.head_moved\n * with cause start for each Branch it adds.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AppendBranch\n */\n appendBranch: {\n methodKind: \"unary\";\n input: typeof AppendBranchRequestSchema;\n output: typeof AppendBranchResponseSchema;\n },\n /**\n * DropChain removes a Chain from an open Change Set: its Branches end, its\n * Planned Releases go and the Change Set's proposals are derived again\n * without them; every Revision written on it stays in history. The\n * Content may get a new Chain in the Change Set afterwards. The Chain of\n * Content born in the Change Set can't be dropped (FailedPrecondition):\n * discard the Change Set instead. It announces nothing (ADR 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DropChain\n */\n dropChain: {\n methodKind: \"unary\";\n input: typeof DropChainRequestSchema;\n output: typeof DropChainResponseSchema;\n },\n /**\n * StartEditing bundles the steps of a one-off edit (ADR 0015): it starts a\n * Chain on a published Content as StartChain does, in change_set_id or,\n * without one, in a new Change Set it opens. It never reuses an open\n * Change Set silently. The new Change Set and the Chain are written in one\n * transaction, so a refused Chain leaves no Change Set behind. It\n * publishes contenthub.change_set.created for a new Change Set and\n * contenthub.branch.head_moved with cause start for each Branch.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.StartEditing\n */\n startEditing: {\n methodKind: \"unary\";\n input: typeof StartEditingRequestSchema;\n output: typeof StartEditingResponseSchema;\n },\n /**\n * UpdateFromMain replays the Chains of an open Change Set (or only\n * chain_id's) onto their current bases: Main's head, a dependency's Branch\n * head, or on Dated Content the Releases In Force a Chain carries, re-laying\n * a Chain whose later Releases changed (CONTEXT.md, Update from Main). It is\n * synchronous and one transaction, and returns its outcome.\n *\n * Each Branch that is behind is merged field by field. A clean merge is a\n * merge Revision, pinned to the newer of the two Blueprint Releases, that\n * becomes the Branch's head; a merge with Conflicts, or whose data the\n * Blueprint Release refuses, moves nothing and stays on the Branch as a\n * Pending Merge. A Branch that already has one is left alone and reported\n * in pending. A moved head makes earlier Check Results on it stale.\n *\n * It publishes contenthub.branch.head_moved for each head it moves (cause\n * merge, or start for a link a re-lay adds) and\n * contenthub.change_set.updated_from_main. Two Blueprint Releases of\n * different Blueprints can't be ordered: a merge meeting them refuses the\n * whole call, FailedPrecondition, nothing written.\n *\n * Without chain_id, a caller who cannot see every Content in the Change\n * Set is PermissionDenied, as Publish refuses them, naming no Content (ADR\n * 0017), with a WithheldWork detail. A Chain on Content they see they\n * update alone, with chain_id.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdateFromMain\n */\n updateFromMain: {\n methodKind: \"unary\";\n input: typeof UpdateFromMainRequestSchema;\n output: typeof UpdateFromMainResponseSchema;\n },\n /**\n * GetPendingMerge returns the Pending Merge on a Branch, with every field\n * a resolution must decide and each side's value, or none when the Branch\n * has none.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.GetPendingMerge\n */\n getPendingMerge: {\n methodKind: \"unary\";\n input: typeof GetPendingMergeRequestSchema;\n output: typeof GetPendingMergeResponseSchema;\n },\n /**\n * ResolveMerge resolves the Pending Merge on a Branch field by field: each\n * field GetPendingMerge lists takes one side's value or the editor's, every\n * other field its merged value. The result is validated like a save,\n * against the Blueprint Release the merge pins, and written as a merge\n * Revision that becomes the Branch's head. A head that moved is Aborted\n * with a StaleHead detail; a field left undecided, decided twice or not\n * listed is InvalidArgument; a Branch without a Pending Merge is\n * FailedPrecondition. It publishes contenthub.branch.head_moved with cause\n * resolve.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ResolveMerge\n */\n resolveMerge: {\n methodKind: \"unary\";\n input: typeof ResolveMergeRequestSchema;\n output: typeof ResolveMergeResponseSchema;\n },\n /**\n * AbortMerge drops the Pending Merge on a Branch and leaves the Branch at\n * its head: it takes saves again, but stays behind its base, so Publish\n * waits for another Update from Main. A Branch without a Pending Merge is\n * FailedPrecondition. It announces nothing (ADR 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AbortMerge\n */\n abortMerge: {\n methodKind: \"unary\";\n input: typeof AbortMergeRequestSchema;\n output: typeof AbortMergeResponseSchema;\n },\n /**\n * AddDependency makes a Change Set depend on another open one: its Chains\n * then build on the other's Planned Releases and Branch heads, and it can\n * be published only after the other (ADR 0002). Adding one it has already\n * changes nothing. A dependency that would close a cycle, or names a\n * closed Change Set, is FailedPrecondition. It announces nothing (ADR\n * 0016).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.AddDependency\n */\n addDependency: {\n methodKind: \"unary\";\n input: typeof AddDependencyRequestSchema;\n output: typeof AddDependencyResponseSchema;\n },\n /**\n * RemoveDependency undoes AddDependency while the Change Set is open.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.RemoveDependency\n */\n removeDependency: {\n methodKind: \"unary\";\n input: typeof RemoveDependencyRequestSchema;\n output: typeof RemoveDependencyResponseSchema;\n },\n /**\n * PlanRelease plans the Release the Change Set's Publish will cut of an\n * editorial Branch's head, with its Validity Period (required for Dated\n * Content, refused for undated) and Release Spec values, and returns it\n * with its final Release id. Release Spec values the Blueprint Release\n * refuses are InvalidArgument with one Violation detail per problem. A\n * Branch is released once: planning it again is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanRelease\n */\n planRelease: {\n methodKind: \"unary\";\n input: typeof PlanReleaseRequestSchema;\n output: typeof PlanReleaseResponseSchema;\n },\n /**\n * UpdatePlannedRelease changes a Planned Release's Validity Period,\n * Release Spec values or the Releases it supersedes while the Change Set\n * is open. The values given are the ones that count from then on. A\n * proposal's Validity Period is derived from the plans and can't be set\n * (InvalidArgument); a new Validity Period that would cover a Release\n * entirely is FailedPrecondition with a CoversRelease detail.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpdatePlannedRelease\n */\n updatePlannedRelease: {\n methodKind: \"unary\";\n input: typeof UpdatePlannedReleaseRequestSchema;\n output: typeof UpdatePlannedReleaseResponseSchema;\n },\n /**\n * PlanDateOnlyRelease plans a date-only Release that re-pins a published\n * Release's Revision with a corrected Validity Period and supersedes it, so\n * a date correction needs no new Revision. Dated Content only.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanDateOnlyRelease\n */\n planDateOnlyRelease: {\n methodKind: \"unary\";\n input: typeof PlanDateOnlyReleaseRequestSchema;\n output: typeof PlanDateOnlyReleaseResponseSchema;\n },\n /**\n * PlanRepeal plans a Repeal of Dated Content: a date-only Release ending\n * the Release In Force on last_day, which also supersedes every Release\n * starting after last_day, so that nothing is In Force after it.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanRepeal\n */\n planRepeal: {\n methodKind: \"unary\";\n input: typeof PlanRepealRequestSchema;\n output: typeof PlanRepealResponseSchema;\n },\n /**\n * PlanWithdrawal plans a Withdrawal of undated Content: a Release that\n * re-pins the Revision In Force at Publish and ends its force from that\n * Publish Time on.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.PlanWithdrawal\n */\n planWithdrawal: {\n methodKind: \"unary\";\n input: typeof PlanWithdrawalRequestSchema;\n output: typeof PlanWithdrawalResponseSchema;\n },\n /**\n * DropPlannedRelease drops a Planned Release from an open Change Set; its\n * id is never cut. A proposed date-only cut is derived from the plans and\n * not dropped on its own (FailedPrecondition).\n *\n * @generated from rpc contenthub.v1.ChangeSetService.DropPlannedRelease\n */\n dropPlannedRelease: {\n methodKind: \"unary\";\n input: typeof DropPlannedReleaseRequestSchema;\n output: typeof DropPlannedReleaseResponseSchema;\n },\n /**\n * UpgradeContent moves Content to a newer Blueprint Release of its\n * Blueprint inside an open Change Set, so that a schema change reaches\n * Content through review like any other change (ADR 0015). For each\n * Content it saves one Revision on the last Branch of its Chain (the tip\n * Main moves to at Publish): the head's data, without the fields\n * drop_fields names, pinned to blueprint_release_id. It is synchronous and\n * one transaction, and refused as a whole, with nothing written:\n *\n * - a head that has moved is Aborted with one StaleHead detail per\n * moved head;\n * - data or Release Spec values the new Blueprint Release refuses are\n * InvalidArgument with one Violation detail per problem, each naming\n * its Content (and its Planned Release, for Release Spec values). A\n * required Field the data leaves empty is not refused: Publish asks\n * for it (missing_required_field);\n * - a Blueprint Release contenthub can't load (CheckBlueprintRelease\n * refuses it) is InvalidArgument with one Refusal detail per reason;\n * - a Content without a Chain in the Change Set, of another Blueprint,\n * or pinning that Release or a newer one already, is\n * FailedPrecondition.\n *\n * Releases of one Blueprint are ordered by their ids, which blueprinthub\n * mints as KSUIDs when it cuts them: a later cut sorts after.\n *\n * It extends ADR 0015's UpgradeContent(change_set, blueprint_release,\n * content_ids | all_pinning_older, drop_fields) by two fields: each named\n * Content carries the head its caller saw, since ADR 0015 refuses an\n * upgrade on a stale head and a head that is never named can't be stale;\n * and first_period, the first Validity Period CONTEXT.md's Dated Content\n * says the upgrading Change Set gives Content its Blueprint makes dated.\n *\n * It publishes contenthub.branch.head_moved with cause upgrade for each\n * Content.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.UpgradeContent\n */\n upgradeContent: {\n methodKind: \"unary\";\n input: typeof UpgradeContentRequestSchema;\n output: typeof UpgradeContentResponseSchema;\n },\n /**\n * RecordCheckResult records the outcome of a Required Check against the\n * heads its recorder saw (ADR 0014): passed, failed, or waived with a\n * note. A Branch-scope result names one head: a Branch's, or the Revision\n * a Branch-less Planned Release re-pins. A Change Set-scope result names\n * every head of the Change Set, both kinds. Results are kept; the latest of a\n * check on one Branch, Planned Release or Change Set counts, and only while\n * its heads are the ones being published: any later save makes it stale.\n *\n * Heads that aren't current are Aborted with a StaleHead detail, nothing\n * recorded. A check that doesn't apply to what the heads name is\n * InvalidArgument. On an independent check, passed and waived from someone\n * who authored a Revision on the Branches the result covers are\n * PermissionDenied; failed is accepted from anyone. It publishes\n * contenthub.change_set.check_result_recorded.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.RecordCheckResult\n */\n recordCheckResult: {\n methodKind: \"unary\";\n input: typeof RecordCheckResultRequestSchema;\n output: typeof RecordCheckResultResponseSchema;\n },\n /**\n * ListCheckResults reads where each Required Check that applies to the\n * Change Set stands: per Branch and per Branch-less Planned Release of\n * covered Content for Branch scope, once for Change Set scope. Each\n * standing carries the heads a result recorded now names, the results\n * recorded on it, newest first, and whether the latest is stale (it names\n * other heads, so a save since made it count for nothing) or clears the\n * check. A check that applies to nothing in the Change Set is left out.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ListCheckResults\n */\n listCheckResults: {\n methodKind: \"unary\";\n input: typeof ListCheckResultsRequestSchema;\n output: typeof ListCheckResultsResponseSchema;\n },\n /**\n * ValidatePublish is Publish's dry run: every blocker a Publish with the\n * same reviewed heads would be refused with now, and the Releases it would\n * cut. It writes nothing and waits on nothing; Publish decides again.\n * It also warns, without blocking, about the referrers a Repeal or\n * Withdrawal will leave with a gap. It is PermissionDenied when Publish\n * would be, for a caller who cannot see every Content in the Change Set.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.ValidatePublish\n */\n validatePublish: {\n methodKind: \"unary\";\n input: typeof ValidatePublishRequestSchema;\n output: typeof ValidatePublishResponseSchema;\n },\n /**\n * Publish closes an open Change Set in one transaction: Main moves to the\n * tip of each Chain (born Content gets its Main Branch) and every Planned\n * Release is cut, or nothing is. reviewed_heads must be exactly the\n * current head of every Branch of the Change Set; any other is refused.\n * So is a Change Set where any Required Check that applies lacks a latest\n * passed or waived result on the reviewed heads (outstanding_check).\n *\n * A refusal is FailedPrecondition with one PublishBlocker detail per\n * blocker, and nothing is written. Repeating a Publish that succeeded,\n * with the same reviewed heads, returns its stored outcome and announces\n * nothing again; with other heads it is FailedPrecondition with a\n * ChangeSetClosed detail.\n *\n * A caller who cannot see every Content in the Change Set, because some\n * is Restricted and they are not granted on it, is PermissionDenied before\n * anything else is looked at (ADR 0017): Publish takes explicit reviewed\n * heads, and nobody publishes work they were never shown. The refusal\n * names no Content, and carries a WithheldWork detail.\n *\n * It publishes contenthub.change_set.published, one\n * contenthub.content.released per Release, and one\n * contenthub.content.in_force_changed (cause publish) per Content whose\n * Release In Force today changed.\n *\n * @generated from rpc contenthub.v1.ChangeSetService.Publish\n */\n publish: {\n methodKind: \"unary\";\n input: typeof PublishRequestSchema;\n output: typeof PublishResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_change_set, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/collection.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/collection.proto.\n */\nexport const file_contenthub_v1_collection: GenFile = /*@__PURE__*/\n fileDesc(\"Ch5jb250ZW50aHViL3YxL2NvbGxlY3Rpb24ucHJvdG8SDWNvbnRlbnRodWIudjEirwEKCkNvbGxlY3Rpb24SCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIRCglwYXJlbnRfaWQYAyABKAkSEgoKcmVzdHJpY3RlZBgEIAEoCBIvCgtjcmVhdGVfdGltZRgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLdXBkYXRlX3RpbWUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIk4KF0NyZWF0ZUNvbGxlY3Rpb25SZXF1ZXN0EgwKBG5hbWUYASABKAkSEQoJcGFyZW50X2lkGAIgASgJEhIKCnJlc3RyaWN0ZWQYAyABKAgiSQoYQ3JlYXRlQ29sbGVjdGlvblJlc3BvbnNlEi0KCmNvbGxlY3Rpb24YASABKAsyGS5jb250ZW50aHViLnYxLkNvbGxlY3Rpb24iGAoWTGlzdENvbGxlY3Rpb25zUmVxdWVzdCJJChdMaXN0Q29sbGVjdGlvbnNSZXNwb25zZRIuCgtjb2xsZWN0aW9ucxgBIAMoCzIZLmNvbnRlbnRodWIudjEuQ29sbGVjdGlvbiIzChdSZW5hbWVDb2xsZWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJIkkKGFJlbmFtZUNvbGxlY3Rpb25SZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIjYKFU1vdmVDb2xsZWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIRCglwYXJlbnRfaWQYAiABKAkiRwoWTW92ZUNvbGxlY3Rpb25SZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIiUKF1JlbW92ZUNvbGxlY3Rpb25SZXF1ZXN0EgoKAmlkGAEgASgJIjcKGFJlbW92ZUNvbGxlY3Rpb25SZXNwb25zZRIbChN1bmZpbGVkX2NvbnRlbnRfaWRzGAEgAygJImAKHlNldENvbGxlY3Rpb25SZXN0cmljdGVkUmVxdWVzdBIKCgJpZBgBIAEoCRISCgpyZXN0cmljdGVkGAIgASgIEh4KFmFja25vd2xlZGdlX2Rpc2Nsb3N1cmUYAyABKAgiUAofU2V0Q29sbGVjdGlvblJlc3RyaWN0ZWRSZXNwb25zZRItCgpjb2xsZWN0aW9uGAEgASgLMhkuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uIlcKD0NvbGxlY3Rpb25HcmFudBIPCgd1c2VyX2lkGAEgASgJEjMKBWxldmVsGAIgASgOMiQuY29udGVudGh1Yi52MS5Db2xsZWN0aW9uQWNjZXNzTGV2ZWwiewocR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJEg8KB3VzZXJfaWQYAiABKAkSMwoFbGV2ZWwYAyABKA4yJC5jb250ZW50aHViLnYxLkNvbGxlY3Rpb25BY2Nlc3NMZXZlbCIfCh1HcmFudENvbGxlY3Rpb25BY2Nlc3NSZXNwb25zZSJHCh1SZXZva2VDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJEg8KB3VzZXJfaWQYAiABKAkiIAoeUmV2b2tlQ29sbGVjdGlvbkFjY2Vzc1Jlc3BvbnNlIjQKG0xpc3RDb2xsZWN0aW9uR3JhbnRzUmVxdWVzdBIVCg1jb2xsZWN0aW9uX2lkGAEgASgJIk4KHExpc3RDb2xsZWN0aW9uR3JhbnRzUmVzcG9uc2USLgoGZ3JhbnRzGAEgAygLMh4uY29udGVudGh1Yi52MS5Db2xsZWN0aW9uR3JhbnQqqwEKFUNvbGxlY3Rpb25BY2Nlc3NMZXZlbBInCiNDT0xMRUNUSU9OX0FDQ0VTU19MRVZFTF9VTlNQRUNJRklFRBAAEiIKHkNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX1ZJRVdFUhABEiIKHkNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX0VESVRPUhACEiEKHUNPTExFQ1RJT05fQUNDRVNTX0xFVkVMX09XTkVSEAMy2QcKEUNvbGxlY3Rpb25TZXJ2aWNlEmMKEENyZWF0ZUNvbGxlY3Rpb24SJi5jb250ZW50aHViLnYxLkNyZWF0ZUNvbGxlY3Rpb25SZXF1ZXN0GicuY29udGVudGh1Yi52MS5DcmVhdGVDb2xsZWN0aW9uUmVzcG9uc2USYAoPTGlzdENvbGxlY3Rpb25zEiUuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbnNSZXF1ZXN0GiYuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbnNSZXNwb25zZRJjChBSZW5hbWVDb2xsZWN0aW9uEiYuY29udGVudGh1Yi52MS5SZW5hbWVDb2xsZWN0aW9uUmVxdWVzdBonLmNvbnRlbnRodWIudjEuUmVuYW1lQ29sbGVjdGlvblJlc3BvbnNlEl0KDk1vdmVDb2xsZWN0aW9uEiQuY29udGVudGh1Yi52MS5Nb3ZlQ29sbGVjdGlvblJlcXVlc3QaJS5jb250ZW50aHViLnYxLk1vdmVDb2xsZWN0aW9uUmVzcG9uc2USYwoQUmVtb3ZlQ29sbGVjdGlvbhImLmNvbnRlbnRodWIudjEuUmVtb3ZlQ29sbGVjdGlvblJlcXVlc3QaJy5jb250ZW50aHViLnYxLlJlbW92ZUNvbGxlY3Rpb25SZXNwb25zZRJ4ChdTZXRDb2xsZWN0aW9uUmVzdHJpY3RlZBItLmNvbnRlbnRodWIudjEuU2V0Q29sbGVjdGlvblJlc3RyaWN0ZWRSZXF1ZXN0Gi4uY29udGVudGh1Yi52MS5TZXRDb2xsZWN0aW9uUmVzdHJpY3RlZFJlc3BvbnNlEnIKFUdyYW50Q29sbGVjdGlvbkFjY2VzcxIrLmNvbnRlbnRodWIudjEuR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVxdWVzdBosLmNvbnRlbnRodWIudjEuR3JhbnRDb2xsZWN0aW9uQWNjZXNzUmVzcG9uc2USdQoWUmV2b2tlQ29sbGVjdGlvbkFjY2VzcxIsLmNvbnRlbnRodWIudjEuUmV2b2tlQ29sbGVjdGlvbkFjY2Vzc1JlcXVlc3QaLS5jb250ZW50aHViLnYxLlJldm9rZUNvbGxlY3Rpb25BY2Nlc3NSZXNwb25zZRJvChRMaXN0Q29sbGVjdGlvbkdyYW50cxIqLmNvbnRlbnRodWIudjEuTGlzdENvbGxlY3Rpb25HcmFudHNSZXF1ZXN0GisuY29udGVudGh1Yi52MS5MaXN0Q29sbGVjdGlvbkdyYW50c1Jlc3BvbnNlQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_google_protobuf_timestamp]);\n\n/**\n * Collection is one node of the workspace's tree.\n *\n * @generated from message contenthub.v1.Collection\n */\nexport type Collection = Message<\"contenthub.v1.Collection\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * One line, at most 200 characters, unique among its siblings.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n\n /**\n * The Collection it sits in; empty at the root.\n *\n * @generated from field: string parent_id = 3;\n */\n parentId: string;\n\n /**\n * Whether it is a Restricted Collection (ADR 0017): the Content filed in\n * it is visible in editing only to those granted on it.\n *\n * @generated from field: bool restricted = 4;\n */\n restricted: boolean;\n\n /**\n * @generated from field: google.protobuf.Timestamp create_time = 5;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * @generated from field: google.protobuf.Timestamp update_time = 6;\n */\n updateTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Collection.\n * Use `create(CollectionSchema)` to create a new message.\n */\nexport const CollectionSchema: GenMessage<Collection> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 0);\n\n/**\n * @generated from message contenthub.v1.CreateCollectionRequest\n */\nexport type CreateCollectionRequest = Message<\"contenthub.v1.CreateCollectionRequest\"> & {\n /**\n * Required: not blank, at most 200 characters, one line. Surrounding\n * whitespace is trimmed.\n *\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * The Collection to create it in; empty for the root.\n *\n * @generated from field: string parent_id = 2;\n */\n parentId: string;\n\n /**\n * Create it as a Restricted Collection; needs `admin`.\n *\n * @generated from field: bool restricted = 3;\n */\n restricted: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.CreateCollectionRequest.\n * Use `create(CreateCollectionRequestSchema)` to create a new message.\n */\nexport const CreateCollectionRequestSchema: GenMessage<CreateCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 1);\n\n/**\n * @generated from message contenthub.v1.CreateCollectionResponse\n */\nexport type CreateCollectionResponse = Message<\"contenthub.v1.CreateCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.CreateCollectionResponse.\n * Use `create(CreateCollectionResponseSchema)` to create a new message.\n */\nexport const CreateCollectionResponseSchema: GenMessage<CreateCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 2);\n\n/**\n * @generated from message contenthub.v1.ListCollectionsRequest\n */\nexport type ListCollectionsRequest = Message<\"contenthub.v1.ListCollectionsRequest\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionsRequest.\n * Use `create(ListCollectionsRequestSchema)` to create a new message.\n */\nexport const ListCollectionsRequestSchema: GenMessage<ListCollectionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 3);\n\n/**\n * @generated from message contenthub.v1.ListCollectionsResponse\n */\nexport type ListCollectionsResponse = Message<\"contenthub.v1.ListCollectionsResponse\"> & {\n /**\n * Every Collection of the workspace, by name, then id.\n *\n * @generated from field: repeated contenthub.v1.Collection collections = 1;\n */\n collections: Collection[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionsResponse.\n * Use `create(ListCollectionsResponseSchema)` to create a new message.\n */\nexport const ListCollectionsResponseSchema: GenMessage<ListCollectionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 4);\n\n/**\n * @generated from message contenthub.v1.RenameCollectionRequest\n */\nexport type RenameCollectionRequest = Message<\"contenthub.v1.RenameCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * As CreateCollectionRequest's name.\n *\n * @generated from field: string name = 2;\n */\n name: string;\n};\n\n/**\n * Describes the message contenthub.v1.RenameCollectionRequest.\n * Use `create(RenameCollectionRequestSchema)` to create a new message.\n */\nexport const RenameCollectionRequestSchema: GenMessage<RenameCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 5);\n\n/**\n * @generated from message contenthub.v1.RenameCollectionResponse\n */\nexport type RenameCollectionResponse = Message<\"contenthub.v1.RenameCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.RenameCollectionResponse.\n * Use `create(RenameCollectionResponseSchema)` to create a new message.\n */\nexport const RenameCollectionResponseSchema: GenMessage<RenameCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 6);\n\n/**\n * @generated from message contenthub.v1.MoveCollectionRequest\n */\nexport type MoveCollectionRequest = Message<\"contenthub.v1.MoveCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Collection to move it under; empty for the root.\n *\n * @generated from field: string parent_id = 2;\n */\n parentId: string;\n};\n\n/**\n * Describes the message contenthub.v1.MoveCollectionRequest.\n * Use `create(MoveCollectionRequestSchema)` to create a new message.\n */\nexport const MoveCollectionRequestSchema: GenMessage<MoveCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 7);\n\n/**\n * @generated from message contenthub.v1.MoveCollectionResponse\n */\nexport type MoveCollectionResponse = Message<\"contenthub.v1.MoveCollectionResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.MoveCollectionResponse.\n * Use `create(MoveCollectionResponseSchema)` to create a new message.\n */\nexport const MoveCollectionResponseSchema: GenMessage<MoveCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 8);\n\n/**\n * @generated from message contenthub.v1.RemoveCollectionRequest\n */\nexport type RemoveCollectionRequest = Message<\"contenthub.v1.RemoveCollectionRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n};\n\n/**\n * Describes the message contenthub.v1.RemoveCollectionRequest.\n * Use `create(RemoveCollectionRequestSchema)` to create a new message.\n */\nexport const RemoveCollectionRequestSchema: GenMessage<RemoveCollectionRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 9);\n\n/**\n * @generated from message contenthub.v1.RemoveCollectionResponse\n */\nexport type RemoveCollectionResponse = Message<\"contenthub.v1.RemoveCollectionResponse\"> & {\n /**\n * The Content the removal unfiled, by id.\n *\n * @generated from field: repeated string unfiled_content_ids = 1;\n */\n unfiledContentIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.RemoveCollectionResponse.\n * Use `create(RemoveCollectionResponseSchema)` to create a new message.\n */\nexport const RemoveCollectionResponseSchema: GenMessage<RemoveCollectionResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 10);\n\n/**\n * @generated from message contenthub.v1.SetCollectionRestrictedRequest\n */\nexport type SetCollectionRestrictedRequest = Message<\"contenthub.v1.SetCollectionRestrictedRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: bool restricted = 2;\n */\n restricted: boolean;\n\n /**\n * Confirms that unrestricting discloses the Collection's Content to every\n * viewer. Required to unrestrict; ignored otherwise.\n *\n * @generated from field: bool acknowledge_disclosure = 3;\n */\n acknowledgeDisclosure: boolean;\n};\n\n/**\n * Describes the message contenthub.v1.SetCollectionRestrictedRequest.\n * Use `create(SetCollectionRestrictedRequestSchema)` to create a new message.\n */\nexport const SetCollectionRestrictedRequestSchema: GenMessage<SetCollectionRestrictedRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 11);\n\n/**\n * @generated from message contenthub.v1.SetCollectionRestrictedResponse\n */\nexport type SetCollectionRestrictedResponse = Message<\"contenthub.v1.SetCollectionRestrictedResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Collection collection = 1;\n */\n collection?: Collection | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetCollectionRestrictedResponse.\n * Use `create(SetCollectionRestrictedResponseSchema)` to create a new message.\n */\nexport const SetCollectionRestrictedResponseSchema: GenMessage<SetCollectionRestrictedResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 12);\n\n/**\n * CollectionGrant is one user's access to a Restricted Collection.\n *\n * @generated from message contenthub.v1.CollectionGrant\n */\nexport type CollectionGrant = Message<\"contenthub.v1.CollectionGrant\"> & {\n /**\n * @generated from field: string user_id = 1;\n */\n userId: string;\n\n /**\n * @generated from field: contenthub.v1.CollectionAccessLevel level = 2;\n */\n level: CollectionAccessLevel;\n};\n\n/**\n * Describes the message contenthub.v1.CollectionGrant.\n * Use `create(CollectionGrantSchema)` to create a new message.\n */\nexport const CollectionGrantSchema: GenMessage<CollectionGrant> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 13);\n\n/**\n * @generated from message contenthub.v1.GrantCollectionAccessRequest\n */\nexport type GrantCollectionAccessRequest = Message<\"contenthub.v1.GrantCollectionAccessRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * The grantee, a member of the workspace; may be the caller.\n *\n * @generated from field: string user_id = 2;\n */\n userId: string;\n\n /**\n * VIEWER or EDITOR.\n *\n * @generated from field: contenthub.v1.CollectionAccessLevel level = 3;\n */\n level: CollectionAccessLevel;\n};\n\n/**\n * Describes the message contenthub.v1.GrantCollectionAccessRequest.\n * Use `create(GrantCollectionAccessRequestSchema)` to create a new message.\n */\nexport const GrantCollectionAccessRequestSchema: GenMessage<GrantCollectionAccessRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 14);\n\n/**\n * @generated from message contenthub.v1.GrantCollectionAccessResponse\n */\nexport type GrantCollectionAccessResponse = Message<\"contenthub.v1.GrantCollectionAccessResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.GrantCollectionAccessResponse.\n * Use `create(GrantCollectionAccessResponseSchema)` to create a new message.\n */\nexport const GrantCollectionAccessResponseSchema: GenMessage<GrantCollectionAccessResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 15);\n\n/**\n * @generated from message contenthub.v1.RevokeCollectionAccessRequest\n */\nexport type RevokeCollectionAccessRequest = Message<\"contenthub.v1.RevokeCollectionAccessRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * @generated from field: string user_id = 2;\n */\n userId: string;\n};\n\n/**\n * Describes the message contenthub.v1.RevokeCollectionAccessRequest.\n * Use `create(RevokeCollectionAccessRequestSchema)` to create a new message.\n */\nexport const RevokeCollectionAccessRequestSchema: GenMessage<RevokeCollectionAccessRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 16);\n\n/**\n * @generated from message contenthub.v1.RevokeCollectionAccessResponse\n */\nexport type RevokeCollectionAccessResponse = Message<\"contenthub.v1.RevokeCollectionAccessResponse\"> & {\n};\n\n/**\n * Describes the message contenthub.v1.RevokeCollectionAccessResponse.\n * Use `create(RevokeCollectionAccessResponseSchema)` to create a new message.\n */\nexport const RevokeCollectionAccessResponseSchema: GenMessage<RevokeCollectionAccessResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 17);\n\n/**\n * @generated from message contenthub.v1.ListCollectionGrantsRequest\n */\nexport type ListCollectionGrantsRequest = Message<\"contenthub.v1.ListCollectionGrantsRequest\"> & {\n /**\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionGrantsRequest.\n * Use `create(ListCollectionGrantsRequestSchema)` to create a new message.\n */\nexport const ListCollectionGrantsRequestSchema: GenMessage<ListCollectionGrantsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 18);\n\n/**\n * @generated from message contenthub.v1.ListCollectionGrantsResponse\n */\nexport type ListCollectionGrantsResponse = Message<\"contenthub.v1.ListCollectionGrantsResponse\"> & {\n /**\n * Every user granted, the owner included, by user id. Unpaginated, as\n * mediahub's: grants are bounded by the workspace's members.\n *\n * @generated from field: repeated contenthub.v1.CollectionGrant grants = 1;\n */\n grants: CollectionGrant[];\n};\n\n/**\n * Describes the message contenthub.v1.ListCollectionGrantsResponse.\n * Use `create(ListCollectionGrantsResponseSchema)` to create a new message.\n */\nexport const ListCollectionGrantsResponseSchema: GenMessage<ListCollectionGrantsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_collection, 19);\n\n/**\n * CollectionAccessLevel is a level of access to a Restricted Collection.\n *\n * @generated from enum contenthub.v1.CollectionAccessLevel\n */\nexport enum CollectionAccessLevel {\n /**\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Sees the Content filed in it.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_VIEWER = 1;\n */\n VIEWER = 1,\n\n /**\n * Also saves that Content and files Content into or out of it.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_EDITOR = 2;\n */\n EDITOR = 2,\n\n /**\n * Also manages the grants. Given to whoever restricted it; never granted.\n *\n * @generated from enum value: COLLECTION_ACCESS_LEVEL_OWNER = 3;\n */\n OWNER = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.CollectionAccessLevel.\n */\nexport const CollectionAccessLevelSchema: GenEnum<CollectionAccessLevel> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_collection, 0);\n\n/**\n * CollectionService manages a workspace's Collection tree (ADR 0015): the\n * Collections editors file Content in. A Collection is editorial organisation,\n * never versioned and never released (CONTEXT.md); filing Content into\n * Collections is ContentService's SetContentCollections, and narrowing a list\n * by one is ListContents' filter.\n *\n * Every RPC acts in the caller's workspace, from the token. Reading the tree\n * needs `viewer`, editing it `editor` (ADR 0017). Tree edits announce no\n * Event (ADR 0016), except that removing a Collection changes the filing of\n * the Content in it, which is announced per Content.\n *\n * A Restricted Collection (ADR 0017) hides the Content filed in it from\n * everyone in editing but those granted on it: `owner → editor → viewer` on\n * `contenthub/collection:<id>` in Guardian. Only a workspace `admin` creates\n * one or toggles restriction, and its owner (whoever restricted it) or a\n * workspace `admin` manages its grants, as mediahub's GrantService does. An\n * admin is granted nothing by being admin: they see Restricted Content only\n * by granting themselves, which is announced like any grant (ADR 0017's\n * 2026-10-03 amendment). In `authz.mode: workspace` every restriction and\n * grant is FailedPrecondition, since nothing could enforce it, with a\n * GuardianModeRequired detail whose feature is \"collection_restriction\".\n *\n * The tree itself, names included, stays visible to every viewer: a\n * restriction hides the Content filed in a Collection, not the Collection.\n *\n * @generated from service contenthub.v1.CollectionService\n */\nexport const CollectionService: GenService<{\n /**\n * CreateCollection creates a Collection at the root of the tree, or inside\n * parent_id. A sibling of the same name is AlreadyExists. Creating it\n * restricted needs `admin`, makes the caller its owner and publishes\n * contenthub.collection.restricted.\n *\n * @generated from rpc contenthub.v1.CollectionService.CreateCollection\n */\n createCollection: {\n methodKind: \"unary\";\n input: typeof CreateCollectionRequestSchema;\n output: typeof CreateCollectionResponseSchema;\n },\n /**\n * ListCollections returns the whole tree, every Collection with its\n * parent, ordered by name. A workspace's tree is small enough to draw at\n * once.\n *\n * @generated from rpc contenthub.v1.CollectionService.ListCollections\n */\n listCollections: {\n methodKind: \"unary\";\n input: typeof ListCollectionsRequestSchema;\n output: typeof ListCollectionsResponseSchema;\n },\n /**\n * RenameCollection renames a Collection, keeping its id, its place and\n * what is filed in it. A sibling of the new name is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.CollectionService.RenameCollection\n */\n renameCollection: {\n methodKind: \"unary\";\n input: typeof RenameCollectionRequestSchema;\n output: typeof RenameCollectionResponseSchema;\n },\n /**\n * MoveCollection moves a Collection, with everything under it, to the\n * root or under another Collection. A move under itself or anything under\n * it would make a cycle and is InvalidArgument; a sibling of the same name\n * at the destination is AlreadyExists.\n *\n * @generated from rpc contenthub.v1.CollectionService.MoveCollection\n */\n moveCollection: {\n methodKind: \"unary\";\n input: typeof MoveCollectionRequestSchema;\n output: typeof MoveCollectionResponseSchema;\n },\n /**\n * RemoveCollection removes a Collection and unfiles the Content filed in\n * it. The Content itself is untouched: no Revision, no Change Set, and it\n * stays in its other Collections. Each Content it unfiles is announced\n * with contenthub.content.collections_changed. A Collection with\n * Collections under it is FailedPrecondition: remove or move those first,\n * so that one call never removes a whole subtree by accident.\n *\n * @generated from rpc contenthub.v1.CollectionService.RemoveCollection\n */\n removeCollection: {\n methodKind: \"unary\";\n input: typeof RemoveCollectionRequestSchema;\n output: typeof RemoveCollectionResponseSchema;\n },\n /**\n * SetCollectionRestricted restricts a Collection, or opens a Restricted\n * one again; `admin` only. Restricting makes the caller its owner and\n * publishes contenthub.collection.restricted. Unrestricting discloses its\n * Content to every viewer, so it must be confirmed with\n * acknowledge_disclosure, or it is FailedPrecondition; it publishes\n * contenthub.collection.unrestricted. Setting what is already set changes\n * and announces nothing.\n *\n * @generated from rpc contenthub.v1.CollectionService.SetCollectionRestricted\n */\n setCollectionRestricted: {\n methodKind: \"unary\";\n input: typeof SetCollectionRestrictedRequestSchema;\n output: typeof SetCollectionRestrictedResponseSchema;\n },\n /**\n * GrantCollectionAccess grants a member of the workspace viewer or editor\n * on a Restricted Collection, replacing what they held there. It needs the\n * Collection's owner or a workspace `admin`, who may grant themselves\n * (break-glass). An open Collection takes no grants (FailedPrecondition);\n * a grantee who is not a member is InvalidArgument. It publishes\n * contenthub.collection.access_granted.\n *\n * @generated from rpc contenthub.v1.CollectionService.GrantCollectionAccess\n */\n grantCollectionAccess: {\n methodKind: \"unary\";\n input: typeof GrantCollectionAccessRequestSchema;\n output: typeof GrantCollectionAccessResponseSchema;\n },\n /**\n * RevokeCollectionAccess takes a user's grant on a Restricted Collection,\n * whatever its level; revoking one who holds none succeeds. The owner\n * stays owner. Who may call it is as for GrantCollectionAccess. It\n * publishes contenthub.collection.access_revoked.\n *\n * @generated from rpc contenthub.v1.CollectionService.RevokeCollectionAccess\n */\n revokeCollectionAccess: {\n methodKind: \"unary\";\n input: typeof RevokeCollectionAccessRequestSchema;\n output: typeof RevokeCollectionAccessResponseSchema;\n },\n /**\n * ListCollectionGrants reads who is granted on a Restricted Collection,\n * its owner included. A grantee sees the Content, never the roster: it\n * needs the owner or a workspace `admin`.\n *\n * @generated from rpc contenthub.v1.CollectionService.ListCollectionGrants\n */\n listCollectionGrants: {\n methodKind: \"unary\";\n input: typeof ListCollectionGrantsRequestSchema;\n output: typeof ListCollectionGrantsResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_collection, 0);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/revision.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp, Value } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_struct, file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/revision.proto.\n */\nexport const file_contenthub_v1_revision: GenFile = /*@__PURE__*/\n fileDesc(\"Chxjb250ZW50aHViL3YxL3JldmlzaW9uLnByb3RvEg1jb250ZW50aHViLnYxInIKFExpc3RSZXZpc2lvbnNSZXF1ZXN0EhQKCmNvbnRlbnRfaWQYASABKAlIABITCglicmFuY2hfaWQYAiABKAlIABIRCglwYWdlX3NpemUYAyABKAUSEgoKcGFnZV90b2tlbhgEIAEoCUIICgZ0YXJnZXQiXAoVTGlzdFJldmlzaW9uc1Jlc3BvbnNlEioKCXJldmlzaW9ucxgBIAMoCzIXLmNvbnRlbnRodWIudjEuUmV2aXNpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIo0CCghSZXZpc2lvbhIKCgJpZBgBIAEoCRISCgpjb250ZW50X2lkGAIgASgJEhEKCXBhcmVudF9pZBgDIAEoCRIYChBzZWNvbmRfcGFyZW50X2lkGAQgASgJEhwKFGJsdWVwcmludF9yZWxlYXNlX2lkGAUgASgJEi8KC2NyZWF0ZV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIOCgZhdXRob3IYByABKAkSKwoFY2F1c2UYCCABKA4yHC5jb250ZW50aHViLnYxLlJldmlzaW9uQ2F1c2USEQoJYnJhbmNoX2lkGAkgASgJEhUKDWNoYW5nZV9zZXRfaWQYCiABKAkiewoOQ29tcGFyZVJlcXVlc3QSEwoLcmV2aXNpb25faWQYASABKAkSGgoQYmFzZV9yZXZpc2lvbl9pZBgCIAEoCUgAEhsKEWZvcmtfb2ZfYnJhbmNoX2lkGAMgASgJSAASEwoJbWFpbl9oZWFkGAQgASgISABCBgoEYmFzZSKQAQoPQ29tcGFyZVJlc3BvbnNlEiUKBGJhc2UYASABKAsyFy5jb250ZW50aHViLnYxLlJldmlzaW9uEikKCHJldmlzaW9uGAIgASgLMhcuY29udGVudGh1Yi52MS5SZXZpc2lvbhIrCgdjaGFuZ2VzGAMgAygLMhouY29udGVudGh1Yi52MS5GaWVsZENoYW5nZSL1AQoLRmllbGRDaGFuZ2USDAoEcGF0aBgBIAEoCRIsCgRraW5kGAIgASgOMh4uY29udGVudGh1Yi52MS5GaWVsZENoYW5nZUtpbmQSJgoGYmVmb3JlGAMgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEiUKBWFmdGVyGAQgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEhkKEWJlZm9yZV9maWVsZF90eXBlGAUgASgJEhgKEGFmdGVyX2ZpZWxkX3R5cGUYBiABKAkSJgoGZGV0YWlsGAcgASgLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlKrUBCg1SZXZpc2lvbkNhdXNlEh4KGlJFVklTSU9OX0NBVVNFX1VOU1BFQ0lGSUVEEAASGQoVUkVWSVNJT05fQ0FVU0VfQ1JFQVRFEAESFwoTUkVWSVNJT05fQ0FVU0VfU0FWRRACEhgKFFJFVklTSU9OX0NBVVNFX01FUkdFEAMSGgoWUkVWSVNJT05fQ0FVU0VfUkVTT0xWRRAEEhoKFlJFVklTSU9OX0NBVVNFX1VQR1JBREUQBSqPAQoPRmllbGRDaGFuZ2VLaW5kEiEKHUZJRUxEX0NIQU5HRV9LSU5EX1VOU1BFQ0lGSUVEEAASGwoXRklFTERfQ0hBTkdFX0tJTkRfQURERUQQARIdChlGSUVMRF9DSEFOR0VfS0lORF9SRU1PVkVEEAISHQoZRklFTERfQ0hBTkdFX0tJTkRfQ0hBTkdFRBADQjxaOmdpdGh1Yi5jb20va25rY3MvY29udGVudGh1Yi9nZW4vY29udGVudGh1Yi92MTtjb250ZW50aHVidjFiBnByb3RvMw\", [file_google_protobuf_struct, file_google_protobuf_timestamp]);\n\n/**\n * @generated from message contenthub.v1.ListRevisionsRequest\n */\nexport type ListRevisionsRequest = Message<\"contenthub.v1.ListRevisionsRequest\"> & {\n /**\n * Whose Revisions to list.\n *\n * @generated from oneof contenthub.v1.ListRevisionsRequest.target\n */\n target: {\n /**\n * Every Revision of the Content, on every Branch it was written on. The\n * Content must be published: Content born in an open Change Set exists\n * only inside it, so its Revisions are listed by its Branch.\n *\n * @generated from field: string content_id = 1;\n */\n value: string;\n case: \"contentId\";\n } | {\n /**\n * The Revisions written on this Branch, a link of a Chain. A Branch\n * that ended with a published Change Set still lists them; one whose\n * born Content vanished with a discard is NotFound, as every read of\n * that Content is.\n *\n * @generated from field: string branch_id = 2;\n */\n value: string;\n case: \"branchId\";\n } | { case: undefined; value?: undefined };\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRevisionsRequest.\n * Use `create(ListRevisionsRequestSchema)` to create a new message.\n */\nexport const ListRevisionsRequestSchema: GenMessage<ListRevisionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 0);\n\n/**\n * @generated from message contenthub.v1.ListRevisionsResponse\n */\nexport type ListRevisionsResponse = Message<\"contenthub.v1.ListRevisionsResponse\"> & {\n /**\n * Newest first.\n *\n * @generated from field: repeated contenthub.v1.Revision revisions = 1;\n */\n revisions: Revision[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListRevisionsResponse.\n * Use `create(ListRevisionsResponseSchema)` to create a new message.\n */\nexport const ListRevisionsResponseSchema: GenMessage<ListRevisionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 1);\n\n/**\n * Revision is one immutable Revision of a Content, without its data: who\n * wrote it, when, why, and where.\n *\n * @generated from message contenthub.v1.Revision\n */\nexport type Revision = Message<\"contenthub.v1.Revision\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * @generated from field: string content_id = 2;\n */\n contentId: string;\n\n /**\n * The Revision it was built on; empty for the Content's first.\n *\n * @generated from field: string parent_id = 3;\n */\n parentId: string;\n\n /**\n * The other side of a merge Revision; empty otherwise.\n *\n * @generated from field: string second_parent_id = 4;\n */\n secondParentId: string;\n\n /**\n * The Blueprint Release it pins.\n *\n * @generated from field: string blueprint_release_id = 5;\n */\n blueprintReleaseId: string;\n\n /**\n * When it was written.\n *\n * @generated from field: google.protobuf.Timestamp create_time = 6;\n */\n createTime?: Timestamp | undefined;\n\n /**\n * The token subject of who wrote it.\n *\n * @generated from field: string author = 7;\n */\n author: string;\n\n /**\n * @generated from field: contenthub.v1.RevisionCause cause = 8;\n */\n cause: RevisionCause;\n\n /**\n * The Branch it was written on, and that Branch's Change Set.\n *\n * @generated from field: string branch_id = 9;\n */\n branchId: string;\n\n /**\n * @generated from field: string change_set_id = 10;\n */\n changeSetId: string;\n};\n\n/**\n * Describes the message contenthub.v1.Revision.\n * Use `create(RevisionSchema)` to create a new message.\n */\nexport const RevisionSchema: GenMessage<Revision> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 2);\n\n/**\n * CompareRequest names two Revisions of one Content: revision_id, whose\n * changes are reported, and a base it is compared against.\n *\n * @generated from message contenthub.v1.CompareRequest\n */\nexport type CompareRequest = Message<\"contenthub.v1.CompareRequest\"> & {\n /**\n * The after side.\n *\n * @generated from field: string revision_id = 1;\n */\n revisionId: string;\n\n /**\n * The before side. One is required.\n *\n * @generated from oneof contenthub.v1.CompareRequest.base\n */\n base: {\n /**\n * Any other Revision of the same Content.\n *\n * @generated from field: string base_revision_id = 2;\n */\n value: string;\n case: \"baseRevisionId\";\n } | {\n /**\n * The Revision this Branch of the same Content forked from, as review\n * compares it: what the Branch last took from upstream (its Main, a\n * dependency's Branch or the previous link), or on a Chain on Dated\n * Content the Revision of the Release the link carries. Content born in\n * its Change Set has no fork: FailedPrecondition.\n *\n * @generated from field: string fork_of_branch_id = 3;\n */\n value: string;\n case: \"forkOfBranchId\";\n } | {\n /**\n * The head of the Content's Main Branch; must be true. Content not\n * published yet has no Main Branch: FailedPrecondition.\n *\n * @generated from field: bool main_head = 4;\n */\n value: boolean;\n case: \"mainHead\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message contenthub.v1.CompareRequest.\n * Use `create(CompareRequestSchema)` to create a new message.\n */\nexport const CompareRequestSchema: GenMessage<CompareRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 3);\n\n/**\n * @generated from message contenthub.v1.CompareResponse\n */\nexport type CompareResponse = Message<\"contenthub.v1.CompareResponse\"> & {\n /**\n * The before side, as resolved from the request's base.\n *\n * @generated from field: contenthub.v1.Revision base = 1;\n */\n base?: Revision | undefined;\n\n /**\n * The after side.\n *\n * @generated from field: contenthub.v1.Revision revision = 2;\n */\n revision?: Revision | undefined;\n\n /**\n * The fields that differ, in the after side's Blueprint order, then those\n * only the before side's declares, then data no Blueprint declares. An\n * unchanged field is left out.\n *\n * @generated from field: repeated contenthub.v1.FieldChange changes = 3;\n */\n changes: FieldChange[];\n};\n\n/**\n * Describes the message contenthub.v1.CompareResponse.\n * Use `create(CompareResponseSchema)` to create a new message.\n */\nexport const CompareResponseSchema: GenMessage<CompareResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 4);\n\n/**\n * FieldChange is one field that differs between two Revisions.\n *\n * @generated from message contenthub.v1.FieldChange\n */\nexport type FieldChange = Message<\"contenthub.v1.FieldChange\"> & {\n /**\n * The field's path from the data's root, as a Violation's path is spelled:\n * \"/\" and its accessor.\n *\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from field: contenthub.v1.FieldChangeKind kind = 2;\n */\n kind: FieldChangeKind;\n\n /**\n * The value in the base and in the revision; unset on the side that\n * doesn't hold the field.\n *\n * @generated from field: google.protobuf.Value before = 3;\n */\n before?: Value | undefined;\n\n /**\n * @generated from field: google.protobuf.Value after = 4;\n */\n after?: Value | undefined;\n\n /**\n * The field's type under each side's Blueprint Release; empty on a side\n * whose Release doesn't declare it.\n *\n * @generated from field: string before_field_type = 5;\n */\n beforeFieldType: string;\n\n /**\n * @generated from field: string after_field_type = 6;\n */\n afterFieldType: string;\n\n /**\n * How the value changed within, for a type that compares finer than a\n * whole value (rows, a record, references, rich text): fieldkit's\n * CompareDetail as it comes. Unset otherwise, and on a type change.\n *\n * @generated from field: google.protobuf.Value detail = 7;\n */\n detail?: Value | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.FieldChange.\n * Use `create(FieldChangeSchema)` to create a new message.\n */\nexport const FieldChangeSchema: GenMessage<FieldChange> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_revision, 5);\n\n/**\n * RevisionCause is why a Revision was written: the cause of the head move it\n * made, as contenthub.branch.head_moved names it. A Branch started on an\n * existing Revision writes none, so `start` is not a cause here.\n *\n * @generated from enum contenthub.v1.RevisionCause\n */\nexport enum RevisionCause {\n /**\n * Not recorded.\n *\n * @generated from enum value: REVISION_CAUSE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * The Content's first Revision (CreateContent).\n *\n * @generated from enum value: REVISION_CAUSE_CREATE = 1;\n */\n CREATE = 1,\n\n /**\n * A save on a Branch (SaveRevision).\n *\n * @generated from enum value: REVISION_CAUSE_SAVE = 2;\n */\n SAVE = 2,\n\n /**\n * A clean merge written by Update from Main.\n *\n * @generated from enum value: REVISION_CAUSE_MERGE = 3;\n */\n MERGE = 3,\n\n /**\n * A merge whose Conflicts the editor resolved.\n *\n * @generated from enum value: REVISION_CAUSE_RESOLVE = 4;\n */\n RESOLVE = 4,\n\n /**\n * A move to a newer Blueprint Release (UpgradeContent).\n *\n * @generated from enum value: REVISION_CAUSE_UPGRADE = 5;\n */\n UPGRADE = 5,\n}\n\n/**\n * Describes the enum contenthub.v1.RevisionCause.\n */\nexport const RevisionCauseSchema: GenEnum<RevisionCause> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_revision, 0);\n\n/**\n * @generated from enum contenthub.v1.FieldChangeKind\n */\nexport enum FieldChangeKind {\n /**\n * @generated from enum value: FIELD_CHANGE_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * Only the revision holds the field.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_ADDED = 1;\n */\n ADDED = 1,\n\n /**\n * Only the base holds the field.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_REMOVED = 2;\n */\n REMOVED = 2,\n\n /**\n * Both hold it with different values, or its type changed.\n *\n * @generated from enum value: FIELD_CHANGE_KIND_CHANGED = 3;\n */\n CHANGED = 3,\n}\n\n/**\n * Describes the enum contenthub.v1.FieldChangeKind.\n */\nexport const FieldChangeKindSchema: GenEnum<FieldChangeKind> = /*@__PURE__*/\n enumDesc(file_contenthub_v1_revision, 1);\n\n","// @generated by protoc-gen-es v2.13.0 with parameter \"target=ts\"\n// @generated from file contenthub/v1/content.proto (package contenthub.v1, syntax proto3)\n/* eslint-disable */\n\nimport type { GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { ChangeSet, ChangeSetState, Content } from \"./change_set_pb\";\nimport { file_contenthub_v1_change_set } from \"./change_set_pb\";\nimport type { InForceAt, ListReferencesRequestSchema, ListReferencesResponseSchema, ListReferrersRequestSchema, ListReferrersResponseSchema } from \"./content_graph_pb\";\nimport { file_contenthub_v1_content_graph } from \"./content_graph_pb\";\nimport type { ListOutdatedPinsRequestSchema, ListOutdatedPinsResponseSchema } from \"./graph_warnings_pb\";\nimport { file_contenthub_v1_graph_warnings } from \"./graph_warnings_pb\";\nimport type { GetReleasesRequestSchema, GetReleasesResponseSchema, GetTimelineRequestSchema, GetTimelineResponseSchema } from \"./release_read_pb\";\nimport { file_contenthub_v1_release_read } from \"./release_read_pb\";\nimport type { CompareRequestSchema, CompareResponseSchema, ListRevisionsRequestSchema, ListRevisionsResponseSchema } from \"./revision_pb\";\nimport { file_contenthub_v1_revision } from \"./revision_pb\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file contenthub/v1/content.proto.\n */\nexport const file_contenthub_v1_content: GenFile = /*@__PURE__*/\n fileDesc(\"Chtjb250ZW50aHViL3YxL2NvbnRlbnQucHJvdG8SDWNvbnRlbnRodWIudjEiSQoRR2V0Q29udGVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNY2hhbmdlX3NldF9pZBgCIAEoCRIRCglicmFuY2hfaWQYAyABKAkijQEKEkdldENvbnRlbnRSZXNwb25zZRInCgdjb250ZW50GAEgASgLMhYuY29udGVudGh1Yi52MS5Db250ZW50EhgKEHJlc29sdmVkX3JlbGVhc2UYAiABKAwSNAoKYXR0cmlidXRlcxgDIAEoCzIgLmNvbnRlbnRodWIudjEuQ29udGVudEF0dHJpYnV0ZXMimAEKEUNvbnRlbnRBdHRyaWJ1dGVzEhYKDmNvbGxlY3Rpb25faWRzGAEgAygJEhQKDGFzc2lnbmVlX2lkcxgCIAMoCRIjCgVibG9jaxgDIAEoCzIULmNvbnRlbnRodWIudjEuQmxvY2sSMAoMYXJjaGl2ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJ+CgVCbG9jaxIXCg9ibG9ja19yZWFzb25faWQYASABKAkSGAoQYWxsb3dlZF91c2VyX2lkcxgCIAMoCRISCgpibG9ja2VkX2J5GAMgASgJEi4KCmJsb2NrX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIpUBChVMaXN0Q2hhbmdlU2V0c1JlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIsCgVzdGF0ZRgCIAEoDjIdLmNvbnRlbnRodWIudjEuQ2hhbmdlU2V0U3RhdGUSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkSEwoLYXNzaWduZWVfaWQYBSABKAkiuQEKE0xpc3RDb250ZW50c1JlcXVlc3QSLAoGZmlsdGVyGAEgASgLMhwuY29udGVudGh1Yi52MS5Db250ZW50RmlsdGVyEhcKDWNoYW5nZV9zZXRfaWQYAiABKAlIABIsCghpbl9mb3JjZRgFIAEoCzIYLmNvbnRlbnRodWIudjEuSW5Gb3JjZUF0SAASEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAlCBgoEdmlldyJ8Cg1Db250ZW50RmlsdGVyEhUKDWNvbGxlY3Rpb25faWQYASABKAkSDgoGc2VhcmNoGAIgASgJEhMKC2Fzc2lnbmVlX2lkGAMgASgJEhgKEGluY2x1ZGVfYXJjaGl2ZWQYBCABKAgSFQoNYmx1ZXByaW50X2lkcxgFIAMoCSJZChRMaXN0Q29udGVudHNSZXNwb25zZRIoCghjb250ZW50cxgBIAMoCzIWLmNvbnRlbnRodWIudjEuQ29udGVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiYwocU2V0Q29udGVudENvbGxlY3Rpb25zUmVxdWVzdBISCgpjb250ZW50X2lkGAEgASgJEhYKDmNvbGxlY3Rpb25faWRzGAIgAygJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJLCh1TZXRDb250ZW50Q29sbGVjdGlvbnNSZXNwb25zZRISCgpjb250ZW50X2lkGAEgASgJEhYKDmNvbGxlY3Rpb25faWRzGAIgAygJIl8KGlNldENvbnRlbnRBc3NpZ25lZXNSZXF1ZXN0EhIKCmNvbnRlbnRfaWQYASABKAkSFAoMYXNzaWduZWVfaWRzGAIgAygJEhcKD2lkZW1wb3RlbmN5X2tleRgDIAEoCSJnChtTZXRDb250ZW50QXNzaWduZWVzUmVzcG9uc2USEgoKY29udGVudF9pZBgBIAEoCRI0CgphdHRyaWJ1dGVzGAIgASgLMiAuY29udGVudGh1Yi52MS5Db250ZW50QXR0cmlidXRlcyJ1ChNCbG9ja0NvbnRlbnRSZXF1ZXN0EhIKCmNvbnRlbnRfaWQYASABKAkSFwoPYmxvY2tfcmVhc29uX2lkGAIgASgJEhgKEGFsbG93ZWRfdXNlcl9pZHMYAyADKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAQgASgJImAKFEJsb2NrQ29udGVudFJlc3BvbnNlEhIKCmNvbnRlbnRfaWQYASABKAkSNAoKYXR0cmlidXRlcxgCIAEoCzIgLmNvbnRlbnRodWIudjEuQ29udGVudEF0dHJpYnV0ZXMiRAoVVW5ibG9ja0NvbnRlbnRSZXF1ZXN0EhIKCmNvbnRlbnRfaWQYASABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAIgASgJImIKFlVuYmxvY2tDb250ZW50UmVzcG9uc2USEgoKY29udGVudF9pZBgBIAEoCRI0CgphdHRyaWJ1dGVzGAIgASgLMiAuY29udGVudGh1Yi52MS5Db250ZW50QXR0cmlidXRlcyJEChVBcmNoaXZlQ29udGVudFJlcXVlc3QSEgoKY29udGVudF9pZBgBIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYAiABKAkiYgoWQXJjaGl2ZUNvbnRlbnRSZXNwb25zZRISCgpjb250ZW50X2lkGAEgASgJEjQKCmF0dHJpYnV0ZXMYAiABKAsyIC5jb250ZW50aHViLnYxLkNvbnRlbnRBdHRyaWJ1dGVzIkYKF1VuYXJjaGl2ZUNvbnRlbnRSZXF1ZXN0EhIKCmNvbnRlbnRfaWQYASABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAIgASgJImQKGFVuYXJjaGl2ZUNvbnRlbnRSZXNwb25zZRISCgpjb250ZW50X2lkGAEgASgJEjQKCmF0dHJpYnV0ZXMYAiABKAsyIC5jb250ZW50aHViLnYxLkNvbnRlbnRBdHRyaWJ1dGVzIj0KDkNvbnRlbnRCbG9ja2VkEhIKCmNvbnRlbnRfaWQYASABKAkSFwoPYmxvY2tfcmVhc29uX2lkGAIgASgJIiUKD0NvbnRlbnRBcmNoaXZlZBISCgpjb250ZW50X2lkGAEgASgJImAKFkxpc3RDaGFuZ2VTZXRzUmVzcG9uc2USLQoLY2hhbmdlX3NldHMYASADKAsyGC5jb250ZW50aHViLnYxLkNoYW5nZVNldBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAky6wsKDkNvbnRlbnRTZXJ2aWNlElEKCkdldENvbnRlbnQSIC5jb250ZW50aHViLnYxLkdldENvbnRlbnRSZXF1ZXN0GiEuY29udGVudGh1Yi52MS5HZXRDb250ZW50UmVzcG9uc2USXQoOTGlzdENoYW5nZVNldHMSJC5jb250ZW50aHViLnYxLkxpc3RDaGFuZ2VTZXRzUmVxdWVzdBolLmNvbnRlbnRodWIudjEuTGlzdENoYW5nZVNldHNSZXNwb25zZRJXCgxMaXN0Q29udGVudHMSIi5jb250ZW50aHViLnYxLkxpc3RDb250ZW50c1JlcXVlc3QaIy5jb250ZW50aHViLnYxLkxpc3RDb250ZW50c1Jlc3BvbnNlEnIKFVNldENvbnRlbnRDb2xsZWN0aW9ucxIrLmNvbnRlbnRodWIudjEuU2V0Q29udGVudENvbGxlY3Rpb25zUmVxdWVzdBosLmNvbnRlbnRodWIudjEuU2V0Q29udGVudENvbGxlY3Rpb25zUmVzcG9uc2USbAoTU2V0Q29udGVudEFzc2lnbmVlcxIpLmNvbnRlbnRodWIudjEuU2V0Q29udGVudEFzc2lnbmVlc1JlcXVlc3QaKi5jb250ZW50aHViLnYxLlNldENvbnRlbnRBc3NpZ25lZXNSZXNwb25zZRJXCgxCbG9ja0NvbnRlbnQSIi5jb250ZW50aHViLnYxLkJsb2NrQ29udGVudFJlcXVlc3QaIy5jb250ZW50aHViLnYxLkJsb2NrQ29udGVudFJlc3BvbnNlEl0KDlVuYmxvY2tDb250ZW50EiQuY29udGVudGh1Yi52MS5VbmJsb2NrQ29udGVudFJlcXVlc3QaJS5jb250ZW50aHViLnYxLlVuYmxvY2tDb250ZW50UmVzcG9uc2USXQoOQXJjaGl2ZUNvbnRlbnQSJC5jb250ZW50aHViLnYxLkFyY2hpdmVDb250ZW50UmVxdWVzdBolLmNvbnRlbnRodWIudjEuQXJjaGl2ZUNvbnRlbnRSZXNwb25zZRJjChBVbmFyY2hpdmVDb250ZW50EiYuY29udGVudGh1Yi52MS5VbmFyY2hpdmVDb250ZW50UmVxdWVzdBonLmNvbnRlbnRodWIudjEuVW5hcmNoaXZlQ29udGVudFJlc3BvbnNlEl0KDkxpc3RSZWZlcmVuY2VzEiQuY29udGVudGh1Yi52MS5MaXN0UmVmZXJlbmNlc1JlcXVlc3QaJS5jb250ZW50aHViLnYxLkxpc3RSZWZlcmVuY2VzUmVzcG9uc2USWgoNTGlzdFJlZmVycmVycxIjLmNvbnRlbnRodWIudjEuTGlzdFJlZmVycmVyc1JlcXVlc3QaJC5jb250ZW50aHViLnYxLkxpc3RSZWZlcnJlcnNSZXNwb25zZRJjChBMaXN0T3V0ZGF0ZWRQaW5zEiYuY29udGVudGh1Yi52MS5MaXN0T3V0ZGF0ZWRQaW5zUmVxdWVzdBonLmNvbnRlbnRodWIudjEuTGlzdE91dGRhdGVkUGluc1Jlc3BvbnNlElQKC0dldFJlbGVhc2VzEiEuY29udGVudGh1Yi52MS5HZXRSZWxlYXNlc1JlcXVlc3QaIi5jb250ZW50aHViLnYxLkdldFJlbGVhc2VzUmVzcG9uc2USVAoLR2V0VGltZWxpbmUSIS5jb250ZW50aHViLnYxLkdldFRpbWVsaW5lUmVxdWVzdBoiLmNvbnRlbnRodWIudjEuR2V0VGltZWxpbmVSZXNwb25zZRJaCg1MaXN0UmV2aXNpb25zEiMuY29udGVudGh1Yi52MS5MaXN0UmV2aXNpb25zUmVxdWVzdBokLmNvbnRlbnRodWIudjEuTGlzdFJldmlzaW9uc1Jlc3BvbnNlEkgKB0NvbXBhcmUSHS5jb250ZW50aHViLnYxLkNvbXBhcmVSZXF1ZXN0Gh4uY29udGVudGh1Yi52MS5Db21wYXJlUmVzcG9uc2VCPFo6Z2l0aHViLmNvbS9rbmtjcy9jb250ZW50aHViL2dlbi9jb250ZW50aHViL3YxO2NvbnRlbnRodWJ2MWIGcHJvdG8z\", [file_contenthub_v1_change_set, file_contenthub_v1_content_graph, file_contenthub_v1_graph_warnings, file_contenthub_v1_release_read, file_contenthub_v1_revision, file_google_protobuf_timestamp]);\n\n/**\n * @generated from message contenthub.v1.GetContentRequest\n */\nexport type GetContentRequest = Message<\"contenthub.v1.GetContentRequest\"> & {\n /**\n * @generated from field: string id = 1;\n */\n id: string;\n\n /**\n * The Change Set to read the Content in; empty reads it on Main.\n *\n * @generated from field: string change_set_id = 2;\n */\n changeSetId: string;\n\n /**\n * The Branch of the Content's Chain in change_set_id to read, at its head;\n * empty reads the Chain's last Branch. An earlier Branch of a multi-Branch\n * Chain is read here at its own head (#252). Needs change_set_id; a Branch\n * that isn't in the Content's Chain there is NotFound.\n *\n * @generated from field: string branch_id = 3;\n */\n branchId: string;\n};\n\n/**\n * Describes the message contenthub.v1.GetContentRequest.\n * Use `create(GetContentRequestSchema)` to create a new message.\n */\nexport const GetContentRequestSchema: GenMessage<GetContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 0);\n\n/**\n * @generated from message contenthub.v1.GetContentResponse\n */\nexport type GetContentResponse = Message<\"contenthub.v1.GetContentResponse\"> & {\n /**\n * @generated from field: contenthub.v1.Content content = 1;\n */\n content?: Content | undefined;\n\n /**\n * The Resolved Release of content.blueprint_release_id, byte for byte as\n * blueprinthub served it when contenthub loaded it.\n *\n * @generated from field: bytes resolved_release = 2;\n */\n resolvedRelease: Uint8Array;\n\n /**\n * The Content's unversioned attributes: the same wherever it is read,\n * since they belong to the Content and not to a Revision.\n *\n * @generated from field: contenthub.v1.ContentAttributes attributes = 3;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.GetContentResponse.\n * Use `create(GetContentResponseSchema)` to create a new message.\n */\nexport const GetContentResponseSchema: GenMessage<GetContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 1);\n\n/**\n * ContentAttributes are a Content's unversioned attributes (ADR 0015).\n *\n * @generated from message contenthub.v1.ContentAttributes\n */\nexport type ContentAttributes = Message<\"contenthub.v1.ContentAttributes\"> & {\n /**\n * The Collections it is filed in, by id, in id order.\n *\n * @generated from field: repeated string collection_ids = 1;\n */\n collectionIds: string[];\n\n /**\n * Who maintains it: odon user ids, in the order they were set.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Its Block; absent while it is not blocked.\n *\n * @generated from field: contenthub.v1.Block block = 3;\n */\n block?: Block | undefined;\n\n /**\n * When it was archived; absent while it is not Archived.\n *\n * @generated from field: google.protobuf.Timestamp archive_time = 4;\n */\n archiveTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ContentAttributes.\n * Use `create(ContentAttributesSchema)` to create a new message.\n */\nexport const ContentAttributesSchema: GenMessage<ContentAttributes> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 2);\n\n/**\n * Block is a Content's Block (CONTEXT.md).\n *\n * @generated from message contenthub.v1.Block\n */\nexport type Block = Message<\"contenthub.v1.Block\"> & {\n /**\n * @generated from field: string block_reason_id = 1;\n */\n blockReasonId: string;\n\n /**\n * Who may still edit it; empty is nobody.\n *\n * @generated from field: repeated string allowed_user_ids = 2;\n */\n allowedUserIds: string[];\n\n /**\n * The odon user who set it, and when.\n *\n * @generated from field: string blocked_by = 3;\n */\n blockedBy: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp block_time = 4;\n */\n blockTime?: Timestamp | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.Block.\n * Use `create(BlockSchema)` to create a new message.\n */\nexport const BlockSchema: GenMessage<Block> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 3);\n\n/**\n * @generated from message contenthub.v1.ListChangeSetsRequest\n */\nexport type ListChangeSetsRequest = Message<\"contenthub.v1.ListChangeSetsRequest\"> & {\n /**\n * Only Change Sets with a Chain on this Content; empty for all.\n *\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Only Change Sets in this state; unspecified for all.\n *\n * @generated from field: contenthub.v1.ChangeSetState state = 2;\n */\n state: ChangeSetState;\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n\n /**\n * Only Change Sets this odon user is assigned to; empty for all.\n *\n * @generated from field: string assignee_id = 5;\n */\n assigneeId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListChangeSetsRequest.\n * Use `create(ListChangeSetsRequestSchema)` to create a new message.\n */\nexport const ListChangeSetsRequestSchema: GenMessage<ListChangeSetsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 4);\n\n/**\n * @generated from message contenthub.v1.ListContentsRequest\n */\nexport type ListContentsRequest = Message<\"contenthub.v1.ListContentsRequest\"> & {\n /**\n * Narrows the list; the zero filter keeps all.\n *\n * @generated from field: contenthub.v1.ContentFilter filter = 1;\n */\n filter?: ContentFilter | undefined;\n\n /**\n * Where each Content is read. Unset reads Main: the Content that has been\n * published, at its Main head.\n *\n * @generated from oneof contenthub.v1.ListContentsRequest.view\n */\n view: {\n /**\n * Reads the Content with a Chain in this Change Set, at the head of its\n * Chain's last Branch, as GetContent with this change_set_id does.\n *\n * @generated from field: string change_set_id = 2;\n */\n value: string;\n case: \"changeSetId\";\n } | {\n /**\n * Reads the Content with a Release In Force at this date and moment, at\n * the Revision that Release pins; content.release_id names it. Unset\n * fields are today and now.\n *\n * @generated from field: contenthub.v1.InForceAt in_force = 5;\n */\n value: InForceAt;\n case: \"inForce\";\n } | { case: undefined; value?: undefined };\n\n /**\n * At most 200; 0 means 50.\n *\n * @generated from field: int32 page_size = 3;\n */\n pageSize: number;\n\n /**\n * The next_page_token of the previous page; empty for the first.\n *\n * @generated from field: string page_token = 4;\n */\n pageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListContentsRequest.\n * Use `create(ListContentsRequestSchema)` to create a new message.\n */\nexport const ListContentsRequestSchema: GenMessage<ListContentsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 5);\n\n/**\n * ContentFilter narrows ListContents. Each field set must hold.\n *\n * @generated from message contenthub.v1.ContentFilter\n */\nexport type ContentFilter = Message<\"contenthub.v1.ContentFilter\"> & {\n /**\n * Only Content filed directly in this Collection, not in Collections\n * under it. An unknown Collection is NotFound.\n *\n * @generated from field: string collection_id = 1;\n */\n collectionId: string;\n\n /**\n * Editor Search (ADR 0019): only Content whose head holds this name, number\n * or phrase, letter for letter but ignoring case, within one field whose\n * `search` isn't `off`; runs of whitespace match any run. At most 200\n * characters.\n *\n * On Main it searches Main heads and every open Branch head alike, so\n * Content born in an open Change Set is found before Publish: a hit on a\n * Branch is read there and names its Change Set and Branch, and a Content\n * is listed once per head that matched. Inside a Change Set it searches\n * that Change Set's open Branch heads. Ordered by Content id, then Branch.\n * With the In Force view it is InvalidArgument: Editor Search covers Main\n * heads and open Branch heads only, never Releases (that is Delivery\n * Search's).\n *\n * @generated from field: string search = 2;\n */\n search: string;\n\n /**\n * Only Content this odon user maintains (SetContentAssignees).\n *\n * @generated from field: string assignee_id = 3;\n */\n assigneeId: string;\n\n /**\n * Archived Content too. Unset, every view leaves it out, since it is put\n * aside (ADR 0015).\n *\n * @generated from field: bool include_archived = 4;\n */\n includeArchived: boolean;\n\n /**\n * Only Content of one of these Blueprints, each Content judged by the\n * Blueprint of the Revision the view reads; empty for every Blueprint. At\n * most 100. A Blueprint named twice counts once, and an unknown one matches\n * nothing.\n *\n * @generated from field: repeated string blueprint_ids = 5;\n */\n blueprintIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.ContentFilter.\n * Use `create(ContentFilterSchema)` to create a new message.\n */\nexport const ContentFilterSchema: GenMessage<ContentFilter> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 6);\n\n/**\n * @generated from message contenthub.v1.ListContentsResponse\n */\nexport type ListContentsResponse = Message<\"contenthub.v1.ListContentsResponse\"> & {\n /**\n * As GetContent reads each, without the Resolved Release.\n *\n * @generated from field: repeated contenthub.v1.Content contents = 1;\n */\n contents: Content[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListContentsResponse.\n * Use `create(ListContentsResponseSchema)` to create a new message.\n */\nexport const ListContentsResponseSchema: GenMessage<ListContentsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 7);\n\n/**\n * @generated from message contenthub.v1.SetContentCollectionsRequest\n */\nexport type SetContentCollectionsRequest = Message<\"contenthub.v1.SetContentCollectionsRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Every Collection the Content is to be filed in, at most 100. A\n * Collection named twice counts once.\n *\n * @generated from field: repeated string collection_ids = 2;\n */\n collectionIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentCollectionsRequest.\n * Use `create(SetContentCollectionsRequestSchema)` to create a new message.\n */\nexport const SetContentCollectionsRequestSchema: GenMessage<SetContentCollectionsRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 8);\n\n/**\n * @generated from message contenthub.v1.SetContentCollectionsResponse\n */\nexport type SetContentCollectionsResponse = Message<\"contenthub.v1.SetContentCollectionsResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The Collections it is now filed in, by id, in id order.\n *\n * @generated from field: repeated string collection_ids = 2;\n */\n collectionIds: string[];\n};\n\n/**\n * Describes the message contenthub.v1.SetContentCollectionsResponse.\n * Use `create(SetContentCollectionsResponseSchema)` to create a new message.\n */\nexport const SetContentCollectionsResponseSchema: GenMessage<SetContentCollectionsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 9);\n\n/**\n * @generated from message contenthub.v1.SetContentAssigneesRequest\n */\nexport type SetContentAssigneesRequest = Message<\"contenthub.v1.SetContentAssigneesRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * The whole new set; empty unassigns everyone.\n *\n * @generated from field: repeated string assignee_ids = 2;\n */\n assigneeIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 3;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentAssigneesRequest.\n * Use `create(SetContentAssigneesRequestSchema)` to create a new message.\n */\nexport const SetContentAssigneesRequestSchema: GenMessage<SetContentAssigneesRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 10);\n\n/**\n * @generated from message contenthub.v1.SetContentAssigneesResponse\n */\nexport type SetContentAssigneesResponse = Message<\"contenthub.v1.SetContentAssigneesResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.SetContentAssigneesResponse.\n * Use `create(SetContentAssigneesResponseSchema)` to create a new message.\n */\nexport const SetContentAssigneesResponseSchema: GenMessage<SetContentAssigneesResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 11);\n\n/**\n * @generated from message contenthub.v1.BlockContentRequest\n */\nexport type BlockContentRequest = Message<\"contenthub.v1.BlockContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * One of the workspace's Block Reasons.\n *\n * @generated from field: string block_reason_id = 2;\n */\n blockReasonId: string;\n\n /**\n * Who may still edit it, at most 50 odon user ids, each once; empty is\n * nobody.\n *\n * @generated from field: repeated string allowed_user_ids = 3;\n */\n allowedUserIds: string[];\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 4;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.BlockContentRequest.\n * Use `create(BlockContentRequestSchema)` to create a new message.\n */\nexport const BlockContentRequestSchema: GenMessage<BlockContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 12);\n\n/**\n * @generated from message contenthub.v1.BlockContentResponse\n */\nexport type BlockContentResponse = Message<\"contenthub.v1.BlockContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.BlockContentResponse.\n * Use `create(BlockContentResponseSchema)` to create a new message.\n */\nexport const BlockContentResponseSchema: GenMessage<BlockContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 13);\n\n/**\n * @generated from message contenthub.v1.UnblockContentRequest\n */\nexport type UnblockContentRequest = Message<\"contenthub.v1.UnblockContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UnblockContentRequest.\n * Use `create(UnblockContentRequestSchema)` to create a new message.\n */\nexport const UnblockContentRequestSchema: GenMessage<UnblockContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 14);\n\n/**\n * @generated from message contenthub.v1.UnblockContentResponse\n */\nexport type UnblockContentResponse = Message<\"contenthub.v1.UnblockContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UnblockContentResponse.\n * Use `create(UnblockContentResponseSchema)` to create a new message.\n */\nexport const UnblockContentResponseSchema: GenMessage<UnblockContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 15);\n\n/**\n * @generated from message contenthub.v1.ArchiveContentRequest\n */\nexport type ArchiveContentRequest = Message<\"contenthub.v1.ArchiveContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.ArchiveContentRequest.\n * Use `create(ArchiveContentRequestSchema)` to create a new message.\n */\nexport const ArchiveContentRequestSchema: GenMessage<ArchiveContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 16);\n\n/**\n * @generated from message contenthub.v1.ArchiveContentResponse\n */\nexport type ArchiveContentResponse = Message<\"contenthub.v1.ArchiveContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.ArchiveContentResponse.\n * Use `create(ArchiveContentResponseSchema)` to create a new message.\n */\nexport const ArchiveContentResponseSchema: GenMessage<ArchiveContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 17);\n\n/**\n * @generated from message contenthub.v1.UnarchiveContentRequest\n */\nexport type UnarchiveContentRequest = Message<\"contenthub.v1.UnarchiveContentRequest\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * Optional: makes a retry safe. A repeat returns the first response (ADR\n * 0016's rule for idempotency keys; Idempotency Key in CONTEXT.md).\n *\n * @generated from field: string idempotency_key = 2;\n */\n idempotencyKey: string;\n};\n\n/**\n * Describes the message contenthub.v1.UnarchiveContentRequest.\n * Use `create(UnarchiveContentRequestSchema)` to create a new message.\n */\nexport const UnarchiveContentRequestSchema: GenMessage<UnarchiveContentRequest> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 18);\n\n/**\n * @generated from message contenthub.v1.UnarchiveContentResponse\n */\nexport type UnarchiveContentResponse = Message<\"contenthub.v1.UnarchiveContentResponse\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: contenthub.v1.ContentAttributes attributes = 2;\n */\n attributes?: ContentAttributes | undefined;\n};\n\n/**\n * Describes the message contenthub.v1.UnarchiveContentResponse.\n * Use `create(UnarchiveContentResponseSchema)` to create a new message.\n */\nexport const UnarchiveContentResponseSchema: GenMessage<UnarchiveContentResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 19);\n\n/**\n * ContentBlocked is a detail of a FailedPrecondition write on blocked\n * Content by a caller its Block doesn't allow: StartChain, StartEditing,\n * SaveRevision, UpdateFromMain's merges, ResolveMerge, UpgradeContent,\n * PlanRelease and UpdatePlannedRelease. A write changing several blocked\n * Contents carries one per Content. Ask someone it allows, or have it\n * unblocked.\n *\n * @generated from message contenthub.v1.ContentBlocked\n */\nexport type ContentBlocked = Message<\"contenthub.v1.ContentBlocked\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n\n /**\n * @generated from field: string block_reason_id = 2;\n */\n blockReasonId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ContentBlocked.\n * Use `create(ContentBlockedSchema)` to create a new message.\n */\nexport const ContentBlockedSchema: GenMessage<ContentBlocked> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 20);\n\n/**\n * ContentArchived is the detail of a FailedPrecondition StartChain or\n * StartEditing on Archived Content: unarchive it first.\n *\n * @generated from message contenthub.v1.ContentArchived\n */\nexport type ContentArchived = Message<\"contenthub.v1.ContentArchived\"> & {\n /**\n * @generated from field: string content_id = 1;\n */\n contentId: string;\n};\n\n/**\n * Describes the message contenthub.v1.ContentArchived.\n * Use `create(ContentArchivedSchema)` to create a new message.\n */\nexport const ContentArchivedSchema: GenMessage<ContentArchived> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 21);\n\n/**\n * @generated from message contenthub.v1.ListChangeSetsResponse\n */\nexport type ListChangeSetsResponse = Message<\"contenthub.v1.ListChangeSetsResponse\"> & {\n /**\n * Without their chains.\n *\n * @generated from field: repeated contenthub.v1.ChangeSet change_sets = 1;\n */\n changeSets: ChangeSet[];\n\n /**\n * Empty on the last page.\n *\n * @generated from field: string next_page_token = 2;\n */\n nextPageToken: string;\n};\n\n/**\n * Describes the message contenthub.v1.ListChangeSetsResponse.\n * Use `create(ListChangeSetsResponseSchema)` to create a new message.\n */\nexport const ListChangeSetsResponseSchema: GenMessage<ListChangeSetsResponse> = /*@__PURE__*/\n messageDesc(file_contenthub_v1_content, 22);\n\n/**\n * ContentService covers editor reads across Change Sets (ADR 0015). It never\n * writes history: that is ChangeSetService's.\n *\n * It also holds Content's unversioned attributes, which are not history:\n * setting one needs no Change Set and writes no Revision, so nothing about it\n * ever reaches a Release (ADR 0015).\n *\n * Every RPC acts in the caller's workspace, from the token. Reads need\n * `viewer`, the attribute setters `editor` (ADR 0017).\n *\n * @generated from service contenthub.v1.ContentService\n */\nexport const ContentService: GenService<{\n /**\n * GetContent reads one Content with the Blueprint Release its Revision\n * pins, as contenthub validated and cached it, so a form is drawn from\n * exactly what contenthub accepted.\n *\n * With change_set_id it reads the Content inside that Change Set, at the\n * head of its Chain's last Branch or of the Branch branch_id names;\n * without, on Main. Content born in a Change Set exists only inside it until\n * Publish: read anywhere else, or after the Change Set was discarded, it is\n * NotFound.\n *\n * @generated from rpc contenthub.v1.ContentService.GetContent\n */\n getContent: {\n methodKind: \"unary\";\n input: typeof GetContentRequestSchema;\n output: typeof GetContentResponseSchema;\n },\n /**\n * ListChangeSets lists Change Sets, newest first, optionally only those\n * with a Chain on one Content, or in one state.\n *\n * @generated from rpc contenthub.v1.ContentService.ListChangeSets\n */\n listChangeSets: {\n methodKind: \"unary\";\n input: typeof ListChangeSetsRequestSchema;\n output: typeof ListChangeSetsResponseSchema;\n },\n /**\n * ListContents lists Content in one view, optionally narrowed to one\n * Collection and by Editor Search (ContentFilter.search), ordered by id.\n *\n * @generated from rpc contenthub.v1.ContentService.ListContents\n */\n listContents: {\n methodKind: \"unary\";\n input: typeof ListContentsRequestSchema;\n output: typeof ListContentsResponseSchema;\n },\n /**\n * SetContentCollections files a Content into exactly the Collections\n * named, unfiling it from any other: an empty list unfiles it from all.\n * Content born in an open Change Set can be filed before it is published.\n *\n * Filing is not a save: it needs no Change Set, writes no Revision, moves\n * no head and never reaches a Release (ADR 0015). A change is announced\n * with contenthub.content.collections_changed; setting the Collections the\n * Content is already in changes nothing and announces nothing. An unknown\n * Content or Collection is NotFound.\n *\n * @generated from rpc contenthub.v1.ContentService.SetContentCollections\n */\n setContentCollections: {\n methodKind: \"unary\";\n input: typeof SetContentCollectionsRequestSchema;\n output: typeof SetContentCollectionsResponseSchema;\n },\n /**\n * SetContentAssignees replaces who maintains a Content (ADR 0015): at most\n * 50 odon user ids, each once. Like filing it is no save, needs no Change\n * Set and writes no Revision. A change is announced with\n * contenthub.content.assignees_changed; the same set again, in any order,\n * changes and announces nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.SetContentAssignees\n */\n setContentAssignees: {\n methodKind: \"unary\";\n input: typeof SetContentAssigneesRequestSchema;\n output: typeof SetContentAssigneesResponseSchema;\n },\n /**\n * BlockContent blocks a Content with one of the workspace's Block Reasons\n * and, optionally, the users still allowed to edit it (CONTEXT.md, Block).\n * While it holds, every write that edits the Content (StartChain,\n * StartEditing, SaveRevision, UpdateFromMain's merges, ResolveMerge,\n * UpgradeContent, PlanRelease, UpdatePlannedRelease) is\n * FailedPrecondition with a ContentBlocked detail for every other caller,\n * on Chains started before the Block too, and a Publish of a\n * Change Set that changes it lists a blocked_content PublishBlocker. A\n * Block controls editing, not seeing: every read is unchanged.\n *\n * Blocking a blocked Content replaces its Block. It is announced with\n * contenthub.content.blocked; the same Block again announces nothing. An\n * unknown Block Reason is NotFound. Like filing it is no save.\n *\n * @generated from rpc contenthub.v1.ContentService.BlockContent\n */\n blockContent: {\n methodKind: \"unary\";\n input: typeof BlockContentRequestSchema;\n output: typeof BlockContentResponseSchema;\n },\n /**\n * UnblockContent lifts a Content's Block, announced with\n * contenthub.content.unblocked. Lifting none changes nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.UnblockContent\n */\n unblockContent: {\n methodKind: \"unary\";\n input: typeof UnblockContentRequestSchema;\n output: typeof UnblockContentResponseSchema;\n },\n /**\n * ArchiveContent puts aside a published Content that has no Release In\n * Force today or later, after a Repeal or a Withdrawal ended its force.\n * ListContents (and so Editor Search and every picker) leaves it out unless\n * asked; StartChain and StartEditing are FailedPrecondition with a\n * ContentArchived detail; a save adding a Reference to it is InvalidArgument\n * with an archived_target Violation; and a Publish that would change it\n * lists an archived_content PublishBlocker. Its Releases stay readable and\n * every pin to them keeps resolving (ADR 0015).\n *\n * Content with a Release In Force today or later, or not yet published, is\n * FailedPrecondition. It is announced with contenthub.content.archived;\n * archiving Archived Content changes nothing. Like filing it is no save.\n *\n * @generated from rpc contenthub.v1.ContentService.ArchiveContent\n */\n archiveContent: {\n methodKind: \"unary\";\n input: typeof ArchiveContentRequestSchema;\n output: typeof ArchiveContentResponseSchema;\n },\n /**\n * UnarchiveContent brings Archived Content back into editing, announced\n * with contenthub.content.unarchived. Unarchiving other Content changes\n * nothing.\n *\n * @generated from rpc contenthub.v1.ContentService.UnarchiveContent\n */\n unarchiveContent: {\n methodKind: \"unary\";\n input: typeof UnarchiveContentRequestSchema;\n output: typeof UnarchiveContentResponseSchema;\n },\n /**\n * ListReferences reads a Content's outgoing edges in the Content Graph, at\n * one Revision, at the Revision a Release pins, or at the Release In Force,\n * and to a depth: References, TOC subtrees and everything else a Revision\n * points at (ADR 0009).\n *\n * @generated from rpc contenthub.v1.ContentService.ListReferences\n */\n listReferences: {\n methodKind: \"unary\";\n input: typeof ListReferencesRequestSchema;\n output: typeof ListReferencesResponseSchema;\n },\n /**\n * ListReferrers reads the incoming edges of a Content, or of an Anchor in\n * it: those of the Releases In Force at a date and moment, and optionally\n * those of the Branch heads of open Change Sets, each naming the Release\n * or the Change Set and Branch it was found in.\n *\n * @generated from rpc contenthub.v1.ContentService.ListReferrers\n */\n listReferrers: {\n methodKind: \"unary\";\n input: typeof ListReferrersRequestSchema;\n output: typeof ListReferrersResponseSchema;\n },\n /**\n * ListOutdatedPins lists the pinned edges of a Branch's head or of a\n * Revision whose Release is superseded, or is not the one In Force on\n * valid_on, each with its target's Timeline as the candidates to re-pin\n * to (#79). A pin is never moved on by itself: re-pinning is a save.\n *\n * @generated from rpc contenthub.v1.ContentService.ListOutdatedPins\n */\n listOutdatedPins: {\n methodKind: \"unary\";\n input: typeof ListOutdatedPinsRequestSchema;\n output: typeof ListOutdatedPinsResponseSchema;\n },\n /**\n * GetReleases reads Releases by id, superseded ones included and marked,\n * as ReleaseService.GetReleases does (#68).\n *\n * @generated from rpc contenthub.v1.ContentService.GetReleases\n */\n getReleases: {\n methodKind: \"unary\";\n input: typeof GetReleasesRequestSchema;\n output: typeof GetReleasesResponseSchema;\n },\n /**\n * GetTimeline reads a Content's Timeline, as ReleaseService.GetTimeline\n * does, with the Planned Releases of open Change Sets beside it (#68).\n * Content born in an open Change Set has only those.\n *\n * @generated from rpc contenthub.v1.ContentService.GetTimeline\n */\n getTimeline: {\n methodKind: \"unary\";\n input: typeof GetTimelineRequestSchema;\n output: typeof GetTimelineResponseSchema;\n },\n /**\n * ListRevisions lists the Revisions of a Content or of one Branch, newest\n * first, each with its author, time and cause.\n *\n * @generated from rpc contenthub.v1.ContentService.ListRevisions\n */\n listRevisions: {\n methodKind: \"unary\";\n input: typeof ListRevisionsRequestSchema;\n output: typeof ListRevisionsResponseSchema;\n },\n /**\n * Compare reports how one Revision differs from a base, field by field,\n * through fieldkit's Compare: another Revision, the fork of a Branch, or\n * Main's head. It only displays; it never decides a merge.\n *\n * @generated from rpc contenthub.v1.ContentService.Compare\n */\n compare: {\n methodKind: \"unary\";\n input: typeof CompareRequestSchema;\n output: typeof CompareResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_contenthub_v1_content, 0);\n\n","import { fromJson, type JsonObject, type JsonValue, toJson } from \"@bufbuild/protobuf\";\nimport { type Timestamp, timestampDate, ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport { Code, ConnectError, createClient, type Transport } from \"@connectrpc/connect\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport {\n\tBlueprintCatalogService,\n\tChangeSetClosedSchema,\n\tChangeSetService,\n\tCollectionService,\n\tContentArchivedSchema,\n\tContentBlockedSchema,\n\tContentService,\n\tCoversReleaseSchema,\n\tGuardianModeRequiredSchema,\n\ttype ProtoBlockReason,\n\tProtoBranchKind,\n\ttype ProtoCatalogRelease,\n\ttype ProtoChangeSet,\n\tProtoChangeSetState,\n\tProtoCheckOutcome,\n\ttype ProtoCheckResult,\n\tProtoCheckScope,\n\ttype ProtoCollection,\n\tProtoCollectionAccessLevel,\n\ttype ProtoContent,\n\ttype ProtoContentAttributes,\n\ttype ProtoEdge,\n\tProtoEdgeKind,\n\tProtoFieldChangeKind,\n\ttype ProtoGapReferrer,\n\ttype ProtoMergeField,\n\tProtoMergeSide,\n\ttype ProtoPendingMerge,\n\tProtoPendingMergeReason,\n\ttype ProtoPlannedRelease,\n\ttype ProtoPublishBlocker,\n\ttype ProtoRelease,\n\tProtoReleaseKind,\n\ttype ProtoRequiredCheck,\n\ttype ProtoRevision,\n\tProtoRevisionCause,\n\ttype ProtoTimelineEntry,\n\ttype ProtoValidityPeriod,\n\tPublishBlockerSchema,\n\tRefusalSchema,\n\tReleaseService,\n\tStaleHeadSchema,\n\tStaleStatusSchema,\n\tStatusTransitionRefusedSchema,\n\tViolationSchema,\n\tWithheldWorkSchema,\n\tWorkspaceConfigService,\n} from \"../gen-bridge\";\nimport type {\n\tBlockReason,\n\tBlueprintReleaseInfo,\n\tChangeSet,\n\tChangeSetState,\n\tCheckOutcome,\n\tCheckResult,\n\tCollection,\n\tCollectionAccessLevel,\n\tContent,\n\tContentAttributes,\n\tEdge,\n\tEdgeKind,\n\tMergeField,\n\tPendingMerge,\n\tPendingMergeRef,\n\tPlannedEnd,\n\tPlannedRelease,\n\tPublishBlocker,\n\tRecorderGrant,\n\tRelease,\n\tReleaseKind,\n\tRequiredCheck,\n\tResolvedBlueprintRelease,\n\tRevision,\n\tRevisionCause,\n\tTimelineEntry,\n\tValidityPeriod,\n} from \"../types\";\nimport {\n\tAccessDeniedError,\n\tBlockReasonNameTakenError,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tContentArchivedError,\n\tContentBlockedError,\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n\tNameTakenError,\n\tPublishRefusedError,\n\tRestrictionUnavailableError,\n\tServiceUnavailableError,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n\tWithheldWorkError,\n} from \"./contenthub-client\";\n\nexport interface CreateConnectContenthubClientOptions {\n\t/**\n\t * Base URL on the host origin, under which `/contenthub.v1.…/…` is served:\n\t * \"\" when contenthub serves the page itself (the harness), the mount prefix\n\t * (`/api/contenthub`) when core proxies it.\n\t */\n\tbaseUrl: string;\n\t/** The fetch every call goes through; a host adds its credentials here. */\n\tfetch?: typeof fetch;\n\t/** A pre-built transport (tests: `createRouterTransport`). Overrides baseUrl/fetch. */\n\ttransport?: Transport;\n}\n\nfunction iso(ts: Timestamp | undefined): string {\n\treturn ts ? timestampDate(ts).toISOString() : \"\";\n}\n\nfunction catalogReleaseFromProto(r: ProtoCatalogRelease): BlueprintReleaseInfo {\n\treturn {\n\t\tid: r.id,\n\t\tblueprintId: r.blueprintId,\n\t\tname: r.name,\n\t\treleaseTime: iso(r.releaseTime),\n\t\trefusals: r.refusals.map((v) => ({ source: v.source, code: v.code, path: v.path })),\n\t};\n}\n\n/** blueprinthub giving no answer through contenthub reads as the service down. */\nasync function catalogRead<T>(call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tconst ce = ConnectError.from(err);\n\t\tif (ce.code === Code.Unavailable) throw new ServiceUnavailableError(ce.rawMessage);\n\t\tthrow err;\n\t}\n}\n\nfunction blockReasonFromProto(r: ProtoBlockReason | undefined): BlockReason {\n\tif (!r) throw new Error(\"the response carried no Block Reason\");\n\treturn { id: r.id, name: r.name, createTime: iso(r.createTime), updateTime: iso(r.updateTime) };\n}\n\nconst STATE_FROM_PROTO: Record<ProtoChangeSetState, ChangeSetState | undefined> = {\n\t[ProtoChangeSetState.UNSPECIFIED]: undefined,\n\t[ProtoChangeSetState.OPEN]: \"open\",\n\t[ProtoChangeSetState.PUBLISHED]: \"published\",\n\t[ProtoChangeSetState.DISCARDED]: \"discarded\",\n};\n\nconst STATE_TO_PROTO: Record<ChangeSetState, ProtoChangeSetState> = {\n\topen: ProtoChangeSetState.OPEN,\n\tpublished: ProtoChangeSetState.PUBLISHED,\n\tdiscarded: ProtoChangeSetState.DISCARDED,\n};\n\nfunction stateFromProto(state: ProtoChangeSetState): ChangeSetState {\n\t// The service never answers UNSPECIFIED; an enum value this build doesn't\n\t// know yet reads as open, the one state that offers no closed-only promise.\n\treturn STATE_FROM_PROTO[state] ?? \"open\";\n}\n\nfunction changeSetFromProto(cs: ProtoChangeSet | undefined): ChangeSet {\n\tif (!cs) throw new Error(\"the response carried no Change Set\");\n\treturn {\n\t\tid: cs.id,\n\t\tname: cs.name,\n\t\tsource: cs.source ? { date: cs.source.date, reference: cs.source.reference } : undefined,\n\t\tstate: stateFromProto(cs.state),\n\t\tcreatedBy: cs.createdBy,\n\t\tcreateTime: iso(cs.createTime),\n\t\tcloseTime: cs.closeTime ? iso(cs.closeTime) : undefined,\n\t\tchains: cs.chains.map((chain) => ({\n\t\t\tid: chain.id,\n\t\t\tcontentId: chain.contentId,\n\t\t\tborn: chain.born,\n\t\t\tbranches: chain.branches.map((b) => ({\n\t\t\t\tid: b.id,\n\t\t\t\tposition: b.position,\n\t\t\t\tkind: b.kind === ProtoBranchKind.CARRY_FORWARD ? \"carry_forward\" : \"editorial\",\n\t\t\t\theadRevisionId: b.headRevisionId,\n\t\t\t\teffectiveOn: b.effectiveOn,\n\t\t\t\tcarriedReleaseId: b.carriedReleaseId,\n\t\t\t\thasPendingMerge: b.hasPendingMerge,\n\t\t\t})),\n\t\t})),\n\t\tdependsOnChangeSetIds: [...cs.dependsOnChangeSetIds],\n\t\tstatus: cs.status,\n\t\tassigneeIds: [...cs.assigneeIds],\n\t\tplannedReleases: cs.plannedReleases.map(plannedReleaseFromProto),\n\t};\n}\n\nconst KIND_FROM_PROTO: Record<ProtoReleaseKind, ReleaseKind> = {\n\t// The service never answers UNSPECIFIED; read it as the common kind.\n\t[ProtoReleaseKind.UNSPECIFIED]: \"revision\",\n\t[ProtoReleaseKind.REVISION]: \"revision\",\n\t[ProtoReleaseKind.DATE_ONLY]: \"date_only\",\n\t[ProtoReleaseKind.REPEAL]: \"repeal\",\n\t[ProtoReleaseKind.WITHDRAWAL]: \"withdrawal\",\n};\n\nfunction periodFromProto(p: ProtoValidityPeriod | undefined): ValidityPeriod | undefined {\n\treturn p ? { firstDay: p.firstDay, lastDay: p.lastDay } : undefined;\n}\n\nfunction plannedReleaseFromProto(pr: ProtoPlannedRelease): PlannedRelease {\n\treturn {\n\t\tid: pr.id,\n\t\tcontentId: pr.contentId,\n\t\tkind: KIND_FROM_PROTO[pr.kind] ?? \"revision\",\n\t\tbranchId: pr.branchId,\n\t\trevisionId: pr.revisionId,\n\t\tvalidityPeriod: periodFromProto(pr.validityPeriod),\n\t\treleaseSpec: pr.releaseSpec ? { ...pr.releaseSpec } : undefined,\n\t\tsupersedesReleaseIds: [...pr.supersedesReleaseIds],\n\t\tproposed: pr.proposed,\n\t\tproposedForReleaseId: pr.proposedForReleaseId,\n\t\tsplitFromReleaseId: pr.splitFromReleaseId,\n\t\twithheld: pr.withheld,\n\t};\n}\n\nfunction releaseFromProto(r: ProtoRelease): Release {\n\treturn {\n\t\tid: r.id,\n\t\tcontentId: r.contentId,\n\t\tkind: KIND_FROM_PROTO[r.kind] ?? \"revision\",\n\t\tbranchId: r.branchId,\n\t\trevisionId: r.revisionId,\n\t\tfirst: r.first,\n\t\tsupersedesReleaseIds: [...r.supersedesReleaseIds],\n\t\tvalidityPeriod: periodFromProto(r.validityPeriod),\n\t};\n}\n\nfunction blockerFromProto(b: ProtoPublishBlocker): PublishBlocker {\n\treturn {\n\t\tcode: b.code,\n\t\tcontentId: b.contentId,\n\t\tbranchId: b.branchId,\n\t\texpectedHeadId: b.expectedHeadId,\n\t\tcurrentHeadId: b.currentHeadId,\n\t\treleaseId: b.releaseId,\n\t\toverlapsReleaseId: b.overlapsReleaseId,\n\t\tdependencyChangeSetId: b.dependencyChangeSetId,\n\t\tpath: b.path,\n\t\ttargetContentId: b.targetContentId,\n\t\tassetId: b.assetId,\n\t\tparentContentIds: [...b.parentContentIds],\n\t\trequiredCheckId: b.requiredCheckId,\n\t\tcoveredReleaseId: b.coveredReleaseId,\n\t\trevisionId: b.revisionId,\n\t};\n}\n\nfunction pendingFromProto(p: ProtoPendingMerge): PendingMergeRef {\n\treturn { branchId: p.branchId, contentId: p.contentId };\n}\n\n/** A google.protobuf.Value as JSON; absent stays absent (a side without the field). */\nfunction jsonOf(v: Parameters<typeof toJson<typeof ValueSchema>>[1] | undefined): unknown {\n\treturn v ? toJson(ValueSchema, v) : undefined;\n}\n\nfunction mergeFieldFromProto(f: ProtoMergeField): MergeField {\n\treturn {\n\t\tpath: f.path,\n\t\tconflictPaths: [...f.conflictPaths],\n\t\tbase: jsonOf(f.base),\n\t\tours: jsonOf(f.ours),\n\t\ttheirs: jsonOf(f.theirs),\n\t};\n}\n\n/**\n * A plan's refusals: Release Spec values the Blueprint Release refuses as\n * one `ContentRefusedError`, a period covering Releases as\n * `CoversReleaseError`, otherwise an edit's.\n */\nfunction planRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst covers = ce.findDetails(CoversReleaseSchema)[0];\n\tif (covers) return new CoversReleaseError(covers.contentId, [...covers.coveredReleaseIds]);\n\treturn saveRefusal(changeSetId, err);\n}\n\n/** A Struct through JSON: a Struct holds no `undefined`, which a form's values may carry. */\nfunction struct(values: Record<string, unknown>): JsonObject {\n\treturn JSON.parse(JSON.stringify(values)) as JsonObject;\n}\n\nconst OUTCOME_FROM_PROTO: Record<ProtoCheckOutcome, CheckOutcome | undefined> = {\n\t[ProtoCheckOutcome.UNSPECIFIED]: undefined,\n\t[ProtoCheckOutcome.PASSED]: \"passed\",\n\t[ProtoCheckOutcome.FAILED]: \"failed\",\n\t[ProtoCheckOutcome.WAIVED]: \"waived\",\n};\n\nconst OUTCOME_TO_PROTO: Record<CheckOutcome, ProtoCheckOutcome> = {\n\tpassed: ProtoCheckOutcome.PASSED,\n\tfailed: ProtoCheckOutcome.FAILED,\n\twaived: ProtoCheckOutcome.WAIVED,\n};\n\nfunction checkResultFromProto(r: ProtoCheckResult | undefined): CheckResult {\n\tif (!r) throw new Error(\"the response carried no Check Result\");\n\treturn {\n\t\tid: r.id,\n\t\trequiredCheckId: r.requiredCheckId,\n\t\theads: { ...r.heads },\n\t\t// An outcome this build doesn't know counts for nothing, as failed does.\n\t\toutcome: OUTCOME_FROM_PROTO[r.outcome] ?? \"failed\",\n\t\tnote: r.note,\n\t\trecordedBy: r.recordedBy,\n\t\trecordTime: iso(r.recordTime),\n\t};\n}\n\nfunction requiredCheckFromProto(c: ProtoRequiredCheck | undefined): RequiredCheck {\n\tif (!c) throw new Error(\"the response carried no Required Check\");\n\treturn {\n\t\tid: c.id,\n\t\tname: c.name,\n\t\tscope: c.scope === ProtoCheckScope.CHANGE_SET ? \"change_set\" : \"branch\",\n\t\tblueprintAccessors: [...c.blueprintAccessors],\n\t\tindependent: c.independent,\n\t};\n}\n\nfunction collectionFromProto(c: ProtoCollection | undefined): Collection {\n\tif (!c) throw new Error(\"the response carried no Collection\");\n\treturn { id: c.id, name: c.name, parentId: c.parentId, restricted: c.restricted };\n}\n\nconst SCOPE_TO_PROTO = {\n\tbranch: ProtoCheckScope.BRANCH,\n\tchange_set: ProtoCheckScope.CHANGE_SET,\n} as const;\n\nconst LEVEL_FROM_PROTO: Record<ProtoCollectionAccessLevel, CollectionAccessLevel> = {\n\t// The service never answers UNSPECIFIED; read it as the least access.\n\t[ProtoCollectionAccessLevel.UNSPECIFIED]: \"viewer\",\n\t[ProtoCollectionAccessLevel.VIEWER]: \"viewer\",\n\t[ProtoCollectionAccessLevel.EDITOR]: \"editor\",\n\t[ProtoCollectionAccessLevel.OWNER]: \"owner\",\n};\n\n/**\n * GuardianModeRequired's feature on workspace mode's refusal of every\n * restriction and grant (internal/authz.RestrictionRefused): the screens\n * read it as `RestrictionUnavailableError`, by the detail and never the text.\n */\nconst COLLECTION_RESTRICTION = \"collection_restriction\";\n\n/**\n * The refusals of a Required Check's or Collection's write, as typed errors.\n * `name` is the one asked for, for AlreadyExists, which carries no detail.\n */\nfunction settingsRefusal(err: unknown, name = \"\"): unknown {\n\tconst ce = ConnectError.from(err);\n\tswitch (ce.code) {\n\t\tcase Code.AlreadyExists:\n\t\t\treturn new NameTakenError(name.trim());\n\t\tcase Code.PermissionDenied:\n\t\t\treturn new AccessDeniedError(ce.rawMessage);\n\t\tcase Code.FailedPrecondition: {\n\t\t\tconst [guardianMode] = ce.findDetails(GuardianModeRequiredSchema);\n\t\t\tif (guardianMode?.feature === COLLECTION_RESTRICTION) {\n\t\t\t\treturn new RestrictionUnavailableError(ce.rawMessage);\n\t\t\t}\n\t\t\tif (guardianMode) return new GuardianModeRequiredError(guardianMode.feature, ce.rawMessage);\n\t\t\treturn new InvalidInputError(ce.rawMessage);\n\t\t}\n\t\tcase Code.InvalidArgument:\n\t\t\treturn new InvalidInputError(ce.rawMessage);\n\t\tcase Code.Unavailable:\n\t\t\treturn new ServiceUnavailableError(ce.rawMessage);\n\t\tdefault:\n\t\t\treturn err;\n\t}\n}\n\n/** A recorder grant as the wire's Recorder oneof. */\nfunction recorderToProto(r: RecorderGrant) {\n\treturn \"everyMember\" in r\n\t\t? { recorder: { case: \"everyMember\" as const, value: true } }\n\t\t: { recorder: { case: \"userId\" as const, value: r.userId } };\n}\n\n/** Runs a settings write, its refusals turned into typed errors. */\nasync function settingsWrite<T>(call: () => Promise<T>, name?: string): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tthrow settingsRefusal(err, name);\n\t}\n}\n\nfunction contentFromProto(c: ProtoContent | undefined): Content {\n\tif (!c) throw new Error(\"the response carried no Content\");\n\treturn {\n\t\tid: c.id,\n\t\tblueprintId: c.blueprintId,\n\t\tblueprintReleaseId: c.blueprintReleaseId,\n\t\trevisionId: c.revisionId,\n\t\tdata: { ...(c.data ?? {}) },\n\t\tchangeSetId: c.changeSetId,\n\t\tbranchId: c.branchId,\n\t\trevisionCreateTime: iso(c.revisionCreateTime),\n\t\treleaseId: c.releaseId,\n\t};\n}\n\nfunction attributesFromProto(a: ProtoContentAttributes | undefined): ContentAttributes {\n\treturn {\n\t\tcollectionIds: [...(a?.collectionIds ?? [])],\n\t\tassigneeIds: [...(a?.assigneeIds ?? [])],\n\t\tblock: a?.block\n\t\t\t? {\n\t\t\t\t\tblockReasonId: a.block.blockReasonId,\n\t\t\t\t\tallowedUserIds: [...a.block.allowedUserIds],\n\t\t\t\t\tblockedBy: a.block.blockedBy,\n\t\t\t\t\tblockTime: iso(a.block.blockTime),\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tarchiveTime: a?.archiveTime ? iso(a.archiveTime) : undefined,\n\t};\n}\n\n/**\n * The Resolved Release's few keys the screens read. It crosses as bytes\n * (blueprinthub ADR 0004) and only grows by optional keys, so a reader takes\n * what it knows and ignores the rest; bytes that aren't such a document read\n * as none, and the page falls back to the bare data.\n */\nexport function resolvedReleaseFromBytes(bytes: Uint8Array): ResolvedBlueprintRelease | undefined {\n\tif (bytes.length === 0) return undefined;\n\ttry {\n\t\tconst doc = JSON.parse(new TextDecoder().decode(bytes)) as {\n\t\t\tdisplay_name?: unknown;\n\t\t\tdated?: unknown;\n\t\t\trelease_spec?: unknown;\n\t\t\tspec?: { fields?: unknown; parts?: unknown } | null;\n\t\t};\n\t\tconst fields = Array.isArray(doc.spec?.fields) ? doc.spec.fields : [];\n\t\tconst parts =\n\t\t\tdoc.spec?.parts && typeof doc.spec.parts === \"object\"\n\t\t\t\t? (doc.spec.parts as ResolvedBlueprintRelease[\"parts\"])\n\t\t\t\t: {};\n\t\treturn {\n\t\t\tdisplayName: typeof doc.display_name === \"string\" ? doc.display_name : \"\",\n\t\t\tdated: doc.dated === true,\n\t\t\tfields: fields as ResolvedBlueprintRelease[\"fields\"],\n\t\t\t// The Release Spec: fieldkit fields, beside the spec's (blueprinthub ADR 0004).\n\t\t\treleaseSpec: Array.isArray(doc.release_spec)\n\t\t\t\t? (doc.release_spec as ResolvedBlueprintRelease[\"fields\"])\n\t\t\t\t: [],\n\t\t\tparts,\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction timelineEntryFromProto(e: ProtoTimelineEntry): TimelineEntry {\n\treturn {\n\t\tordinal: e.ordinal,\n\t\treleaseId: e.releaseId,\n\t\tkind: KIND_FROM_PROTO[e.kind] ?? \"revision\",\n\t\trevisionId: e.revisionId,\n\t\tblueprintReleaseId: e.blueprintReleaseId,\n\t\tvalidityPeriod: periodFromProto(e.validityPeriod),\n\t\tpublishTime: iso(e.publishTime),\n\t\tfirst: e.first,\n\t};\n}\n\n/** A Planned Release a response must carry. */\nfunction requiredPlannedRelease(p: ProtoPlannedRelease | undefined): PlannedRelease {\n\tif (!p) throw new Error(\"the response carried no Planned Release\");\n\treturn plannedReleaseFromProto(p);\n}\n\nconst CAUSES: Record<ProtoRevisionCause, RevisionCause> = {\n\t[ProtoRevisionCause.UNSPECIFIED]: \"unspecified\",\n\t[ProtoRevisionCause.CREATE]: \"create\",\n\t[ProtoRevisionCause.SAVE]: \"save\",\n\t[ProtoRevisionCause.MERGE]: \"merge\",\n\t[ProtoRevisionCause.RESOLVE]: \"resolve\",\n\t[ProtoRevisionCause.UPGRADE]: \"upgrade\",\n};\n\nfunction revisionFromProto(r: ProtoRevision | undefined): Revision {\n\tif (!r) throw new Error(\"the response carried no Revision\");\n\treturn {\n\t\tid: r.id,\n\t\tcontentId: r.contentId,\n\t\tparentId: r.parentId,\n\t\tsecondParentId: r.secondParentId,\n\t\tblueprintReleaseId: r.blueprintReleaseId,\n\t\tcreateTime: iso(r.createTime),\n\t\tauthor: r.author,\n\t\tcause: CAUSES[r.cause] ?? \"unspecified\",\n\t\tbranchId: r.branchId,\n\t\tchangeSetId: r.changeSetId,\n\t};\n}\n\nconst EDGE_KINDS: Record<ProtoEdgeKind, EdgeKind> = {\n\t[ProtoEdgeKind.UNSPECIFIED]: \"unspecified\",\n\t[ProtoEdgeKind.REFERENCE]: \"reference\",\n\t[ProtoEdgeKind.TOC]: \"toc\",\n\t[ProtoEdgeKind.INCLUDE]: \"include\",\n\t[ProtoEdgeKind.EXCLUDE]: \"exclude\",\n\t[ProtoEdgeKind.REPLACE]: \"replace\",\n\t[ProtoEdgeKind.ANNOTATE]: \"annotate\",\n\t[ProtoEdgeKind.LINK]: \"link\",\n\t[ProtoEdgeKind.FOOTNOTE]: \"footnote\",\n\t[ProtoEdgeKind.ANCHOR]: \"anchor\",\n\t[ProtoEdgeKind.MEDIA]: \"media\",\n\t[ProtoEdgeKind.BLUEPRINT]: \"blueprint\",\n};\n\nfunction edgeFromProto(e: ProtoEdge | undefined): Edge {\n\treturn {\n\t\tsourceContentId: e?.sourceContentId ?? \"\",\n\t\tsourceRevisionId: e?.sourceRevisionId ?? \"\",\n\t\tpath: e?.path ?? \"\",\n\t\tkind: e ? (EDGE_KINDS[e.kind] ?? \"unspecified\") : \"unspecified\",\n\t\ttargetContentId: e?.targetContentId ?? \"\",\n\t\ttargetAssetId: e?.targetAssetId ?? \"\",\n\t\ttargetBlueprintReleaseId: e?.targetBlueprintReleaseId ?? \"\",\n\t\tpinReleaseId: e?.pinReleaseId ?? \"\",\n\t};\n}\n\nfunction plannedEndFromProto(res: {\n\tplannedRelease?: ProtoPlannedRelease;\n\tgapReferrers: ProtoGapReferrer[];\n}): PlannedEnd {\n\treturn {\n\t\tplannedRelease: requiredPlannedRelease(res.plannedRelease),\n\t\tgapReferrers: res.gapReferrers.map((g) => ({\n\t\t\tedge: edgeFromProto(g.edge),\n\t\t\treleaseId: g.releaseId,\n\t\t})),\n\t};\n}\n\n/**\n * An edit's refusals on a Content: its Block, its being Archived, and\n * otherwise any Change Set write's.\n */\nfunction editRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst blocked = ce.findDetails(ContentBlockedSchema)[0];\n\tif (blocked) return new ContentBlockedError(blocked.contentId, blocked.blockReasonId);\n\tconst archived = ce.findDetails(ContentArchivedSchema)[0];\n\tif (archived) return new ContentArchivedError(archived.contentId);\n\treturn changeSetRefusal(changeSetId, err);\n}\n\n/** An attribute setter's refusal: the service's guidance, fit to show. */\nasync function attributeWrite<T>(call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tconst ce = ConnectError.from(err);\n\t\tif (ce.code === Code.InvalidArgument || ce.code === Code.FailedPrecondition) {\n\t\t\tthrow new InvalidInputError(ce.rawMessage);\n\t\t}\n\t\tthrow err;\n\t}\n}\n\n/**\n * A new Content's refusals: the data's Violations or the Release's Refusals\n * as one `ContentRefusedError`, everything else as any Change Set write's.\n */\nfunction contentRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst reasons = [...ce.findDetails(ViolationSchema), ...ce.findDetails(RefusalSchema)].map(\n\t\t(r) => ({ source: r.source, code: r.code, path: r.path }),\n\t);\n\tif (reasons.length > 0) return new ContentRefusedError(ce.rawMessage, reasons);\n\treturn changeSetRefusal(changeSetId, err);\n}\n\n/**\n * A save's refusals: the data's Violations (or the Release's Refusals) as one `ContentRefusedError`,\n * otherwise an edit's (the Content's Block or Archive, a moved head, a\n * closed Change Set).\n */\nfunction saveRefusal(changeSetId: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst reasons = [...ce.findDetails(ViolationSchema), ...ce.findDetails(RefusalSchema)].map(\n\t\t(r) => ({ source: r.source, code: r.code, path: r.path }),\n\t);\n\tif (reasons.length > 0) return new ContentRefusedError(ce.rawMessage, reasons);\n\treturn editRefusal(changeSetId, err);\n}\n\n/**\n * The refusals any write to Change Set `id` can meet, as typed errors: the\n * Change Set closed, and (for a status move) statushub's no, a stale status\n * and statushub out of reach. InvalidArgument and the remaining\n * FailedPreconditions (a dependency cycle, a closed dependency, whose\n * ChangeSetClosed detail names the other Change Set) carry the service's\n * guidance, fit to show.\n */\nfunction changeSetRefusal(id: string, err: unknown): unknown {\n\tconst ce = ConnectError.from(err);\n\tconst refused = ce.findDetails(StatusTransitionRefusedSchema)[0];\n\tif (refused) {\n\t\treturn new StatusTransitionRefusedError({\n\t\t\tfromStatus: refused.fromStatus,\n\t\t\ttoStatus: refused.toStatus,\n\t\t\treason: refused.reason,\n\t\t\trequiresPermission: refused.requiresPermission,\n\t\t});\n\t}\n\tconst stale = ce.findDetails(StaleStatusSchema)[0];\n\tif (stale) return new StaleStatusError(stale.currentStatus);\n\tconst closed = ce.findDetails(ChangeSetClosedSchema)[0];\n\tif (closed && (closed.changeSetId === id || closed.changeSetId === \"\")) {\n\t\treturn new ChangeSetClosedError(stateFromProto(closed.state));\n\t}\n\tconst blockers = ce.findDetails(PublishBlockerSchema);\n\tif (blockers.length > 0) return new PublishRefusedError(blockers.map(blockerFromProto));\n\tconst moved = ce.findDetails(StaleHeadSchema)[0];\n\tif (moved) return new StaleHeadError(moved);\n\tif (ce.findDetails(WithheldWorkSchema).length > 0) return new WithheldWorkError(ce.rawMessage);\n\tif (ce.code === Code.Unavailable) return new ServiceUnavailableError(ce.rawMessage);\n\tif (ce.code === Code.InvalidArgument || ce.code === Code.FailedPrecondition) {\n\t\treturn new InvalidInputError(ce.rawMessage);\n\t}\n\treturn err;\n}\n\n/** Runs a write to Change Set `id`, its refusals turned into typed errors. */\nasync function changeSetWrite<T>(id: string, call: () => Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await call();\n\t} catch (err) {\n\t\tthrow changeSetRefusal(id, err);\n\t}\n}\n\n/**\n * Turns the service's refusals of a name into the typed errors the screens\n * act on. `name` is the one asked for: AlreadyExists carries no detail, and\n * the caller knows what it sent. InvalidArgument's message is the service's\n * guidance (commons surfaces it), so it is passed on as it is.\n */\nfunction nameRefusal(err: unknown, name: string): unknown {\n\tconst ce = ConnectError.from(err);\n\tif (ce.code === Code.AlreadyExists) return new BlockReasonNameTakenError(name.trim());\n\tif (ce.code === Code.InvalidArgument) return new InvalidInputError(ce.rawMessage);\n\treturn err;\n}\n\n/** The production `ContenthubClient`, over Connect. */\nexport function createConnectContenthubClient(\n\toptions: CreateConnectContenthubClientOptions,\n): ContenthubClient {\n\tconst transport =\n\t\toptions.transport ?? createConnectTransport({ baseUrl: options.baseUrl, fetch: options.fetch });\n\tconst config = createClient(WorkspaceConfigService, transport);\n\tconst changeSets = createClient(ChangeSetService, transport);\n\tconst contents = createClient(ContentService, transport);\n\tconst collections = createClient(CollectionService, transport);\n\tconst releases = createClient(ReleaseService, transport);\n\tconst catalog = createClient(BlueprintCatalogService, transport);\n\n\treturn {\n\t\tasync listBlockReasons() {\n\t\t\tconst res = await config.listBlockReasons({});\n\t\t\treturn res.blockReasons.map(blockReasonFromProto);\n\t\t},\n\t\tasync createBlockReason({ name }) {\n\t\t\ttry {\n\t\t\t\tconst res = await config.createBlockReason({ name });\n\t\t\t\treturn blockReasonFromProto(res.blockReason);\n\t\t\t} catch (err) {\n\t\t\t\tthrow nameRefusal(err, name);\n\t\t\t}\n\t\t},\n\t\tasync renameBlockReason({ id, name }) {\n\t\t\ttry {\n\t\t\t\tconst res = await config.renameBlockReason({ id, name });\n\t\t\t\treturn blockReasonFromProto(res.blockReason);\n\t\t\t} catch (err) {\n\t\t\t\tthrow nameRefusal(err, name);\n\t\t\t}\n\t\t},\n\t\tasync deleteBlockReason({ id }) {\n\t\t\tawait config.deleteBlockReason({ id });\n\t\t},\n\n\t\tasync listChangeSets(input = {}) {\n\t\t\tconst res = await contents.listChangeSets({\n\t\t\t\tstate: input.state ? STATE_TO_PROTO[input.state] : ProtoChangeSetState.UNSPECIFIED,\n\t\t\t\tassigneeId: input.assigneeId ?? \"\",\n\t\t\t\tcontentId: input.contentId ?? \"\",\n\t\t\t\tpageSize: input.pageSize ?? 0,\n\t\t\t\tpageToken: input.pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tchangeSets: res.changeSets.map(changeSetFromProto),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync createChangeSet({ name, source }) {\n\t\t\tconst res = await changeSetWrite(\"\", () => changeSets.createChangeSet({ name, source }));\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync getChangeSet(id) {\n\t\t\tconst res = await changeSets.getChangeSet({ id });\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync updateChangeSet({ id, updateMask, name, source, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.updateChangeSet({\n\t\t\t\t\tid,\n\t\t\t\t\tname: name ?? \"\",\n\t\t\t\t\tsource,\n\t\t\t\t\tupdateMask: { fields: updateMask },\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync setChangeSetStatus({ id, expectedStatus, status }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.setChangeSetStatus({ changeSetId: id, expectedStatus, status }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync setChangeSetAssignees({ id, assigneeIds }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.setChangeSetAssignees({ changeSetId: id, assigneeIds }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync addDependency({ id, dependsOnId }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.addDependency({ changeSetId: id, dependsOnChangeSetId: dependsOnId }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync removeDependency({ id, dependsOnId }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.removeDependency({ changeSetId: id, dependsOnChangeSetId: dependsOnId }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync validatePublish({ id, reviewedHeads }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.validatePublish({ changeSetId: id, reviewedHeads }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tblockers: res.blockers.map(blockerFromProto),\n\t\t\t\treleases: res.releases.map(releaseFromProto),\n\t\t\t\tpublished: res.published,\n\t\t\t};\n\t\t},\n\t\tasync publish({ id, reviewedHeads }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.publish({ changeSetId: id, reviewedHeads }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\tpublishTime: iso(res.publishTime),\n\t\t\t\treleases: res.releases.map(releaseFromProto),\n\t\t\t};\n\t\t},\n\t\tasync updateFromMain({ id, chainId, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(id, () =>\n\t\t\t\tchangeSets.updateFromMain({\n\t\t\t\t\tchangeSetId: id,\n\t\t\t\t\tchainId: chainId ?? \"\",\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\tmergedBranchIds: [...res.mergedBranchIds],\n\t\t\t\tconflicted: res.conflicted.map(pendingFromProto),\n\t\t\t\tpending: res.pending.map(pendingFromProto),\n\t\t\t\tendedBranchIds: [...res.endedBranchIds],\n\t\t\t};\n\t\t},\n\t\tasync discardChangeSet(id) {\n\t\t\tconst res = await changeSetWrite(id, () => changeSets.discardChangeSet({ id }));\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync listCheckResults(changeSetId) {\n\t\t\tconst res = await changeSets.listCheckResults({ changeSetId });\n\t\t\treturn res.standings.map((st) => ({\n\t\t\t\tcheck: requiredCheckFromProto(st.requiredCheck),\n\t\t\t\tcontentId: st.contentId,\n\t\t\t\tbranchId: st.branchId,\n\t\t\t\treleaseId: st.releaseId,\n\t\t\t\theads: { ...st.heads },\n\t\t\t\tresults: st.results.map(checkResultFromProto),\n\t\t\t\tstale: st.stale,\n\t\t\t\tcleared: st.cleared,\n\t\t\t}));\n\t\t},\n\t\tasync recordCheckResult({ changeSetId, requiredCheckId, heads, outcome, note }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.recordCheckResult({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\trequiredCheckId,\n\t\t\t\t\theads,\n\t\t\t\t\toutcome: OUTCOME_TO_PROTO[outcome],\n\t\t\t\t\tnote,\n\t\t\t\t});\n\t\t\t\treturn checkResultFromProto(res.checkResult);\n\t\t\t} catch (err) {\n\t\t\t\tconst ce = ConnectError.from(err);\n\t\t\t\t// The service's reason says which check and why: fit to show.\n\t\t\t\tif (ce.code === Code.PermissionDenied) throw new CheckResultDeniedError(ce.rawMessage);\n\t\t\t\tthrow changeSetRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\n\t\tasync listRequiredChecks() {\n\t\t\tconst res = await config.listRequiredChecks({});\n\t\t\treturn res.requiredChecks.map(requiredCheckFromProto);\n\t\t},\n\t\tasync createRequiredCheck(input) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() =>\n\t\t\t\t\tconfig.createRequiredCheck({\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\tscope: SCOPE_TO_PROTO[input.scope],\n\t\t\t\t\t\tblueprintAccessors: input.blueprintAccessors,\n\t\t\t\t\t\tindependent: input.independent,\n\t\t\t\t\t}),\n\t\t\t\tinput.name,\n\t\t\t);\n\t\t\treturn requiredCheckFromProto(res.requiredCheck);\n\t\t},\n\t\tasync updateRequiredCheck(input) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() =>\n\t\t\t\t\tconfig.updateRequiredCheck({\n\t\t\t\t\t\tid: input.id,\n\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\tscope: SCOPE_TO_PROTO[input.scope],\n\t\t\t\t\t\tblueprintAccessors: input.blueprintAccessors,\n\t\t\t\t\t\tindependent: input.independent,\n\t\t\t\t\t}),\n\t\t\t\tinput.name,\n\t\t\t);\n\t\t\treturn requiredCheckFromProto(res.requiredCheck);\n\t\t},\n\t\tasync deleteRequiredCheck({ id }) {\n\t\t\tawait settingsWrite(() => config.deleteRequiredCheck({ id }));\n\t\t},\n\t\tasync listRequiredCheckRecorders(requiredCheckId) {\n\t\t\tconst res = await settingsWrite(() => config.listRequiredCheckRecorders({ requiredCheckId }));\n\t\t\treturn { everyMember: res.everyMember, userIds: [...res.userIds] };\n\t\t},\n\t\tasync grantRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tconfig.grantRequiredCheckRecorder({ requiredCheckId, recorder: recorderToProto(recorder) }),\n\t\t\t);\n\t\t},\n\t\tasync revokeRequiredCheckRecorder({ requiredCheckId, recorder }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tconfig.revokeRequiredCheckRecorder({\n\t\t\t\t\trequiredCheckId,\n\t\t\t\t\trecorder: recorderToProto(recorder),\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\n\t\tasync searchBlueprints({ query, pageToken = \"\", signal }) {\n\t\t\tconst res = await catalogRead(() =>\n\t\t\t\tcatalog.searchBlueprints({ query, pageToken }, { signal }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tblueprints: res.blueprints.map((b) => ({ id: b.id, name: b.name })),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync listBlueprintReleases(blueprintId) {\n\t\t\tconst res = await catalogRead(() => catalog.listBlueprintReleases({ blueprintId }));\n\t\t\treturn res.releases.map(catalogReleaseFromProto);\n\t\t},\n\t\tasync getBlueprints(ids) {\n\t\t\tconst res = await catalogRead(() => catalog.getBlueprints({ ids }));\n\t\t\treturn res.blueprints.map((b) => ({ id: b.id, name: b.name }));\n\t\t},\n\n\t\tasync listCollections() {\n\t\t\tconst res = await collections.listCollections({});\n\t\t\treturn res.collections.map(collectionFromProto);\n\t\t},\n\t\tasync createCollection({ name, parentId = \"\", restricted = false }) {\n\t\t\tconst res = await settingsWrite(\n\t\t\t\t() => collections.createCollection({ name, parentId, restricted }),\n\t\t\t\tname,\n\t\t\t);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync renameCollection({ id, name }) {\n\t\t\tconst res = await settingsWrite(() => collections.renameCollection({ id, name }), name);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync moveCollection({ id, parentId }) {\n\t\t\t// AlreadyExists names the moved Collection's own name, which the\n\t\t\t// caller has and the request doesn't carry.\n\t\t\tconst res = await settingsWrite(() => collections.moveCollection({ id, parentId }));\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync removeCollection({ id }) {\n\t\t\tconst res = await settingsWrite(() => collections.removeCollection({ id }));\n\t\t\treturn [...res.unfiledContentIds];\n\t\t},\n\t\tasync setCollectionRestricted({ id, restricted, acknowledgeDisclosure = false }) {\n\t\t\tconst res = await settingsWrite(() =>\n\t\t\t\tcollections.setCollectionRestricted({ id, restricted, acknowledgeDisclosure }),\n\t\t\t);\n\t\t\treturn collectionFromProto(res.collection);\n\t\t},\n\t\tasync listCollectionGrants(collectionId) {\n\t\t\tconst res = await settingsWrite(() => collections.listCollectionGrants({ collectionId }));\n\t\t\treturn res.grants.map((g) => ({\n\t\t\t\tuserId: g.userId,\n\t\t\t\tlevel: LEVEL_FROM_PROTO[g.level] ?? \"viewer\",\n\t\t\t}));\n\t\t},\n\t\tasync grantCollectionAccess({ collectionId, userId, level }) {\n\t\t\tawait settingsWrite(() =>\n\t\t\t\tcollections.grantCollectionAccess({\n\t\t\t\t\tcollectionId,\n\t\t\t\t\tuserId,\n\t\t\t\t\tlevel:\n\t\t\t\t\t\tlevel === \"editor\"\n\t\t\t\t\t\t\t? ProtoCollectionAccessLevel.EDITOR\n\t\t\t\t\t\t\t: ProtoCollectionAccessLevel.VIEWER,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\tasync revokeCollectionAccess({ collectionId, userId }) {\n\t\t\tawait settingsWrite(() => collections.revokeCollectionAccess({ collectionId, userId }));\n\t\t},\n\t\tasync listContents(input = {}) {\n\t\t\tconst view = input.view ?? { kind: \"main\" };\n\t\t\ttry {\n\t\t\t\tconst res = await contents.listContents({\n\t\t\t\t\tfilter: {\n\t\t\t\t\t\tcollectionId: input.collectionId ?? \"\",\n\t\t\t\t\t\tsearch: input.search ?? \"\",\n\t\t\t\t\t\tassigneeId: input.assigneeId ?? \"\",\n\t\t\t\t\t\tblueprintIds: input.blueprintIds ?? [],\n\t\t\t\t\t},\n\t\t\t\t\tview:\n\t\t\t\t\t\tview.kind === \"change_set\"\n\t\t\t\t\t\t\t? { case: \"changeSetId\", value: view.changeSetId }\n\t\t\t\t\t\t\t: view.kind === \"in_force\"\n\t\t\t\t\t\t\t\t? { case: \"inForce\", value: {} }\n\t\t\t\t\t\t\t\t: { case: undefined },\n\t\t\t\t\tpageSize: input.pageSize ?? 0,\n\t\t\t\t\tpageToken: input.pageToken ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn { contents: res.contents.map(contentFromProto), nextPageToken: res.nextPageToken };\n\t\t\t} catch (err) {\n\t\t\t\tconst ce = ConnectError.from(err);\n\t\t\t\tif (ce.code === Code.InvalidArgument) throw new InvalidInputError(ce.rawMessage);\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t\tasync createContent({ changeSetId, blueprintReleaseId, copyFrom }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.createContent({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tblueprintReleaseId,\n\t\t\t\t\t// A copy takes the source's data when none is given; a new\n\t\t\t\t\t// Content starts from empty data.\n\t\t\t\t\tdata: copyFrom ? undefined : {},\n\t\t\t\t\tcopyFrom: copyFrom\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tsource:\n\t\t\t\t\t\t\t\t\t\"revisionId\" in copyFrom\n\t\t\t\t\t\t\t\t\t\t? { case: \"revisionId\", value: copyFrom.revisionId }\n\t\t\t\t\t\t\t\t\t\t: { case: \"releaseId\", value: copyFrom.releaseId },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow contentRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync saveRevision({ changeSetId, branchId, expectedHeadId, data, fieldMask, idempotencyKey }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.saveRevision({\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId,\n\t\t\t\t\t// Through JSON: a Struct holds no `undefined`, which a form's\n\t\t\t\t\t// values may still carry under a key.\n\t\t\t\t\tdata: JSON.parse(JSON.stringify(data)) as JsonObject,\n\t\t\t\t\tfieldMask: fieldMask ? { fields: fieldMask } : undefined,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow saveRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\n\t\tasync getContent({ id, changeSetId, branchId }) {\n\t\t\tconst res = await contents.getContent({\n\t\t\t\tid,\n\t\t\t\tchangeSetId: changeSetId ?? \"\",\n\t\t\t\tbranchId: branchId ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: contentFromProto(res.content),\n\t\t\t\tblueprintRelease: resolvedReleaseFromBytes(res.resolvedRelease),\n\t\t\t\tattributes: attributesFromProto(res.attributes),\n\t\t\t};\n\t\t},\n\t\tasync getTimeline(contentId) {\n\t\t\tconst res = await contents.getTimeline({ contentId });\n\t\t\treturn {\n\t\t\t\tentries: res.entries.map(timelineEntryFromProto),\n\t\t\t\tplannedReleases: res.plannedReleases.map((p) => ({\n\t\t\t\t\tchangeSetId: p.changeSetId,\n\t\t\t\t\tplannedRelease: requiredPlannedRelease(p.plannedRelease),\n\t\t\t\t})),\n\t\t\t};\n\t\t},\n\t\tasync listRevisions({ target, pageSize, pageToken }) {\n\t\t\tconst res = await contents.listRevisions({\n\t\t\t\ttarget:\n\t\t\t\t\t\"contentId\" in target\n\t\t\t\t\t\t? { case: \"contentId\", value: target.contentId }\n\t\t\t\t\t\t: { case: \"branchId\", value: target.branchId },\n\t\t\t\tpageSize: pageSize ?? 0,\n\t\t\t\tpageToken: pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\trevisions: res.revisions.map(revisionFromProto),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync compare({ revisionId, base }) {\n\t\t\tconst res = await contents.compare({\n\t\t\t\trevisionId,\n\t\t\t\tbase:\n\t\t\t\t\tbase.kind === \"revision\"\n\t\t\t\t\t\t? { case: \"baseRevisionId\", value: base.revisionId }\n\t\t\t\t\t\t: base.kind === \"fork\"\n\t\t\t\t\t\t\t? { case: \"forkOfBranchId\", value: base.branchId }\n\t\t\t\t\t\t\t: { case: \"mainHead\", value: true },\n\t\t\t});\n\t\t\tconst kinds: Record<ProtoFieldChangeKind, \"added\" | \"removed\" | \"changed\"> = {\n\t\t\t\t[ProtoFieldChangeKind.UNSPECIFIED]: \"changed\",\n\t\t\t\t[ProtoFieldChangeKind.ADDED]: \"added\",\n\t\t\t\t[ProtoFieldChangeKind.REMOVED]: \"removed\",\n\t\t\t\t[ProtoFieldChangeKind.CHANGED]: \"changed\",\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tbase: revisionFromProto(res.base),\n\t\t\t\trevision: revisionFromProto(res.revision),\n\t\t\t\tchanges: res.changes.map((c) => ({\n\t\t\t\t\tpath: c.path,\n\t\t\t\t\tkind: kinds[c.kind] ?? \"changed\",\n\t\t\t\t\tbefore: c.before ? toJson(ValueSchema, c.before) : undefined,\n\t\t\t\t\tafter: c.after ? toJson(ValueSchema, c.after) : undefined,\n\t\t\t\t})),\n\t\t\t};\n\t\t},\n\t\tasync listReferences({ contentId, revisionId }) {\n\t\t\tconst res = await contents.listReferences({\n\t\t\t\tcontentId,\n\t\t\t\tat: { case: \"revisionId\", value: revisionId },\n\t\t\t\tdepth: 1,\n\t\t\t});\n\t\t\treturn res.references.map((r) => edgeFromProto(r.edge));\n\t\t},\n\t\tasync listReferrers({ contentId, includeOpenChangeSets, pageSize, pageToken }) {\n\t\t\tconst res = await contents.listReferrers({\n\t\t\t\tcontentId,\n\t\t\t\tincludeOpenChangeSets: includeOpenChangeSets ?? false,\n\t\t\t\tpageSize: pageSize ?? 0,\n\t\t\t\tpageToken: pageToken ?? \"\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\treferrers: res.referrers.map((r) => ({\n\t\t\t\t\tedge: edgeFromProto(r.edge),\n\t\t\t\t\treleaseId: r.releaseId,\n\t\t\t\t\tchangeSetId: r.changeSetId,\n\t\t\t\t\tbranchId: r.branchId,\n\t\t\t\t})),\n\t\t\t\tnextPageToken: res.nextPageToken,\n\t\t\t};\n\t\t},\n\t\tasync listOutdatedPins(input) {\n\t\t\tconst res = await contents.listOutdatedPins({\n\t\t\t\tsource:\n\t\t\t\t\t\"branchId\" in input\n\t\t\t\t\t\t? { case: \"branchId\", value: input.branchId }\n\t\t\t\t\t\t: { case: \"revisionId\", value: input.revisionId },\n\t\t\t});\n\t\t\treturn res.pins.map((p) => ({\n\t\t\t\tedge: edgeFromProto(p.edge),\n\t\t\t\tsupersededByReleaseId: p.supersededByReleaseId,\n\t\t\t\tinForceReleaseId: p.inForceReleaseId,\n\t\t\t}));\n\t\t},\n\n\t\tasync setContentCollections({ contentId, collectionIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.setContentCollections({ contentId, collectionIds }),\n\t\t\t);\n\t\t\treturn [...res.collectionIds];\n\t\t},\n\t\tasync setContentAssignees({ contentId, assigneeIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.setContentAssignees({ contentId, assigneeIds }),\n\t\t\t);\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync blockContent({ contentId, blockReasonId, allowedUserIds }) {\n\t\t\tconst res = await attributeWrite(() =>\n\t\t\t\tcontents.blockContent({ contentId, blockReasonId, allowedUserIds }),\n\t\t\t);\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync unblockContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.unblockContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync archiveContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.archiveContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\t\tasync unarchiveContent(contentId) {\n\t\t\tconst res = await attributeWrite(() => contents.unarchiveContent({ contentId }));\n\t\t\treturn attributesFromProto(res.attributes);\n\t\t},\n\n\t\tasync startEditing({ contentId, changeSetId, effectiveOn, changeSetName }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.startEditing({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tchangeSetId: changeSetId ?? \"\",\n\t\t\t\t\teffectiveOn: effectiveOn ?? \"\",\n\t\t\t\t\tchangeSetName: changeSetName ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tchangeSet: changeSetFromProto(res.changeSet),\n\t\t\t\t\tcontent: contentFromProto(res.content),\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId ?? \"\", err);\n\t\t\t}\n\t\t},\n\t\tasync previewChain({ changeSetId, contentId, effectiveOn, validityPeriod }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.previewChain({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tcontentId,\n\t\t\t\t\teffectiveOn,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t});\n\t\t\t\tconst p = res.preview;\n\t\t\t\treturn {\n\t\t\t\t\tforkReleaseId: p?.forkReleaseId ?? \"\",\n\t\t\t\t\tcarryForwardReleaseIds: [...(p?.carryForwardReleaseIds ?? [])],\n\t\t\t\t\tmergesMain: p?.mergesMain ?? false,\n\t\t\t\t\tcutIntoReleaseIds: (p?.cutInto ?? []).map((c) => c.releaseId),\n\t\t\t\t\tcoveredReleaseIds: [...(p?.coveredReleaseIds ?? [])],\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tthrow changeSetRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planRepeal({ changeSetId, contentId, lastDay }) {\n\t\t\ttry {\n\t\t\t\treturn plannedEndFromProto(\n\t\t\t\t\tawait changeSets.planRepeal({ changeSetId, contentId, lastDay }),\n\t\t\t\t);\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planWithdrawal({ changeSetId, contentId }) {\n\t\t\ttry {\n\t\t\t\treturn plannedEndFromProto(await changeSets.planWithdrawal({ changeSetId, contentId }));\n\t\t\t} catch (err) {\n\t\t\t\tthrow editRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync planRelease({\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\tvalidityPeriod,\n\t\t\treleaseSpec,\n\t\t\tsupersedesReleaseIds,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.planRelease({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\treleaseSpec: releaseSpec ? struct(releaseSpec) : undefined,\n\t\t\t\t\tsupersedesReleaseIds: supersedesReleaseIds ?? [],\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn requiredPlannedRelease(res.plannedRelease);\n\t\t\t} catch (err) {\n\t\t\t\tthrow planRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync updatePlannedRelease({\n\t\t\tchangeSetId,\n\t\t\tplannedReleaseId,\n\t\t\tvalidityPeriod,\n\t\t\treleaseSpec,\n\t\t\tsupersedesReleaseIds,\n\t\t\tidempotencyKey,\n\t\t}) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.updatePlannedRelease({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tplannedReleaseId,\n\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\treleaseSpec: releaseSpec ? struct(releaseSpec) : undefined,\n\t\t\t\t\tsupersedes: supersedesReleaseIds ? { releaseIds: supersedesReleaseIds } : undefined,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn requiredPlannedRelease(res.plannedRelease);\n\t\t\t} catch (err) {\n\t\t\t\tthrow planRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync appendBranch({ changeSetId, chainId, effectiveOn, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.appendBranch({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tchainId,\n\t\t\t\t\teffectiveOn,\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn { changeSet: changeSetFromProto(res.changeSet), branchId: res.branchId };\n\t\t},\n\t\tasync dropChain({ changeSetId, chainId, idempotencyKey }) {\n\t\t\tconst res = await changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.dropChain({ changeSetId, chainId, idempotencyKey: idempotencyKey ?? \"\" }),\n\t\t\t);\n\t\t\treturn changeSetFromProto(res.changeSet);\n\t\t},\n\t\tasync getPendingMerge(branchId) {\n\t\t\tconst res = await changeSets.getPendingMerge({ branchId });\n\t\t\tconst p = res.pendingMerge;\n\t\t\tif (!p) return null;\n\t\t\treturn {\n\t\t\t\tbranchId: p.branchId,\n\t\t\t\tcontentId: p.contentId,\n\t\t\t\treason: p.reason === ProtoPendingMergeReason.INVALID ? \"invalid\" : \"conflict\",\n\t\t\t\toursRevisionId: p.oursRevisionId,\n\t\t\t\ttheirsRevisionId: p.theirsRevisionId,\n\t\t\t\tcarried: p.carried,\n\t\t\t\tfields: res.fields.map(mergeFieldFromProto),\n\t\t\t\tmerged: res.merged ? { ...res.merged } : {},\n\t\t\t} satisfies PendingMerge;\n\t\t},\n\t\tasync resolveMerge({ changeSetId, branchId, expectedHeadId, resolutions, idempotencyKey }) {\n\t\t\ttry {\n\t\t\t\tconst res = await changeSets.resolveMerge({\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId,\n\t\t\t\t\tresolutions: resolutions.map((r) => ({\n\t\t\t\t\t\tpath: r.path,\n\t\t\t\t\t\tchoice:\n\t\t\t\t\t\t\t\"side\" in r\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tcase: \"side\" as const,\n\t\t\t\t\t\t\t\t\t\tvalue: r.side === \"ours\" ? ProtoMergeSide.OURS : ProtoMergeSide.THEIRS,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\tcase: \"value\" as const,\n\t\t\t\t\t\t\t\t\t\tvalue: fromJson(ValueSchema, (r.value ?? null) as JsonValue),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t})),\n\t\t\t\t\tidempotencyKey: idempotencyKey ?? \"\",\n\t\t\t\t});\n\t\t\t\treturn contentFromProto(res.content);\n\t\t\t} catch (err) {\n\t\t\t\tthrow saveRefusal(changeSetId, err);\n\t\t\t}\n\t\t},\n\t\tasync abortMerge({ changeSetId, branchId, idempotencyKey }) {\n\t\t\tawait changeSetWrite(changeSetId, () =>\n\t\t\t\tchangeSets.abortMerge({ branchId, idempotencyKey: idempotencyKey ?? \"\" }),\n\t\t\t);\n\t\t},\n\t\tasync previewInForce({ contentId, changeSetId, validOn }) {\n\t\t\tconst res = await releases.getInForce({\n\t\t\t\tcontentIds: [contentId],\n\t\t\t\tat: { validOn: validOn ?? \"\" },\n\t\t\t\tpreviewChangeSetId: changeSetId,\n\t\t\t});\n\t\t\tconst row = res.contents.find((c) => c.contentId === contentId);\n\t\t\tif (!row) return null;\n\t\t\treturn {\n\t\t\t\treleaseId: row.releaseId,\n\t\t\t\trevisionId: row.revisionId,\n\t\t\t\tplanned: row.planned,\n\t\t\t\twithheld: row.withheld,\n\t\t\t\tvalidityPeriod: periodFromProto(row.validityPeriod),\n\t\t\t\tdata: row.data ? { ...row.data } : {},\n\t\t\t};\n\t\t},\n\t};\n}\n","import { createContext, type ReactNode, useContext } from \"react\";\n\n/** The settings page's tabs, as `?tab=` names them. */\nexport type ContenthubSettingsTab = \"required-checks\" | \"block-reasons\" | \"collections\";\n\n/**\n * Where the host mounts this package's screens, for the links the screens draw\n * themselves (breadcrumbs), which have to be a plain `to`. Navigation a\n * screen asks for is never a path from here: only the host knows its router,\n * so that goes through callbacks (knkcms/core ADR 0003). Keys join as\n * screens arrive.\n */\nexport interface ContenthubPaths {\n\t/**\n\t * The host's settings index, which contenthub's settings screens sit under\n\t * in its navigation. Without one, their \"Settings\" breadcrumb is text.\n\t */\n\tsettings?: string;\n\t/**\n\t * contenthub's settings page (`ContenthubSettings`). Its tabs are\n\t * addressed as `?tab=`: build a link to one with `contenthubSettingsPath`.\n\t */\n\tcontenthubSettings: string;\n\t/** The Change Sets index, which a Change Set's page leads back to. */\n\tchangeSets: string;\n\t/** The Content Library, which a Content's page leads back to. */\n\tcontents: string;\n}\n\n/** The harness's paths (ADR 0020): it has no settings index of its own. */\nexport const STANDALONE_CONTENTHUB_PATHS: ContenthubPaths = {\n\tcontenthubSettings: \"/settings\",\n\tchangeSets: \"/change-sets\",\n\tcontents: \"/content\",\n};\n\n/**\n * contenthub's settings page in `paths`, at `tab` when one is named\n * (`?tab=block-reasons`); without one it opens on its first tab.\n */\nexport function contenthubSettingsPath(\n\tpaths: ContenthubPaths,\n\ttab?: ContenthubSettingsTab,\n): string {\n\treturn tab ? `${paths.contenthubSettings}?tab=${tab}` : paths.contenthubSettings;\n}\n\nconst PathsContext = createContext<ContenthubPaths>(STANDALONE_CONTENTHUB_PATHS);\n\nexport interface ContenthubPathsProviderProps {\n\tpaths: ContenthubPaths;\n\tchildren: ReactNode;\n}\n\nexport function ContenthubPathsProvider({ paths, children }: ContenthubPathsProviderProps) {\n\treturn <PathsContext.Provider value={paths}>{children}</PathsContext.Provider>;\n}\n\nexport function useContenthubPaths(): ContenthubPaths {\n\treturn useContext(PathsContext);\n}\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { z } from \"zod\";\nimport {\n\tBLOCK_REASON_NAME_MAX,\n\tBlockReasonNameTakenError,\n\tInvalidInputError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\n\ntype NameValues = { name: string };\n\nexport interface BlockReasonNameModalProps {\n\topen: boolean;\n\t/** Which of the two the modal is: its title, its submit and its form id follow. */\n\tmode: \"create\" | \"rename\";\n\t/** The name the field starts from each time the modal opens. */\n\tinitialName: string;\n\tonClose: () => void;\n\t/**\n\t * Sends the name. A `BlockReasonNameTakenError` or `InvalidInputError` it\n\t * rejects with is shown on the field; anything else above it.\n\t */\n\tonSubmit: (name: string) => Promise<void>;\n}\n\n/**\n * Asks for a Block Reason's name, for a create or a rename. The form checks\n * the service's rule first (internal/workspaceconfig: trimmed, not blank, at\n * most 200 characters, one line) so most mistakes are said before a request;\n * the service's own refusals land on the same field.\n *\n * Kept mounted and driven by `open`, with `lazyMount unmountOnExit`, as\n * anker's Modal rule says; every opening resets the form, since an\n * interrupted exit never unmounts the content.\n */\nexport function BlockReasonNameModal({\n\topen,\n\tmode,\n\tinitialName,\n\tonClose,\n\tonSubmit,\n}: BlockReasonNameModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst formId = `contenthub-block-reason-${mode}`;\n\tconst schema = useMemo(\n\t\t() =>\n\t\t\tz.object({\n\t\t\t\tname: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.trim()\n\t\t\t\t\t.min(1, t(\"blockReasons.form.nameRequired\"))\n\t\t\t\t\t.max(\n\t\t\t\t\t\tBLOCK_REASON_NAME_MAX,\n\t\t\t\t\t\tt(\"blockReasons.form.nameTooLong\", { max: BLOCK_REASON_NAME_MAX }),\n\t\t\t\t\t)\n\t\t\t\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\t\t\t\t.regex(/^[^\\u0000-\\u001f\\u007f]*$/, t(\"blockReasons.form.oneLine\")),\n\t\t\t}),\n\t\t[t],\n\t);\n\tconst methods = useForm<NameValues>({\n\t\tresolver: zodResolver(schema),\n\t\tdefaultValues: { name: initialName },\n\t});\n\tconst [failed, setFailed] = useState(false);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ name: initialName });\n\t\t\tsetFailed(false);\n\t\t}\n\t}, [open, initialName, methods]);\n\n\tconst submit = methods.handleSubmit(async ({ name }) => {\n\t\tsetFailed(false);\n\t\ttry {\n\t\t\tawait onSubmit(name);\n\t\t} catch (err) {\n\t\t\tif (err instanceof BlockReasonNameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"blockReasons.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tmethods.setError(\"name\", { message: err.message });\n\t\t\t} else {\n\t\t\t\tsetFailed(true);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\n\t\t\t\tmode === \"create\" ? \"blockReasons.form.createTitle\" : \"blockReasons.form.renameTitle\",\n\t\t\t)}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={formId} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\n\t\t\t\t\t\t\tmode === \"create\"\n\t\t\t\t\t\t\t\t? \"blockReasons.form.createSubmit\"\n\t\t\t\t\t\t\t\t: \"blockReasons.form.renameSubmit\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={formId}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<NameValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"blockReasons.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"blockReasons.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{failed ? <Alert status=\"error\" title={t(\"blockReasons.form.failed\")} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlockReason } from \"../types\";\n\nexport interface RemoveBlockReasonModalProps {\n\t/** The Block Reason to remove; null while the modal is closed. */\n\treason: BlockReason | null;\n\tonClose: () => void;\n\tonConfirm: (reason: BlockReason) => Promise<void>;\n}\n\n/**\n * Confirms removing a Block Reason. The screen renders it rather than relying\n * on a host's confirm provider: a host mounting this screen owes it nothing\n * beyond the host contract.\n */\nexport function RemoveBlockReasonModal({\n\treason,\n\tonClose,\n\tonConfirm,\n}: RemoveBlockReasonModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst open = reason !== null;\n\t// Latched, so the name doesn't go blank while the modal animates out.\n\tconst [shown, setShown] = useState<BlockReason | null>(reason);\n\tif (reason && reason !== shown) setShown(reason);\n\tconst [removing, setRemoving] = useState(false);\n\tconst [failed, setFailed] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetRemoving(false);\n\t\t\tsetFailed(false);\n\t\t}\n\t}, [open]);\n\n\tconst confirm = async () => {\n\t\tif (!reason) return;\n\t\tsetRemoving(true);\n\t\tsetFailed(false);\n\t\ttry {\n\t\t\tawait onConfirm(reason);\n\t\t} catch {\n\t\t\tsetFailed(true);\n\t\t} finally {\n\t\t\tsetRemoving(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"blockReasons.removeDialog.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={removing}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"blockReasons.removeDialog.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text>{t(\"blockReasons.removeDialog.message\", { name: shown?.name ?? \"\" })}</Text>\n\t\t\t\t{failed ? <Alert status=\"error\" title={t(\"blockReasons.removeDialog.failed\")} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DateCell, MenuCell, Toolbar, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { IndexPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { Lock, Pencil, Plus, Trash2 } from \"lucide-react\";\nimport { type ReactNode, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubSettingsPath, useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlockReason } from \"../types\";\nimport { BlockReasonNameModal } from \"./block-reason-name-modal\";\nimport { RemoveBlockReasonModal } from \"./remove-block-reason-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype BlockReasonRow = BlockReason & Record<string, unknown>;\n\nexport interface BlockReasonsSettingsProps {\n\tclient: ContenthubClient;\n}\n\nfunction useBlockReasons(client: ContenthubClient) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t});\n}\n\n/**\n * The create button. Its label is passed in, never translated here: as a\n * reported header action it renders outside the screen's providers.\n */\nfunction CreateBlockReasonButton({ label, onClick }: { label: string; onClick: () => void }) {\n\treturn (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClick}>\n\t\t\t<Plus size={16} />\n\t\t\t{label}\n\t\t</Button>\n\t);\n}\n\ninterface BlockReasonsBodyProps {\n\tclient: ContenthubClient;\n\t/** The create Modal is open; the caller places the button that opens it. */\n\tcreating: boolean;\n\tonCreatingChange: (creating: boolean) => void;\n\t/** Drawn above the table: the Toolbar, wherever the caller wants its create button. */\n\ttoolbar?: ReactNode;\n}\n\n/**\n * The Block Reasons table with its Modals, shared by the settings page's tab\n * and the standalone screen, which differ only in where the create button\n * sits. Every change goes through the client and is then read back, so the\n * list shows what contenthub holds.\n */\nfunction BlockReasonsBody({ client, creating, onCreatingChange, toolbar }: BlockReasonsBodyProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst [renaming, setRenaming] = useState<BlockReason | null>(null);\n\tconst [removing, setRemoving] = useState<BlockReason | null>(null);\n\tconst query = useBlockReasons(client);\n\tconst reasons = query.data ?? [];\n\tconst refresh = () => queryClient.invalidateQueries({ queryKey: contenthubKeys.blockReasons() });\n\n\tconst columns = useMemo<ColumnDef<BlockReasonRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"blockReasons.columns.name\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={row.original.name} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"updated\",\n\t\t\t\theader: t(\"blockReasons.columns.updated\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.updateTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"blockReasons.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<MenuCell\n\t\t\t\t\t\t// Both inline: two actions are no menu's worth.\n\t\t\t\t\t\tmenuThreshold={2}\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"blockReasons.rename\"),\n\t\t\t\t\t\t\t\ticon: Pencil,\n\t\t\t\t\t\t\t\tonClick: () => setRenaming(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"blockReasons.remove\"),\n\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\tonClick: () => setRemoving(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t{toolbar}\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"blockReasons.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={reasons as BlockReasonRow[]}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<Lock size={32} />}\n\t\t\t\t\t\theader={t(\"blockReasons.empty\")}\n\t\t\t\t\t\tdescription={t(\"blockReasons.emptyHint\")}\n\t\t\t\t\t\tactions={\n\t\t\t\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\t\t\t\tonClick={() => onCreatingChange(true)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<BlockReasonNameModal\n\t\t\t\topen={creating}\n\t\t\t\tmode=\"create\"\n\t\t\t\tinitialName=\"\"\n\t\t\t\tonClose={() => onCreatingChange(false)}\n\t\t\t\tonSubmit={async (name) => {\n\t\t\t\t\tawait client.createBlockReason({ name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tonCreatingChange(false);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<BlockReasonNameModal\n\t\t\t\topen={renaming !== null}\n\t\t\t\tmode=\"rename\"\n\t\t\t\tinitialName={renaming?.name ?? \"\"}\n\t\t\t\tonClose={() => setRenaming(null)}\n\t\t\t\tonSubmit={async (name) => {\n\t\t\t\t\tif (!renaming) return;\n\t\t\t\t\tawait client.renameBlockReason({ id: renaming.id, name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRenaming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<RemoveBlockReasonModal\n\t\t\t\treason={removing}\n\t\t\t\tonClose={() => setRemoving(null)}\n\t\t\t\tonConfirm={async (reason) => {\n\t\t\t\t\tawait client.deleteBlockReason({ id: reason.id });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRemoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n\nfunction BlockReasonsCount({ client }: { client: ContenthubClient }) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst count = useBlockReasons(client).data?.length ?? 0;\n\treturn <Toolbar.Count>{t(\"blockReasons.count\", { count })}</Toolbar.Count>;\n}\n\n/**\n * The Block Reasons as a tab of the settings page (`ContenthubSettings`):\n * its create button sits in the tab's Toolbar, as anker places a tab's add.\n */\nexport function BlockReasonsTab({ client }: BlockReasonsSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [creating, setCreating] = useState(false);\n\treturn (\n\t\t<BlockReasonsBody\n\t\t\tclient={client}\n\t\t\tcreating={creating}\n\t\t\tonCreatingChange={setCreating}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<BlockReasonsCount client={client} />\n\t\t\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t/>\n\t);\n}\n\n/**\n * The workspace's Block Reasons (CONTEXT.md) on a page of their own, for a\n * host that mounts them apart from `ContenthubSettings`, which holds them as\n * a tab: listed by name, created from the header in a Modal (anker: no\n * inline create form above a DataTable), renamed and removed from each row.\n *\n * An index page, not a settings template: it is one list, and\n * SettingsPageTemplate is for two or more tabs.\n */\nexport function BlockReasonsSettings({ client }: BlockReasonsSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst [creating, setCreating] = useState(false);\n\n\treturn (\n\t\t<IndexPageTemplate\n\t\t\ttitle={t(\"blockReasons.title\")}\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"settings.section\"), to: paths.settings },\n\t\t\t\t{ label: t(\"settings.title\"), to: contenthubSettingsPath(paths) },\n\t\t\t\t{ label: t(\"blockReasons.title\") },\n\t\t\t]}\n\t\t\t// Rendered by the host away from the screen's providers: it closes\n\t\t\t// over state, and the Modal it opens is rendered by the screen.\n\t\t\tactions={\n\t\t\t\t<CreateBlockReasonButton\n\t\t\t\t\tlabel={t(\"blockReasons.create\")}\n\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t/>\n\t\t\t}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<BlockReasonsCount client={client} />\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t>\n\t\t\t<BlockReasonsBody client={client} creating={creating} onCreatingChange={setCreating} />\n\t\t</IndexPageTemplate>\n\t);\n}\n\nBlockReasonsSettings.displayName = \"BlockReasonsSettings\";\n","import { useCallback, useRef } from \"react\";\nimport {\n\tChangeSetClosedError,\n\tContentRefusedError,\n\tCoversReleaseError,\n\tInvalidInputError,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\n\n/**\n * Whether a failure is the service's answer to the write (a refusal), so\n * its key is spent and the next attempt is a new one; anything else (the\n * network, the service away) leaves the outcome unknown and the key kept.\n */\nexport function isAnswer(err: unknown): boolean {\n\treturn (\n\t\terr instanceof InvalidInputError ||\n\t\terr instanceof StaleHeadError ||\n\t\terr instanceof ContentRefusedError ||\n\t\terr instanceof ChangeSetClosedError ||\n\t\terr instanceof CoversReleaseError\n\t);\n}\n\n/**\n * A fresh Idempotency Key for one write attempt (CONTEXT.md, Idempotency\n * Key): sent again only when the same attempt is retried after a failure\n * whose outcome is unknown, so a write that did commit is answered rather\n * than repeated.\n */\nexport function newIdempotencyKey(what: string): string {\n\treturn `contenthub-ui/${what}/${globalThis.crypto.randomUUID()}`;\n}\n\n/**\n * The keys of one kind of write: `keyFor(asked)` answers the key of the\n * attempt still unanswered when it asked the same (a retry), and a new key\n * otherwise; `settle()` after any answer, success or refusal, so the next\n * write is a new attempt.\n */\nexport function useAttemptKey(what: string) {\n\tconst attempt = useRef<{ asked: string; key: string } | null>(null);\n\tconst keyFor = useCallback(\n\t\t(asked: unknown) => {\n\t\t\tconst json = JSON.stringify(asked);\n\t\t\tif (attempt.current?.asked !== json) {\n\t\t\t\tattempt.current = { asked: json, key: newIdempotencyKey(what) };\n\t\t\t}\n\t\t\treturn attempt.current.key;\n\t\t},\n\t\t[what],\n\t);\n\tconst settle = useCallback(() => {\n\t\tattempt.current = null;\n\t}, []);\n\treturn { keyFor, settle };\n}\n","import { Card, DescriptionList } from \"@knkcs/anker/components\";\nimport { Box, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentDetail, ResolvedField } from \"../types\";\n\nconst ContentDataFields = lazy(() => import(\"./content-data-fields\"));\n\n/** A value shown as text: strings as they are, anything else as JSON. */\nexport function valueText(value: unknown): string {\n\tif (value === undefined || value === null || value === \"\") return \"—\";\n\treturn typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\n/**\n * The fields to show without fieldkit: the Blueprint Release's, by their\n * names, then any data no field declares, by its accessor.\n */\nexport function plainRows(fields: ResolvedField[], data: Record<string, unknown>) {\n\tconst declared = fields\n\t\t.filter((f) => !f.config.hidden)\n\t\t.map((f) => ({\n\t\t\tkey: f.config.api_accessor,\n\t\t\tlabel: f.config.name,\n\t\t\tvalue: data[f.config.api_accessor],\n\t\t}));\n\tconst known = new Set(fields.map((f) => f.config.api_accessor));\n\tconst rest = Object.keys(data)\n\t\t.filter((k) => !known.has(k))\n\t\t.map((k) => ({ key: k, label: k, value: data[k] }));\n\treturn [...declared, ...rest];\n}\n\n/**\n * The Data tab (spec #56, story 90): the Content's data as read, Main's head\n * or, for Content born in a Change Set, its Branch head, read-only. Editing\n * happens in a Branch, never here. A form tab, so it pads itself.\n */\nexport function ContentDataTab({ detail }: { detail: ContentDetail }) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { content, blueprintRelease } = detail;\n\tconst labels = useMemo(\n\t\t() => ({\n\t\t\tdefaultTab: t(\"content.data.general\"),\n\t\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\t\tsearchLabel: t(\"content.data.find\"),\n\t\t\tnoResults: t(\"content.data.noFields\"),\n\t\t\tbooleanYes: t(\"content.data.yes\"),\n\t\t\tbooleanNo: t(\"content.data.no\"),\n\t\t}),\n\t\t[t],\n\t);\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{content.changeSetId\n\t\t\t\t\t\t? t(\"content.data.readOnBranch\", { revision: content.revisionId })\n\t\t\t\t\t\t: t(\"content.data.readOnMain\", { revision: content.revisionId })}\n\t\t\t\t</Text>\n\t\t\t\t{blueprintRelease && blueprintRelease.fields.length > 0 ? (\n\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t<ContentDataFields\n\t\t\t\t\t\t\tfields={blueprintRelease.fields}\n\t\t\t\t\t\t\tdata={content.data}\n\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Suspense>\n\t\t\t\t) : (\n\t\t\t\t\t<Card>\n\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t{plainRows(blueprintRelease?.fields ?? [], content.data).map((row) => (\n\t\t\t\t\t\t\t\t<DescriptionList.Row key={row.key} label={row.label}>\n\t\t\t\t\t\t\t\t\t{valueText(row.value)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t</Card>\n\t\t\t\t)}\n\t\t\t</Stack>\n\t\t</Box>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CompareBase, FieldChange } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\nimport { valueText } from \"./content-data-tab\";\n\ntype ChangeRow = FieldChange & Record<string, unknown>;\n\n/** What the Compare tab compares the Branch's head against. */\nexport type BranchCompareBase = \"fork\" | \"main\";\n\n/**\n * The Compare tab (spec #56, story 23): the Branch's head against the\n * Revision its Branch forked from, or against Main's head, field by field.\n * It compares what is saved: a draft not yet saved isn't in it. Content born\n * in the Change Set has no Main to compare with. A table, so flush below its\n * own padded switch.\n */\nexport function BranchCompareTab({\n\tclient,\n\tcontentId,\n\tbranchId,\n\theadRevisionId,\n\tchain,\n\tcompareBase,\n\tonCompareBase,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst born = chain?.born ?? false;\n\tconst against: BranchCompareBase = born ? \"fork\" : compareBase;\n\tconst base: CompareBase = against === \"main\" ? { kind: \"main_head\" } : { kind: \"fork\", branchId };\n\tconst comparison = useQuery({\n\t\tqueryKey: contenthubKeys.contentCompare(contentId, headRevisionId, base),\n\t\tqueryFn: () => client.compare({ revisionId: headRevisionId, base }),\n\t\tenabled: headRevisionId !== \"\",\n\t});\n\tconst columns = useMemo<ColumnDef<ChangeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"field\",\n\t\t\t\theader: t(\"content.compare.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.compare.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.compare.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"before\",\n\t\t\t\theader: t(\"content.compare.columns.before\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.before)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"after\",\n\t\t\t\theader: t(\"content.compare.columns.after\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.after)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"6\" pb=\"4\">\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant={against === \"fork\" ? \"solid\" : \"outline\"}\n\t\t\t\t\t\taria-pressed={against === \"fork\"}\n\t\t\t\t\t\tonClick={() => onCompareBase(\"fork\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.compare.fork\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant={against === \"main\" ? \"solid\" : \"outline\"}\n\t\t\t\t\t\taria-pressed={against === \"main\"}\n\t\t\t\t\t\tdisabled={born}\n\t\t\t\t\t\tonClick={() => onCompareBase(\"main\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.compare.main\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t\t{comparison.data ? (\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.compare.between\", {\n\t\t\t\t\t\t\thead: comparison.data.revision.id,\n\t\t\t\t\t\t\tbase: comparison.data.base.id,\n\t\t\t\t\t\t})}\n\t\t\t\t\t</Text>\n\t\t\t\t) : null}\n\t\t\t\t{born ? (\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.compare.born\")}\n\t\t\t\t\t</Text>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t\t{comparison.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.compare.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : !comparison.data ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={comparison.data.changes as ChangeRow[]}\n\t\t\t\t\tgetRowId={(row) => row.path}\n\t\t\t\t\temptyState={<EmptyState header={t(\"content.compare.same\")} />}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\nconst BranchContentFields = lazy(() => import(\"./branch-content-fields\"));\n\n/**\n * The Content tab (spec #56): the Branch's data in the Blueprint Release's\n * form. Its draft is the form the editor holds above the tabs; this tab only\n * draws it, so leaving and coming back loses nothing. A form tab, so it pads\n * itself.\n */\nexport function BranchContentTab({\n\tclient,\n\tchangeSetId,\n\tbranchId,\n\trecord,\n\treadOnly,\n\tmediaSource,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst labels = useMemo(\n\t\t() => ({\n\t\t\tdefaultTab: t(\"content.data.general\"),\n\t\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\t\tsearchLabel: t(\"content.data.find\"),\n\t\t\tnoResults: t(\"content.data.noFields\"),\n\t\t\tunsavedChanges: t(\"branch.unsavedChanges\"),\n\t\t\tbooleanYes: t(\"content.data.yes\"),\n\t\t\tbooleanNo: t(\"content.data.no\"),\n\t\t}),\n\t\t[t],\n\t);\n\tconst release = record.blueprintRelease;\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t{release ? (\n\t\t\t\t// noValidate: fieldkit's fields render the native `required`, and a\n\t\t\t\t// browser refuses to submit a form whose invalid control sits in a\n\t\t\t\t// hidden section; the resolver validates (fieldkit's spec-form.mdx).\n\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t<BranchContentFields\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\t\t\t\tbranchId={branchId}\n\t\t\t\t\t\t\tfields={release.fields}\n\t\t\t\t\t\t\tparts={release.parts}\n\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\tmediaSource={mediaSource}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Suspense>\n\t\t\t\t</form>\n\t\t\t) : (\n\t\t\t\t<Alert status=\"warning\" title={t(\"branch.noRelease\")} />\n\t\t\t)}\n\t\t</Box>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DescriptionList, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField } from \"@knkcs/anker/forms\";\nimport { Alert, Box, Heading, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { CalendarPlus } from \"lucide-react\";\nimport { lazy, Suspense, useMemo } from \"react\";\nimport { type FieldValues, FormProvider, type UseFormReturn, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedRelease, ResolvedField, ValidityPeriod } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\nconst BranchContentFields = lazy(() => import(\"./branch-content-fields\"));\n\n/** The Release tab's period and supersedes: the Planned Release's own, beside its Release Spec values. */\nexport interface PlanValues {\n\tfirstDay: string;\n\tlastDay: string;\n\tsupersedes: string[];\n\t/** Whether the Branch's Release is planned, or is to be by the next Save. */\n\tplan: boolean;\n}\n\n/**\n * The Release tab's draft, held above the tabs as the Content's form is\n * (anker ADR 0004): the plan's period and supersedes in one form, its\n * Release Spec values in fieldkit's form over the Blueprint Release's\n * Release Spec. The editor's Save sends it after the Content.\n */\nexport interface ReleaseDraft {\n\tplan: UseFormReturn<PlanValues>;\n\tspec: UseFormReturn<FieldValues>;\n\t/** The Branch's Planned Release as the editor loaded or last saved it; absent while unplanned. */\n\tplanned?: PlannedRelease;\n\t/** The Release Spec Fields of the Blueprint Release the Branch's head pins. */\n\tspecFields: ResolvedField[];\n\t/** Whether the drafts are seeded: until then the tab shows a spinner. */\n\tseeded: boolean;\n}\n\n/** A Validity Period as a line: \"2026-10-01 – …\" for an open end. */\nexport function periodText(p: ValidityPeriod | undefined): string {\n\treturn p ? `${p.firstDay} – ${p.lastDay || \"…\"}` : \"—\";\n}\n\n/**\n * The plan's own check, before anything is sent: a first day for Dated\n * Content, and a last day, if any, on or after it. The service checks again.\n */\nexport function planIssues(\n\tvalues: PlanValues,\n\tdated: boolean,\n): { path: \"firstDay\" | \"lastDay\"; key: string }[] {\n\tif (!values.plan || !dated) return [];\n\tconst issues: { path: \"firstDay\" | \"lastDay\"; key: string }[] = [];\n\tif (!DAY.test(values.firstDay))\n\t\tissues.push({ path: \"firstDay\", key: \"branch.release.firstDayRequired\" });\n\tif (values.lastDay !== \"\" && (!DAY.test(values.lastDay) || values.lastDay < values.firstDay)) {\n\t\tissues.push({ path: \"lastDay\", key: \"branch.release.lastDayBefore\" });\n\t}\n\treturn issues;\n}\n\ntype ProposalRow = PlannedRelease & Record<string, unknown>;\n\n/**\n * The Release tab (spec #56, stories 27 to 31): the Branch's Planned Release\n * (its Validity Period and Release Spec values, and the Releases it\n * supersedes) as a draft the header's Save sends, and, read-only, what the\n * plan causes: the cuts and tails the Change Set proposes for the Content,\n * and the Releases a period would cover entirely. Proposals are derived from\n * the plans by the service, never edited here. A form tab, so it pads itself.\n *\n * Release Spec values are typed; prefilling them from the Source or a\n * Content field waits on blueprinthub declaring where they come from (#108).\n */\nexport function BranchReleaseTab(ctx: BranchTabContext) {\n\tconst { client, changeSetId, contentId, branchId, record, readOnly, release, changeSet, chain } =\n\t\tctx;\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst dated = record.blueprintRelease?.dated ?? false;\n\tconst planning = useWatch({ control: release.plan.control, name: \"plan\" });\n\tconst firstDay = useWatch({ control: release.plan.control, name: \"firstDay\" }) ?? \"\";\n\tconst lastDay = useWatch({ control: release.plan.control, name: \"lastDay\" }) ?? \"\";\n\tconst published = chain ? !chain.born : false;\n\n\tconst timeline = useQuery({\n\t\tqueryKey: contenthubKeys.contentTimeline(contentId),\n\t\tqueryFn: () => client.getTimeline(contentId),\n\t\tenabled: published,\n\t});\n\tconst releaseOptions = useMemo(\n\t\t() =>\n\t\t\t(timeline.data?.entries ?? []).map((e) => ({\n\t\t\t\tid: e.releaseId,\n\t\t\t\tlabel: e.validityPeriod\n\t\t\t\t\t? `#${e.ordinal} · ${periodText(e.validityPeriod)}`\n\t\t\t\t\t: `#${e.ordinal} · ${e.publishTime.slice(0, 10)}`,\n\t\t\t})),\n\t\t[timeline.data],\n\t);\n\n\t// What the drafted period would cut into and cover, before it is saved:\n\t// PreviewChain's answer for the period, which writes nothing.\n\tconst canPreview =\n\t\tplanning && dated && published && DAY.test(firstDay) && (lastDay === \"\" || DAY.test(lastDay));\n\tconst preview = useQuery({\n\t\tqueryKey: contenthubKeys.chainPreview(contentId, changeSetId, firstDay, lastDay),\n\t\tqueryFn: () =>\n\t\t\tclient.previewChain({\n\t\t\t\tchangeSetId,\n\t\t\t\tcontentId,\n\t\t\t\teffectiveOn: firstDay,\n\t\t\t\tvalidityPeriod: { firstDay, lastDay },\n\t\t\t}),\n\t\tenabled: canPreview,\n\t});\n\n\tconst proposals = useMemo(\n\t\t() =>\n\t\t\t(changeSet?.plannedReleases ?? []).filter(\n\t\t\t\t(p) => p.contentId === contentId && p.proposed,\n\t\t\t) as ProposalRow[],\n\t\t[changeSet, contentId],\n\t);\n\tconst columns = useMemo<ColumnDef<ProposalRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"branch.release.columns.ends\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.proposedForReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"what\",\n\t\t\t\theader: t(\"branch.release.columns.what\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.splitFromReleaseId\n\t\t\t\t\t\t\t\t? t(\"branch.release.tail\", { release: row.original.splitFromReleaseId })\n\t\t\t\t\t\t\t\t: t(\"branch.release.cut\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsubText={row.original.withheld ? t(\"branch.release.withheld\") : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"branch.release.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(row.original.validityPeriod)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\tif (!release.seeded) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\n\tconst labels = {\n\t\tdefaultTab: t(\"branch.release.specTitle\"),\n\t\tsearchPlaceholder: t(\"content.data.find\"),\n\t\tsearchLabel: t(\"content.data.find\"),\n\t\tnoResults: t(\"content.data.noFields\"),\n\t\tunsavedChanges: t(\"branch.unsavedChanges\"),\n\t\tbooleanYes: t(\"content.data.yes\"),\n\t\tbooleanNo: t(\"content.data.no\"),\n\t};\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t{!planning ? (\n\t\t\t\t\t<Stack gap=\"3\" align=\"start\">\n\t\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.release.unplanned\")} />\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\trelease.plan.setValue(\"plan\", true, { shouldDirty: true, shouldTouch: true })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CalendarPlus size={16} />\n\t\t\t\t\t\t\t{t(\"branch.release.planIt\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t) : (\n\t\t\t\t\t<Stack gap=\"5\">\n\t\t\t\t\t\t<FormProvider {...release.plan}>\n\t\t\t\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t\t\t\t<HStack gap=\"4\" align=\"start\">\n\t\t\t\t\t\t\t\t\t\t\t<InputField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\t\tname=\"firstDay\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.firstDay\")}\n\t\t\t\t\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t<InputField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\t\tname=\"lastDay\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.lastDay\")}\n\t\t\t\t\t\t\t\t\t\t\t\thelperText={t(\"branch.release.lastDayHelp\")}\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"branch.release.undated\")}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{published ? (\n\t\t\t\t\t\t\t\t\t\t<BaseSelectField<PlanValues>\n\t\t\t\t\t\t\t\t\t\t\tname=\"supersedes\"\n\t\t\t\t\t\t\t\t\t\t\tlabel={t(\"branch.release.supersedes\")}\n\t\t\t\t\t\t\t\t\t\t\thelperText={t(\"branch.release.supersedesHelp\")}\n\t\t\t\t\t\t\t\t\t\t\toptions={releaseOptions}\n\t\t\t\t\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\t\t\t\t\tplaceholder={t(\"branch.release.supersedesNone\")}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={readOnly}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</FormProvider>\n\t\t\t\t\t\t{release.specFields.length > 0 ? (\n\t\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t\t<Heading size=\"sm\">{t(\"branch.release.specTitle\")}</Heading>\n\t\t\t\t\t\t\t\t<FormProvider {...release.spec}>\n\t\t\t\t\t\t\t\t\t<form noValidate onSubmit={(e) => e.preventDefault()}>\n\t\t\t\t\t\t\t\t\t\t<Suspense fallback={<Spinner size=\"sm\" />}>\n\t\t\t\t\t\t\t\t\t\t\t<BranchContentFields\n\t\t\t\t\t\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\t\t\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\t\t\t\t\t\t\t\t\t// SpecForm's record key: the Release Spec's form is\n\t\t\t\t\t\t\t\t\t\t\t\t// its own record, apart from the Content's.\n\t\t\t\t\t\t\t\t\t\t\t\tbranchId={`${branchId}/release`}\n\t\t\t\t\t\t\t\t\t\t\t\tfields={release.specFields}\n\t\t\t\t\t\t\t\t\t\t\t\tparts={record.blueprintRelease?.parts ?? {}}\n\t\t\t\t\t\t\t\t\t\t\t\tlabels={labels}\n\t\t\t\t\t\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</Suspense>\n\t\t\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t\t\t</FormProvider>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data ? (\n\t\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.release.cutsInto\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.cutIntoReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.release.covers\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.coveredReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data && preview.data.coveredReleaseIds.length > 0 ? (\n\t\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\t\ttitle={t(\"branch.release.coversWarning\", {\n\t\t\t\t\t\t\t\t\treleases: preview.data.coveredReleaseIds.join(\", \"),\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t)}\n\t\t\t</Box>\n\t\t\t<Box role=\"region\" aria-label={t(\"branch.release.proposals\")}>\n\t\t\t\t<Box px=\"8\" pb=\"2\">\n\t\t\t\t\t<Heading size=\"sm\">{t(\"branch.release.proposals\")}</Heading>\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t{t(\"branch.release.proposalsHelp\")}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={proposals}\n\t\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\t\temptyState={<EmptyState header={t(\"branch.release.noProposals\")} />}\n\t\t\t\t/>\n\t\t\t</Box>\n\t\t</Stack>\n\t);\n}\n","import type { TFunction } from \"i18next\";\nimport {\n\tChangeSetClosedError,\n\tContentArchivedError,\n\tContentBlockedError,\n\tContentRefusedError,\n\tInvalidInputError,\n\tServiceUnavailableError,\n} from \"../client/contenthub-client\";\n\n/**\n * Why a write on a Content was refused, in the page's words: its Block, its\n * being Archived, a closed Change Set, or the service's own guidance, which\n * is fit to show as it comes.\n */\nexport function contentRefusalText(t: TFunction, err: unknown): string {\n\tif (err instanceof ContentBlockedError) return t(\"content.refused.blocked\");\n\tif (err instanceof ContentArchivedError) return t(\"content.refused.archived\");\n\tif (err instanceof ChangeSetClosedError) return t(\"library.create.changeSetClosed\");\n\tif (err instanceof ServiceUnavailableError) return t(\"changeSet.refused.unavailable\");\n\tif (err instanceof ContentRefusedError) {\n\t\tconst reasons = err.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \");\n\t\treturn t(\"library.create.refused\", { reasons });\n\t}\n\tif (err instanceof InvalidInputError) return err.message;\n\treturn t(\"content.refused.failed\");\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { DescriptionList, Modal } from \"@knkcs/anker/components\";\nimport { InputField, RadioGroupField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, StaleHeadError } from \"../client/contenthub-client\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PendingMerge, ResolvedField, UpdateFromMainOutcome } from \"../types\";\nimport { periodText } from \"./branch-release-tab\";\nimport { plainRows, valueText } from \"./content-data-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\n// The dialogs the Branch editor's rail opens (anker ADR 0004: a rail node\n// renders outside the screen's providers, so the screen renders these).\n// Each stays mounted, driven by `open`, with `lazyMount unmountOnExit`\n// (anker's Modal rule), and starts afresh on every opening. Every write\n// sends an Idempotency Key, the same one again only when it retries the\n// same request after a failure whose outcome is unknown.\n\n/** Update from Main for the Branch's Chain alone, and what it did to this Branch. */\nexport function BranchUpdateModal({\n\topen,\n\tbranchId,\n\tonClose,\n\tonConfirm,\n\tonResolve,\n}: {\n\topen: boolean;\n\tbranchId: string;\n\tonClose: () => void;\n\t/** Runs the update under the key given; its outcome is shown until the dialog closes. */\n\tonConfirm: (idempotencyKey: string) => Promise<UpdateFromMainOutcome>;\n\t/** Opens the merge resolution of this Branch. */\n\tonResolve: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { keyFor, settle } = useAttemptKey(\"update-from-main\");\n\tconst [outcome, setOutcome] = useState<UpdateFromMainOutcome | null>(null);\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetOutcome(null);\n\t\t\tsetFailure(null);\n\t\t\tsettle();\n\t\t}\n\t}, [open, settle]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tsetOutcome(await onConfirm(keyFor([\"update\", branchId])));\n\t\t\tsettle();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\tconst stopped = outcome\n\t\t? [...outcome.conflicted, ...outcome.pending].some((p) => p.branchId === branchId)\n\t\t: false;\n\tconst merged = outcome?.mergedBranchIds.includes(branchId) ?? false;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"branch.update.title\")}\n\t\t\tfooter={\n\t\t\t\toutcome ? (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t{stopped ? (\n\t\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onResolve}>\n\t\t\t\t\t\t\t\t{t(\"branch.update.resolve\")}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<Button size=\"sm\" variant={stopped ? \"ghost\" : \"solid\"} onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={running} onClick={() => void run()}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.confirm\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{outcome ? (\n\t\t\t\t\tstopped ? (\n\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.update.stopped\")} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"success\"\n\t\t\t\t\t\t\ttitle={merged ? t(\"branch.update.merged\") : t(\"branch.update.upToDate\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t) : (\n\t\t\t\t\t<Text fontSize=\"sm\">{t(\"branch.update.message\")}</Text>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\ntype MergeValues = { choices: string[] };\n\n/**\n * The Pending Merge on the Branch, resolved field by field: each field it\n * lists takes the Branch's value or the merged-in one, every other field\n * its merged value (ResolveMerge). Or aborted, which leaves the Branch at\n * its head, still behind its base.\n */\nexport function ResolveMergeModal({\n\topen,\n\tclient,\n\tchangeSetId,\n\tbranchId,\n\tfields,\n\tonClose,\n\tonDone,\n}: {\n\topen: boolean;\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\tbranchId: string;\n\t/** The Blueprint Release's fields, for their names. */\n\tfields: ResolvedField[];\n\tonClose: () => void;\n\t/** The merge was resolved (a new head) or aborted. */\n\tonDone: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst resolveKey = useAttemptKey(\"resolve-merge\");\n\tconst abortKey = useAttemptKey(\"abort-merge\");\n\tconst pending = useQuery({\n\t\tqueryKey: contenthubKeys.pendingMerge(branchId),\n\t\tqueryFn: () => client.getPendingMerge(branchId),\n\t\tenabled: open,\n\t\tgcTime: 0,\n\t});\n\tconst methods = useForm<MergeValues>({ defaultValues: { choices: [] } });\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState<\"resolve\" | \"abort\" | null>(null);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\t// The form outlives a closing (the dialog stays mounted): every\n\t\t\t// opening starts with no choice made.\n\t\t\tmethods.reset({ choices: [] });\n\t\t\tsetFailure(null);\n\t\t\tresolveKey.settle();\n\t\t\tabortKey.settle();\n\t\t}\n\t}, [open, methods, resolveKey.settle, abortKey.settle]);\n\tconst pm: PendingMerge | null | undefined = pending.data;\n\tuseEffect(() => {\n\t\tif (open && pm) methods.reset({ choices: pm.fields.map(() => \"\") });\n\t}, [open, pm, methods]);\n\n\tconst nameOf = (path: string) => {\n\t\tconst accessor = path.replace(/^\\//, \"\");\n\t\treturn fields.find((f) => f.config.api_accessor === accessor)?.config.name ?? accessor;\n\t};\n\n\tconst resolve = methods.handleSubmit(async ({ choices }) => {\n\t\tif (!pm) return;\n\t\tconst undecided = pm.fields.findIndex(\n\t\t\t(_, i) => choices[i] !== \"ours\" && choices[i] !== \"theirs\",\n\t\t);\n\t\tif (undecided >= 0) {\n\t\t\tmethods.setError(`choices.${undecided}`, { message: t(\"branch.merge.decide\") });\n\t\t\treturn;\n\t\t}\n\t\tconst request = {\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\texpectedHeadId: pm.oursRevisionId,\n\t\t\tresolutions: pm.fields.map((f, i) => ({\n\t\t\t\tpath: f.path,\n\t\t\t\tside: choices[i] as \"ours\" | \"theirs\",\n\t\t\t})),\n\t\t};\n\t\tsetBusy(\"resolve\");\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait client.resolveMerge({ ...request, idempotencyKey: resolveKey.keyFor(request) });\n\t\t\tresolveKey.settle();\n\t\t\tonDone();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) resolveKey.settle();\n\t\t\tsetFailure(\n\t\t\t\terr instanceof StaleHeadError ? t(\"branch.merge.stale\") : contentRefusalText(t, err),\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(null);\n\t\t}\n\t});\n\n\tconst abort = async () => {\n\t\tsetBusy(\"abort\");\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait client.abortMerge({\n\t\t\t\tchangeSetId,\n\t\t\t\tbranchId,\n\t\t\t\tidempotencyKey: abortKey.keyFor([\"abort\", branchId]),\n\t\t\t});\n\t\t\tabortKey.settle();\n\t\t\tonDone();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) abortKey.settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetBusy(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"branch.merge.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tdisabled={!pm}\n\t\t\t\t\t\tloading={busy === \"abort\"}\n\t\t\t\t\t\tonClick={() => void abort()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.merge.abort\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tdisabled={!pm}\n\t\t\t\t\t\tloading={busy === \"resolve\"}\n\t\t\t\t\t\tonClick={() => void resolve()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"branch.merge.resolve\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t{pending.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"branch.merge.loadError\")} />\n\t\t\t\t) : pending.data === undefined ? (\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t) : !pm ? (\n\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.merge.none\")} />\n\t\t\t\t) : (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<Text fontSize=\"sm\">\n\t\t\t\t\t\t\t{pm.reason === \"invalid\" ? t(\"branch.merge.invalid\") : t(\"branch.merge.conflict\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{pm.fields.map((f, i) => (\n\t\t\t\t\t\t\t<RadioGroupField<MergeValues>\n\t\t\t\t\t\t\t\tkey={f.path}\n\t\t\t\t\t\t\t\tname={`choices.${i}`}\n\t\t\t\t\t\t\t\tlabel={nameOf(f.path)}\n\t\t\t\t\t\t\t\thelperText={t(\"branch.merge.base\", { value: valueText(f.base) })}\n\t\t\t\t\t\t\t\toptions={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: \"ours\",\n\t\t\t\t\t\t\t\t\t\tlabel: t(\"branch.merge.ours\", { value: valueText(f.ours) }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: \"theirs\",\n\t\t\t\t\t\t\t\t\t\tlabel: t(\"branch.merge.theirs\", { value: valueText(f.theirs) }),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</FormProvider>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\ntype DayValues = { day: string };\n\n/**\n * Preview (ADR 0006): the Content In Force on a day as if the Change Set\n * were published now, through ReleaseService, which reads it the way\n * template and export will.\n */\nexport function PreviewModal({\n\topen,\n\tclient,\n\tchangeSetId,\n\tcontentId,\n\tfields,\n\tdefaultDay,\n\tonClose,\n}: {\n\topen: boolean;\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\tcontentId: string;\n\tfields: ResolvedField[];\n\t/** The day to start from; today when \"\". */\n\tdefaultDay: string;\n\tonClose: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst methods = useForm<DayValues>({ defaultValues: { day: defaultDay } });\n\tuseEffect(() => {\n\t\tif (open) methods.reset({ day: defaultDay });\n\t}, [open, defaultDay, methods]);\n\tconst day = useWatch({ control: methods.control, name: \"day\" }) ?? \"\";\n\tconst valid = day === \"\" || DAY.test(day);\n\tconst preview = useQuery({\n\t\tqueryKey: contenthubKeys.previewInForce(contentId, changeSetId, day),\n\t\tqueryFn: () => client.previewInForce({ contentId, changeSetId, validOn: day || undefined }),\n\t\tenabled: open && valid,\n\t\tgcTime: 0,\n\t});\n\tconst row = preview.data;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"branch.preview.title\")}\n\t\t\tfooter={\n\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t<InputField<DayValues>\n\t\t\t\t\t\tname=\"day\"\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tlabel={t(\"branch.preview.day\")}\n\t\t\t\t\t\thelperText={t(\"branch.preview.dayHelp\")}\n\t\t\t\t\t/>\n\t\t\t\t</FormProvider>\n\t\t\t\t{preview.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={contentRefusalText(t, preview.error)} />\n\t\t\t\t) : !valid ? (\n\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.preview.badDay\")} />\n\t\t\t\t) : preview.data === undefined ? (\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t) : row === null ? (\n\t\t\t\t\t<Alert status=\"info\" title={t(\"branch.preview.nothing\")} />\n\t\t\t\t) : row ? (\n\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus={row.planned ? \"success\" : \"info\"}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\trow.withheld\n\t\t\t\t\t\t\t\t\t? t(\"branch.preview.withheld\")\n\t\t\t\t\t\t\t\t\t: row.planned\n\t\t\t\t\t\t\t\t\t\t? t(\"branch.preview.planned\", { release: row.releaseId })\n\t\t\t\t\t\t\t\t\t\t: t(\"branch.preview.published\", { release: row.releaseId })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t{row.validityPeriod ? (\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"branch.preview.period\")}>\n\t\t\t\t\t\t\t\t\t{periodText(row.validityPeriod)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{plainRows(fields, row.data).map((r) => (\n\t\t\t\t\t\t\t\t<DescriptionList.Row key={r.key} label={r.label}>\n\t\t\t\t\t\t\t\t\t{valueText(r.value)}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\n/** Append a Branch: the Chain amended again from a later date. */\nexport function AppendBranchModal({\n\topen,\n\tafter,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\t/** The Chain's last editorial Branch's date, which the new one comes after; \"\" for none. */\n\tafter: string;\n\tonClose: () => void;\n\tonConfirm: (effectiveOn: string, idempotencyKey: string) => Promise<void>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { keyFor, settle } = useAttemptKey(\"append-branch\");\n\tconst methods = useForm<{ effectiveOn: string }>({ defaultValues: { effectiveOn: \"\" } });\n\tconst [failure, setFailure] = useState<string | null>(null);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ effectiveOn: \"\" });\n\t\t\tsetFailure(null);\n\t\t\tsettle();\n\t\t}\n\t}, [open, methods, settle]);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst submit = methods.handleSubmit(async ({ effectiveOn }) => {\n\t\tsetFailure(null);\n\t\tif (!DAY.test(effectiveOn) || (after !== \"\" && effectiveOn <= after)) {\n\t\t\tmethods.setError(\"effectiveOn\", {\n\t\t\t\tmessage: after ? t(\"branch.append.after\", { day: after }) : t(\"branch.append.required\"),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait onConfirm(effectiveOn, keyFor([\"append\", effectiveOn]));\n\t\t\tsettle();\n\t\t} catch (err) {\n\t\t\tif (isAnswer(err)) settle();\n\t\t\tsetFailure(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"branch.append.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={submitting} onClick={() => void submit()}>\n\t\t\t\t\t\t{t(\"branch.append.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tnoValidate\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"3\">\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"branch.append.message\")}</Text>\n\t\t\t\t\t\t<InputField<{ effectiveOn: string }>\n\t\t\t\t\t\t\tname=\"effectiveOn\"\n\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\tlabel={t(\"branch.append.effectiveOn\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{failure ? <Alert status=\"error\" title={failure} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { ContextRail, DescriptionList } from \"@knkcs/anker/components\";\nimport {\n\tEye,\n\tGitCompare,\n\tGitMerge,\n\tGitPullRequestArrow,\n\tInfo,\n\tTrash2,\n\tWrench,\n\tZap,\n} from \"lucide-react\";\n\n/** One of the rail's actions; absent from `BranchRailProps.actions` when it isn't offered. */\nexport type BranchRailAction =\n\t| \"updateFromMain\"\n\t| \"resolveMerge\"\n\t| \"compareFork\"\n\t| \"preview\"\n\t| \"appendBranch\"\n\t| \"dropChain\";\n\nconst ICONS: Record<BranchRailAction, typeof Eye> = {\n\tupdateFromMain: GitMerge,\n\tresolveMerge: Wrench,\n\tcompareFork: GitCompare,\n\tpreview: Eye,\n\tappendBranch: GitPullRequestArrow,\n\tdropChain: Trash2,\n};\n\nexport interface BranchRailProps {\n\ttitle: string;\n\t/** Every string the rail shows, translated by the screen. */\n\tlabels: {\n\t\teyebrow: string;\n\t\tactions: string;\n\t\tabout: string;\n\t\tfork: string;\n\t\teffectiveOn: string;\n\t\tposition: string;\n\t\thead: string;\n\t\tpendingMerge: string;\n\t\taction: Record<BranchRailAction, string>;\n\t};\n\t/** The actions offered, in the order shown. */\n\tactions: BranchRailAction[];\n\tonAction: (action: BranchRailAction) => void;\n\tabout: {\n\t\tfork: string;\n\t\teffectiveOn: string;\n\t\tposition: string;\n\t\thead: string;\n\t\t/** Present while a Pending Merge waits on the Branch. */\n\t\tpendingMerge?: string;\n\t};\n}\n\n/**\n * The Branch editor's rail (anker ADR 0004; spec #56, story 99): what one\n * does to the Branch and its Chain in Actions, never Save; the Branch's\n * place at a glance in About. Reported to the host and drawn away from the\n * screen's providers, so it reads no context: every string arrives\n * translated, and every action is a callback that sets screen state, the\n * screen rendering the dialog.\n */\nexport function BranchRail({ title, labels, actions, onAction, about }: BranchRailProps) {\n\treturn (\n\t\t<ContextRail storageKey=\"contenthub-branch-rail\">\n\t\t\t<ContextRail.Header eyebrow={labels.eyebrow} title={title} />\n\t\t\t{actions.length > 0 ? (\n\t\t\t\t<ContextRail.Section id=\"actions\" icon={<Zap size={16} />} label={labels.actions}>\n\t\t\t\t\t{actions.map((action) => {\n\t\t\t\t\t\tconst Icon = ICONS[action];\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\t\tkey={action}\n\t\t\t\t\t\t\t\tlabel={labels.action[action]}\n\t\t\t\t\t\t\t\ticon={<Icon size={16} />}\n\t\t\t\t\t\t\t\ttone={\n\t\t\t\t\t\t\t\t\taction === \"dropChain\"\n\t\t\t\t\t\t\t\t\t\t? \"outline-red\"\n\t\t\t\t\t\t\t\t\t\t: action === \"resolveMerge\"\n\t\t\t\t\t\t\t\t\t\t\t? \"primary\"\n\t\t\t\t\t\t\t\t\t\t\t: \"default\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonClick={() => onAction(action)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</ContextRail.Section>\n\t\t\t) : null}\n\t\t\t<ContextRail.Section id=\"about\" icon={<Info size={16} />} label={labels.about}>\n\t\t\t\t<DescriptionList>\n\t\t\t\t\t<DescriptionList.Row label={labels.fork}>{about.fork}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.effectiveOn}>{about.effectiveOn}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.position}>{about.position}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.head}>{about.head}</DescriptionList.Row>\n\t\t\t\t\t{about.pendingMerge ? (\n\t\t\t\t\t\t<DescriptionList.Row label={labels.pendingMerge}>\n\t\t\t\t\t\t\t{about.pendingMerge}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t) : null}\n\t\t\t\t</DescriptionList>\n\t\t\t</ContextRail.Section>\n\t\t</ContextRail>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { type UseQueryResult, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Edge, OutdatedPin } from \"../types\";\nimport type { BranchTabContext } from \"./branch-editor\";\n\ntype EdgeRow = Edge & Record<string, unknown>;\ntype PinRow = OutdatedPin & Record<string, unknown>;\n\n/** What an edge points at: a Content, an Asset or a Blueprint Release, by id. */\nfunction targetOf(edge: Edge): string {\n\treturn edge.targetContentId || edge.targetAssetId || edge.targetBlueprintReleaseId;\n}\n\nfunction Section<T>({\n\ttitle,\n\tquery,\n\tchildren,\n}: {\n\ttitle: string;\n\tquery: UseQueryResult<T>;\n\tchildren: (data: T) => ReactNode;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"0\" role=\"region\" aria-label={title}>\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{title}</Heading>\n\t\t\t</Box>\n\t\t\t{query.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.references.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : query.data === undefined ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\tchildren(query.data)\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * The References tab (spec #56; ADR 0009): the outgoing edges of the\n * Branch's head as saved, and its pins outdated today, which a save\n * re-pins (#79). What a draft not yet saved references isn't here. Tables,\n * so flush.\n */\nexport function BranchReferencesTab({\n\tclient,\n\tcontentId,\n\tbranchId,\n\theadRevisionId,\n}: BranchTabContext) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst outgoing = useQuery({\n\t\tqueryKey: contenthubKeys.contentReferences(contentId, headRevisionId),\n\t\tqueryFn: () => client.listReferences({ contentId, revisionId: headRevisionId }),\n\t\tenabled: headRevisionId !== \"\",\n\t});\n\t// Keyed by the head too: a save may re-pin, and the pins are the head's.\n\tconst pins = useQuery({\n\t\tqueryKey: contenthubKeys.contentOutdatedPins(contentId, { branchId, headRevisionId }),\n\t\tqueryFn: () => client.listOutdatedPins({ branchId }),\n\t});\n\n\tconst outgoingColumns = useMemo<ColumnDef<EdgeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.pinReleaseId || t(\"content.references.followsInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst pinColumns = useMemo<ColumnDef<PinRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original.edge)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.pinReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.references.columns.inForceNow\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={row.original.inForceReleaseId || t(\"content.references.gap\")} />\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Section title={t(\"content.references.outgoing\")} query={outgoing}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={outgoingColumns}\n\t\t\t\t\t\tdata={data as EdgeRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutgoing\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t<Section title={t(\"content.references.outdated\")} query={pins}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={pinColumns}\n\t\t\t\t\t\tdata={data as PinRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutdated\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { InvalidInputError } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\n\nexport interface ConfirmModalProps {\n\topen: boolean;\n\ttitle: string;\n\t/** What confirming does, said in full. */\n\tmessage: string;\n\tconfirmLabel: string;\n\t/** A destructive or disclosing confirm is red. */\n\tdanger?: boolean;\n\t/** Shown when `onConfirm` rejects with anything but an `InvalidInputError`. */\n\tfailedMessage: string;\n\tonClose: () => void;\n\t/**\n\t * Does it. An `InvalidInputError` it rejects with shows the service's\n\t * guidance; anything else `failedMessage`. The caller closes the modal.\n\t */\n\tonConfirm: () => Promise<void>;\n}\n\n/**\n * Asks before a settings write that can't be taken back or discloses\n * something: removing a Required Check or Collection, restricting or opening\n * a Collection. The screen renders it rather than relying on a host's confirm\n * provider: a host owes these screens nothing beyond the host contract.\n */\nexport function ConfirmModal({\n\topen,\n\ttitle,\n\tmessage,\n\tconfirmLabel,\n\tdanger = false,\n\tfailedMessage,\n\tonClose,\n\tonConfirm,\n}: ConfirmModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\t// Latched while open, so a caller that clears its subject on close\n\t// doesn't blank or swap the text while the modal animates out.\n\tconst [shown, setShown] = useState({ title, message, confirmLabel, danger, failedMessage });\n\tif (\n\t\topen &&\n\t\t(shown.title !== title ||\n\t\t\tshown.message !== message ||\n\t\t\tshown.confirmLabel !== confirmLabel ||\n\t\t\tshown.danger !== danger ||\n\t\t\tshown.failedMessage !== failedMessage)\n\t) {\n\t\tsetShown({ title, message, confirmLabel, danger, failedMessage });\n\t}\n\tconst [busy, setBusy] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetBusy(false);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open]);\n\n\tconst confirm = async () => {\n\t\tsetBusy(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onConfirm();\n\t\t} catch (err) {\n\t\t\tsetRefusal(err instanceof InvalidInputError ? err.message : shown.failedMessage);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={shown.title}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette={shown.danger ? \"red\" : undefined}\n\t\t\t\t\t\tloading={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{shown.confirmLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text>{shown.message}</Text>\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { ResolvedField } from \"../types\";\n\n/**\n * The fields with none required, at any depth: a field's children, and the\n * fields its settings hold (a Block Type's, a Reference's embedded\n * Reference Spec), found as fieldkit finds them, an object with a\n * `field_type` and a `config`.\n *\n * A save may leave required fields empty, and Publish refuses until they are\n * filled (#180, decision D1 of #176), so the Branch editor validates a save\n * against these. The form is still drawn from the fields as declared, which\n * keeps each required field marked. The input is never changed.\n */\nexport function withoutRequired(fields: ResolvedField[]): ResolvedField[] {\n\treturn fields.map((f) => clear(f) as ResolvedField);\n}\n\nfunction clear(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(clear);\n\tif (value === null || typeof value !== \"object\") return value;\n\tconst out: Record<string, unknown> = {};\n\tfor (const [key, v] of Object.entries(value)) out[key] = clear(v);\n\tconst config = out.config;\n\tif (\n\t\t\"field_type\" in out &&\n\t\tconfig !== null &&\n\t\ttypeof config === \"object\" &&\n\t\t\"required\" in config\n\t) {\n\t\tout.config = { ...config, required: false };\n\t}\n\treturn out;\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { usePageRail } from \"@knkcs/anker/host\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { TFunction } from \"i18next\";\nimport { RotateCcw, Save } from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n\ttype FieldPath,\n\ttype FieldValues,\n\tFormProvider,\n\ttype UseFormReturn,\n\tuseForm,\n} from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport {\n\ttype ContenthubClient,\n\tContentRefusedError,\n\tCoversReleaseError,\n\ttype RefusalReason,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type {\n\tChangeSet,\n\tChangeSetBranch,\n\tChangeSetChain,\n\tContentDetail,\n\tMediaSource,\n\tPlannedRelease,\n\tValidityPeriod,\n} from \"../types\";\nimport { type BranchCompareBase, BranchCompareTab } from \"./branch-compare-tab\";\nimport { BranchContentTab } from \"./branch-content-tab\";\nimport {\n\tAppendBranchModal,\n\tBranchUpdateModal,\n\tPreviewModal,\n\tResolveMergeModal,\n} from \"./branch-dialogs\";\nimport type { BranchFormKit } from \"./branch-form-kit\";\nimport { BranchRail, type BranchRailAction } from \"./branch-rail\";\nimport { BranchReferencesTab } from \"./branch-references-tab\";\nimport {\n\tBranchReleaseTab,\n\ttype PlanValues,\n\tplanIssues,\n\ttype ReleaseDraft,\n} from \"./branch-release-tab\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { ConfirmModal } from \"./confirm-modal\";\nimport { contentLabel } from \"./content-library\";\nimport { contentRefusalText } from \"./content-refusal\";\nimport { withoutRequired } from \"./required-fields\";\n\nexport interface BranchEditorProps {\n\tclient: ContenthubClient;\n\t/** The Change Set the Branch is in. */\n\tchangeSetId: string;\n\tcontentId: string;\n\t/** The Branch to edit: the Chain's last editorial one, as the Contents tab opens it. */\n\tbranchId: string;\n\t/**\n\t * mediahub, for media fields and images in rich text. Without it a media\n\t * field offers nothing to pick (ADR 0020).\n\t */\n\tmediaSource?: MediaSource;\n\t/**\n\t * Host navigation to another Branch: where the rail's Append a Branch\n\t * takes the editor. Without it, the new Branch is announced but not opened.\n\t */\n\tonOpenBranch?: (target: OpenBranchTarget) => void;\n\t/** The Chain was dropped from the Change Set: the Branch is gone, so leave the editor. */\n\tonDeleted?: () => void;\n}\n\n/**\n * What one of the editor's header tabs is handed: the Branch, the record it\n * was loaded at, and whether it may be edited. The tabs are contenthub's own\n * (ADR 0020: Content, Release, Compare, References); a Blueprint's sections\n * render inside the Content tab, never here.\n */\nexport interface BranchTabContext extends BranchEditorProps {\n\trecord: ContentDetail;\n\treadOnly: boolean;\n\t/** The Change Set as last read; absent until it is. */\n\tchangeSet?: ChangeSet;\n\t/** The Content's Chain in it, and the Branch; absent until the Change Set is read. */\n\tchain?: ChangeSetChain;\n\tbranch?: ChangeSetBranch;\n\t/**\n\t * The Branch's head as saved: the Change Set's word for it, which an\n\t * earlier Branch of the Chain has too, else the record's.\n\t */\n\theadRevisionId: string;\n\t/** The Release tab's draft, held above the tabs. */\n\trelease: ReleaseDraft;\n\t/** What the Compare tab compares against, which the rail's Compare to the fork sets. */\n\tcompareBase: BranchCompareBase;\n\tonCompareBase: (base: BranchCompareBase) => void;\n}\n\n/** One header tab: its key (the URL's `?tab=` and its dirty mark) and its body. */\nexport interface BranchEditorTab {\n\tid: string;\n\tlabel: (t: TFunction) => string;\n\trender: (ctx: BranchTabContext) => ReactNode;\n}\n\nconst CONTENT = \"content\";\nconst RELEASE = \"release\";\nconst COMPARE = \"compare\";\n\n/**\n * The editor's header tabs, in order. Content and Release hold their\n * drafts above the tabs and publish their dirty marks under their own ids;\n * Compare and References read what is saved.\n */\nexport const BRANCH_EDITOR_TABS: BranchEditorTab[] = [\n\t{\n\t\tid: CONTENT,\n\t\tlabel: (t) => t(\"branch.tabs.content\"),\n\t\trender: (ctx) => <BranchContentTab {...ctx} />,\n\t},\n\t{\n\t\tid: RELEASE,\n\t\tlabel: (t) => t(\"branch.tabs.release\"),\n\t\trender: (ctx) => <BranchReleaseTab {...ctx} />,\n\t},\n\t{\n\t\tid: COMPARE,\n\t\tlabel: (t) => t(\"branch.tabs.compare\"),\n\t\trender: (ctx) => <BranchCompareTab {...ctx} />,\n\t},\n\t{\n\t\tid: \"references\",\n\t\tlabel: (t) => t(\"branch.tabs.references\"),\n\t\trender: (ctx) => <BranchReferencesTab {...ctx} />,\n\t},\n];\n\n/**\n * The Branch editor (spec #56; ADR 0020): one Content inside a Change Set,\n * at one of its Branches. The Content tab renders the Blueprint Release's\n * form, the Release tab the Branch's Planned Release; the header's one Save\n * (anker ADR 0004) persists every changed tab: one `SaveRevision` on top of\n * the head the editor loaded, with a field mask of what changed, then the\n * plan. A moved head is refused with Reload, never merged. The rail holds\n * what one does to the Branch and its Chain: Update from Main and the merge\n * it may leave, Preview, Append a Branch and Drop Chain.\n *\n * The draft registry and the forms are keyed by the Branch, so another\n * Content or Branch starts clean, with forms of its own.\n */\nexport function BranchEditor(props: BranchEditorProps) {\n\treturn <BranchEditorFrame {...props} />;\n}\n\nBranchEditor.displayName = \"BranchEditor\";\n\n/** The editor over a given set of tabs: `BranchEditor` with its own, a test with more. */\nexport function BranchEditorFrame({\n\ttabs = BRANCH_EDITOR_TABS,\n\t...props\n}: BranchEditorProps & { tabs?: BranchEditorTab[] }) {\n\treturn (\n\t\t<TabDirtyProvider key={`${props.changeSetId}/${props.contentId}/${props.branchId}`}>\n\t\t\t<BranchScreen {...props} tabs={tabs} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\n// fieldkit's schema layer, loaded once per page: see branch-form-kit.ts.\nlet kitLoad: Promise<BranchFormKit> | undefined;\nfunction loadKit(): Promise<BranchFormKit> {\n\tkitLoad ??= import(\"./branch-form-kit\").then((m) => m.branchFormKit);\n\treturn kitLoad;\n}\n\nfunction useFormKit(): BranchFormKit | undefined {\n\tconst [kit, setKit] = useState<BranchFormKit>();\n\tuseEffect(() => {\n\t\tlet live = true;\n\t\tvoid loadKit().then((loaded) => {\n\t\t\tif (live) setKit(loaded);\n\t\t});\n\t\treturn () => {\n\t\t\tlive = false;\n\t\t};\n\t}, []);\n\treturn kit;\n}\n\n/** Why the last Save stopped. A Release refusal says whether the Content was saved first. */\ntype Refusal =\n\t| { kind: \"stale\"; currentHeadId: string }\n\t| { kind: \"violations\"; reasons: RefusalReason[] }\n\t| { kind: \"invalid\" }\n\t| { kind: \"other\"; message: string }\n\t| { kind: \"releaseInvalid\" }\n\t| { kind: \"covers\"; releaseIds: string[]; contentSaved: boolean }\n\t| { kind: \"releaseViolations\"; reasons: RefusalReason[]; contentSaved: boolean }\n\t| { kind: \"release\"; message: string; contentSaved: boolean };\n\n/** Equal as JSON, whatever the order of an object's keys. */\nfunction sameJSON(a: unknown, b: unknown): boolean {\n\tconst canonical = (value: unknown) =>\n\t\tJSON.stringify(value ?? null, (_, v) =>\n\t\t\tv && typeof v === \"object\" && !Array.isArray(v)\n\t\t\t\t? Object.fromEntries(Object.entries(v).sort(([x], [y]) => x.localeCompare(y)))\n\t\t\t\t: v,\n\t\t);\n\treturn canonical(a) === canonical(b);\n}\n\n/** The top-level fields whose value differs from the baseline: the save's field mask. */\nfunction changedFields(baseline: Record<string, unknown>, draft: Record<string, unknown>) {\n\tconst keys = new Set([...Object.keys(baseline), ...Object.keys(draft)]);\n\treturn [...keys].filter((key) => !sameJSON(baseline[key], draft[key])).sort();\n}\n\n/** A Violation's path (\"/body/0/text\") as the form names the field (\"body.0.text\"). */\nfunction formPath(path: string): string {\n\t// JSON Pointer escapes: \"~1\" is \"/\", \"~0\" is \"~\" (RFC 6901).\n\treturn path\n\t\t.replace(/^\\//, \"\")\n\t\t.split(\"/\")\n\t\t.map((part) => part.replace(/~1/g, \"/\").replace(/~0/g, \"~\"))\n\t\t.join(\".\");\n}\n\n/** The Release tab's period and supersedes as a plan has them, or as an unplanned Branch starts. */\nfunction planValuesOf(planned: PlannedRelease | undefined, branch?: ChangeSetBranch): PlanValues {\n\treturn planned\n\t\t? {\n\t\t\t\tfirstDay: planned.validityPeriod?.firstDay ?? \"\",\n\t\t\t\tlastDay: planned.validityPeriod?.lastDay ?? \"\",\n\t\t\t\tsupersedes: [...planned.supersedesReleaseIds],\n\t\t\t\tplan: true,\n\t\t\t}\n\t\t: { firstDay: branch?.effectiveOn ?? \"\", lastDay: \"\", supersedes: [], plan: false };\n}\n\n/** Resets a form to `sent`, keeping its values: edits made since stay dirty against it. */\nfunction settleForm(form: UseFormReturn<FieldValues>, sent: FieldValues) {\n\tform.reset(sent, { keepValues: true, keepSubmitCount: true });\n\tform.reset(form.getValues(), { keepDefaultValues: true, keepSubmitCount: true });\n}\n\nfunction BranchScreen({ tabs, ...props }: BranchEditorProps & { tabs: BranchEditorTab[] }) {\n\tconst { client, changeSetId, contentId, branchId, onOpenBranch, onDeleted } = props;\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\");\n\tconst tab = tabs.some((each) => each.id === tabParam) ? (tabParam as string) : CONTENT;\n\tconst kit = useFormKit();\n\n\t// The Content at THIS Branch's head, under a key of its own: a read of\n\t// another Branch of the Chain, cached before an Append or a switch,\n\t// never seeds this one (#252).\n\tconst readKey = useMemo(\n\t\t() => contenthubKeys.contentBranchRead(contentId, changeSetId, branchId),\n\t\t[contentId, changeSetId, branchId],\n\t);\n\tconst query = useQuery({\n\t\tqueryKey: readKey,\n\t\tqueryFn: () => client.getContent({ id: contentId, changeSetId, branchId }),\n\t});\n\tconst changeSetKey = contenthubKeys.changeSet(changeSetId);\n\tconst changeSet = useQuery({\n\t\tqueryKey: changeSetKey,\n\t\tqueryFn: () => client.getChangeSet(changeSetId),\n\t});\n\tconst chain = changeSet.data?.chains.find((each) => each.contentId === contentId);\n\tconst branch = chain?.branches.find((each) => each.id === branchId);\n\n\t// The RECORD: the Content as the editor loaded it, the head its next Save\n\t// builds on. Latched from the first read, moved only by this editor's own\n\t// saves and by Reload: a refetch must neither change the expected head\n\t// under the author nor re-seed the form over their edits (fieldkit#340).\n\tconst [record, setRecord] = useState<ContentDetail | null>(null);\n\tif (record === null && query.data) setRecord(query.data);\n\tconst head = useRef(\"\");\n\tconst baseline = useRef<Record<string, unknown>>({});\n\tconst contentKey = useAttemptKey(\"save\");\n\tconst releaseKey = useAttemptKey(\"plan\");\n\n\t// The Content tab's draft: the form IS the draft, held here above the\n\t// tabs, so it outlives the tab's mount (anker ADR 0004; fieldkit's\n\t// spec-form.mdx). The resolver is fieldkit's schema for the record's\n\t// fields, read through a ref because the schema layer loads lazily.\n\tconst resolverRef = useRef<ReturnType<BranchFormKit[\"resolver\"]> | null>(null);\n\tconst methods = useForm<FieldValues>({\n\t\tresolver: (values, context, options) =>\n\t\t\tresolverRef.current ? resolverRef.current(values, context, options) : { values, errors: {} },\n\t});\n\tconst [seeded, setSeeded] = useState(false);\n\n\t// The Release tab's draft, likewise above the tabs: the plan's period and\n\t// supersedes, and its Release Spec values in fieldkit's form over the\n\t// Blueprint Release's Release Spec.\n\tconst planForm = useForm<PlanValues>({\n\t\tdefaultValues: { firstDay: \"\", lastDay: \"\", supersedes: [], plan: false },\n\t});\n\tconst specResolverRef = useRef<ReturnType<BranchFormKit[\"resolver\"]> | null>(null);\n\tconst specForm = useForm<FieldValues>({\n\t\tresolver: (values, context, options) =>\n\t\t\tspecResolverRef.current\n\t\t\t\t? specResolverRef.current(values, context, options)\n\t\t\t\t: { values, errors: {} },\n\t});\n\tconst [planned, setPlanned] = useState<PlannedRelease | undefined>(undefined);\n\tconst [releaseSeeded, setReleaseSeeded] = useState(false);\n\n\t/** Seeds the form from a record, as loaded: a new baseline and head, the draft gone. */\n\tconst seed = useCallback(\n\t\t(detail: ContentDetail, loaded: BranchFormKit) => {\n\t\t\tconst fields = detail.blueprintRelease?.fields ?? [];\n\t\t\t// A save may leave required fields empty; Publish asks for them\n\t\t\t// (#180). The form still marks them, drawn from the fields as\n\t\t\t// declared. Release Spec values stay required (specResolverRef).\n\t\t\tresolverRef.current = loaded.resolver(withoutRequired(fields));\n\t\t\tconst defaults = loaded.defaults(fields, detail.content.data);\n\t\t\tbaseline.current = structuredClone(defaults);\n\t\t\thead.current = detail.content.revisionId;\n\t\t\t// keepSubmitCount: a Reload re-seeds the same record, and SpecForm\n\t\t\t// tells a new failed save from one it has handled by submitCount\n\t\t\t// (fieldkit's spec-form.mdx, \"Known limitations\").\n\t\t\tmethods.reset(defaults, { keepSubmitCount: true });\n\t\t\tsetSeeded(true);\n\t\t},\n\t\t[methods],\n\t);\n\t// Once per record: the editor remounts for another Content or Branch, so\n\t// this never re-seeds over the author's edits.\n\tuseEffect(() => {\n\t\tif (record && kit && !seeded) seed(record, kit);\n\t}, [record, kit, seeded, seed]);\n\n\t// The Release draft, once the Change Set says what is planned: later\n\t// reads of it (proposals recomputed) never re-seed over the author's edits.\n\tuseEffect(() => {\n\t\tif (releaseSeeded || !record || !kit || !changeSet.data) return;\n\t\tconst specFields = record.blueprintRelease?.releaseSpec ?? [];\n\t\tspecResolverRef.current = kit.resolver(specFields);\n\t\tconst plan = changeSet.data.plannedReleases.find((p) => p.branchId === branchId && !p.proposed);\n\t\tplanForm.reset(planValuesOf(plan, branch));\n\t\tspecForm.reset(kit.defaults(specFields, plan?.releaseSpec ?? {}), { keepSubmitCount: true });\n\t\tsetPlanned(plan);\n\t\tsetReleaseSeeded(true);\n\t}, [releaseSeeded, record, kit, changeSet.data, branchId, branch, planForm, specForm]);\n\n\tconst contentDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(CONTENT, contentDirty), [contentDirty, setTabDirty]);\n\tconst releaseDirty = planForm.formState.isDirty || specForm.formState.isDirty;\n\tuseEffect(() => setTabDirty(RELEASE, releaseDirty), [releaseDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [saved, setSaved] = useState(false);\n\tconst changed = dirtyTabs.length;\n\tuseEffect(() => {\n\t\tif (changed > 0) setSaved(false);\n\t}, [changed]);\n\n\tconst [compareBase, setCompareBase] = useState<BranchCompareBase>(\"fork\");\n\ttype Dialog = \"update\" | \"merge\" | \"preview\" | \"append\" | \"drop\";\n\tconst [dialog, setDialog] = useState<Dialog | null>(null);\n\tconst closeDialog = useCallback(() => setDialog(null), []);\n\tconst dropKey = useAttemptKey(\"drop-chain\");\n\n\tconst selectTab = useCallback(\n\t\t(next: string) => {\n\t\t\tsetSearchParams(\n\t\t\t\t(current) => {\n\t\t\t\t\tconst params = new URLSearchParams(current);\n\t\t\t\t\tparams.set(\"tab\", next);\n\t\t\t\t\treturn params;\n\t\t\t\t},\n\t\t\t\t{ replace: true },\n\t\t\t);\n\t\t},\n\t\t[setSearchParams],\n\t);\n\n\tconst dated = record?.blueprintRelease?.dated ?? false;\n\n\t/**\n\t * The Content's SaveRevision, of the fields that changed, on the head the\n\t * editor loaded. The baseline afterwards is what was SENT (the snapshot\n\t * taken as Save started), so an edit made while the save was in flight\n\t * stays dirty (fieldkit's spec-form.mdx). True when it saved or had\n\t * nothing to send.\n\t */\n\tconst saveContent = useCallback(\n\t\tasync (parsed: FieldValues, snapshot: FieldValues): Promise<boolean> => {\n\t\t\tconst mask = changedFields(baseline.current, snapshot);\n\t\t\tif (mask.length === 0) {\n\t\t\t\t// Edited back to what was loaded: nothing to write, only the\n\t\t\t\t// dirty mark to clear.\n\t\t\t\tmethods.reset(snapshot, { keepValues: true, keepSubmitCount: true });\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst data = Object.fromEntries(\n\t\t\t\tmask.filter((key) => key in parsed).map((key) => [key, parsed[key]]),\n\t\t\t);\n\t\t\t// One Idempotency Key per save attempt, sent again when the author\n\t\t\t// retries the same save after a failure whose outcome is unknown\n\t\t\t// (the network, the service): if the first attempt committed, the\n\t\t\t// retry answers it rather than being refused as stale.\n\t\t\tconst key = contentKey.keyFor([head.current, mask, data]);\n\t\t\ttry {\n\t\t\t\tconst content = await client.saveRevision({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\tbranchId,\n\t\t\t\t\texpectedHeadId: head.current,\n\t\t\t\t\tdata,\n\t\t\t\t\tfieldMask: mask,\n\t\t\t\t\tidempotencyKey: key,\n\t\t\t\t});\n\t\t\t\tcontentKey.settle();\n\t\t\t\thead.current = content.revisionId;\n\t\t\t\tbaseline.current = snapshot;\n\t\t\t\tsettleForm(methods, snapshot);\n\t\t\t\tsetRecord((current) => (current ? { ...current, content } : current));\n\t\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (current) =>\n\t\t\t\t\tcurrent ? { ...current, content } : current,\n\t\t\t\t);\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\t// A refusal is an answer: the next Save is a new attempt.\n\t\t\t\tif (isAnswer(err)) contentKey.settle();\n\t\t\t\tif (err instanceof StaleHeadError) {\n\t\t\t\t\tsetRefusal({ kind: \"stale\", currentHeadId: err.currentHeadId });\n\t\t\t\t} else if (err instanceof ContentRefusedError) {\n\t\t\t\t\tfor (const reason of err.reasons) {\n\t\t\t\t\t\tif (!reason.path) continue;\n\t\t\t\t\t\tmethods.setError(formPath(reason.path) as FieldPath<FieldValues>, {\n\t\t\t\t\t\t\ttype: reason.code,\n\t\t\t\t\t\t\tmessage: t(\"branch.violation\", { code: reason.code, source: reason.source }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tsetRefusal({ kind: \"violations\", reasons: err.reasons });\n\t\t\t\t\tselectTab(CONTENT);\n\t\t\t\t} else {\n\t\t\t\t\tsetRefusal({ kind: \"other\", message: contentRefusalText(t, err) });\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[methods, contentKey, client, changeSetId, branchId, queryClient, readKey, selectTab, t],\n\t);\n\n\t/**\n\t * The Release tab's write: PlanRelease for an unplanned Branch,\n\t * UpdatePlannedRelease otherwise, with every Release Spec value (the\n\t * service takes them as the whole set). Proposals are the service's to\n\t * derive again, so the Change Set is read again afterwards.\n\t */\n\tconst saveRelease = useCallback(\n\t\tasync (sentPlan: PlanValues, spec: FieldValues, contentSaved: boolean) => {\n\t\t\tconst validityPeriod: ValidityPeriod | undefined = dated\n\t\t\t\t? { firstDay: sentPlan.firstDay, lastDay: sentPlan.lastDay }\n\t\t\t\t: undefined;\n\t\t\tconst releaseSpec = JSON.parse(JSON.stringify(spec)) as Record<string, unknown>;\n\t\t\tconst supersedesReleaseIds = [...sentPlan.supersedes];\n\t\t\tconst asked = {\n\t\t\t\tplanned: planned?.id ?? \"\",\n\t\t\t\tvalidityPeriod,\n\t\t\t\treleaseSpec,\n\t\t\t\tsupersedesReleaseIds,\n\t\t\t};\n\t\t\tconst idempotencyKey = releaseKey.keyFor(asked);\n\t\t\ttry {\n\t\t\t\tconst result = planned\n\t\t\t\t\t? await client.updatePlannedRelease({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tplannedReleaseId: planned.id,\n\t\t\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\t\t\treleaseSpec,\n\t\t\t\t\t\t\tsupersedesReleaseIds,\n\t\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t\t})\n\t\t\t\t\t: await client.planRelease({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tbranchId,\n\t\t\t\t\t\t\tvalidityPeriod,\n\t\t\t\t\t\t\treleaseSpec,\n\t\t\t\t\t\t\tsupersedesReleaseIds,\n\t\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t\t});\n\t\t\t\treleaseKey.settle();\n\t\t\t\tsetPlanned(result);\n\t\t\t\tsettleForm(planForm as unknown as UseFormReturn<FieldValues>, sentPlan);\n\t\t\t\tsettleForm(specForm, spec);\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\tif (isAnswer(err)) releaseKey.settle();\n\t\t\t\tif (err instanceof CoversReleaseError) {\n\t\t\t\t\tsetRefusal({ kind: \"covers\", releaseIds: err.coveredReleaseIds, contentSaved });\n\t\t\t\t} else if (err instanceof ContentRefusedError) {\n\t\t\t\t\tfor (const reason of err.reasons) {\n\t\t\t\t\t\tif (!reason.path) continue;\n\t\t\t\t\t\tspecForm.setError(formPath(reason.path) as FieldPath<FieldValues>, {\n\t\t\t\t\t\t\ttype: reason.code,\n\t\t\t\t\t\t\tmessage: t(\"branch.violation\", { code: reason.code, source: reason.source }),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tsetRefusal({ kind: \"releaseViolations\", reasons: err.reasons, contentSaved });\n\t\t\t\t} else {\n\t\t\t\t\tsetRefusal({ kind: \"release\", message: contentRefusalText(t, err), contentSaved });\n\t\t\t\t}\n\t\t\t\tselectTab(RELEASE);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tdated,\n\t\t\tplanned,\n\t\t\treleaseKey,\n\t\t\tclient,\n\t\t\tchangeSetId,\n\t\t\tbranchId,\n\t\t\tcontentId,\n\t\t\tplanForm,\n\t\t\tspecForm,\n\t\t\tqueryClient,\n\t\t\tselectTab,\n\t\t\tt,\n\t\t],\n\t);\n\n\t/**\n\t * The header's Save: every changed tab, as one change. Each is validated\n\t * first, whether or not its tab is mounted, and nothing is sent while one\n\t * is invalid. Then the Content's SaveRevision, then the plan: a refused\n\t * save stops there and sends no plan, so both stay changed for the next\n\t * Save; a refused plan after a saved Content leaves the Release alone\n\t * changed, and the next Save sends only it. The plan pins the Branch's\n\t * head at Publish, not at planning, so the order costs nothing.\n\t */\n\tconst save = useCallback(async () => {\n\t\tif (!seeded) return;\n\t\tconst doContent = methods.formState.isDirty;\n\t\tconst doRelease = releaseSeeded && (planForm.formState.isDirty || specForm.formState.isDirty);\n\t\tconst snapshot = structuredClone(methods.getValues());\n\t\tconst planSnapshot = structuredClone(planForm.getValues());\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tlet parsed: FieldValues | null = null;\n\t\t\tif (doContent) {\n\t\t\t\tawait methods.handleSubmit(\n\t\t\t\t\t(values) => {\n\t\t\t\t\t\tparsed = values;\n\t\t\t\t\t},\n\t\t\t\t\t() => {},\n\t\t\t\t)();\n\t\t\t\tif (!parsed) {\n\t\t\t\t\t// SpecForm, mounted there, opens the section of the first error.\n\t\t\t\t\tsetRefusal({ kind: \"invalid\" });\n\t\t\t\t\tselectTab(CONTENT);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet spec: FieldValues | null = null;\n\t\t\tif (doRelease) {\n\t\t\t\tplanForm.clearErrors();\n\t\t\t\tconst issues = planIssues(planSnapshot, dated);\n\t\t\t\tfor (const issue of issues) planForm.setError(issue.path, { message: t(issue.key) });\n\t\t\t\tawait specForm.handleSubmit(\n\t\t\t\t\t(values) => {\n\t\t\t\t\t\tspec = values;\n\t\t\t\t\t},\n\t\t\t\t\t() => {},\n\t\t\t\t)();\n\t\t\t\tif (issues.length > 0 || !spec) {\n\t\t\t\t\tsetRefusal({ kind: \"releaseInvalid\" });\n\t\t\t\t\tselectTab(RELEASE);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet contentSaved = false;\n\t\t\tif (doContent && parsed) {\n\t\t\t\tif (!(await saveContent(parsed, snapshot))) return;\n\t\t\t\tcontentSaved = true;\n\t\t\t}\n\t\t\tif (doRelease && spec) {\n\t\t\t\tif (!(await saveRelease(planSnapshot, spec, contentSaved))) return;\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} finally {\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [\n\t\tseeded,\n\t\treleaseSeeded,\n\t\tmethods,\n\t\tplanForm,\n\t\tspecForm,\n\t\tdated,\n\t\tsaveContent,\n\t\tsaveRelease,\n\t\tselectTab,\n\t\tt,\n\t]);\n\n\t/** Stale head: the author chose to throw the draft away and edit the current head. */\n\tconst reload = useCallback(async () => {\n\t\tconst fresh = await query.refetch();\n\t\tif (!fresh.data || !kit) return;\n\t\tsetRecord(fresh.data);\n\t\tseed(fresh.data, kit);\n\t\tsetRefusal(null);\n\t}, [query, kit, seed]);\n\n\t/**\n\t * The head moved by the rail's own doing (a merge, a resolution): the\n\t * Change Set is read again, and the Content too unless the author has\n\t * unsaved edits, which a later Save then offers to reload as stale.\n\t */\n\tconst headMoved = useCallback(async () => {\n\t\tawait queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\tif (!methods.formState.isDirty) await reload();\n\t}, [queryClient, changeSetId, methods, reload]);\n\n\tconst open = changeSet.data ? changeSet.data.state === \"open\" : true;\n\tconst pendingMerge = branch?.hasPendingMerge ?? false;\n\tconst born = chain?.born ?? false;\n\tconst railActions = useMemo<BranchRailAction[]>(() => {\n\t\tconst offered: BranchRailAction[] = [];\n\t\tif (open && chain) {\n\t\t\toffered.push(pendingMerge ? \"resolveMerge\" : \"updateFromMain\");\n\t\t}\n\t\toffered.push(\"compareFork\");\n\t\tif (open && chain) {\n\t\t\toffered.push(\"preview\");\n\t\t\tif (dated && !born) offered.push(\"appendBranch\");\n\t\t\tif (!born) offered.push(\"dropChain\");\n\t\t}\n\t\treturn offered;\n\t}, [open, chain, pendingMerge, dated, born]);\n\tconst onRailAction = useCallback(\n\t\t(action: BranchRailAction) => {\n\t\t\tswitch (action) {\n\t\t\t\tcase \"updateFromMain\":\n\t\t\t\t\tsetDialog(\"update\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"resolveMerge\":\n\t\t\t\t\tsetDialog(\"merge\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"compareFork\":\n\t\t\t\t\tsetCompareBase(\"fork\");\n\t\t\t\t\tselectTab(COMPARE);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"preview\":\n\t\t\t\t\tsetDialog(\"preview\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"appendBranch\":\n\t\t\t\t\tsetDialog(\"append\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"dropChain\":\n\t\t\t\t\tsetDialog(\"drop\");\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t},\n\t\t[selectTab],\n\t);\n\tconst title = record ? contentLabel(record.content.data) || record.content.id : \"\";\n\tconst headRevisionId = branch?.headRevisionId || record?.content.revisionId || \"\";\n\t// The rail closes over this screen's state and reads no context: the host\n\t// draws it away from the screen's providers (anker's host contract).\n\tusePageRail(\n\t\trecord && changeSet.data ? (\n\t\t\t<BranchRail\n\t\t\t\ttitle={title}\n\t\t\t\tlabels={{\n\t\t\t\t\teyebrow: t(\"branch.rail.eyebrow\"),\n\t\t\t\t\tactions: t(\"branch.rail.actions\"),\n\t\t\t\t\tabout: t(\"branch.rail.about\"),\n\t\t\t\t\tfork: t(\"branch.rail.fork\"),\n\t\t\t\t\teffectiveOn: t(\"branch.rail.effectiveOn\"),\n\t\t\t\t\tposition: t(\"branch.rail.position\"),\n\t\t\t\t\thead: t(\"branch.rail.head\"),\n\t\t\t\t\tpendingMerge: t(\"branch.rail.pendingMerge\"),\n\t\t\t\t\taction: {\n\t\t\t\t\t\tupdateFromMain: t(\"branch.rail.updateFromMain\"),\n\t\t\t\t\t\tresolveMerge: t(\"branch.rail.resolveMerge\"),\n\t\t\t\t\t\tcompareFork: t(\"branch.rail.compareFork\"),\n\t\t\t\t\t\tpreview: t(\"branch.rail.preview\"),\n\t\t\t\t\t\tappendBranch: t(\"branch.rail.appendBranch\"),\n\t\t\t\t\t\tdropChain: t(\"branch.rail.dropChain\"),\n\t\t\t\t\t},\n\t\t\t\t}}\n\t\t\t\tactions={railActions}\n\t\t\t\tonAction={onRailAction}\n\t\t\t\tabout={{\n\t\t\t\t\tfork:\n\t\t\t\t\t\tchain?.branches[0]?.carriedReleaseId ||\n\t\t\t\t\t\t(born ? t(\"branch.rail.forkBorn\") : t(\"branch.rail.forkMain\")),\n\t\t\t\t\teffectiveOn: branch?.effectiveOn || t(\"branch.rail.undated\"),\n\t\t\t\t\tposition: branch\n\t\t\t\t\t\t? t(\"branch.rail.positionOf\", {\n\t\t\t\t\t\t\t\tposition: branch.position + 1,\n\t\t\t\t\t\t\t\tcount: chain?.branches.length ?? 1,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: \"—\",\n\t\t\t\t\thead: headRevisionId,\n\t\t\t\t\tpendingMerge: pendingMerge ? t(\"branch.rail.pendingMergeYes\") : undefined,\n\t\t\t\t}}\n\t\t\t/>\n\t\t) : null,\n\t);\n\n\tif (!record) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\"), to: paths.changeSets }]}\n\t\t\t\ttitle={query.isError ? t(\"branch.unavailable\") : t(\"branch.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert status=\"error\" title={notFound ? t(\"branch.notFound\") : t(\"branch.loadError\")} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\t// Only the Chain's last Branch is edited here (#166): an earlier one is\n\t// shown at its own head, read-only. Which one is last is the Change\n\t// Set's word, read with it; until it is read nothing is editable. A\n\t// record of another Branch (a service that ignores branch_id) is never\n\t// edited either.\n\tconst earlier = chain ? chain.branches.at(-1)?.id !== branchId : false;\n\tconst otherBranch = earlier || record.content.branchId !== branchId;\n\t// Not while saving: an edit made during a save is kept, still dirty.\n\tconst readOnly = !open || otherBranch || changeSet.isPending;\n\tconst release: ReleaseDraft = {\n\t\tplan: planForm,\n\t\tspec: specForm,\n\t\tplanned,\n\t\tspecFields: record.blueprintRelease?.releaseSpec ?? [],\n\t\tseeded: releaseSeeded,\n\t};\n\tconst ctx: BranchTabContext = {\n\t\t...props,\n\t\trecord,\n\t\treadOnly,\n\t\tchangeSet: changeSet.data,\n\t\tchain,\n\t\tbranch,\n\t\theadRevisionId,\n\t\trelease,\n\t\tcompareBase,\n\t\tonCompareBase: setCompareBase,\n\t};\n\tconst active = tabs.find((each) => each.id === tab) ?? tabs[0];\n\tconst lastEditorial = chain?.branches.filter((b) => b.kind === \"editorial\").at(-1);\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"changeSets.title\"), to: paths.changeSets },\n\t\t\t\t{ label: changeSet.data?.name ?? changeSetId },\n\t\t\t\t{ label: title },\n\t\t\t]}\n\t\t\ttitle={title}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t<TypeBadge\n\t\t\t\t\t\tname={record.blueprintRelease?.displayName || record.content.blueprintId}\n\t\t\t\t\t\tcolorPalette=\"gray\"\n\t\t\t\t\t/>\n\t\t\t\t\t{!open && changeSet.data ? (\n\t\t\t\t\t\t<TypeBadge name={t(`changeSets.state.${changeSet.data.state}`)} colorPalette=\"gray\" />\n\t\t\t\t\t) : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t// A Pending Merge takes no saves (CONTEXT.md); a plan alone may still go.\n\t\t\t\t\tdisabled={changed === 0 || readOnly || (pendingMerge && contentDirty)}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void save()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"branch.save\") : t(\"branch.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={active.id} onValueChange={(e) => selectTab(e.value)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{tabs.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each.id} value={each.id}>\n\t\t\t\t\t\t\t\t{each.label(t)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved || otherBranch || !open || pendingMerge ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{otherBranch ? <Alert status=\"info\" title={t(\"branch.otherBranch\")} /> : null}\n\t\t\t\t\t{!open && changeSet.data ? <Alert status=\"info\" title={t(\"branch.closed\")} /> : null}\n\t\t\t\t\t{pendingMerge && open ? (\n\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"branch.pendingMerge\")} />\n\t\t\t\t\t) : null}\n\t\t\t\t\t{refusal ? (\n\t\t\t\t\t\t<RefusalAlert\n\t\t\t\t\t\t\trefusal={refusal}\n\t\t\t\t\t\t\treloading={query.isFetching}\n\t\t\t\t\t\t\tonReload={reload}\n\t\t\t\t\t\t\tonSupersede={(ids) => {\n\t\t\t\t\t\t\t\tconst current = planForm.getValues(\"supersedes\");\n\t\t\t\t\t\t\t\tplanForm.setValue(\"supersedes\", [...new Set([...current, ...ids])], {\n\t\t\t\t\t\t\t\t\tshouldDirty: true,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tsetRefusal(null);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"branch.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t{seeded ? (\n\t\t\t\t<FormProvider {...(methods as UseFormReturn<FieldValues>)}>\n\t\t\t\t\t{active.render(ctx)}\n\t\t\t\t</FormProvider>\n\t\t\t) : (\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t)}\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"branch.leave.title\")}\n\t\t\t\tmessage={t(\"branch.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"branch.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"branch.leave.cancel\")}\n\t\t\t/>\n\t\t\t<BranchUpdateModal\n\t\t\t\topen={dialog === \"update\"}\n\t\t\t\tbranchId={branchId}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonResolve={() => setDialog(\"merge\")}\n\t\t\t\tonConfirm={async (idempotencyKey) => {\n\t\t\t\t\tconst outcome = await client.updateFromMain({\n\t\t\t\t\t\tid: changeSetId,\n\t\t\t\t\t\tchainId: chain?.id,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t});\n\t\t\t\t\tqueryClient.setQueryData(changeSetKey, outcome.changeSet);\n\t\t\t\t\tif (outcome.mergedBranchIds.includes(branchId)) await headMoved();\n\t\t\t\t\treturn outcome;\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ResolveMergeModal\n\t\t\t\topen={dialog === \"merge\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\tbranchId={branchId}\n\t\t\t\tfields={record.blueprintRelease?.fields ?? []}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonDone={() => {\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tvoid headMoved();\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<PreviewModal\n\t\t\t\topen={dialog === \"preview\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSetId={changeSetId}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tfields={record.blueprintRelease?.fields ?? []}\n\t\t\t\tdefaultDay={planned?.validityPeriod?.firstDay ?? branch?.effectiveOn ?? \"\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t/>\n\t\t\t<AppendBranchModal\n\t\t\t\topen={dialog === \"append\"}\n\t\t\t\tafter={lastEditorial?.effectiveOn ?? \"\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={async (effectiveOn, idempotencyKey) => {\n\t\t\t\t\tif (!chain) throw new Error(\"the Change Set holds no Chain on this Content\");\n\t\t\t\t\tconst appended = await client.appendBranch({\n\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\tchainId: chain.id,\n\t\t\t\t\t\teffectiveOn,\n\t\t\t\t\t\tidempotencyKey,\n\t\t\t\t\t});\n\t\t\t\t\tqueryClient.setQueryData(changeSetKey, appended.changeSet);\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tonOpenBranch?.({ changeSetId, contentId, branchId: appended.branchId });\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={dialog === \"drop\"}\n\t\t\t\ttitle={t(\"branch.drop.title\")}\n\t\t\t\tmessage={t(\"branch.drop.message\", { content: title })}\n\t\t\t\tconfirmLabel={t(\"branch.drop.confirm\")}\n\t\t\t\tdanger\n\t\t\t\tfailedMessage={t(\"branch.drop.failed\")}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!chain) throw new Error(\"the Change Set holds no Chain on this Content\");\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait client.dropChain({\n\t\t\t\t\t\t\tchangeSetId,\n\t\t\t\t\t\t\tchainId: chain.id,\n\t\t\t\t\t\t\tidempotencyKey: dropKey.keyFor([\"drop\", chain.id]),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdropKey.settle();\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (isAnswer(err)) dropKey.settle();\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\t\t\tsetDialog(null);\n\t\t\t\t\tonDeleted?.();\n\t\t\t\t}}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n\nfunction RefusalAlert({\n\trefusal,\n\treloading,\n\tonReload,\n\tonSupersede,\n}: {\n\trefusal: Refusal;\n\treloading: boolean;\n\tonReload: () => void;\n\t/** Adds the covered Releases to the plan's supersedes, for the next Save. */\n\tonSupersede: (releaseIds: string[]) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst savedFirst = (r: { contentSaved: boolean }) =>\n\t\tr.contentSaved ? t(\"branch.refused.contentSaved\") : undefined;\n\tswitch (refusal.kind) {\n\t\tcase \"stale\":\n\t\t\t// ADR 0020: a moved head is refused, never merged. The draft stays\n\t\t\t// until the author reloads, which throws it away.\n\t\t\treturn (\n\t\t\t\t<Alert status=\"warning\" title={t(\"branch.refused.stale\")}>\n\t\t\t\t\t<Stack gap=\"2\" align=\"start\">\n\t\t\t\t\t\t{t(\"branch.refused.staleHint\")}\n\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" loading={reloading} onClick={onReload}>\n\t\t\t\t\t\t\t<RotateCcw size={14} />\n\t\t\t\t\t\t\t{t(\"branch.reload\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"violations\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(\"branch.refused.violations\", { count: refusal.reasons.length })}\n\t\t\t\t>\n\t\t\t\t\t{refusal.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \")}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"invalid\":\n\t\t\treturn <Alert status=\"error\" title={t(\"branch.refused.invalid\")} />;\n\t\tcase \"releaseInvalid\":\n\t\t\treturn <Alert status=\"error\" title={t(\"branch.refused.releaseInvalid\")} />;\n\t\tcase \"covers\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\ttitle={t(\"branch.refused.covers\", { releases: refusal.releaseIds.join(\", \") })}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"2\" align=\"start\">\n\t\t\t\t\t\t{[savedFirst(refusal), t(\"branch.refused.coversHint\")].filter(Boolean).join(\" \")}\n\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" onClick={() => onSupersede(refusal.releaseIds)}>\n\t\t\t\t\t\t\t{t(\"branch.refused.supersede\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"releaseViolations\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(\"branch.refused.releaseViolations\", { count: refusal.reasons.length })}\n\t\t\t\t>\n\t\t\t\t\t{[\n\t\t\t\t\t\tsavedFirst(refusal),\n\t\t\t\t\t\trefusal.reasons.map((r) => (r.path ? `${r.code} (${r.path})` : r.code)).join(\", \"),\n\t\t\t\t\t]\n\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t.join(\" \")}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"release\":\n\t\t\treturn (\n\t\t\t\t<Alert status=\"error\" title={refusal.message}>\n\t\t\t\t\t{savedFirst(refusal)}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn <Alert status=\"error\" title={refusal.message} />;\n\t}\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useCallback, useMemo } from \"react\";\nimport type { ChangeSetStatusInfo, StatusSource } from \"../types\";\nimport { contenthubKeys } from \"./query-keys\";\n\nconst NO_STATUSES: ChangeSetStatusInfo[] = [];\n\nexport interface ChangeSetStatuses {\n\t/** The catalogue, in statushub's order; empty without a `StatusSource`. */\n\tstatuses: ChangeSetStatusInfo[];\n\t/** Whether the host filled the port: without it there is no picker. */\n\tavailable: boolean;\n\t/**\n\t * A slug as a label: statushub's name and colour, or the bare slug when\n\t * the port is empty, still loading, or no longer holds it (ADR 0020).\n\t * \"\" (no status set yet) reads as the catalogue's default status (ADR 0014\n\t * D9); without one it is `undefined`, for the caller to word.\n\t */\n\tlabelOf: (slug: string) => ChangeSetStatusInfo | undefined;\n}\n\n/** The workspace's Change Set statuses, through the host-filled port. */\nexport function useChangeSetStatuses(source: StatusSource | undefined): ChangeSetStatuses {\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.changeSetStatuses(),\n\t\tqueryFn: () => (source as StatusSource).listChangeSetStatuses(),\n\t\tenabled: source !== undefined,\n\t\t// A catalogue changes rarely and every row reads it.\n\t\tstaleTime: 60_000,\n\t});\n\tconst statuses = query.data ?? NO_STATUSES;\n\tconst labelOf = useCallback(\n\t\t(slug: string) => {\n\t\t\tif (slug === \"\") return statuses.find((s) => s.isDefault);\n\t\t\treturn statuses.find((s) => s.slug === slug) ?? { slug, name: slug };\n\t\t},\n\t\t[statuses],\n\t);\n\tconst available = source !== undefined;\n\t// One object while nothing changes, so a table's columns built from it\n\t// are not rebuilt on every render.\n\treturn useMemo(() => ({ statuses, available, labelOf }), [statuses, available, labelOf]);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport type { TFunction } from \"i18next\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ChangeSetClosedError, WithheldWorkError } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { UpdateFromMainOutcome } from \"../types\";\n\n// The rail's other two actions, each confirmed in a dialog the screen\n// renders (anker ADR 0004: a rail node renders outside the screen's\n// providers). Both kept mounted and driven by `open`, with `lazyMount\n// unmountOnExit` (anker's Modal rule); each opening starts afresh.\n\ntype Failure = \"closed\" | \"withheld\" | \"failed\";\n\n// Withheld: the Change Set holds work the caller can't see (ADR 0017), which\n// the service says by a typed detail and without naming any of it.\nconst failureOf = (err: unknown): Failure =>\n\terr instanceof ChangeSetClosedError\n\t\t? \"closed\"\n\t\t: err instanceof WithheldWorkError\n\t\t\t? \"withheld\"\n\t\t\t: \"failed\";\n\n// The line under the outcome's title. \"Up to date\" only when nothing merged\n// AND no Branch holds a Pending Merge: a Branch the merge stopped on is not\n// up to date, whether this update or an earlier one stopped there (#251).\nfunction summaryOf(outcome: UpdateFromMainOutcome, stopped: number, t: TFunction): string {\n\tconst merged = outcome.mergedBranchIds.length;\n\tif (merged > 0) return t(\"changeSet.update.merged\", { count: merged });\n\treturn stopped > 0 ? t(\"changeSet.update.noneMerged\") : t(\"changeSet.update.nothingMerged\");\n}\n\nexport function UpdateFromMainModal({\n\topen,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\tonClose: () => void;\n\t/** Runs the update; its outcome is shown here until the dialog closes. */\n\tonConfirm: () => Promise<UpdateFromMainOutcome>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [outcome, setOutcome] = useState<UpdateFromMainOutcome | null>(null);\n\tconst [failure, setFailure] = useState<Failure | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tsetOutcome(null);\n\t\t\tsetFailure(null);\n\t\t}\n\t}, [open]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tsetOutcome(await onConfirm());\n\t\t} catch (err) {\n\t\t\tsetFailure(failureOf(err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\t// Only which Branches were left with a Pending Merge: showing the merge\n\t// itself is the Branch editor's.\n\tconst pending = outcome ? [...outcome.conflicted, ...outcome.pending] : [];\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.update.title\")}\n\t\t\tfooter={\n\t\t\t\toutcome ? (\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"changeSet.update.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" loading={running} onClick={() => void run()}>\n\t\t\t\t\t\t\t{t(\"changeSet.update.confirm\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{outcome ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus={pending.length > 0 ? \"warning\" : \"success\"}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\tpending.length > 0\n\t\t\t\t\t\t\t\t\t? t(\"changeSet.update.stopped\", { count: pending.length })\n\t\t\t\t\t\t\t\t\t: t(\"changeSet.update.done\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{summaryOf(outcome, pending.length, t)}\n\t\t\t\t\t\t</Alert>\n\t\t\t\t\t\t{pending.length > 0 ? (\n\t\t\t\t\t\t\t<Stack gap=\"1\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.update.pendingTitle\")}</Text>\n\t\t\t\t\t\t\t\t<Stack as=\"ul\" gap=\"1\" listStyleType=\"none\">\n\t\t\t\t\t\t\t\t\t{pending.map((p) => (\n\t\t\t\t\t\t\t\t\t\t<Text as=\"li\" key={p.branchId} fontSize=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"changeSet.update.pendingLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tcontent: p.contentId,\n\t\t\t\t\t\t\t\t\t\t\t\tbranch: p.branchId,\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.update.message\")}</Text>\n\t\t\t\t)}\n\t\t\t\t{failure ? <Alert status=\"error\" title={t(`changeSet.update.${failure}`)} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\nexport function DiscardChangeSetModal({\n\topen,\n\tname,\n\tonClose,\n\tonConfirm,\n}: {\n\topen: boolean;\n\tname: string;\n\tonClose: () => void;\n\tonConfirm: () => Promise<void>;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [failure, setFailure] = useState<Failure | null>(null);\n\tconst [running, setRunning] = useState(false);\n\tuseEffect(() => {\n\t\tif (open) setFailure(null);\n\t}, [open]);\n\n\tconst run = async () => {\n\t\tsetRunning(true);\n\t\tsetFailure(null);\n\t\ttry {\n\t\t\tawait onConfirm();\n\t\t} catch (err) {\n\t\t\tsetFailure(failureOf(err));\n\t\t} finally {\n\t\t\tsetRunning(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.discard.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={running}\n\t\t\t\t\t\tonClick={() => void run()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"changeSet.discard.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.discard.message\", { name })}</Text>\n\t\t\t\t{failure ? <Alert status=\"error\" title={t(`changeSet.discard.${failure}`)} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { ActionCell, DataTable, StatusBadgeCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { ClipboardCheck, ListChecks } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckStanding } from \"../types\";\n\ntype StandingRow = CheckStanding & Record<string, unknown>;\n\n/** What a standing is about, in words: the whole Change Set, or its Content's Branch or Release. */\nexport function subjectText(t: TFunction, st: CheckStanding): string {\n\tif (st.check.scope === \"change_set\") return t(\"changeSet.checks.wholeChangeSet\");\n\tif (st.branchId) {\n\t\treturn t(\"changeSet.checks.onBranch\", { content: st.contentId, branch: st.branchId });\n\t}\n\treturn t(\"changeSet.checks.onRelease\", { content: st.contentId, release: st.releaseId });\n}\n\n/** A standing's row key: one per check and subject. */\nexport const standingKey = (st: CheckStanding) =>\n\t`${st.check.id}/${st.branchId || st.releaseId || \"change-set\"}`;\n\n/**\n * Each Required Check that applies, on each thing it applies to, with its\n * latest result and whether a save since made it stale (ADR 0014). A row's\n * action opens the screen's Record dialog: results are recorded against the\n * heads the row shows. A table tab, so flush.\n */\nexport function ChangeSetChecksTab({\n\tstandings,\n\tloading,\n\tfailed,\n\tcanRecord,\n\tonRecord,\n}: {\n\tstandings: CheckStanding[];\n\tloading: boolean;\n\tfailed: boolean;\n\t/** Whether the Change Set is open: a closed one takes no more results. */\n\tcanRecord: boolean;\n\tonRecord: (standing: CheckStanding) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst columns = useMemo<ColumnDef<StandingRow, unknown>[]>(() => {\n\t\tconst standingLabel = (st: CheckStanding) =>\n\t\t\tst.cleared\n\t\t\t\t? t(\"changeSet.checks.cleared\")\n\t\t\t\t: st.stale\n\t\t\t\t\t? t(\"changeSet.checks.stale\")\n\t\t\t\t\t: t(\"changeSet.checks.outstanding\");\n\t\tconst out: ColumnDef<StandingRow, unknown>[] = [\n\t\t\t{\n\t\t\t\tid: \"check\",\n\t\t\t\theader: t(\"changeSet.checks.columns.check\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.check.name}\n\t\t\t\t\t\tsubText={row.original.check.independent ? t(\"changeSet.checks.independent\") : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"on\",\n\t\t\t\theader: t(\"changeSet.checks.columns.on\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={subjectText(t, row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"latest\",\n\t\t\t\theader: t(\"changeSet.checks.columns.latest\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst latest = row.original.results[0];\n\t\t\t\t\tif (!latest) return <TruncatedTextCell value={t(\"changeSet.checks.none\")} />;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={t(\"changeSet.checks.latest\", {\n\t\t\t\t\t\t\t\toutcome: t(`changeSet.checks.outcome.${latest.outcome}`),\n\t\t\t\t\t\t\t\twho: members.byId(latest.recordedBy)?.displayName ?? latest.recordedBy,\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\tsubText={latest.note || undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"standing\",\n\t\t\t\theader: t(\"changeSet.checks.columns.standing\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst label = standingLabel(row.original);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\t\tvalue={label}\n\t\t\t\t\t\t\tcolorMap={{\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.cleared\")]: \"green\",\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.stale\")]: \"orange\",\n\t\t\t\t\t\t\t\t[t(\"changeSet.checks.outstanding\")]: \"red\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\t\tif (canRecord) {\n\t\t\tout.push({\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"changeSet.checks.columns.actions\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<ActionCell\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ticon: ClipboardCheck,\n\t\t\t\t\t\t\t\tlabel: t(\"changeSet.checks.record\"),\n\t\t\t\t\t\t\t\tonClick: () => onRecord(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}, [t, members, canRecord, onRecord]);\n\n\tif (failed) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.checks.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (loading) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={standings as StandingRow[]}\n\t\t\tgetRowId={standingKey}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<ListChecks size={32} />}\n\t\t\t\t\theader={t(\"changeSet.checks.empty\")}\n\t\t\t\t\tdescription={t(\"changeSet.checks.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { BooleanCell, CountCell, DataTable, SlugCell } from \"@knkcs/anker/components\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FileText } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, ChangeSetChain } from \"../types\";\n\ntype ChainRow = ChangeSetChain & Record<string, unknown>;\n\n/** What the Branch editor is opened on: a Content inside a Change Set, at one of its Branches. */\nexport interface OpenBranchTarget {\n\tchangeSetId: string;\n\tcontentId: string;\n\t/**\n\t * The Branch to open: the Chain's last editorial Branch, the one a new\n\t * save continues (the tip Publish moves Main to).\n\t */\n\tbranchId: string;\n}\n\n/** The Branch a Chain's row opens: its last editorial one, or its last at all. */\nexport function branchToOpen(chain: ChangeSetChain): string {\n\tconst editorial = chain.branches.filter((b) => b.kind === \"editorial\");\n\treturn (editorial.at(-1) ?? chain.branches.at(-1))?.id ?? \"\";\n}\n\n/**\n * The Chains a Change Set holds, one row per Content, each opening the\n * Branch editor on it. A table tab, so flush (anker: only form tabs pad).\n */\nexport function ChangeSetContentsTab({\n\tchangeSet,\n\tonOpenBranch,\n}: {\n\tchangeSet: ChangeSet;\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst columns = useMemo<ColumnDef<ChainRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"content\",\n\t\t\t\theader: t(\"changeSet.contents.columns.content\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.contentId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"branches\",\n\t\t\t\theader: t(\"changeSet.contents.columns.branches\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<CountCell\n\t\t\t\t\t\tvalue={row.original.branches}\n\t\t\t\t\t\tsingular={t(\"changeSet.contents.branch\")}\n\t\t\t\t\t\tplural={t(\"changeSet.contents.branches\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"born\",\n\t\t\t\theader: t(\"changeSet.contents.columns.born\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.born}\n\t\t\t\t\t\ttrueLabel={t(\"changeSet.contents.bornHere\")}\n\t\t\t\t\t\tfalseLabel={t(\"changeSet.contents.onMain\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={changeSet.chains as ChainRow[]}\n\t\t\tgetRowId={(row) => row.id}\n\t\t\tvariant=\"hoverable\"\n\t\t\tonRowClick={(chain) =>\n\t\t\t\tonOpenBranch({\n\t\t\t\t\tchangeSetId: changeSet.id,\n\t\t\t\t\tcontentId: chain.contentId,\n\t\t\t\t\tbranchId: branchToOpen(chain),\n\t\t\t\t})\n\t\t\t}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<FileText size={32} />}\n\t\t\t\t\theader={t(\"changeSet.contents.empty\")}\n\t\t\t\t\tdescription={t(\"changeSet.contents.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import type { BaseOption, LookupResolve, LookupSearch } from \"@knkcs/anker/atoms\";\nimport { Card, DescriptionList } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, LookupSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Box, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useCallback, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport type { ChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet } from \"../types\";\n\n/** The General tab's draft: what of a Change Set its page can change. */\nexport interface GeneralValues {\n\tname: string;\n\t/** The Source's day as YYYY-MM-DD; \"\" with the reference for none. */\n\tsourceDate: string;\n\tsourceReference: string;\n\t/** A status slug; \"\" for none yet. */\n\tstatus: string;\n\tassigneeIds: string[];\n\tdependsOnIds: string[];\n}\n\nexport function generalValuesOf(cs: ChangeSet): GeneralValues {\n\treturn {\n\t\tname: cs.name,\n\t\tsourceDate: cs.source?.date ?? \"\",\n\t\tsourceReference: cs.source?.reference ?? \"\",\n\t\tstatus: cs.status,\n\t\tassigneeIds: [...cs.assigneeIds],\n\t\tdependsOnIds: [...cs.dependsOnChangeSetIds],\n\t};\n}\n\n/** How many open Change Sets the dependency picker searches; the service's page limit. */\nconst DEPENDENCY_CANDIDATES = 200;\n\n/**\n * A Change Set's General tab: what it is (name, Source, state, who opened it)\n * and the things its page changes: its name and Source while it is open\n * (#126), its status label, its assignees and its dependencies. The draft is\n * the page's form, held above the tab, so it survives switching tabs; the\n * header's one Save persists it.\n *\n * A closed Change Set shows its name and Source, not edits them: the Source\n * freezes at Publish, since its Releases and their Event carry it.\n */\nexport function ChangeSetGeneralTab({\n\tclient,\n\tchangeSet,\n\tstatuses,\n}: {\n\tclient: ContenthubClient;\n\tchangeSet: ChangeSet;\n\tstatuses: ChangeSetStatuses;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst closed = changeSet.state !== \"open\";\n\n\t// A status the catalogue no longer holds stays offered, by its slug, so\n\t// the field shows where the Change Set is rather than \"no status\".\n\tconst statusOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = statuses.statuses.map((s) => ({ id: s.slug, label: s.name }));\n\t\tconst current = changeSet.status;\n\t\treturn current === \"\" || known.some((o) => o.id === current)\n\t\t\t? known\n\t\t\t: [...known, { id: current, label: current }];\n\t}, [statuses.statuses, changeSet.status]);\n\t// Members first; an assignee who is no longer one stays listed by id, so\n\t// saving never drops someone the page cannot name.\n\tconst assigneeOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = members.list().map((m) => ({ id: m.userId, label: m.displayName }));\n\t\tconst unknown = changeSet.assigneeIds\n\t\t\t.filter((id) => !members.byId(id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [members, changeSet.assigneeIds]);\n\n\tconst searchDependencies = useCallback<LookupSearch<BaseOption>>(\n\t\tasync ({ query }) => {\n\t\t\tconst { changeSets } = await client.listChangeSets({\n\t\t\t\tstate: \"open\",\n\t\t\t\tpageSize: DEPENDENCY_CANDIDATES,\n\t\t\t});\n\t\t\tconst q = query.trim().toLocaleLowerCase();\n\t\t\treturn {\n\t\t\t\titems: changeSets\n\t\t\t\t\t.filter((cs) => cs.id !== changeSet.id)\n\t\t\t\t\t.filter((cs) => q === \"\" || cs.name.toLocaleLowerCase().includes(q))\n\t\t\t\t\t.map((cs) => ({ id: cs.id, label: cs.name })),\n\t\t\t};\n\t\t},\n\t\t[client, changeSet.id],\n\t);\n\tconst resolveDependencies = useCallback<LookupResolve<BaseOption>>(\n\t\t({ ids }) =>\n\t\t\tPromise.all(\n\t\t\t\tids.map((id) =>\n\t\t\t\t\tclient.getChangeSet(id).then(\n\t\t\t\t\t\t(cs) => ({ id, label: cs.name }),\n\t\t\t\t\t\t// One the page can't read is still shown, by id.\n\t\t\t\t\t\t() => ({ id, label: id }),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t[client],\n\t);\n\n\tconst createdBy = members.byId(changeSet.createdBy)?.displayName ?? changeSet.createdBy;\n\tconst status = statuses.labelOf(changeSet.status);\n\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Card title={t(\"changeSet.general.about\")}>\n\t\t\t\t\t{closed ? null : (\n\t\t\t\t\t\t<Stack gap=\"4\" mb=\"4\">\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSet.general.name\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.nameHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"sourceDate\"\n\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSets.form.sourceDate\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.sourceDateHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<InputField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"sourceReference\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSets.form.sourceReference\")}\n\t\t\t\t\t\t\t\thelperText={t(\"changeSets.form.sourceReferenceHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t{closed ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.name\")}>\n\t\t\t\t\t\t\t\t\t{changeSet.name}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.source\")}>\n\t\t\t\t\t\t\t\t\t{changeSet.source\n\t\t\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tdate: changeSet.source.date,\n\t\t\t\t\t\t\t\t\t\t\t\treference: changeSet.source.reference,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t: t(\"changeSet.general.noSource\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.state\")}>\n\t\t\t\t\t\t\t{t(`changeSets.state.${changeSet.state}`)}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.createdBy\")}>\n\t\t\t\t\t\t\t{createdBy}\n\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t{statuses.available ? null : (\n\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"changeSet.general.status\")}>\n\t\t\t\t\t\t\t\t{status?.name ?? t(\"changeSet.general.noStatus\")}\n\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t{closed ? (\n\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\" mt=\"3\">\n\t\t\t\t\t\t\t{t(\"changeSet.general.frozenHint\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t) : null}\n\t\t\t\t</Card>\n\t\t\t\t<Card title={t(\"changeSet.general.work\")}>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{statuses.available ? (\n\t\t\t\t\t\t\t<BaseSelectField<GeneralValues>\n\t\t\t\t\t\t\t\tname=\"status\"\n\t\t\t\t\t\t\t\tlabel={t(\"changeSet.general.status\")}\n\t\t\t\t\t\t\t\thelperText={t(\n\t\t\t\t\t\t\t\t\tclosed ? \"changeSet.general.statusFrozen\" : \"changeSet.general.statusHelp\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\toptions={statusOptions}\n\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t\tplaceholder={statuses.labelOf(\"\")?.name ?? t(\"changeSet.general.noStatus\")}\n\t\t\t\t\t\t\t\tdisabled={closed}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<GeneralValues>\n\t\t\t\t\t\t\tname=\"assigneeIds\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.general.assignees\")}\n\t\t\t\t\t\t\thelperText={t(\"changeSet.general.assigneesHelp\")}\n\t\t\t\t\t\t\toptions={assigneeOptions}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<LookupSelectField<GeneralValues>\n\t\t\t\t\t\t\tname=\"dependsOnIds\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.general.dependencies\")}\n\t\t\t\t\t\t\thelperText={t(\n\t\t\t\t\t\t\t\tclosed\n\t\t\t\t\t\t\t\t\t? \"changeSet.general.dependenciesClosed\"\n\t\t\t\t\t\t\t\t\t: \"changeSet.general.dependenciesHelp\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tsearch={searchDependencies}\n\t\t\t\t\t\t\tresolve={resolveDependencies}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.noDependencies\")}\n\t\t\t\t\t\t\tdisabled={closed}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Stack>\n\t\t\t\t</Card>\n\t\t\t</Stack>\n\t\t</Box>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, StatusBadgeCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Box, Heading, Stack, Text } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { CalendarRange } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, PlannedRelease, PublishBlocker, ValidityPeriod } from \"../types\";\n\ntype PlanRow = PlannedRelease & Record<string, unknown>;\n\n/** A published Release a plan of this Change Set covers. */\ninterface CoveredRow extends Record<string, unknown> {\n\treleaseId: string;\n\t/** The Planned Release covering it. */\n\tbyReleaseId: string;\n\tcontentId: string;\n\t/** Superseded at Publish, or blocking it (covers_release) until replanned. */\n\tsuperseded: boolean;\n}\n\nexport function periodText(t: TFunction, period: ValidityPeriod | undefined): string {\n\tif (!period) return t(\"changeSet.releases.undated\");\n\treturn t(\"changeSet.releases.period\", {\n\t\tfirst: period.firstDay,\n\t\tlast: period.lastDay || t(\"changeSet.releases.openEnd\"),\n\t});\n}\n\n/**\n * The Releases a plan covers: those a plan supersedes, which Publish\n * supersedes with it, and those the latest review reports as covered by a\n * plan that doesn't supersede them (covers_release), which block Publish.\n * A Release a proposal ends is no covered one: it is cut, not superseded\n * whole, so proposals are left out.\n */\nfunction coveredRows(changeSet: ChangeSet, blockers: PublishBlocker[]): CoveredRow[] {\n\tconst rows: CoveredRow[] = [];\n\tfor (const pr of changeSet.plannedReleases) {\n\t\tif (pr.proposed) continue;\n\t\tfor (const id of pr.supersedesReleaseIds) {\n\t\t\trows.push({ releaseId: id, byReleaseId: pr.id, contentId: pr.contentId, superseded: true });\n\t\t}\n\t}\n\tfor (const b of blockers) {\n\t\tif (b.code !== \"covers_release\") continue;\n\t\trows.push({\n\t\t\treleaseId: b.coveredReleaseId,\n\t\t\tbyReleaseId: b.releaseId,\n\t\t\tcontentId: b.contentId,\n\t\t\tsuperseded: false,\n\t\t});\n\t}\n\treturn rows;\n}\n\n/**\n * What Publish will cut: the Change Set's Planned Releases, the proposals\n * among them read-only (they follow from the planned periods and are\n * recomputed with every plan), and the published Releases its plans cover.\n * Plans are made in the Branch editor; this tab reviews them.\n */\nexport function ChangeSetReleasesTab({\n\tchangeSet,\n\tblockers,\n}: {\n\tchangeSet: ChangeSet;\n\t/** The latest review's blockers, for the covered Releases that block Publish. */\n\tblockers: PublishBlocker[];\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst columns = useMemo<ColumnDef<PlanRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"content\",\n\t\t\t\theader: t(\"changeSet.releases.columns.content\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.contentId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"changeSet.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(`changeSet.releases.kind.${row.original.kind}`)}\n\t\t\t\t\t\tfallbackColor={row.original.kind === \"revision\" ? \"blue\" : \"gray\"}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"changeSet.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(t, row.original.validityPeriod)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pins\",\n\t\t\t\theader: t(\"changeSet.releases.columns.pins\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.branchId\n\t\t\t\t\t\t\t\t? t(\"changeSet.releases.branchHead\", { branch: row.original.branchId })\n\t\t\t\t\t\t\t\t: t(\"changeSet.releases.revision\", { revision: row.original.revisionId })\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"origin\",\n\t\t\t\theader: t(\"changeSet.releases.columns.origin\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={originText(t, row.original)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst covered = coveredRows(changeSet, blockers);\n\tconst coveredColumns = useMemo<ColumnDef<CoveredRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.release\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.releaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"by\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.by\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.byReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"outcome\",\n\t\t\t\theader: t(\"changeSet.releases.coveredColumns.outcome\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(\n\t\t\t\t\t\t\trow.original.superseded\n\t\t\t\t\t\t\t\t? \"changeSet.releases.superseded\"\n\t\t\t\t\t\t\t\t: \"changeSet.releases.blocks\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tfallbackColor={row.original.superseded ? \"gray\" : \"orange\"}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\t// Both tables are flush (anker: table tabs reach both edges); only the\n\t// prose between them is inset, to line up with the header.\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={changeSet.plannedReleases as PlanRow[]}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarRange size={32} />}\n\t\t\t\t\t\theader={t(\"changeSet.releases.empty\")}\n\t\t\t\t\t\tdescription={t(\"changeSet.releases.emptyHint\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<Box px=\"8\" pt=\"2\">\n\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t{t(\"changeSet.releases.proposedHint\")}\n\t\t\t\t</Text>\n\t\t\t</Box>\n\t\t\t<Stack gap=\"1\" px=\"8\" pt=\"6\" pb=\"3\">\n\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t{t(\"changeSet.releases.covered\")}\n\t\t\t\t</Heading>\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"changeSet.releases.coveredHint\")}\n\t\t\t\t</Text>\n\t\t\t</Stack>\n\t\t\t<DataTable\n\t\t\t\tcolumns={coveredColumns}\n\t\t\t\tdata={covered}\n\t\t\t\tgetRowId={(row) => `${row.byReleaseId}/${row.releaseId}`}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarRange size={32} />}\n\t\t\t\t\t\theader={t(\"changeSet.releases.noCovered\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n\n/** Planned by hand, or proposed: for which Release, resuming which, withheld or not. */\nfunction originText(t: TFunction, pr: PlannedRelease): string {\n\tif (!pr.proposed) return t(\"changeSet.releases.plannedByHand\");\n\tif (pr.withheld) return t(\"changeSet.releases.withheld\");\n\tif (pr.splitFromReleaseId) {\n\t\treturn t(\"changeSet.releases.splitFrom\", { release: pr.splitFromReleaseId });\n\t}\n\treturn t(\"changeSet.releases.proposed\", { release: pr.proposedForReleaseId });\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport type { TFunction } from \"i18next\";\nimport { useTranslation } from \"react-i18next\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PublishBlocker } from \"../types\";\n\n/**\n * The codes this build words. Each names what the blocker is about (ADR\n * 0015): a code the service adds later still shows, by its code.\n */\nconst KNOWN = new Set([\n\t\"moved_head\",\n\t\"unplanned_branch\",\n\t\"several_branches\",\n\t\"behind_base\",\n\t\"superseded_release\",\n\t\"overlapping_periods\",\n\t\"covers_release\",\n\t\"pending_merge\",\n\t\"nothing_in_force\",\n\t\"withdrawal_with_chain\",\n\t\"dated_changed\",\n\t\"unpublished_dependency\",\n\t\"discarded_dependency\",\n\t\"dangling_pin\",\n\t\"second_toc_parent\",\n\t\"missing_asset\",\n\t\"media_unavailable\",\n\t\"outstanding_check\",\n\t\"missing_required_field\",\n]);\n\n/**\n * One blocker in words, naming what it names: its Content, Branch, heads,\n * Releases, Revision, dependency, path, Asset, TOC parents or Required Check.\n * `checkName` turns a Required Check's id into its name, falling back to\n * the id.\n */\nexport function blockerMessage(\n\tt: TFunction,\n\tb: PublishBlocker,\n\tcheckName: (id: string) => string,\n): string {\n\tconst values = {\n\t\tcontent: b.contentId,\n\t\tbranch: b.branchId,\n\t\texpected: b.expectedHeadId,\n\t\tcurrent: b.currentHeadId,\n\t\trelease: b.releaseId,\n\t\toverlaps: b.overlapsReleaseId,\n\t\tcovered: b.coveredReleaseId,\n\t\trevision: b.revisionId,\n\t\tdependency: b.dependencyChangeSetId,\n\t\tpath: b.path,\n\t\ttarget: b.targetContentId,\n\t\tasset: b.assetId,\n\t\tparents: b.parentContentIds.join(\", \"),\n\t\tcheck: checkName(b.requiredCheckId),\n\t\tsubject: b.branchId || b.releaseId,\n\t\tcode: b.code,\n\t};\n\tif (!KNOWN.has(b.code)) return t(\"changeSet.blockers.unknown\", values);\n\tif (b.code === \"moved_head\") {\n\t\t// versionkit reports a Branch the review left out with no expected\n\t\t// head, and a reviewed one the Change Set no longer holds with no\n\t\t// current head.\n\t\tif (b.expectedHeadId === \"\") return t(\"changeSet.blockers.moved_head_unreviewed\", values);\n\t\tif (b.currentHeadId === \"\") return t(\"changeSet.blockers.moved_head_gone\", values);\n\t}\n\tif (b.code === \"outstanding_check\" && b.contentId !== \"\") {\n\t\treturn t(\"changeSet.blockers.outstanding_check_on\", values);\n\t}\n\treturn t(`changeSet.blockers.${b.code}`, values);\n}\n\n/** The blockers fixed by editing their Content, which offer to open it. */\nconst FIXED_IN_EDITOR = new Set([\"missing_required_field\"]);\n\n/**\n * Every blocker, one Alert each, in the order the service gave them. A\n * blocker fixed in its Content's Branch editor (a required field left empty)\n * links to it through `onOpenContent`, when the screen gives one.\n */\nexport function PublishBlockerList({\n\tblockers,\n\tcheckName,\n\tonOpenContent,\n}: {\n\tblockers: PublishBlocker[];\n\tcheckName: (id: string) => string;\n\tonOpenContent?: (contentId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"2\" as=\"ul\" listStyleType=\"none\">\n\t\t\t{blockers.map((b, i) => (\n\t\t\t\t// Blockers carry no id, and two can name the same things.\n\t\t\t\t// biome-ignore lint/suspicious/noArrayIndexKey: the list never reorders\n\t\t\t\t<li key={i}>\n\t\t\t\t\t<Alert\n\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\ttitle={blockerMessage(t, b, checkName)}\n\t\t\t\t\t\tendElement={\n\t\t\t\t\t\t\tonOpenContent && b.contentId !== \"\" && FIXED_IN_EDITOR.has(b.code) ? (\n\t\t\t\t\t\t\t\t<Button size=\"xs\" variant=\"outline\" onClick={() => onOpenContent(b.contentId)}>\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.openContent\", { content: b.contentId })}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t) : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, Heading, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { Send } from \"lucide-react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tChangeSetClosedError,\n\ttype ContenthubClient,\n\tPublishRefusedError,\n\tWithheldWorkError,\n} from \"../client/contenthub-client\";\nimport { headsOf } from \"../common/heads\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, PublishOutcome, PublishReview } from \"../types\";\nimport { periodText } from \"./change-set-releases-tab\";\nimport { PublishBlockerList } from \"./publish-blockers\";\n\nexport interface PublishReviewModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Change Set as the page has it now; its heads are latched when a review runs. */\n\tchangeSet: ChangeSet;\n\tcheckName: (id: string) => string;\n\tonClose: () => void;\n\tonPublished: (outcome: PublishOutcome) => void;\n\t/**\n\t * Every review that ran, with the Change Set it read, for the page to\n\t * refresh what depends on the heads (the readiness tile, the Checks tab).\n\t */\n\tonReviewed?: (changeSet: ChangeSet) => void;\n\t/**\n\t * Opens a Content of the Change Set in its Branch editor, from a blocker\n\t * fixed there (a required field left empty). Without it, none links.\n\t */\n\tonOpenContent?: (contentId: string) => void;\n}\n\ntype Stage =\n\t| { kind: \"checking\" }\n\t| { kind: \"reviewed\"; review: PublishReview }\n\t| { kind: \"withheld\" }\n\t| { kind: \"failed\" };\n\ntype Refusal = \"refused\" | \"closed\" | \"withheld\" | \"failed\";\n\n/**\n * Publish's review (ADR 0020, anker ADR 0004): it reads the Change Set's\n * heads afresh and latches them, runs ValidatePublish with them, shows those\n * heads, every blocker and the Releases it would cut, and publishes exactly\n * the heads it showed. A head that moves after the review is the service's to\n * refuse (moved_head): the dialog never swaps in heads nobody reviewed.\n * \"Review again\" reads and latches the heads anew.\n *\n * Opened from the rail, rendered by the screen; kept mounted and driven by\n * `open`, with `lazyMount unmountOnExit` (anker's Modal rule).\n */\nexport function PublishReviewModal({\n\topen,\n\tclient,\n\tchangeSet,\n\tcheckName,\n\tonClose,\n\tonPublished,\n\tonReviewed,\n\tonOpenContent,\n}: PublishReviewModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [reviewed, setReviewed] = useState<Record<string, string>>({});\n\tconst [stage, setStage] = useState<Stage>({ kind: \"checking\" });\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [publishing, setPublishing] = useState(false);\n\t// Only the latest review's answer counts; an earlier one arriving late is\n\t// for heads no longer shown.\n\tconst session = useRef(0);\n\tconst latest = useRef(changeSet);\n\tlatest.current = changeSet;\n\t// Until the first read answers, no heads are shown, so none can be sent.\n\n\tconst review = useCallback(async () => {\n\t\tconst run = ++session.current;\n\t\tsetStage({ kind: \"checking\" });\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\t// The heads as the service has them now, not as the page last read\n\t\t\t// them: after a moved_head refusal, reviewing again must see the move.\n\t\t\tconst current = await client.getChangeSet(latest.current.id);\n\t\t\tif (run !== session.current) return;\n\t\t\tconst heads = headsOf(current);\n\t\t\tsetReviewed(heads);\n\t\t\tconst answer = await client.validatePublish({ id: current.id, reviewedHeads: heads });\n\t\t\tif (run !== session.current) return;\n\t\t\tsetStage({ kind: \"reviewed\", review: answer });\n\t\t\tonReviewed?.(current);\n\t\t} catch (err) {\n\t\t\t// Work the caller can't see refuses the dry run as it would Publish.\n\t\t\tif (run === session.current) {\n\t\t\t\tsetStage({ kind: err instanceof WithheldWorkError ? \"withheld\" : \"failed\" });\n\t\t\t}\n\t\t}\n\t}, [client, onReviewed]);\n\n\tuseEffect(() => {\n\t\tif (open) void review();\n\t\telse session.current++;\n\t}, [open, review]);\n\n\tconst publish = async () => {\n\t\tsetPublishing(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\t// Exactly the heads shown: never re-read here.\n\t\t\tonPublished(await client.publish({ id: changeSet.id, reviewedHeads: reviewed }));\n\t\t} catch (err) {\n\t\t\tif (err instanceof PublishRefusedError) {\n\t\t\t\tconst previous = stage.kind === \"reviewed\" ? stage.review : undefined;\n\t\t\t\tsetStage({\n\t\t\t\t\tkind: \"reviewed\",\n\t\t\t\t\treview: {\n\t\t\t\t\t\tblockers: err.blockers,\n\t\t\t\t\t\treleases: previous?.releases ?? [],\n\t\t\t\t\t\tpublished: false,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tsetRefusal(\"refused\");\n\t\t\t} else if (err instanceof ChangeSetClosedError) {\n\t\t\t\tsetRefusal(\"closed\");\n\t\t\t} else if (err instanceof WithheldWorkError) {\n\t\t\t\tsetRefusal(\"withheld\");\n\t\t\t} else {\n\t\t\t\tsetRefusal(\"failed\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetPublishing(false);\n\t\t}\n\t};\n\n\tconst contentOf = (branchId: string) =>\n\t\tchangeSet.chains.find((c) => c.branches.some((b) => b.id === branchId))?.contentId ?? \"\";\n\tconst ready =\n\t\tstage.kind === \"reviewed\" &&\n\t\t(stage.review.blockers.length === 0 || stage.review.published) &&\n\t\tchangeSet.state === \"open\";\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"lg\"\n\t\t\theader={t(\"changeSet.review.title\", { name: changeSet.name })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tonClick={() => void review()}\n\t\t\t\t\t\tdisabled={stage.kind === \"checking\" || publishing}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"changeSet.review.again\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tonClick={() => void publish()}\n\t\t\t\t\t\tdisabled={!ready}\n\t\t\t\t\t\tloading={publishing}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Send size={16} />\n\t\t\t\t\t\t{t(\"changeSet.review.publish\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"5\">\n\t\t\t\t{refusal ? <Alert status=\"error\" title={t(refusalKey[refusal])} /> : null}\n\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t{t(\"changeSet.review.headsTitle\")}\n\t\t\t\t\t</Heading>\n\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t{t(\"changeSet.review.headsHint\")}\n\t\t\t\t\t</Text>\n\t\t\t\t\t{Object.keys(reviewed).length === 0 ? (\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.noHeads\")}</Text>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Stack\n\t\t\t\t\t\t\tas=\"ul\"\n\t\t\t\t\t\t\tgap=\"1\"\n\t\t\t\t\t\t\tlistStyleType=\"none\"\n\t\t\t\t\t\t\taria-label={t(\"changeSet.review.headsTitle\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{Object.entries(reviewed).map(([branch, head]) => (\n\t\t\t\t\t\t\t\t<Text as=\"li\" key={branch} fontSize=\"sm\" fontFamily=\"mono\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.headLine\", { content: contentOf(branch), branch, head })}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\t\t\t\t</Stack>\n\t\t\t\t{stage.kind === \"checking\" ? (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.checking\")}</Text>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"withheld\" ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.review.withheld\")} />\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"failed\" ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.review.loadError\")} />\n\t\t\t\t) : null}\n\t\t\t\t{stage.kind === \"reviewed\" ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{stage.review.published ? (\n\t\t\t\t\t\t\t<Alert status=\"info\" title={t(\"changeSet.review.alreadyPublished\")} />\n\t\t\t\t\t\t) : stage.review.blockers.length === 0 ? (\n\t\t\t\t\t\t\t<Alert status=\"success\" title={t(\"changeSet.review.ready\")} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.blockersTitle\", { count: stage.review.blockers.length })}\n\t\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.blockersHint\")}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<PublishBlockerList\n\t\t\t\t\t\t\t\t\tblockers={stage.review.blockers}\n\t\t\t\t\t\t\t\t\tcheckName={checkName}\n\t\t\t\t\t\t\t\t\tonOpenContent={onOpenContent}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t\t<Heading as=\"h3\" size=\"sm\">\n\t\t\t\t\t\t\t\t{t(\"changeSet.review.releasesTitle\")}\n\t\t\t\t\t\t\t</Heading>\n\t\t\t\t\t\t\t{stage.review.releases.length === 0 ? (\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"changeSet.review.noReleases\")}</Text>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Stack as=\"ul\" gap=\"1\" listStyleType=\"none\">\n\t\t\t\t\t\t\t\t\t{stage.review.releases.map((r) => (\n\t\t\t\t\t\t\t\t\t\t<Text as=\"li\" key={r.id} fontSize=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t{t(\"changeSet.review.releaseLine\", {\n\t\t\t\t\t\t\t\t\t\t\t\tcontent: r.contentId,\n\t\t\t\t\t\t\t\t\t\t\t\tkind: t(`changeSet.releases.kind.${r.kind}`),\n\t\t\t\t\t\t\t\t\t\t\t\tperiod: periodText(t, r.validityPeriod),\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n\nconst refusalKey: Record<Refusal, string> = {\n\trefused: \"changeSet.review.refused\",\n\tclosed: \"changeSet.review.closed\",\n\twithheld: \"changeSet.review.withheld\",\n\tfailed: \"changeSet.review.failed\",\n};\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, TextareaField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { z } from \"zod\";\nimport {\n\tCHECK_NOTE_MAX,\n\tChangeSetClosedError,\n\tCheckResultDeniedError,\n\tInvalidInputError,\n\tStaleHeadError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckOutcome, CheckStanding } from \"../types\";\nimport { subjectText } from \"./change-set-checks-tab\";\n\ntype RecordValues = { outcome: CheckOutcome; note: string };\n\nconst EMPTY: RecordValues = { outcome: \"passed\", note: \"\" };\nconst FORM_ID = \"contenthub-record-check-result\";\nconst OUTCOMES = [\"passed\", \"failed\", \"waived\"] as const satisfies readonly CheckOutcome[];\n\nexport interface RecordCheckResultModalProps {\n\topen: boolean;\n\t/** The check and subject the result is about, latched while the dialog is open. */\n\tstanding: CheckStanding | null;\n\tonClose: () => void;\n\t/**\n\t * Records it against the standing's heads. Its typed rejections are\n\t * worded here; anything else is a generic failure.\n\t */\n\tonSubmit: (input: { outcome: CheckOutcome; note: string }) => Promise<void>;\n}\n\n/**\n * Records a Check Result: passed, failed, or waived with a note saying why\n * (ADR 0014). A waiver without a note never reaches the service: the form\n * refuses it first, as the service would.\n *\n * Kept mounted and driven by `open`, with `lazyMount unmountOnExit` (anker's\n * Modal rule); every opening resets the form.\n */\nexport function RecordCheckResultModal({\n\topen,\n\tstanding,\n\tonClose,\n\tonSubmit,\n}: RecordCheckResultModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst schema = useMemo(\n\t\t() =>\n\t\t\tz\n\t\t\t\t.object({\n\t\t\t\t\toutcome: z.enum(OUTCOMES),\n\t\t\t\t\tnote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.max(CHECK_NOTE_MAX, t(\"changeSet.checks.form.noteTooLong\", { max: CHECK_NOTE_MAX })),\n\t\t\t\t})\n\t\t\t\t.superRefine((v, ctx) => {\n\t\t\t\t\tif (v.outcome === \"waived\" && v.note.trim() === \"\") {\n\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\tcode: \"custom\",\n\t\t\t\t\t\t\tpath: [\"note\"],\n\t\t\t\t\t\t\tmessage: t(\"changeSet.checks.form.noteRequired\"),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t[t],\n\t);\n\tconst methods = useForm<RecordValues>({ resolver: zodResolver(schema), defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onSubmit({ outcome: values.outcome, note: values.note.trim() });\n\t\t} catch (err) {\n\t\t\tif (err instanceof StaleHeadError) setRefusal(t(\"changeSet.checks.form.stale\"));\n\t\t\telse if (err instanceof CheckResultDeniedError) {\n\t\t\t\tsetRefusal(`${t(\"changeSet.checks.form.denied\")} ${err.message}`);\n\t\t\t} else if (err instanceof ChangeSetClosedError) setRefusal(t(\"changeSet.checks.form.closed\"));\n\t\t\telse if (err instanceof InvalidInputError) setRefusal(err.message);\n\t\t\telse setRefusal(t(\"changeSet.checks.form.failed\"));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"changeSet.checks.form.title\", { check: standing?.check.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"changeSet.checks.form.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{standing ? (\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"changeSet.checks.form.on\", { subject: subjectText(t, standing) })}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<RecordValues>\n\t\t\t\t\t\t\tname=\"outcome\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.checks.form.outcome\")}\n\t\t\t\t\t\t\toptions={OUTCOMES.map((o) => ({\n\t\t\t\t\t\t\t\tid: o,\n\t\t\t\t\t\t\t\tlabel: t(`changeSet.checks.outcome.${o}`),\n\t\t\t\t\t\t\t}))}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<TextareaField<RecordValues>\n\t\t\t\t\t\t\tname=\"note\"\n\t\t\t\t\t\t\tlabel={t(\"changeSet.checks.form.note\")}\n\t\t\t\t\t\t\thelperText={t(\"changeSet.checks.form.noteHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, StatusBadge, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { ContextRail } from \"@knkcs/anker/components\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs, Text } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate, usePageRail } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { GitMerge, Info, Save, Send, Trash2, Zap } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport {\n\tChangeSetClosedError,\n\ttype ChangeSetUpdateField,\n\ttype ContenthubClient,\n\tInvalidInputError,\n\tServiceUnavailableError,\n\tStaleHeadError,\n\tStaleStatusError,\n\tStatusTransitionRefusedError,\n} from \"../client/contenthub-client\";\nimport { headsOf } from \"../common/heads\";\nimport { isAnswer, useAttemptKey } from \"../common/idempotency\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, CheckStanding, PublishOutcome, StatusSource } from \"../types\";\nimport { DiscardChangeSetModal, UpdateFromMainModal } from \"./change-set-action-modals\";\nimport { ChangeSetChecksTab } from \"./change-set-checks-tab\";\nimport {\n\tbranchToOpen,\n\tChangeSetContentsTab,\n\ttype OpenBranchTarget,\n} from \"./change-set-contents-tab\";\nimport { ChangeSetGeneralTab, type GeneralValues, generalValuesOf } from \"./change-set-general-tab\";\nimport { ChangeSetReleasesTab } from \"./change-set-releases-tab\";\nimport { PublishReviewModal } from \"./publish-review-modal\";\nimport { RecordCheckResultModal } from \"./record-check-result-modal\";\n\nexport type { OpenBranchTarget } from \"./change-set-contents-tab\";\n\ntype Tab = \"general\" | \"contents\" | \"releases\" | \"checks\";\nconst TABS: Tab[] = [\"general\", \"contents\", \"releases\", \"checks\"];\n\n/** The rail's dialogs, which the screen renders (anker ADR 0004). */\ntype Dialog = \"publish\" | \"update\" | \"discard\" | \"record\";\nconst GENERAL: Tab = \"general\";\nconst NO_VALUES: GeneralValues = {\n\tname: \"\",\n\tsourceDate: \"\",\n\tsourceReference: \"\",\n\tstatus: \"\",\n\tassigneeIds: [],\n\tdependsOnIds: [],\n};\n\nexport interface ChangeSetPageProps {\n\tclient: ContenthubClient;\n\tchangeSetId: string;\n\t/**\n\t * statushub's labels and the status picker. Without it the status shows\n\t * as its slug and cannot be changed here (ADR 0020).\n\t */\n\tstatusSource?: StatusSource;\n\t/** Host navigation to the Branch editor, from a row of the Contents tab. */\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n\t/** Told after a Publish from the rail; the page stays, showing it published. */\n\tonPublished?: (outcome: PublishOutcome) => void;\n\t/** Told after a Discard from the rail; the page stays, showing it discarded. */\n\tonDiscarded?: (changeSetId: string) => void;\n}\n\n/**\n * A Change Set's page (spec #56, stories 102–106): General, Contents,\n * Releases and Checks, saved from the header's one Save (anker ADR 0004);\n * the rail holds what is done *to* it (Publish, Update from Main, Discard)\n * and what it is at a glance (readiness, status label, Source). Each rail\n * action opens a dialog the screen renders, since a rail node renders away\n * from the screen's providers.\n *\n * The draft registry is keyed by the Change Set, so moving to another one\n * starts clean rather than carrying the last one's dirty marks.\n */\nexport function ChangeSetPage(props: ChangeSetPageProps) {\n\treturn (\n\t\t<TabDirtyProvider key={props.changeSetId}>\n\t\t\t<ChangeSetEditor {...props} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\nChangeSetPage.displayName = \"ChangeSetPage\";\n\n/** Why the last Save stopped, in the words the page shows it with. */\ntype Refusal =\n\t| { kind: \"transition\"; from: string; to: string; reason: string; guarded: boolean }\n\t| { kind: \"staleStatus\"; current: string }\n\t| { kind: \"closed\" }\n\t| { kind: \"invalid\"; message: string }\n\t| { kind: \"unavailable\" }\n\t| { kind: \"failed\" };\n\n/**\n * The same ids, in any order: neither assignees nor dependencies mean\n * anything by their order, and the service may answer in another one.\n */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n\treturn a.length === b.length && a.every((id) => b.includes(id));\n}\n\n/** The draft as the service would store it: the name and the Source trimmed. */\nfunction trimmed(v: GeneralValues): GeneralValues {\n\treturn {\n\t\t...v,\n\t\tname: v.name.trim(),\n\t\tsourceDate: v.sourceDate.trim(),\n\t\tsourceReference: v.sourceReference.trim(),\n\t};\n}\n\n/** What of the name and the Source the draft changes, as `updateChangeSet`'s mask. */\nfunction updateMaskOf(base: ChangeSet, draft: GeneralValues): ChangeSetUpdateField[] {\n\tconst was = generalValuesOf(base);\n\tconst mask: ChangeSetUpdateField[] = [];\n\tif (draft.name !== was.name) mask.push(\"name\");\n\tif (draft.sourceDate !== was.sourceDate || draft.sourceReference !== was.sourceReference) {\n\t\tmask.push(\"source\");\n\t}\n\treturn mask;\n}\n\nfunction ChangeSetEditor({\n\tclient,\n\tchangeSetId,\n\tstatusSource,\n\tonOpenBranch,\n\tonPublished,\n\tonDiscarded,\n}: ChangeSetPageProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst statuses = useChangeSetStatuses(statusSource);\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\") as Tab | null;\n\tconst tab: Tab = tabParam && TABS.includes(tabParam) ? tabParam : GENERAL;\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.changeSet(changeSetId),\n\t\tqueryFn: () => client.getChangeSet(changeSetId),\n\t});\n\n\t// The BASELINE: the Change Set as the editor started from, moved only by\n\t// this page's own saves. Not the query's data: a refetch that brought a\n\t// colleague's status move would otherwise become the expected_status the\n\t// next Save names, and the compare-and-swap would pass exactly when it\n\t// exists to fail. Latched from the first answer, during render.\n\tconst [baseline, setBaseline] = useState<ChangeSet | null>(null);\n\tif (baseline === null && query.data) setBaseline(query.data);\n\tconst latest = useRef(baseline);\n\tlatest.current = baseline;\n\n\t// The General tab's draft, held here, above the tab, so it outlives the\n\t// tab's mount (anker ADR 0004).\n\tconst methods = useForm<GeneralValues>({ defaultValues: NO_VALUES });\n\tconst seeded = useRef(false);\n\tuseEffect(() => {\n\t\tif (baseline && !seeded.current) {\n\t\t\tseeded.current = true;\n\t\t\tmethods.reset(generalValuesOf(baseline));\n\t\t}\n\t}, [baseline, methods]);\n\tconst generalDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(GENERAL, generalDirty), [generalDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [refusal, setRefusal] = useState<Refusal | null>(null);\n\tconst [saved, setSaved] = useState(false);\n\t// One Idempotency Key per attempt at the name and Source, sent again when\n\t// the same change is retried after a failure whose outcome is unknown, as\n\t// the Branch editor's Save does.\n\tconst { keyFor: updateKeyFor, settle: settleUpdateKey } = useAttemptKey(\"update-change-set\");\n\t// \"Saved\" speaks of the last Save only: a new edit retires it.\n\tuseEffect(() => {\n\t\tif (generalDirty) setSaved(false);\n\t}, [generalDirty]);\n\n\t/**\n\t * Persists every changed part of the draft, one RPC per kind of change:\n\t * the name and the Source in one UpdateChangeSet, dependencies, then\n\t * assignees, then the status, which statushub may refuse and so goes\n\t * last. A refusal stops there; what was saved before it becomes the new\n\t * baseline, and what wasn't stays in the draft.\n\t */\n\tconst saveAll = useCallback(async () => {\n\t\tconst base = latest.current;\n\t\tif (!base) return;\n\t\tconst draft = trimmed(methods.getValues());\n\t\tlet current = base;\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tconst updateMask = updateMaskOf(base, draft);\n\t\t\tif (updateMask.length > 0) {\n\t\t\t\t// Both Source fields empty is no Source: the masked source is\n\t\t\t\t// sent absent, which clears it.\n\t\t\t\tconst source =\n\t\t\t\t\tdraft.sourceDate === \"\" && draft.sourceReference === \"\"\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: { date: draft.sourceDate, reference: draft.sourceReference };\n\t\t\t\tconst asked = { id: base.id, updateMask, name: draft.name, source };\n\t\t\t\ttry {\n\t\t\t\t\tcurrent = await client.updateChangeSet({\n\t\t\t\t\t\t...asked,\n\t\t\t\t\t\tidempotencyKey: updateKeyFor(asked),\n\t\t\t\t\t});\n\t\t\t\t\tsettleUpdateKey();\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// A refusal is an answer: the next Save is a new attempt.\n\t\t\t\t\tif (isAnswer(err)) settleUpdateKey();\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const id of draft.dependsOnIds) {\n\t\t\t\tif (!base.dependsOnChangeSetIds.includes(id)) {\n\t\t\t\t\tcurrent = await client.addDependency({ id: base.id, dependsOnId: id });\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const id of base.dependsOnChangeSetIds) {\n\t\t\t\tif (!draft.dependsOnIds.includes(id)) {\n\t\t\t\t\tcurrent = await client.removeDependency({ id: base.id, dependsOnId: id });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!sameIds(draft.assigneeIds, base.assigneeIds)) {\n\t\t\t\tcurrent = await client.setChangeSetAssignees({\n\t\t\t\t\tid: base.id,\n\t\t\t\t\tassigneeIds: draft.assigneeIds,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (draft.status !== base.status) {\n\t\t\t\tcurrent = await client.setChangeSetStatus({\n\t\t\t\t\tid: base.id,\n\t\t\t\t\texpectedStatus: base.status,\n\t\t\t\t\tstatus: draft.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} catch (err) {\n\t\t\tif (err instanceof StatusTransitionRefusedError) {\n\t\t\t\tsetRefusal({\n\t\t\t\t\tkind: \"transition\",\n\t\t\t\t\tfrom: err.fromStatus,\n\t\t\t\t\tto: err.toStatus,\n\t\t\t\t\treason: err.reason,\n\t\t\t\t\tguarded: err.requiresPermission,\n\t\t\t\t});\n\t\t\t} else if (err instanceof StaleStatusError) {\n\t\t\t\t// The next Save moves from the status that is there now.\n\t\t\t\tcurrent = { ...current, status: err.currentStatus };\n\t\t\t\tsetRefusal({ kind: \"staleStatus\", current: err.currentStatus });\n\t\t\t} else if (err instanceof ChangeSetClosedError) {\n\t\t\t\tsetRefusal({ kind: \"closed\" });\n\t\t\t\tcurrent = await client.getChangeSet(base.id).catch(() => current);\n\t\t\t} else if (err instanceof ServiceUnavailableError) {\n\t\t\t\tsetRefusal({ kind: \"unavailable\" });\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal({ kind: \"invalid\", message: err.message });\n\t\t\t} else {\n\t\t\t\tsetRefusal({ kind: \"failed\" });\n\t\t\t}\n\t\t} finally {\n\t\t\t// The new baseline, with the unsaved rest of the draft laid back on\n\t\t\t// top of it, still dirty.\n\t\t\tconst next = generalValuesOf(current);\n\t\t\tmethods.reset(next);\n\t\t\tfor (const key of Object.keys(next) as (keyof GeneralValues)[]) {\n\t\t\t\tconst wanted = draft[key];\n\t\t\t\tconst same = Array.isArray(wanted)\n\t\t\t\t\t? sameIds(wanted, next[key] as string[])\n\t\t\t\t\t: wanted === next[key];\n\t\t\t\tif (!same) methods.setValue(key, wanted, { shouldDirty: true });\n\t\t\t}\n\t\t\tlatest.current = current;\n\t\t\tsetBaseline(current);\n\t\t\tqueryClient.setQueryData(contenthubKeys.changeSet(changeSetId), current);\n\t\t\t// The lists only: the detail was just written from the answer.\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSetLists() });\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [client, changeSetId, methods, queryClient, updateKeyFor, settleUpdateKey]);\n\n\t// The freshest Change Set: its Chains, heads and state are no draft.\n\tconst fresh = query.data ?? baseline;\n\tconst isOpen = fresh?.state === \"open\";\n\tconst freshHeads = useMemo(() => (fresh ? headsOf(fresh) : {}), [fresh]);\n\n\t// The rail's readiness tile is ValidatePublish at the current heads: the\n\t// same answer the Publish review starts from.\n\tconst readiness = useQuery({\n\t\tqueryKey: contenthubKeys.publishReadinessAt(changeSetId, freshHeads),\n\t\tqueryFn: () => client.validatePublish({ id: changeSetId, reviewedHeads: freshHeads }),\n\t\tenabled: isOpen,\n\t});\n\tconst standings = useQuery({\n\t\tqueryKey: contenthubKeys.checkStandings(changeSetId),\n\t\tqueryFn: () => client.listCheckResults(changeSetId),\n\t\tenabled: !!fresh,\n\t});\n\tconst checkNames = useMemo(() => {\n\t\tconst names = new Map<string, string>();\n\t\tfor (const st of standings.data ?? []) names.set(st.check.id, st.check.name);\n\t\treturn names;\n\t}, [standings.data]);\n\tconst checkName = useCallback((id: string) => checkNames.get(id) ?? id, [checkNames]);\n\n\tconst [dialog, setDialog] = useState<Dialog | null>(null);\n\t// The row a Record dialog is about, latched while it is open.\n\tconst [recording, setRecording] = useState<CheckStanding | null>(null);\n\tconst closeDialog = useCallback(() => setDialog(null), []);\n\n\t/** Everything that depends on the heads, asked again. */\n\tconst refreshReview = useCallback(() => {\n\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.publishReadiness(changeSetId) });\n\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.checkStandings(changeSetId) });\n\t}, [queryClient, changeSetId]);\n\n\t/** A Change Set the service just read: what depends on its heads asks again. */\n\tconst reviewed = useCallback(\n\t\t(next: ChangeSet) => {\n\t\t\tqueryClient.setQueryData(contenthubKeys.changeSet(changeSetId), next);\n\t\t\trefreshReview();\n\t\t},\n\t\t[queryClient, changeSetId, refreshReview],\n\t);\n\n\t/**\n\t * A Change Set a rail action answered with. Its state reaches the\n\t * baseline (the header shows it published or discarded); the General\n\t * fields don't: the baseline's status is the next Save's expected_status,\n\t * and taking a colleague's move from here would let that Save pass the\n\t * compare-and-swap it exists to fail.\n\t */\n\tconst adopt = useCallback(\n\t\t(next: ChangeSet) => {\n\t\t\treviewed(next);\n\t\t\tconst base = latest.current;\n\t\t\tconst kept = base\n\t\t\t\t? {\n\t\t\t\t\t\t...next,\n\t\t\t\t\t\tname: base.name,\n\t\t\t\t\t\tsource: base.source,\n\t\t\t\t\t\tstatus: base.status,\n\t\t\t\t\t\tassigneeIds: base.assigneeIds,\n\t\t\t\t\t\tdependsOnChangeSetIds: base.dependsOnChangeSetIds,\n\t\t\t\t\t}\n\t\t\t\t: next;\n\t\t\tlatest.current = kept;\n\t\t\tsetBaseline(kept);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSetLists() });\n\t\t},\n\t\t[queryClient, reviewed],\n\t);\n\n\tconst published = useCallback(\n\t\t(outcome: PublishOutcome) => {\n\t\t\tsetDialog(null);\n\t\t\tadopt(outcome.changeSet);\n\t\t\tonPublished?.(outcome);\n\t\t},\n\t\t[adopt, onPublished],\n\t);\n\tconst updateFromMain = useCallback(async () => {\n\t\tconst outcome = await client.updateFromMain({ id: changeSetId });\n\t\tadopt(outcome.changeSet);\n\t\treturn outcome;\n\t}, [client, changeSetId, adopt]);\n\tconst discard = useCallback(async () => {\n\t\tadopt(await client.discardChangeSet(changeSetId));\n\t\tsetDialog(null);\n\t\tonDiscarded?.(changeSetId);\n\t}, [client, changeSetId, adopt, onDiscarded]);\n\tconst record = useCallback(\n\t\tasync ({\n\t\t\toutcome,\n\t\t\tnote,\n\t\t}: {\n\t\t\toutcome: CheckStanding[\"results\"][number][\"outcome\"];\n\t\t\tnote: string;\n\t\t}) => {\n\t\t\tif (!recording) return;\n\t\t\ttry {\n\t\t\t\tawait client.recordCheckResult({\n\t\t\t\t\tchangeSetId,\n\t\t\t\t\trequiredCheckId: recording.check.id,\n\t\t\t\t\t// The heads the row showed: a save since is the service's to refuse.\n\t\t\t\t\theads: recording.heads,\n\t\t\t\t\toutcome,\n\t\t\t\t\tnote,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\t// The rows behind the dialog show the new heads by the time it closes.\n\t\t\t\tif (err instanceof StaleHeadError) {\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSet(changeSetId) });\n\t\t\t\t\trefreshReview();\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tsetDialog(null);\n\t\t\trefreshReview();\n\t\t},\n\t\t[client, changeSetId, recording, refreshReview, queryClient],\n\t);\n\tconst openRecord = useCallback((st: CheckStanding) => {\n\t\tsetRecording(st);\n\t\tsetDialog(\"record\");\n\t}, []);\n\n\tconst blockerCount = readiness.data?.blockers.length;\n\tconst railStatus = fresh ? statuses.labelOf(fresh.status) : undefined;\n\t// The rail closes over this screen's state and reads no context: the host\n\t// draws it away from the screen's providers (anker's host contract).\n\tusePageRail(\n\t\tfresh ? (\n\t\t\t<ContextRail storageKey=\"contenthub-change-set\">\n\t\t\t\t<ContextRail.Header eyebrow={t(\"changeSet.rail.eyebrow\")} title={fresh.name} />\n\t\t\t\t{isOpen ? (\n\t\t\t\t\t<ContextRail.Section\n\t\t\t\t\t\tid=\"actions\"\n\t\t\t\t\t\ticon={<Zap size={16} />}\n\t\t\t\t\t\tlabel={t(\"changeSet.rail.actions\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.publish\")}\n\t\t\t\t\t\t\ticon={<Send size={16} />}\n\t\t\t\t\t\t\ttone=\"primary\"\n\t\t\t\t\t\t\tonClick={() => setDialog(\"publish\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.updateFromMain\")}\n\t\t\t\t\t\t\ticon={<GitMerge size={16} />}\n\t\t\t\t\t\t\tonClick={() => setDialog(\"update\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.discard\")}\n\t\t\t\t\t\t\ticon={<Trash2 size={16} />}\n\t\t\t\t\t\t\ttone=\"outline-red\"\n\t\t\t\t\t\t\tonClick={() => setDialog(\"discard\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ContextRail.Section>\n\t\t\t\t) : null}\n\t\t\t\t<ContextRail.Section id=\"about\" icon={<Info size={16} />} label={t(\"changeSet.rail.about\")}>\n\t\t\t\t\t{isOpen ? (\n\t\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\t\tkeepWhenEmpty\n\t\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\t\treadiness.isError\n\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.unknownReadiness\")\n\t\t\t\t\t\t\t\t\t: blockerCount === undefined\n\t\t\t\t\t\t\t\t\t\t? \"…\"\n\t\t\t\t\t\t\t\t\t\t: blockerCount === 0\n\t\t\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.ready\")\n\t\t\t\t\t\t\t\t\t\t\t: blockerCount\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlabel={\n\t\t\t\t\t\t\t\tblockerCount\n\t\t\t\t\t\t\t\t\t? t(\"changeSet.rail.blockers\", { count: blockerCount })\n\t\t\t\t\t\t\t\t\t: t(\"changeSet.rail.readiness\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\t\tvalue={t(`changeSets.state.${fresh.state}`)}\n\t\t\t\t\t\t\tlabel={t(\"changeSet.rail.state\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t<ContextRail.ValueTile\n\t\t\t\t\t\tkeepWhenEmpty\n\t\t\t\t\t\tvalue={railStatus?.name ?? t(\"changeSet.rail.noStatus\")}\n\t\t\t\t\t\tlabel={t(\"changeSet.rail.status\")}\n\t\t\t\t\t\tmuted={!railStatus}\n\t\t\t\t\t/>\n\t\t\t\t\t<Stack gap=\"0\" mt=\"2\">\n\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t\t{t(\"changeSet.rail.source\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t<Text fontSize=\"sm\">\n\t\t\t\t\t\t\t{fresh.source\n\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\tdate: fresh.source.date,\n\t\t\t\t\t\t\t\t\t\treference: fresh.source.reference,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: t(\"changeSet.rail.noSource\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Stack>\n\t\t\t\t</ContextRail.Section>\n\t\t\t</ContextRail>\n\t\t) : null,\n\t);\n\n\tconst changeSet = baseline;\n\tif (!changeSet) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\"), to: paths.changeSets }]}\n\t\t\t\ttitle={query.isError ? t(\"changeSet.unavailable\") : t(\"changeSet.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\ttitle={notFound ? t(\"changeSet.notFound\") : t(\"changeSet.loadError\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\tconst changed = dirtyTabs.length;\n\tconst status = statuses.labelOf(changeSet.status);\n\tconst selectTab = (next: Tab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params, { replace: true });\n\t};\n\tconst contents = fresh ?? changeSet;\n\t/** A blocker's Content, opened where it is fixed: the Branch its Chain's row opens. */\n\tconst openContent = (contentId: string) => {\n\t\tconst chain = contents.chains.find((c) => c.contentId === contentId);\n\t\tif (!chain) return;\n\t\tcloseDialog();\n\t\tonOpenBranch({ changeSetId: contents.id, contentId, branchId: branchToOpen(chain) });\n\t};\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"changeSets.title\"), to: paths.changeSets },\n\t\t\t\t{ label: changeSet.name },\n\t\t\t]}\n\t\t\ttitle={changeSet.name}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t<TypeBadge\n\t\t\t\t\t\tname={t(`changeSets.state.${changeSet.state}`)}\n\t\t\t\t\t\tcolorPalette={changeSet.state === \"open\" ? \"blue\" : \"gray\"}\n\t\t\t\t\t/>\n\t\t\t\t\t{status ? <StatusBadge label={status.name} color={status.color ?? \"gray\"} /> : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\tdisabled={changed === 0}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void saveAll()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"changeSet.save\") : t(\"changeSet.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => selectTab(e.value as Tab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(`changeSet.tabs.${each}`)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{refusal ? <RefusalAlert refusal={refusal} labelOf={statuses.labelOf} /> : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"changeSet.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t{tab === \"general\" ? (\n\t\t\t\t\t<ChangeSetGeneralTab client={client} changeSet={changeSet} statuses={statuses} />\n\t\t\t\t) : null}\n\t\t\t</FormProvider>\n\t\t\t{tab === \"contents\" ? (\n\t\t\t\t<ChangeSetContentsTab changeSet={contents} onOpenBranch={onOpenBranch} />\n\t\t\t) : null}\n\t\t\t{tab === \"releases\" ? (\n\t\t\t\t<ChangeSetReleasesTab changeSet={contents} blockers={readiness.data?.blockers ?? []} />\n\t\t\t) : null}\n\t\t\t{tab === \"checks\" ? (\n\t\t\t\t<ChangeSetChecksTab\n\t\t\t\t\tstandings={standings.data ?? []}\n\t\t\t\t\tloading={standings.isPending}\n\t\t\t\t\tfailed={standings.isError}\n\t\t\t\t\tcanRecord={contents.state === \"open\"}\n\t\t\t\t\tonRecord={openRecord}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<PublishReviewModal\n\t\t\t\topen={dialog === \"publish\"}\n\t\t\t\tclient={client}\n\t\t\t\tchangeSet={contents}\n\t\t\t\tcheckName={checkName}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonPublished={published}\n\t\t\t\tonReviewed={reviewed}\n\t\t\t\tonOpenContent={openContent}\n\t\t\t/>\n\t\t\t<UpdateFromMainModal\n\t\t\t\topen={dialog === \"update\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={updateFromMain}\n\t\t\t/>\n\t\t\t<DiscardChangeSetModal\n\t\t\t\topen={dialog === \"discard\"}\n\t\t\t\tname={contents.name}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonConfirm={discard}\n\t\t\t/>\n\t\t\t<RecordCheckResultModal\n\t\t\t\topen={dialog === \"record\"}\n\t\t\t\tstanding={recording}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tonSubmit={record}\n\t\t\t/>\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"changeSet.leave.title\")}\n\t\t\t\tmessage={t(\"changeSet.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"changeSet.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"changeSet.leave.cancel\")}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n\nfunction RefusalAlert({\n\trefusal,\n\tlabelOf,\n}: {\n\trefusal: Refusal;\n\tlabelOf: (slug: string) => { name: string } | undefined;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst name = (slug: string) => labelOf(slug)?.name ?? t(\"changeSet.general.noStatus\");\n\tswitch (refusal.kind) {\n\t\tcase \"transition\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\ttitle={t(refusal.guarded ? \"changeSet.refused.guarded\" : \"changeSet.refused.transition\", {\n\t\t\t\t\t\tfrom: name(refusal.from),\n\t\t\t\t\t\tto: name(refusal.to),\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t{refusal.reason}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tcase \"staleStatus\":\n\t\t\treturn (\n\t\t\t\t<Alert\n\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\ttitle={t(\"changeSet.refused.staleStatus\", { current: name(refusal.current) })}\n\t\t\t\t/>\n\t\t\t);\n\t\tcase \"unavailable\":\n\t\t\treturn <Alert status=\"warning\" title={t(\"changeSet.refused.unavailable\")} />;\n\t\tcase \"closed\":\n\t\t\treturn <Alert status=\"error\" title={t(\"changeSet.refused.closed\")} />;\n\t\tcase \"invalid\":\n\t\t\treturn (\n\t\t\t\t<Alert status=\"error\" title={t(\"changeSet.refused.invalid\")}>\n\t\t\t\t\t{refusal.message}\n\t\t\t\t</Alert>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn <Alert status=\"error\" title={t(\"changeSet.refused.failed\")} />;\n\t}\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tDataTable,\n\tDateCell,\n\tStatusBadgeCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, NativeSelect, Stack } from \"@knkcs/anker/primitives\";\nimport { IndexPageTemplate } from \"@knkcs/anker/templates\";\nimport { keepPreviousData, useInfiniteQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FolderGit2, Plus } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useChangeSetStatuses } from \"../common/use-change-set-statuses\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, ChangeSetState, StatusSource } from \"../types\";\nimport { CreateChangeSetModal } from \"./create-change-set-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype ChangeSetRow = ChangeSet & Record<string, unknown>;\n\nconst STATES: ChangeSetState[] = [\"open\", \"published\", \"discarded\"];\n/** The toolbar's \"me\" filter, distinct from any user id. */\nconst ME = \"@me\";\n/** Change Sets per page; \"Show more\" asks for the next. */\nconst PAGE_SIZE = 50;\n\nexport interface ChangeSetsIndexProps {\n\tclient: ContenthubClient;\n\t/**\n\t * statushub's labels for the status column. Without it the column shows\n\t * the bare slug (ADR 0020).\n\t */\n\tstatusSource?: StatusSource;\n\t/** Host navigation to a Change Set's page: a row's click, and a new one once created. */\n\tonOpenChangeSet: (changeSetId: string) => void;\n}\n\n/**\n * The workspace's Change Sets, newest first, narrowed by state and by who\n * is assigned (spec #56, story 101), created from the header in a Modal\n * (anker: no inline create form above a DataTable). Creating one opens its\n * page, where the work happens.\n */\nexport function ChangeSetsIndex({ client, statusSource, onOpenChangeSet }: ChangeSetsIndexProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst { userId, members } = useHostIdentity();\n\tconst statuses = useChangeSetStatuses(statusSource);\n\tconst [creating, setCreating] = useState(false);\n\t// Open work is what an editor comes here for.\n\tconst [state, setState] = useState<ChangeSetState | \"\">(\"open\");\n\tconst [assignee, setAssignee] = useState(\"\");\n\n\tconst filter = useMemo(\n\t\t() => ({\n\t\t\tstate: state || undefined,\n\t\t\tassigneeId: assignee === ME ? userId : assignee || undefined,\n\t\t}),\n\t\t[state, assignee, userId],\n\t);\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.changeSetList(filter),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listChangeSets({ ...filter, pageSize: PAGE_SIZE, pageToken: pageParam }),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t\t// A filter change keeps the rows on screen until the new ones arrive.\n\t\tplaceholderData: keepPreviousData,\n\t});\n\tconst changeSets = useMemo(\n\t\t() => query.data?.pages.flatMap((page) => page.changeSets) ?? [],\n\t\t[query.data],\n\t);\n\n\t// An assignee who is no longer a member is still shown, by id.\n\tconst nameOf = useCallback((id: string) => members.byId(id)?.displayName ?? id, [members]);\n\n\tconst columns = useMemo<ColumnDef<ChangeSetRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"changeSets.columns.name\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst source = row.original.source;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\t\tsource\n\t\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", { date: source.date, reference: source.reference })\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"state\",\n\t\t\t\theader: t(\"changeSets.columns.state\"),\n\t\t\t\tcell: ({ row }) => <StatusBadgeCell value={t(`changeSets.state.${row.original.state}`)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"status\",\n\t\t\t\theader: t(\"changeSets.columns.status\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst label = statuses.labelOf(row.original.status);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\t\tvalue={label?.name ?? null}\n\t\t\t\t\t\t\tcolorMap={label?.color ? { [label.name]: label.color } : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"assignees\",\n\t\t\t\theader: t(\"changeSets.columns.assignees\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.assigneeIds.map(nameOf).join(\", \") || null}\n\t\t\t\t\t\tmaxLength={60}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"created\",\n\t\t\t\theader: t(\"changeSets.columns.created\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t],\n\t\t[t, statuses, nameOf],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setCreating(true)}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"changeSets.create\")}\n\t\t</Button>\n\t);\n\n\treturn (\n\t\t<IndexPageTemplate\n\t\t\ttitle={t(\"changeSets.title\")}\n\t\t\tbreadcrumbs={[{ label: t(\"changeSets.title\") }]}\n\t\t\tactions={createButton}\n\t\t\ttoolbar={\n\t\t\t\t<Toolbar>\n\t\t\t\t\t<Toolbar.Filters>\n\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label={t(\"changeSets.filter.state\")}\n\t\t\t\t\t\t\tvalue={state}\n\t\t\t\t\t\t\tonChange={(e) => setState(e.target.value as ChangeSetState | \"\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<option value=\"\">{t(\"changeSets.filter.anyState\")}</option>\n\t\t\t\t\t\t\t{STATES.map((s) => (\n\t\t\t\t\t\t\t\t<option key={s} value={s}>\n\t\t\t\t\t\t\t\t\t{t(`changeSets.state.${s}`)}\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label={t(\"changeSets.filter.assignee\")}\n\t\t\t\t\t\t\tvalue={assignee}\n\t\t\t\t\t\t\tonChange={(e) => setAssignee(e.target.value)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<option value=\"\">{t(\"changeSets.filter.anyone\")}</option>\n\t\t\t\t\t\t\t<option value={ME}>{t(\"changeSets.filter.me\")}</option>\n\t\t\t\t\t\t\t{members\n\t\t\t\t\t\t\t\t.list()\n\t\t\t\t\t\t\t\t.filter((m) => m.userId !== userId)\n\t\t\t\t\t\t\t\t.map((m) => (\n\t\t\t\t\t\t\t\t\t<option key={m.userId} value={m.userId}>\n\t\t\t\t\t\t\t\t\t\t{m.displayName}\n\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t</Toolbar.Filters>\n\t\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t\t<Toolbar.Count>\n\t\t\t\t\t\t\t{t(\"changeSets.count\", { count: changeSets.length })}\n\t\t\t\t\t\t\t{query.hasNextPage ? \"+\" : \"\"}\n\t\t\t\t\t\t</Toolbar.Count>\n\t\t\t\t\t</Toolbar.Right>\n\t\t\t\t</Toolbar>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t{query.isError ? (\n\t\t\t\t\t<Alert status=\"error\" title={t(\"changeSets.loadError\")} mx=\"8\" mt=\"4\" />\n\t\t\t\t) : null}\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={changeSets as ChangeSetRow[]}\n\t\t\t\t\tloading={query.isLoading}\n\t\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\t\tonRowClick={(row) => onOpenChangeSet(row.id)}\n\t\t\t\t\tvariant=\"hoverable\"\n\t\t\t\t\temptyState={\n\t\t\t\t\t\t<EmptyState\n\t\t\t\t\t\t\ticon={<FolderGit2 size={32} />}\n\t\t\t\t\t\t\theader={t(\"changeSets.empty\")}\n\t\t\t\t\t\t\tdescription={t(\"changeSets.emptyHint\")}\n\t\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t\t{query.hasNextPage ? (\n\t\t\t\t\t<HStack justify=\"center\" pb=\"4\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tloading={query.isFetchingNextPage}\n\t\t\t\t\t\t\tonClick={() => void query.fetchNextPage()}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"changeSets.more\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t</Stack>\n\t\t\t{/* Rendered by the screen, never inside the reported header action:\n\t\t\t a host draws that action outside these providers (anker). */}\n\t\t\t<CreateChangeSetModal\n\t\t\t\topen={creating}\n\t\t\t\tonClose={() => setCreating(false)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tconst created = await client.createChangeSet(input);\n\t\t\t\t\tsetCreating(false);\n\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\t\t\tonOpenChangeSet(created.id);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</IndexPageTemplate>\n\t);\n}\n\nChangeSetsIndex.displayName = \"ChangeSetsIndex\";\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentAttributes } from \"../types\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nexport interface ArchiveContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** The Content was archived: its attributes now. */\n\tonArchived: (attributes: ContentAttributes) => void;\n}\n\n/**\n * Archive's confirmation (spec #56, story 92): archiving puts the Content\n * aside, out of the Library, every picker and editing, so it asks first.\n * Its Releases stay readable and every pin to them keeps resolving (ADR\n * 0015), and Unarchive brings it back.\n */\nexport function ArchiveContentModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tonArchived,\n}: ArchiveContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst [busy, setBusy] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (open) setRefusal(null);\n\t}, [open]);\n\n\tasync function confirm() {\n\t\tsetBusy(true);\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tonArchived(await client.archiveContent(contentId));\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"sm\"\n\t\t\theader={t(\"content.archive.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\tloading={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"content.archive.confirm\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"3\">\n\t\t\t\t<Text>{t(\"content.archive.message\")}</Text>\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Link, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { Link as RouterLink } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubSettingsPath, useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ContentAttributes, ContentBlock } from \"../types\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-block-content\";\n\ntype BlockValues = { blockReasonId: string | null; allowedUserIds: string[] };\n\nexport interface BlockContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** The Block it has, which a new one replaces; absent while it has none. */\n\tcurrent?: ContentBlock;\n\t/** The Content was blocked: its attributes now. */\n\tonBlocked: (attributes: ContentAttributes) => void;\n}\n\n/**\n * Block (spec #56, story 92; CONTEXT.md, Block): one of the workspace's\n * Block Reasons and who may still edit it. Blocking a blocked Content\n * replaces its Block. Like filing, it is no save and writes no Revision.\n */\nexport function BlockContentModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tcurrent,\n\tonBlocked,\n}: BlockContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst reasons = useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t\tenabled: open,\n\t});\n\tconst empty = useMemo<BlockValues>(\n\t\t() => ({\n\t\t\tblockReasonId: current?.blockReasonId ?? null,\n\t\t\tallowedUserIds: [...(current?.allowedUserIds ?? [])],\n\t\t}),\n\t\t[current],\n\t);\n\tconst methods = useForm<BlockValues>({ defaultValues: empty });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(empty);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods, empty]);\n\n\tconst reasonOptions = useMemo<BaseOption[]>(\n\t\t() => (reasons.data ?? []).map((r) => ({ id: r.id, label: r.name })),\n\t\t[reasons.data],\n\t);\n\tconst userOptions = useMemo<BaseOption[]>(\n\t\t() => members.list().map((m) => ({ id: m.userId, label: m.displayName })),\n\t\t[members],\n\t);\n\tconst noReasons = reasons.isSuccess && reasons.data.length === 0;\n\tconst paths = useContenthubPaths();\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tif (!values.blockReasonId) {\n\t\t\tmethods.setError(\"blockReasonId\", { message: t(\"content.block.reasonRequired\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tonBlocked(\n\t\t\t\tawait client.blockContent({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tblockReasonId: values.blockReasonId,\n\t\t\t\t\tallowedUserIds: values.allowedUserIds,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.block.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\tform={FORM_ID}\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tloading={submitting}\n\t\t\t\t\t\tdisabled={noReasons}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"content.block.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t{noReasons ? (\n\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"content.block.noReasons\")}>\n\t\t\t\t\t\t\t\t<Link asChild>\n\t\t\t\t\t\t\t\t\t<RouterLink to={contenthubSettingsPath(paths, \"block-reasons\")}>\n\t\t\t\t\t\t\t\t\t\t{t(\"content.block.openBlockReasons\")}\n\t\t\t\t\t\t\t\t\t</RouterLink>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</Alert>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<BaseSelectField<BlockValues>\n\t\t\t\t\t\t\tname=\"blockReasonId\"\n\t\t\t\t\t\t\tlabel={t(\"content.block.reason\")}\n\t\t\t\t\t\t\thelperText={t(\"content.block.reasonHelp\")}\n\t\t\t\t\t\t\toptions={reasonOptions}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<BaseSelectField<BlockValues>\n\t\t\t\t\t\t\tname=\"allowedUserIds\"\n\t\t\t\t\t\t\tlabel={t(\"content.block.allowed\")}\n\t\t\t\t\t\t\thelperText={t(\"content.block.allowedHelp\")}\n\t\t\t\t\t\t\toptions={userOptions}\n\t\t\t\t\t\t\tisMulti\n\t\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, DateCell, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useInfiniteQuery, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { History } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet, CompareBase, Content, FieldChange, Revision } from \"../types\";\nimport { valueText } from \"./content-data-tab\";\n\ntype RevisionRow = Revision & Record<string, unknown>;\ntype ChangeRow = FieldChange & Record<string, unknown>;\n\n/** Revisions read at once; a Content with a longer history shows more on request. */\nconst REVISIONS_PAGE = 100;\n\n/** Every Change Set with a Chain on the Content, whatever its state. */\nexport function useContentChangeSets(client: ContenthubClient, contentId: string) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.contentChangeSets(contentId),\n\t\tqueryFn: () => client.listChangeSets({ contentId, pageSize: 200 }),\n\t});\n}\n\n/**\n * The Revisions tab (spec #56, story 90): who wrote what, when and why,\n * newest first, and how a chosen Revision differs from the one it was built\n * on (Compare). A published Content lists every Revision on every Branch;\n * Content born in an open Change Set, which versionkit can't list by Item\n * until it is published, lists its Branch's (#65). Revisions written in a\n * Change Set since discarded stay in history, and are marked so.\n */\nexport function ContentRevisionsTab({\n\tclient,\n\tcontent,\n\tpublished,\n}: {\n\tclient: ContenthubClient;\n\tcontent: Content;\n\t/** Whether it has a Main Branch, which a first Revision is compared against. */\n\tpublished: boolean;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst target = useMemo(\n\t\t() =>\n\t\t\tpublished || !content.branchId ? { contentId: content.id } : { branchId: content.branchId },\n\t\t[published, content.branchId, content.id],\n\t);\n\tconst revisions = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.contentRevisions(content.id, target),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listRevisions({ target, pageSize: REVISIONS_PAGE, pageToken: pageParam }),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t});\n\tconst rows = useMemo(\n\t\t() => (revisions.data?.pages ?? []).flatMap((p) => p.revisions) as RevisionRow[],\n\t\t[revisions.data],\n\t);\n\tconst changeSets = useContentChangeSets(client, content.id);\n\tconst [selected, setSelected] = useState<Revision | null>(null);\n\n\tconst changeSetOf = useCallback(\n\t\t(id: string): ChangeSet | undefined => changeSets.data?.changeSets.find((cs) => cs.id === id),\n\t\t[changeSets.data],\n\t);\n\n\tconst columns = useMemo<ColumnDef<RevisionRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"revision\",\n\t\t\t\theader: t(\"content.revisions.columns.revision\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.id} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"written\",\n\t\t\t\theader: t(\"content.revisions.columns.written\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"author\",\n\t\t\t\theader: t(\"content.revisions.columns.author\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={members.byId(row.original.author)?.displayName ?? row.original.author}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"cause\",\n\t\t\t\theader: t(\"content.revisions.columns.cause\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.revisions.cause.${row.original.cause}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"changeSet\",\n\t\t\t\theader: t(\"content.revisions.columns.changeSet\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst cs = changeSetOf(row.original.changeSetId);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={cs?.name ?? row.original.changeSetId}\n\t\t\t\t\t\t\tsubText={cs?.state === \"discarded\" ? t(\"content.revisions.discarded\") : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[t, members, changeSetOf],\n\t);\n\n\tif (revisions.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.revisions.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!revisions.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={rows}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\tvariant=\"hoverable\"\n\t\t\t\tonRowClick={(row) => setSelected(row)}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState icon={<History size={32} />} header={t(\"content.revisions.empty\")} />\n\t\t\t\t}\n\t\t\t/>\n\t\t\t{revisions.hasNextPage ? (\n\t\t\t\t<Box px=\"8\" py=\"3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tloading={revisions.isFetchingNextPage}\n\t\t\t\t\t\tonClick={() => void revisions.fetchNextPage()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"library.more\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</Box>\n\t\t\t) : null}\n\t\t\t{selected ? (\n\t\t\t\t<RevisionComparison\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontentId={content.id}\n\t\t\t\t\trevision={selected}\n\t\t\t\t\tpublished={published}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<Box px=\"8\" py=\"4\">\n\t\t\t\t\t<Alert status=\"info\" title={t(\"content.revisions.pickToCompare\")} />\n\t\t\t\t</Box>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * Compare: how a Revision differs from the one it was built on, or for a\n * Content's first Revision from Main's head. It only displays; it never\n * decides a merge.\n */\nfunction RevisionComparison({\n\tclient,\n\tcontentId,\n\trevision,\n\tpublished,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\trevision: Revision;\n\tpublished: boolean;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst base: CompareBase | null = revision.parentId\n\t\t? { kind: \"revision\", revisionId: revision.parentId }\n\t\t: published\n\t\t\t? { kind: \"main_head\" }\n\t\t\t: null;\n\tconst comparison = useQuery({\n\t\tqueryKey: contenthubKeys.contentCompare(contentId, revision.id, base ?? {}),\n\t\tqueryFn: () => client.compare({ revisionId: revision.id, base: base as CompareBase }),\n\t\tenabled: base !== null,\n\t});\n\tconst columns = useMemo<ColumnDef<ChangeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"field\",\n\t\t\t\theader: t(\"content.compare.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.compare.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.compare.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"before\",\n\t\t\t\theader: t(\"content.compare.columns.before\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.before)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"after\",\n\t\t\t\theader: t(\"content.compare.columns.after\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={valueText(row.original.after)} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">\n\t\t\t\t\t{base?.kind === \"revision\"\n\t\t\t\t\t\t? t(\"content.compare.titleParent\", { revision: revision.id, base: base.revisionId })\n\t\t\t\t\t\t: base?.kind === \"main_head\"\n\t\t\t\t\t\t\t? t(\"content.compare.titleMain\", { revision: revision.id })\n\t\t\t\t\t\t\t: t(\"content.compare.title\", { revision: revision.id })}\n\t\t\t\t</Heading>\n\t\t\t</Box>\n\t\t\t{base === null ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"info\" title={t(\"content.compare.nothing\")} />\n\t\t\t\t</Box>\n\t\t\t) : comparison.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.compare.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : !comparison.data ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\t<DataTable\n\t\t\t\t\tcolumns={columns}\n\t\t\t\t\tdata={comparison.data.changes as ChangeRow[]}\n\t\t\t\t\tgetRowId={(row) => row.path}\n\t\t\t\t\temptyState={<EmptyState header={t(\"content.compare.same\")} />}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport { CountCell, DataTable, DateCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Spinner } from \"@knkcs/anker/primitives\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { GitBranch } from \"lucide-react\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { ChangeSet } from \"../types\";\nimport { useContentChangeSets } from \"./content-revisions-tab\";\n\ntype ChangeSetRow = ChangeSet & Record<string, unknown>;\n\n/**\n * The Change Sets tab (spec #56, story 90): the open Change Sets with a\n * Chain on this Content, newest first: the work in progress on it. A table,\n * so flush.\n */\nexport function ContentChangeSetsTab({\n\tclient,\n\tcontentId,\n\tonOpenChangeSet,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Host navigation to a Change Set's page; without it, rows don't open. */\n\tonOpenChangeSet?: (changeSetId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst query = useContentChangeSets(client, contentId);\n\tconst open = useMemo(\n\t\t() => (query.data?.changeSets ?? []).filter((cs) => cs.state === \"open\") as ChangeSetRow[],\n\t\t[query.data],\n\t);\n\tconst columns = useMemo<ColumnDef<ChangeSetRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"changeSets.columns.name\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\trow.original.source\n\t\t\t\t\t\t\t\t? t(\"changeSets.sourceLine\", {\n\t\t\t\t\t\t\t\t\t\tdate: row.original.source.date,\n\t\t\t\t\t\t\t\t\t\treference: row.original.source.reference,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"assignees\",\n\t\t\t\theader: t(\"changeSet.general.assignees\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<CountCell\n\t\t\t\t\t\tvalue={row.original.assigneeIds}\n\t\t\t\t\t\tsingular={t(\"content.changeSets.assignee\")}\n\t\t\t\t\t\tplural={t(\"content.changeSets.assignees\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"created\",\n\t\t\t\theader: t(\"content.changeSets.opened\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.createTime} />,\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\n\tif (query.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.changeSets.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!query.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<DataTable\n\t\t\tcolumns={columns}\n\t\t\tdata={open}\n\t\t\tgetRowId={(row) => row.id}\n\t\t\tvariant={onOpenChangeSet ? \"hoverable\" : undefined}\n\t\t\tonRowClick={onOpenChangeSet ? (row) => onOpenChangeSet(row.id) : undefined}\n\t\t\temptyState={\n\t\t\t\t<EmptyState\n\t\t\t\t\ticon={<GitBranch size={32} />}\n\t\t\t\t\theader={t(\"content.changeSets.empty\")}\n\t\t\t\t\tdescription={t(\"content.changeSets.emptyHint\")}\n\t\t\t\t/>\n\t\t\t}\n\t\t/>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Card } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Box, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection, ContentAttributes } from \"../types\";\n\n/** The Filing tab's draft: a Content's unversioned attributes that its page changes. */\nexport interface FilingValues {\n\tcollectionIds: string[];\n\tassigneeIds: string[];\n}\n\nexport function filingValuesOf(a: ContentAttributes): FilingValues {\n\treturn { collectionIds: [...a.collectionIds], assigneeIds: [...a.assigneeIds] };\n}\n\n/** A Collection by its path from the root, \"Laws / BGB\", so two of one name are told apart. */\nfunction pathOf(c: Collection, all: Collection[]): string {\n\tconst names = [c.name];\n\tconst seen = new Set([c.id]);\n\tlet parent = all.find((p) => p.id === c.parentId);\n\twhile (parent && !seen.has(parent.id)) {\n\t\tnames.unshift(parent.name);\n\t\tseen.add(parent.id);\n\t\tparent = all.find((p) => p.id === parent?.parentId);\n\t}\n\treturn names.join(\" / \");\n}\n\n/**\n * The Filing tab (spec #56, story 91): the Collections a Content is filed\n * in and who maintains it. Unversioned attributes (ADR 0015): the header's\n * Save sets them, and never writes a Revision. The draft is the page's\n * form, held above the tab, so it survives switching tabs.\n */\nexport function ContentFilingTab({\n\tclient,\n\tattributes,\n}: {\n\tclient: ContenthubClient;\n\tattributes: ContentAttributes;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst collections = useQuery({\n\t\tqueryKey: contenthubKeys.collections(),\n\t\tqueryFn: () => client.listCollections(),\n\t});\n\t// A Collection the reader can't see (restricted, ADR 0017) stays listed by\n\t// id, so saving never unfiles it by accident.\n\tconst collectionOptions = useMemo<BaseOption[]>(() => {\n\t\tconst all = collections.data ?? [];\n\t\tconst known = all\n\t\t\t.map((c) => ({ id: c.id, label: pathOf(c, all) }))\n\t\t\t.sort((a, b) => a.label.localeCompare(b.label));\n\t\tconst unknown = attributes.collectionIds\n\t\t\t.filter((id) => !all.some((c) => c.id === id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [collections.data, attributes.collectionIds]);\n\tconst assigneeOptions = useMemo<BaseOption[]>(() => {\n\t\tconst known = members.list().map((m) => ({ id: m.userId, label: m.displayName }));\n\t\tconst unknown = attributes.assigneeIds\n\t\t\t.filter((id) => !members.byId(id))\n\t\t\t.map((id) => ({ id, label: id }));\n\t\treturn [...known, ...unknown];\n\t}, [members, attributes.assigneeIds]);\n\n\treturn (\n\t\t<Box px=\"8\" py=\"6\">\n\t\t\t<Card title={t(\"content.filing.title\")}>\n\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t<BaseSelectField<FilingValues>\n\t\t\t\t\t\tname=\"collectionIds\"\n\t\t\t\t\t\tlabel={t(\"content.filing.collections\")}\n\t\t\t\t\t\thelperText={t(\"content.filing.collectionsHelp\")}\n\t\t\t\t\t\toptions={collectionOptions}\n\t\t\t\t\t\tisMulti\n\t\t\t\t\t\tplaceholder={t(\"content.filing.nowhere\")}\n\t\t\t\t\t/>\n\t\t\t\t\t<BaseSelectField<FilingValues>\n\t\t\t\t\t\tname=\"assigneeIds\"\n\t\t\t\t\t\tlabel={t(\"content.filing.assignees\")}\n\t\t\t\t\t\thelperText={t(\"content.filing.assigneesHelp\")}\n\t\t\t\t\t\toptions={assigneeOptions}\n\t\t\t\t\t\tisMulti\n\t\t\t\t\t\tplaceholder={t(\"changeSet.general.nobody\")}\n\t\t\t\t\t/>\n\t\t\t\t\t<Text fontSize=\"xs\" color=\"muted\">\n\t\t\t\t\t\t{t(\"content.filing.notASave\")}\n\t\t\t\t\t</Text>\n\t\t\t\t</Stack>\n\t\t\t</Card>\n\t\t</Box>\n\t);\n}\n","import { ContextRail, DescriptionList } from \"@knkcs/anker/components\";\nimport {\n\tArchive,\n\tArchiveRestore,\n\tBan,\n\tCopy,\n\tFileX,\n\tLock,\n\tLockOpen,\n\tPencilLine,\n} from \"lucide-react\";\n\n/** One of the rail's actions; absent from `ContentRailProps.actions` when it isn't offered. */\nexport type ContentRailAction =\n\t| \"startEditing\"\n\t| \"openBranch\"\n\t| \"duplicate\"\n\t| \"repeal\"\n\t| \"withdraw\"\n\t| \"block\"\n\t| \"unblock\"\n\t| \"archive\"\n\t| \"unarchive\";\n\nconst ICONS: Record<ContentRailAction, typeof Copy> = {\n\tstartEditing: PencilLine,\n\topenBranch: PencilLine,\n\tduplicate: Copy,\n\trepeal: FileX,\n\twithdraw: Ban,\n\tblock: Lock,\n\tunblock: LockOpen,\n\tarchive: Archive,\n\tunarchive: ArchiveRestore,\n};\n\nexport interface ContentRailProps {\n\ttitle: string;\n\t/** Every string the rail shows, translated by the screen. */\n\tlabels: {\n\t\teyebrow: string;\n\t\tactions: string;\n\t\tabout: string;\n\t\tblueprint: string;\n\t\tinForce: string;\n\t\tblock: string;\n\t\tarchived: string;\n\t\taction: Record<ContentRailAction, string>;\n\t};\n\t/** The actions offered, in the order shown. */\n\tactions: ContentRailAction[];\n\tonAction: (action: ContentRailAction) => void;\n\tabout: {\n\t\tblueprint: string;\n\t\tinForce: string;\n\t\tblock: string;\n\t\t/** Absent while it is not Archived. */\n\t\tarchived?: string;\n\t};\n}\n\n/**\n * The Content page's rail (anker ADR 0004): what one does to the Content in\n * Actions, the facts at a glance in About. It is reported to the host and\n * drawn away from the screen's providers, so it reads no context of the\n * screen's: every string arrives translated and every action is a callback\n * that sets screen state, the screen rendering the dialog.\n */\nexport function ContentRail({ title, labels, actions, onAction, about }: ContentRailProps) {\n\treturn (\n\t\t<ContextRail storageKey=\"contenthub-content-rail\">\n\t\t\t<ContextRail.Header eyebrow={labels.eyebrow} title={title} />\n\t\t\t<ContextRail.Section id=\"actions\" label={labels.actions}>\n\t\t\t\t{actions.map((action) => {\n\t\t\t\t\tconst Icon = ICONS[action];\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<ContextRail.IconButton\n\t\t\t\t\t\t\tkey={action}\n\t\t\t\t\t\t\tlabel={labels.action[action]}\n\t\t\t\t\t\t\ticon={<Icon size={16} />}\n\t\t\t\t\t\t\ttone={action === \"archive\" ? \"outline-red\" : \"default\"}\n\t\t\t\t\t\t\tonClick={() => onAction(action)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ContextRail.Section>\n\t\t\t<ContextRail.Section id=\"about\" label={labels.about}>\n\t\t\t\t<DescriptionList>\n\t\t\t\t\t<DescriptionList.Row label={labels.blueprint}>{about.blueprint}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.inForce}>{about.inForce}</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label={labels.block}>{about.block}</DescriptionList.Row>\n\t\t\t\t\t{about.archived ? (\n\t\t\t\t\t\t<DescriptionList.Row label={labels.archived}>{about.archived}</DescriptionList.Row>\n\t\t\t\t\t) : null}\n\t\t\t\t</DescriptionList>\n\t\t\t</ContextRail.Section>\n\t\t</ContextRail>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport { DataTable, SlugCell, TruncatedTextCell } from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useInfiniteQuery, useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Content, Edge, OutdatedPin, Referrer } from \"../types\";\n\ntype EdgeRow = Edge & Record<string, unknown>;\ntype ReferrerRow = Referrer & Record<string, unknown>;\ntype PinRow = OutdatedPin & Record<string, unknown>;\n\n/** Referrers read at once; a Content cited more often shows more on request. */\nconst REFERRERS_PAGE = 100;\n\n/** What an edge points at: a Content, an Asset or a Blueprint Release, by id. */\nfunction targetOf(edge: Edge): string {\n\treturn edge.targetContentId || edge.targetAssetId || edge.targetBlueprintReleaseId;\n}\n\n/** A table's place on the tab: a heading, then its rows, its spinner or its failure. */\nfunction Section<T>({\n\ttitle,\n\tquery,\n\tchildren,\n}: {\n\ttitle: string;\n\t/** What a query read: whether it failed, and its data once read. */\n\tquery: { isError: boolean; data: T | undefined };\n\tchildren: (data: T) => ReactNode;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{title}</Heading>\n\t\t\t</Box>\n\t\t\t{query.isError ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Alert status=\"error\" title={t(\"content.references.loadError\")} />\n\t\t\t\t</Box>\n\t\t\t) : query.data === undefined ? (\n\t\t\t\t<Box px=\"8\" pb=\"4\">\n\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\tchildren(query.data)\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n\n/**\n * The References tab (spec #56, story 90): the Content Graph around this\n * Content (ADR 0009). Its outgoing edges at the Revision shown; the edges\n * pointing at it from Releases In Force today and from open Change Sets'\n * Branch heads; and its pins that are outdated today, which only a save\n * re-pins, never contenthub by itself (#79). Tables, so flush.\n */\nexport function ContentReferencesTab({\n\tclient,\n\tcontent,\n\tonOpenContent,\n}: {\n\tclient: ContenthubClient;\n\tcontent: Content;\n\t/** Host navigation to another Content's page; without it, rows don't open. */\n\tonOpenContent?: (contentId: string) => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst outgoing = useQuery({\n\t\tqueryKey: contenthubKeys.contentReferences(content.id, content.revisionId),\n\t\tqueryFn: () => client.listReferences({ contentId: content.id, revisionId: content.revisionId }),\n\t});\n\tconst referrerPages = useInfiniteQuery({\n\t\tqueryKey: contenthubKeys.contentReferrers(content.id),\n\t\tqueryFn: ({ pageParam }) =>\n\t\t\tclient.listReferrers({\n\t\t\t\tcontentId: content.id,\n\t\t\t\tincludeOpenChangeSets: true,\n\t\t\t\tpageSize: REFERRERS_PAGE,\n\t\t\t\tpageToken: pageParam,\n\t\t\t}),\n\t\tinitialPageParam: \"\",\n\t\tgetNextPageParam: (last) => last.nextPageToken || undefined,\n\t});\n\t// The pages read so far, as one list, so the section reads it as any other.\n\tconst referrers = {\n\t\tisError: referrerPages.isError,\n\t\tdata: referrerPages.data?.pages.flatMap((page) => page.referrers),\n\t};\n\tconst pinSource = content.branchId\n\t\t? { branchId: content.branchId }\n\t\t: { revisionId: content.revisionId };\n\tconst pins = useQuery({\n\t\tqueryKey: contenthubKeys.contentOutdatedPins(content.id, pinSource),\n\t\tqueryFn: () => client.listOutdatedPins(pinSource),\n\t});\n\n\tconst kindColumn = useMemo<ColumnDef<{ edge: Edge } & Record<string, unknown>, unknown>>(\n\t\t() => ({\n\t\t\tid: \"kind\",\n\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\tcell: ({ row }) => (\n\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.edge.kind}`)} />\n\t\t\t),\n\t\t}),\n\t\t[t],\n\t);\n\tconst pathColumn = useMemo<ColumnDef<{ edge: Edge } & Record<string, unknown>, unknown>>(\n\t\t() => ({\n\t\t\tid: \"path\",\n\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.path || \"—\"} />,\n\t\t}),\n\t\t[t],\n\t);\n\n\tconst outgoingColumns = useMemo<ColumnDef<EdgeRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.references.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.references.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"path\",\n\t\t\t\theader: t(\"content.references.columns.field\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.path || \"—\"} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={row.original.pinReleaseId || t(\"content.references.followsInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t],\n\t);\n\tconst referrerColumns = useMemo<ColumnDef<ReferrerRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"source\",\n\t\t\t\theader: t(\"content.references.columns.source\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.sourceContentId} />,\n\t\t\t},\n\t\t\tkindColumn as ColumnDef<ReferrerRow, unknown>,\n\t\t\tpathColumn as ColumnDef<ReferrerRow, unknown>,\n\t\t\t{\n\t\t\t\tid: \"foundIn\",\n\t\t\t\theader: t(\"content.references.columns.foundIn\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.releaseId\n\t\t\t\t\t\t\t\t? t(\"content.references.inRelease\", { release: row.original.releaseId })\n\t\t\t\t\t\t\t\t: t(\"content.references.inChangeSet\", { changeSet: row.original.changeSetId })\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, kindColumn, pathColumn],\n\t);\n\tconst pinColumns = useMemo<ColumnDef<PinRow, unknown>[]>(\n\t\t() => [\n\t\t\tpathColumn as ColumnDef<PinRow, unknown>,\n\t\t\t{\n\t\t\t\tid: \"target\",\n\t\t\t\theader: t(\"content.references.columns.target\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={targetOf(row.original.edge)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"pin\",\n\t\t\t\theader: t(\"content.references.columns.pin\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.edge.pinReleaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.references.columns.inForceNow\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={row.original.inForceReleaseId || t(\"content.references.gap\")} />\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, pathColumn],\n\t);\n\n\tconst openTarget = onOpenContent\n\t\t? (contentId: string) => {\n\t\t\t\tif (contentId) onOpenContent(contentId);\n\t\t\t}\n\t\t: undefined;\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Section title={t(\"content.references.outgoing\")} query={outgoing}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={outgoingColumns}\n\t\t\t\t\t\tdata={data as EdgeRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.path}:${index}`}\n\t\t\t\t\t\tvariant={openTarget ? \"hoverable\" : undefined}\n\t\t\t\t\t\tonRowClick={openTarget ? (row) => openTarget(row.targetContentId) : undefined}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutgoing\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t<Section title={t(\"content.references.referrers\")} query={referrers}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={referrerColumns}\n\t\t\t\t\t\tdata={data as ReferrerRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.sourceContentId}:${row.edge.path}:${index}`}\n\t\t\t\t\t\tvariant={openTarget ? \"hoverable\" : undefined}\n\t\t\t\t\t\tonRowClick={openTarget ? (row) => openTarget(row.edge.sourceContentId) : undefined}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noReferrers\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t\t{referrerPages.hasNextPage ? (\n\t\t\t\t<Box px=\"8\" py=\"3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tloading={referrerPages.isFetchingNextPage}\n\t\t\t\t\t\tonClick={() => void referrerPages.fetchNextPage()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"library.more\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</Box>\n\t\t\t) : null}\n\t\t\t<Section title={t(\"content.references.outdated\")} query={pins}>\n\t\t\t\t{(data) => (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={pinColumns}\n\t\t\t\t\t\tdata={data as PinRow[]}\n\t\t\t\t\t\tgetRowId={(row, index) => `${row.edge.path}:${index}`}\n\t\t\t\t\t\temptyState={<EmptyState header={t(\"content.references.noOutdated\")} />}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Section>\n\t\t</Stack>\n\t);\n}\n","import { EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tBooleanCell,\n\tDataTable,\n\tDateCell,\n\tNumberCell,\n\tSlugCell,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { Alert, Box, Heading, Spinner, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport type { TFunction } from \"i18next\";\nimport { CalendarClock } from \"lucide-react\";\nimport { useCallback, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { localToday, releaseInForceOn } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { useOpenChangeSets } from \"../common/use-open-change-sets\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedRelease, TimelineEntry, ValidityPeriod } from \"../types\";\n\ntype EntryRow = TimelineEntry & Record<string, unknown>;\ntype PlannedRow = { changeSetId: string; plannedRelease: PlannedRelease } & Record<string, unknown>;\n\n/** A Validity Period as \"first – last\", an open end as \"first –\"; undated Content has none. */\nexport function periodText(t: TFunction, period: ValidityPeriod | undefined): string {\n\tif (!period) return t(\"content.releases.undated\");\n\treturn period.lastDay\n\t\t? t(\"content.releases.period\", { first: period.firstDay, last: period.lastDay })\n\t\t: t(\"content.releases.openPeriod\", { first: period.firstDay });\n}\n\n/** The Content's Timeline, read once for the Releases tab and the rail's About and Actions. */\nexport function useContentTimeline(client: ContenthubClient, contentId: string) {\n\treturn useQuery({\n\t\tqueryKey: contenthubKeys.contentTimeline(contentId),\n\t\tqueryFn: () => client.getTimeline(contentId),\n\t});\n}\n\n/**\n * The Releases tab (spec #56, story 90): the Timeline as known now, the\n * Release In Force today marked, and below it the Planned Releases of open\n * Change Sets, which may join it when they are published. Tables, so flush.\n */\nexport function ContentReleasesTab({\n\tclient,\n\tcontentId,\n}: {\n\tclient: ContenthubClient;\n\tcontentId: string;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst timeline = useContentTimeline(client, contentId);\n\tconst openChangeSets = useOpenChangeSets(client);\n\tconst inForce = releaseInForceOn(timeline.data?.entries ?? [], localToday());\n\tconst changeSetName = useCallback(\n\t\t(id: string) => openChangeSets.data?.changeSets.find((cs) => cs.id === id)?.name ?? id,\n\t\t[openChangeSets.data],\n\t);\n\n\tconst entryColumns = useMemo<ColumnDef<EntryRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"ordinal\",\n\t\t\t\theader: t(\"content.releases.columns.ordinal\"),\n\t\t\t\tcell: ({ row }) => <NumberCell value={row.original.ordinal} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"release\",\n\t\t\t\theader: t(\"content.releases.columns.release\"),\n\t\t\t\tcell: ({ row }) => <SlugCell value={row.original.releaseId} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={t(`content.releases.kind.${row.original.kind}`)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"content.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={periodText(t, row.original.validityPeriod)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"published\",\n\t\t\t\theader: t(\"content.releases.columns.published\"),\n\t\t\t\tcell: ({ row }) => <DateCell value={row.original.publishTime} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"inForce\",\n\t\t\t\theader: t(\"content.releases.columns.inForce\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.releaseId === inForce?.releaseId}\n\t\t\t\t\t\ttrueLabel={t(\"content.releases.inForceToday\")}\n\t\t\t\t\t\tfalseLabel={t(\"content.releases.notInForce\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, inForce?.releaseId],\n\t);\n\n\tconst plannedColumns = useMemo<ColumnDef<PlannedRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"changeSet\",\n\t\t\t\theader: t(\"content.releases.columns.changeSet\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={changeSetName(row.original.changeSetId)} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"kind\",\n\t\t\t\theader: t(\"content.releases.columns.kind\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={t(`content.releases.kind.${row.original.plannedRelease.kind}`)}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"period\",\n\t\t\t\theader: t(\"content.releases.columns.period\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell value={periodText(t, row.original.plannedRelease.validityPeriod)} />\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"proposed\",\n\t\t\t\theader: t(\"content.releases.columns.proposed\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.plannedRelease.proposed}\n\t\t\t\t\t\ttrueLabel={t(\"content.releases.proposed\")}\n\t\t\t\t\t\tfalseLabel={t(\"content.releases.planned\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, changeSetName],\n\t);\n\n\tif (timeline.isError) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Alert status=\"error\" title={t(\"content.releases.loadError\")} />\n\t\t\t</Box>\n\t\t);\n\t}\n\tif (!timeline.data) {\n\t\treturn (\n\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t</Box>\n\t\t);\n\t}\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<DataTable\n\t\t\t\tcolumns={entryColumns}\n\t\t\t\tdata={timeline.data.entries as EntryRow[]}\n\t\t\t\tgetRowId={(row) => row.releaseId}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<CalendarClock size={32} />}\n\t\t\t\t\t\theader={t(\"content.releases.empty\")}\n\t\t\t\t\t\tdescription={t(\"content.releases.emptyHint\")}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<Box px=\"8\" pt=\"6\" pb=\"2\">\n\t\t\t\t<Heading size=\"sm\">{t(\"content.releases.plannedTitle\")}</Heading>\n\t\t\t</Box>\n\t\t\t<DataTable\n\t\t\t\tcolumns={plannedColumns}\n\t\t\t\tdata={timeline.data.plannedReleases as PlannedRow[]}\n\t\t\t\tgetRowId={(row) => row.plannedRelease.id}\n\t\t\t\temptyState={<EmptyState header={t(\"content.releases.noPlanned\")} />}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-duplicate-content\";\nconst EMPTY: ChangeSetChoiceValues = { changeSetId: NEW_CHANGE_SET, changeSetName: \"\" };\n\nexport interface DuplicateContentModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\t/** The Revision the copy takes its data from: the one the page shows. */\n\trevisionId: string;\n\t/** The copy was created: open its Branch in the Branch editor. */\n\tonCreated: (target: OpenBranchTarget) => void;\n}\n\n/**\n * Duplicate (spec #56, story 92): a new Content in a Change Set picked or\n * opened here, whose first Revision copies the shown Revision's data and\n * pins its Blueprint Release (CreateContent's copy_from). The copy is new\n * Content, with no history of its own; it exists only in the Change Set\n * until it is published.\n *\n * A new Change Set is opened before the copy is created. If the copy is then\n * refused, the form switches to that Change Set, so trying again never opens\n * a second one.\n */\nexport function DuplicateContentModal({\n\topen,\n\tonClose,\n\tclient,\n\trevisionId,\n\tonCreated,\n}: DuplicateContentModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<ChangeSetChoiceValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tlet target = values.changeSetId as string;\n\t\ttry {\n\t\t\tif (target === NEW_CHANGE_SET) {\n\t\t\t\tconst created = await client.createChangeSet({ name: values.changeSetName.trim() });\n\t\t\t\ttarget = created.id;\n\t\t\t\tmethods.setValue(\"changeSetId\", target);\n\t\t\t}\n\t\t\tconst copy = await client.createContent({\n\t\t\t\tchangeSetId: target,\n\t\t\t\tblueprintReleaseId: \"\",\n\t\t\t\tcopyFrom: { revisionId },\n\t\t\t});\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contents() });\n\t\t\tonCreated({ changeSetId: target, contentId: copy.id, branchId: copy.branchId });\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.duplicate.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"content.duplicate.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t{t(\"content.duplicate.hint\")}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t<ChangeSetChoiceFields<ChangeSetChoiceValues>\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\thelperText={t(\"content.duplicate.changeSetHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { PlannedEnd } from \"../types\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-end-force\";\n\ntype EndValues = ChangeSetChoiceValues & { lastDay: string };\nconst EMPTY: EndValues = { changeSetId: NEW_CHANGE_SET, changeSetName: \"\", lastDay: \"\" };\n\nexport interface EndForceModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Dated Content is Repealed on a last day; undated Content is Withdrawn. */\n\tdated: boolean;\n}\n\n/**\n * Repeal or Withdraw (spec #56, story 92): plans the Release ending the\n * Content's force in a Change Set picked or opened here; Publish cuts it.\n * The referrers the gap will strand come back as a warning, never a refusal\n * (ADR 0009), and the dialog stays open to show them.\n */\nexport function EndForceModal({ open, onClose, client, contentId, dated }: EndForceModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<EndValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [planned, setPlanned] = useState<PlannedEnd | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst kind = dated ? \"repeal\" : \"withdraw\";\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t\tsetPlanned(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tif (dated && !DAY.test(values.lastDay)) {\n\t\t\tmethods.setError(\"lastDay\", { message: t(\"content.endForce.lastDayRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tlet target = values.changeSetId as string;\n\t\ttry {\n\t\t\tif (target === NEW_CHANGE_SET) {\n\t\t\t\tconst created = await client.createChangeSet({ name: values.changeSetName.trim() });\n\t\t\t\ttarget = created.id;\n\t\t\t\tmethods.setValue(\"changeSetId\", target);\n\t\t\t}\n\t\t\tconst result = dated\n\t\t\t\t? await client.planRepeal({ changeSetId: target, contentId, lastDay: values.lastDay })\n\t\t\t\t: await client.planWithdrawal({ changeSetId: target, contentId });\n\t\t\tsetPlanned(result);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentTimeline(contentId) });\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(`content.endForce.${kind}.title`)}\n\t\t\tfooter={\n\t\t\t\tplanned ? (\n\t\t\t\t\t<Button size=\"sm\" variant=\"solid\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"content.endForce.done\")}\n\t\t\t\t\t</Button>\n\t\t\t\t) : (\n\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t\t{t(`content.endForce.${kind}.submit`)}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t)\n\t\t\t}\n\t\t>\n\t\t\t{planned ? (\n\t\t\t\t<Stack gap=\"3\">\n\t\t\t\t\t<Alert status=\"success\" title={t(`content.endForce.${kind}.planned`)} />\n\t\t\t\t\t{planned.gapReferrers.length > 0 ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\ttitle={t(\"content.endForce.gapReferrers\", { count: planned.gapReferrers.length })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{planned.gapReferrers\n\t\t\t\t\t\t\t\t.map((g) => `${g.edge.sourceContentId} (${g.edge.path || g.releaseId})`)\n\t\t\t\t\t\t\t\t.join(\", \")}\n\t\t\t\t\t\t</Alert>\n\t\t\t\t\t) : null}\n\t\t\t\t</Stack>\n\t\t\t) : (\n\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(`content.endForce.${kind}.hint`)}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<ChangeSetChoiceFields<EndValues>\n\t\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\t\thelperText={t(\"content.endForce.changeSetHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t\t<InputField<EndValues>\n\t\t\t\t\t\t\t\t\tname=\"lastDay\"\n\t\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"content.endForce.lastDay\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"content.endForce.lastDayHelp\")}\n\t\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</form>\n\t\t\t\t</FormProvider>\n\t\t\t)}\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { DescriptionList, Modal } from \"@knkcs/anker/components\";\nimport { InputField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useState } from \"react\";\nimport { FormProvider, useForm, useWatch } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { DAY } from \"../common/in-force\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport {\n\tChangeSetChoiceFields,\n\ttype ChangeSetChoiceValues,\n\tchangeSetChoiceIssue,\n\tNEW_CHANGE_SET,\n} from \"./change-set-choice\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\n\nconst FORM_ID = \"contenthub-start-editing\";\n\ntype StartValues = ChangeSetChoiceValues & { effectiveOn: string };\n\nexport interface StartEditingModalProps {\n\topen: boolean;\n\tonClose: () => void;\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/** Dated Content's Chain takes the date its change takes effect; undated Content's none. */\n\tdated: boolean;\n\t/** The Chain was started: open its Branch in the Branch editor. */\n\tonStarted: (target: OpenBranchTarget) => void;\n}\n\n/**\n * Start editing (spec #56, story 92; ADR 0015's one-off edit): a Change Set\n * picked or opened here, and for Dated Content the effective date, then\n * StartEditing, which starts the Chain and opens a new Change Set in one\n * transaction, so a refusal leaves nothing behind. With an open Change Set\n * and a date, PreviewChain shows what the Chain would fork from first.\n */\nexport function StartEditingModal({\n\topen,\n\tonClose,\n\tclient,\n\tcontentId,\n\tdated,\n\tonStarted,\n}: StartEditingModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst methods = useForm<StartValues>({\n\t\tdefaultValues: { changeSetId: NEW_CHANGE_SET, changeSetName: \"\", effectiveOn: \"\" },\n\t});\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst changeSetId = useWatch({ control: methods.control, name: \"changeSetId\" });\n\tconst effectiveOn = useWatch({ control: methods.control, name: \"effectiveOn\" });\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset({ changeSetId: NEW_CHANGE_SET, changeSetName: \"\", effectiveOn: \"\" });\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst canPreview =\n\t\topen && dated && !!changeSetId && changeSetId !== NEW_CHANGE_SET && DAY.test(effectiveOn);\n\tconst preview = useQuery({\n\t\tqueryKey: [...contenthubKeys.content(contentId), \"preview\", changeSetId, effectiveOn],\n\t\tqueryFn: () =>\n\t\t\tclient.previewChain({ changeSetId: changeSetId as string, contentId, effectiveOn }),\n\t\tenabled: canPreview,\n\t});\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst issue = changeSetChoiceIssue(t, values, true);\n\t\tif (issue) {\n\t\t\tmethods.setError(issue.path, { message: issue.message });\n\t\t\treturn;\n\t\t}\n\t\tif (dated && !DAY.test(values.effectiveOn)) {\n\t\t\tmethods.setError(\"effectiveOn\", { message: t(\"content.startEditing.dateRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tconst isNew = values.changeSetId === NEW_CHANGE_SET;\n\t\ttry {\n\t\t\tconst started = await client.startEditing({\n\t\t\t\tcontentId,\n\t\t\t\tchangeSetId: isNew ? undefined : (values.changeSetId as string),\n\t\t\t\teffectiveOn: dated ? values.effectiveOn : undefined,\n\t\t\t\tchangeSetName: isNew ? values.changeSetName.trim() : undefined,\n\t\t\t});\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() });\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.content(contentId) });\n\t\t\tonStarted({\n\t\t\t\tchangeSetId: started.changeSet.id,\n\t\t\t\tcontentId,\n\t\t\t\tbranchId: started.content.branchId,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"content.startEditing.title\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\"content.startEditing.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<ChangeSetChoiceFields<StartValues>\n\t\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\thelperText={t(\"content.startEditing.changeSetHelp\")}\n\t\t\t\t\t\t\tnameHelperText={t(\"content.startEditing.nameHelp\")}\n\t\t\t\t\t\t\tnameOptional\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{dated ? (\n\t\t\t\t\t\t\t<InputField<StartValues>\n\t\t\t\t\t\t\t\tname=\"effectiveOn\"\n\t\t\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\t\t\tlabel={t(\"content.startEditing.effectiveOn\")}\n\t\t\t\t\t\t\t\thelperText={t(\"content.startEditing.effectiveOnHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data ? (\n\t\t\t\t\t\t\t<DescriptionList>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.forksFrom\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.forkReleaseId || t(\"content.startEditing.forksFromMain\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.carriesForward\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.carryForwardReleaseIds.length}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t\t<DescriptionList.Row label={t(\"content.startEditing.cutsInto\")}>\n\t\t\t\t\t\t\t\t\t{preview.data.cutIntoReleaseIds.join(\", \") || t(\"content.none\")}\n\t\t\t\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t\t\t</DescriptionList>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{canPreview && preview.data && preview.data.coveredReleaseIds.length > 0 ? (\n\t\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\t\tstatus=\"warning\"\n\t\t\t\t\t\t\t\ttitle={t(\"content.startEditing.covers\", {\n\t\t\t\t\t\t\t\t\treleases: preview.data.coveredReleaseIds.join(\", \"),\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Code as ConnectCode, ConnectError } from \"@connectrpc/connect\";\nimport { Button, TypeBadge } from \"@knkcs/anker/atoms\";\nimport { useHostIdentity, usePageRail } from \"@knkcs/anker/host\";\nimport { TabDirtyProvider, UnsavedChangesGuard, useTabDirty } from \"@knkcs/anker/navigation\";\nimport { Alert, Box, HStack, Spinner, Stack, Tabs } from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate } from \"@knkcs/anker/templates\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Save } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { useBlueprintSource } from \"../common/blueprint-source\";\nimport { inForceOnOrAfter, localToday, releaseInForceOn } from \"../common/in-force\";\nimport { useContenthubPaths } from \"../common/paths\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { BlueprintSource, ContentAttributes, ContentDetail } from \"../types\";\nimport { ArchiveContentModal } from \"./archive-content-modal\";\nimport { BlockContentModal } from \"./block-content-modal\";\nimport type { OpenBranchTarget } from \"./change-set-contents-tab\";\nimport { ContentChangeSetsTab } from \"./content-change-sets-tab\";\nimport { ContentDataTab } from \"./content-data-tab\";\nimport { ContentFilingTab, type FilingValues, filingValuesOf } from \"./content-filing-tab\";\nimport { contentLabel, type OpenContentTarget } from \"./content-library\";\nimport { ContentRail, type ContentRailAction } from \"./content-rail\";\nimport { ContentReferencesTab } from \"./content-references-tab\";\nimport { contentRefusalText } from \"./content-refusal\";\nimport { ContentReleasesTab, periodText, useContentTimeline } from \"./content-releases-tab\";\nimport { ContentRevisionsTab } from \"./content-revisions-tab\";\nimport { DuplicateContentModal } from \"./duplicate-content-modal\";\nimport { EndForceModal } from \"./end-force-modal\";\nimport { StartEditingModal } from \"./start-editing-modal\";\n\ntype Tab = \"data\" | \"releases\" | \"revisions\" | \"references\" | \"changeSets\" | \"filing\";\nconst TABS: Tab[] = [\"data\", \"releases\", \"revisions\", \"references\", \"changeSets\", \"filing\"];\nconst NO_FILING: FilingValues = { collectionIds: [], assigneeIds: [] };\n\n/** A dialog the rail opened, which the screen renders. */\ntype Dialog = \"startEditing\" | \"duplicate\" | \"endForce\" | \"block\" | \"archive\" | null;\n\nexport interface ContentPageProps {\n\tclient: ContenthubClient;\n\tcontentId: string;\n\t/**\n\t * The Change Set to read the Content in: one a Library row was read in.\n\t * Content born in an open Change Set exists only there, so its page needs\n\t * it; a published Content's page reads Main without it.\n\t */\n\tchangeSetId?: string;\n\t/**\n\t * Overrides where About reads the Blueprint's name. Absent, it reads\n\t * contenthub's own `BlueprintCatalogService` through `client` (#238);\n\t * a name it can't find falls back to the Release's own name, or the id.\n\t */\n\tblueprintSource?: BlueprintSource;\n\t/** Host navigation to the Branch editor: after Start editing or Duplicate, or a born Content's Branch. */\n\tonOpenBranch: (target: OpenBranchTarget) => void;\n\t/** Host navigation to another Content's page, from the References tab. */\n\tonOpenContent?: (target: OpenContentTarget) => void;\n\t/** Host navigation to a Change Set's page, from the Change Sets tab. */\n\tonOpenChangeSet?: (changeSetId: string) => void;\n}\n\n/**\n * A Content's page (spec #56, stories 89–92): every angle on one Content in\n * tabs, the header's one Save for its Filing, and the rail's Actions and\n * About (anker ADR 0004). Its data is read-only here; it is edited in a\n * Branch, which Start editing opens.\n *\n * The draft registry is keyed by the Content (and the Change Set it is read\n * in), so moving to another starts clean.\n */\nexport function ContentPage(props: ContentPageProps) {\n\treturn (\n\t\t<TabDirtyProvider key={`${props.contentId}@${props.changeSetId ?? \"\"}`}>\n\t\t\t<ContentScreen {...props} />\n\t\t</TabDirtyProvider>\n\t);\n}\n\nContentPage.displayName = \"ContentPage\";\n\n/** The same ids, in any order: neither Collections nor assignees mean anything by order here. */\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n\treturn a.length === b.length && a.every((id) => b.includes(id));\n}\n\nfunction ContentScreen({\n\tclient,\n\tcontentId,\n\tchangeSetId,\n\tblueprintSource,\n\tonOpenBranch,\n\tonOpenContent,\n\tonOpenChangeSet,\n}: ContentPageProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst source = useBlueprintSource(client, blueprintSource);\n\tconst paths = useContenthubPaths();\n\tconst queryClient = useQueryClient();\n\tconst { members } = useHostIdentity();\n\tconst { dirtyTabs, setTabDirty } = useTabDirty();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst tabParam = searchParams.get(\"tab\") as Tab | null;\n\tconst tab: Tab = tabParam && TABS.includes(tabParam) ? tabParam : \"data\";\n\n\tconst readKey = useMemo(\n\t\t() => contenthubKeys.contentRead(contentId, changeSetId ?? \"\"),\n\t\t[contentId, changeSetId],\n\t);\n\tconst query = useQuery({\n\t\tqueryKey: readKey,\n\t\tqueryFn: () => client.getContent({ id: contentId, changeSetId }),\n\t});\n\tconst detail = query.data;\n\tconst timeline = useContentTimeline(client, contentId);\n\tconst blueprintName = useQuery({\n\t\tqueryKey: contenthubKeys.blueprintNames(detail ? [detail.content.blueprintId] : []),\n\t\tqueryFn: () => source.getBlueprints([detail?.content.blueprintId ?? \"\"]),\n\t\tenabled: !!detail,\n\t});\n\tconst blockReasons = useQuery({\n\t\tqueryKey: contenthubKeys.blockReasons(),\n\t\tqueryFn: () => client.listBlockReasons(),\n\t\tenabled: !!detail?.attributes.block,\n\t});\n\n\t// The Filing draft, held above the tab so it outlives the tab's mount\n\t// (anker ADR 0004). It follows every read while it is untouched, so a\n\t// colleague's filing shows up and a later Save never puts back what the\n\t// page first saw; once edited, it keeps the editor's draft.\n\tconst methods = useForm<FilingValues>({ defaultValues: NO_FILING });\n\tconst baseline = useRef<FilingValues | null>(null);\n\tuseEffect(() => {\n\t\tif (detail && (baseline.current === null || !methods.formState.isDirty)) {\n\t\t\tbaseline.current = filingValuesOf(detail.attributes);\n\t\t\tmethods.reset(baseline.current);\n\t\t}\n\t}, [detail, methods]);\n\tconst filingDirty = methods.formState.isDirty;\n\tuseEffect(() => setTabDirty(\"filing\", filingDirty), [filingDirty, setTabDirty]);\n\n\tconst [saving, setSaving] = useState(false);\n\tconst [saved, setSaved] = useState(false);\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [dialog, setDialog] = useState<Dialog>(null);\n\tuseEffect(() => {\n\t\tif (filingDirty) setSaved(false);\n\t}, [filingDirty]);\n\n\t/** The attributes a write answered with, laid into the read so every tab sees them. */\n\tconst applyAttributes = useCallback(\n\t\t(attributes: ContentAttributes) => {\n\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (old) =>\n\t\t\t\told ? { ...old, attributes } : old,\n\t\t\t);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t},\n\t\t[queryClient, readKey],\n\t);\n\n\t/**\n\t * Persists the Filing draft: the attribute setters only, one per changed\n\t * attribute. Filing writes no Revision and needs no Change Set (ADR\n\t * 0015). A refusal stops there, and what wasn't saved stays in\n\t * the draft.\n\t */\n\tconst saveAll = useCallback(async () => {\n\t\tconst base = baseline.current;\n\t\tif (!base) return;\n\t\tconst draft = methods.getValues();\n\t\tconst next = { ...base };\n\t\tsetSaving(true);\n\t\tsetRefusal(null);\n\t\tsetSaved(false);\n\t\ttry {\n\t\t\tif (!sameIds(draft.collectionIds, base.collectionIds)) {\n\t\t\t\tnext.collectionIds = await client.setContentCollections({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tcollectionIds: draft.collectionIds,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!sameIds(draft.assigneeIds, base.assigneeIds)) {\n\t\t\t\tconst attributes = await client.setContentAssignees({\n\t\t\t\t\tcontentId,\n\t\t\t\t\tassigneeIds: draft.assigneeIds,\n\t\t\t\t});\n\t\t\t\tnext.assigneeIds = attributes.assigneeIds;\n\t\t\t}\n\t\t\tsetSaved(true);\n\t\t} catch (err) {\n\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t} finally {\n\t\t\tbaseline.current = next;\n\t\t\tmethods.reset(next);\n\t\t\tfor (const key of [\"collectionIds\", \"assigneeIds\"] as const) {\n\t\t\t\tif (!sameIds(draft[key], next[key]))\n\t\t\t\t\tmethods.setValue(key, draft[key], { shouldDirty: true });\n\t\t\t}\n\t\t\tqueryClient.setQueryData<ContentDetail>(readKey, (old) =>\n\t\t\t\told ? { ...old, attributes: { ...old.attributes, ...next } } : old,\n\t\t\t);\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: contenthubKeys.contentLists() });\n\t\t\tsetSaving(false);\n\t\t}\n\t}, [client, contentId, methods, queryClient, readKey, t]);\n\n\t/** A rail action that writes at once, with no dialog: Unblock and Unarchive. */\n\tconst writeNow = useCallback(\n\t\tasync (write: () => Promise<ContentAttributes>) => {\n\t\t\tsetRefusal(null);\n\t\t\ttry {\n\t\t\t\tapplyAttributes(await write());\n\t\t\t} catch (err) {\n\t\t\t\tsetRefusal(contentRefusalText(t, err));\n\t\t\t}\n\t\t},\n\t\t[applyAttributes, t],\n\t);\n\n\tconst entries = timeline.data?.entries ?? [];\n\tconst today = localToday();\n\tconst content = detail?.content;\n\tconst attributes = detail?.attributes;\n\t// Read on Main, it is published; read in a Change Set, only its Timeline\n\t// says so, so until that arrives the page claims neither.\n\tconst publishedKnown = !!content && (!content.changeSetId || timeline.isSuccess);\n\tconst published = !!content && (!content.changeSetId || entries.length > 0);\n\tconst dated = detail?.blueprintRelease?.dated ?? entries.some((e) => e.validityPeriod);\n\tconst archived = !!attributes?.archiveTime;\n\tconst live = inForceOnOrAfter(entries, today);\n\n\tconst actions = useMemo<ContentRailAction[]>(() => {\n\t\tif (!content || !attributes) return [];\n\t\tconst list: ContentRailAction[] = [];\n\t\tif (publishedKnown && !published) list.push(\"openBranch\");\n\t\telse if (published && !archived) list.push(\"startEditing\");\n\t\tlist.push(\"duplicate\");\n\t\tif (published && !archived && timeline.isSuccess && live) {\n\t\t\tlist.push(dated ? \"repeal\" : \"withdraw\");\n\t\t}\n\t\tlist.push(attributes.block ? \"unblock\" : \"block\");\n\t\tif (archived) list.push(\"unarchive\");\n\t\t// Archive is offered only where ArchiveContent allows it: published,\n\t\t// with nothing In Force today or later (ADR 0015).\n\t\telse if (published && timeline.isSuccess && !live) list.push(\"archive\");\n\t\treturn list;\n\t}, [content, attributes, publishedKnown, published, archived, timeline.isSuccess, live, dated]);\n\n\tconst onAction = useCallback(\n\t\t(action: ContentRailAction) => {\n\t\t\tif (!content) return;\n\t\t\tswitch (action) {\n\t\t\t\tcase \"openBranch\":\n\t\t\t\t\tonOpenBranch({\n\t\t\t\t\t\tchangeSetId: content.changeSetId,\n\t\t\t\t\t\tcontentId: content.id,\n\t\t\t\t\t\tbranchId: content.branchId,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\tcase \"startEditing\":\n\t\t\t\t\tsetDialog(\"startEditing\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"duplicate\":\n\t\t\t\t\tsetDialog(\"duplicate\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"repeal\":\n\t\t\t\tcase \"withdraw\":\n\t\t\t\t\tsetDialog(\"endForce\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"block\":\n\t\t\t\t\tsetDialog(\"block\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"archive\":\n\t\t\t\t\tsetDialog(\"archive\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"unblock\":\n\t\t\t\t\tvoid writeNow(() => client.unblockContent(content.id));\n\t\t\t\t\treturn;\n\t\t\t\tcase \"unarchive\":\n\t\t\t\t\tvoid writeNow(() => client.unarchiveContent(content.id));\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t},\n\t\t[client, content, onOpenBranch, writeNow],\n\t);\n\n\tconst title = content ? contentLabel(content.data) || content.id : \"\";\n\tconst inForce = releaseInForceOn(entries, today);\n\tconst blockReason = blockReasons.data?.find((r) => r.id === attributes?.block?.blockReasonId);\n\tconst blockedBy = attributes?.block\n\t\t? (members.byId(attributes.block.blockedBy)?.displayName ?? attributes.block.blockedBy)\n\t\t: \"\";\n\tconst railLabels = useMemo(\n\t\t() => ({\n\t\t\teyebrow: t(\"content.rail.eyebrow\"),\n\t\t\tactions: t(\"content.rail.actions\"),\n\t\t\tabout: t(\"content.rail.about\"),\n\t\t\tblueprint: t(\"content.rail.blueprint\"),\n\t\t\tinForce: t(\"content.rail.inForce\"),\n\t\t\tblock: t(\"content.rail.block\"),\n\t\t\tarchived: t(\"content.rail.archived\"),\n\t\t\taction: {\n\t\t\t\tstartEditing: t(\"content.actions.startEditing\"),\n\t\t\t\topenBranch: t(\"content.actions.openBranch\"),\n\t\t\t\tduplicate: t(\"content.actions.duplicate\"),\n\t\t\t\trepeal: t(\"content.actions.repeal\"),\n\t\t\t\twithdraw: t(\"content.actions.withdraw\"),\n\t\t\t\tblock: t(\"content.actions.block\"),\n\t\t\t\tunblock: t(\"content.actions.unblock\"),\n\t\t\t\tarchive: t(\"content.actions.archive\"),\n\t\t\t\tunarchive: t(\"content.actions.unarchive\"),\n\t\t\t},\n\t\t}),\n\t\t[t],\n\t);\n\tconst about = useMemo(\n\t\t() => ({\n\t\t\tblueprint:\n\t\t\t\tblueprintName.data?.[0]?.name ||\n\t\t\t\tdetail?.blueprintRelease?.displayName ||\n\t\t\t\tdetail?.content.blueprintId ||\n\t\t\t\t\"\",\n\t\t\tinForce: !timeline.isSuccess\n\t\t\t\t? \"…\"\n\t\t\t\t: inForce\n\t\t\t\t\t? t(\"content.rail.inForceRelease\", {\n\t\t\t\t\t\t\tordinal: inForce.ordinal,\n\t\t\t\t\t\t\tperiod: periodText(t, inForce.validityPeriod),\n\t\t\t\t\t\t})\n\t\t\t\t\t: t(\"content.rail.noneInForce\"),\n\t\t\tblock: attributes?.block\n\t\t\t\t? t(\"content.rail.blockedBy\", {\n\t\t\t\t\t\treason: blockReason?.name ?? attributes.block.blockReasonId,\n\t\t\t\t\t\twho: blockedBy,\n\t\t\t\t\t})\n\t\t\t\t: t(\"content.rail.notBlocked\"),\n\t\t\tarchived: attributes?.archiveTime\n\t\t\t\t? new Date(attributes.archiveTime).toLocaleDateString()\n\t\t\t\t: undefined,\n\t\t}),\n\t\t[\n\t\t\tblueprintName.data,\n\t\t\tdetail,\n\t\t\ttimeline.isSuccess,\n\t\t\tinForce,\n\t\t\tattributes,\n\t\t\tblockReason,\n\t\t\tblockedBy,\n\t\t\tt,\n\t\t],\n\t);\n\tconst rail = useMemo(\n\t\t() =>\n\t\t\tcontent ? (\n\t\t\t\t<ContentRail\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tlabels={railLabels}\n\t\t\t\t\tactions={actions}\n\t\t\t\t\tonAction={onAction}\n\t\t\t\t\tabout={about}\n\t\t\t\t/>\n\t\t\t) : null,\n\t\t[content, title, railLabels, actions, onAction, about],\n\t);\n\tusePageRail(rail);\n\n\tif (!detail || !content || !attributes) {\n\t\tconst notFound =\n\t\t\tquery.error instanceof ConnectError && query.error.code === ConnectCode.NotFound;\n\t\treturn (\n\t\t\t<DetailPageTemplate\n\t\t\t\tbreadcrumbs={[{ label: t(\"library.title\"), to: paths.contents }]}\n\t\t\t\ttitle={query.isError ? t(\"content.unavailable\") : t(\"content.loading\")}\n\t\t\t>\n\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t{query.isError ? (\n\t\t\t\t\t\t<Alert\n\t\t\t\t\t\t\tstatus=\"error\"\n\t\t\t\t\t\t\ttitle={notFound ? t(\"content.notFound\") : t(\"content.loadError\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t</DetailPageTemplate>\n\t\t);\n\t}\n\n\tconst changed = dirtyTabs.length;\n\tconst selectTab = (next: Tab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params, { replace: true });\n\t};\n\tconst closeDialog = () => setDialog(null);\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[{ label: t(\"library.title\"), to: paths.contents }, { label: title }]}\n\t\t\ttitle={title}\n\t\t\tbadges={\n\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t{!publishedKnown || published ? null : (\n\t\t\t\t\t\t<TypeBadge name={t(\"content.badges.born\")} colorPalette=\"blue\" />\n\t\t\t\t\t)}\n\t\t\t\t\t{attributes.block ? (\n\t\t\t\t\t\t<TypeBadge name={t(\"content.badges.blocked\")} colorPalette=\"orange\" />\n\t\t\t\t\t) : null}\n\t\t\t\t\t{archived ? <TypeBadge name={t(\"content.badges.archived\")} colorPalette=\"gray\" /> : null}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\t// Closes over this screen's state, reads no context: the host draws\n\t\t\t// it away from the screen's providers (anker's host contract).\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\tdisabled={changed === 0}\n\t\t\t\t\tloading={saving}\n\t\t\t\t\tonClick={() => void saveAll()}\n\t\t\t\t>\n\t\t\t\t\t<Save size={16} />\n\t\t\t\t\t{changed === 0 ? t(\"changeSet.save\") : t(\"changeSet.saveChanged\", { count: changed })}\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => selectTab(e.value as Tab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(`content.tabs.${each}`)}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{refusal || saved ? (\n\t\t\t\t<Stack gap=\"2\" px=\"8\" pt=\"4\">\n\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t{saved ? <Alert status=\"success\" title={t(\"content.filing.saved\")} /> : null}\n\t\t\t\t</Stack>\n\t\t\t) : null}\n\t\t\t{tab === \"data\" ? <ContentDataTab detail={detail} /> : null}\n\t\t\t{tab === \"releases\" ? <ContentReleasesTab client={client} contentId={contentId} /> : null}\n\t\t\t{tab === \"revisions\" ? (\n\t\t\t\tpublishedKnown ? (\n\t\t\t\t\t<ContentRevisionsTab client={client} content={content} published={published} />\n\t\t\t\t) : (\n\t\t\t\t\t<Box px=\"8\" py=\"6\">\n\t\t\t\t\t\t<Spinner size=\"sm\" />\n\t\t\t\t\t</Box>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t\t{tab === \"references\" ? (\n\t\t\t\t<ContentReferencesTab\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontent={content}\n\t\t\t\t\t// Content born in this Change Set exists only in it, so a\n\t\t\t\t\t// Reference read here opens there.\n\t\t\t\t\tonOpenContent={\n\t\t\t\t\t\tonOpenContent\n\t\t\t\t\t\t\t? (id) =>\n\t\t\t\t\t\t\t\t\tonOpenContent({ contentId: id, changeSetId: content.changeSetId || undefined })\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{tab === \"changeSets\" ? (\n\t\t\t\t<ContentChangeSetsTab\n\t\t\t\t\tclient={client}\n\t\t\t\t\tcontentId={contentId}\n\t\t\t\t\tonOpenChangeSet={onOpenChangeSet}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t{tab === \"filing\" ? <ContentFilingTab client={client} attributes={attributes} /> : null}\n\t\t\t</FormProvider>\n\t\t\t<StartEditingModal\n\t\t\t\topen={dialog === \"startEditing\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tdated={dated}\n\t\t\t\tonStarted={(target) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tonOpenBranch(target);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<DuplicateContentModal\n\t\t\t\topen={dialog === \"duplicate\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\trevisionId={content.revisionId}\n\t\t\t\tonCreated={(target) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tonOpenBranch(target);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<EndForceModal\n\t\t\t\topen={dialog === \"endForce\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tdated={dated}\n\t\t\t/>\n\t\t\t<BlockContentModal\n\t\t\t\topen={dialog === \"block\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tcurrent={attributes.block}\n\t\t\t\tonBlocked={(next) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tapplyAttributes(next);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ArchiveContentModal\n\t\t\t\topen={dialog === \"archive\"}\n\t\t\t\tonClose={closeDialog}\n\t\t\t\tclient={client}\n\t\t\t\tcontentId={contentId}\n\t\t\t\tonArchived={(next) => {\n\t\t\t\t\tcloseDialog();\n\t\t\t\t\tapplyAttributes(next);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<UnsavedChangesGuard\n\t\t\t\tisDirty={changed > 0}\n\t\t\t\ttitle={t(\"changeSet.leave.title\")}\n\t\t\t\tmessage={t(\"changeSet.leave.message\")}\n\t\t\t\tconfirmLabel={t(\"changeSet.leave.confirm\")}\n\t\t\t\tcancelLabel={t(\"changeSet.leave.cancel\")}\n\t\t\t/>\n\t\t</DetailPageTemplate>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tAccessDeniedError,\n\ttype ContenthubClient,\n\tInvalidInputError,\n\tRestrictionUnavailableError,\n} from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection, CollectionAccessLevel, CollectionGrant } from \"../types\";\n\ninterface GrantValues {\n\tuserId: string | null;\n\tlevel: GrantLevel | null;\n}\n\n/** What a grant gives: the owner's level comes from restricting, never from a grant. */\ntype GrantLevel = Exclude<CollectionAccessLevel, \"owner\">;\n\nconst EMPTY: GrantValues = { userId: null, level: \"viewer\" };\n\nconst LEVEL_KEYS: Record<CollectionAccessLevel, string> = {\n\towner: \"collections.access.levels.owner\",\n\teditor: \"collections.access.levels.editor\",\n\tviewer: \"collections.access.levels.viewer\",\n};\n\nexport interface CollectionAccessModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Restricted Collection whose grants are managed; null while closed. */\n\tcollection: Collection | null;\n\tonClose: () => void;\n\t/** Workspace mode refused it: the tab then says so and offers restriction no more. */\n\tonRestrictionUnavailable: () => void;\n}\n\n/**\n * Who may see a Restricted Collection's Content (ADR 0017): its owner, who\n * restricted it and is never granted, and each grantee as viewer or editor.\n * A grant replaces what the grantee held, so changing someone's level is\n * granting them again. Grantees are the host's members\n * (`useHostIdentity().members`, ADR 0020); granting oneself is the admin's\n * break-glass, announced to the owner like any grant (ADR 0017's 2026-10-03\n * amendment), so the picker offers it and says so.\n *\n * Only the owner or a workspace admin reads the roster: anyone else is told\n * that rather than shown an empty one.\n */\nexport function CollectionAccessModal({\n\topen,\n\tclient,\n\tcollection,\n\tonClose,\n\tonRestrictionUnavailable,\n}: CollectionAccessModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { userId: me, members } = useHostIdentity();\n\tconst queryClient = useQueryClient();\n\tconst id = collection?.id ?? \"\";\n\tconst grants = useQuery({\n\t\tqueryKey: contenthubKeys.collectionGrants(id),\n\t\tqueryFn: () => client.listCollectionGrants(id),\n\t\tenabled: open && id !== \"\",\n\t});\n\tconst methods = useForm<GrantValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst picked = methods.watch(\"userId\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst unavailable = grants.error instanceof RestrictionUnavailableError;\n\tuseEffect(() => {\n\t\tif (unavailable) onRestrictionUnavailable();\n\t}, [unavailable, onRestrictionUnavailable]);\n\n\tconst nameOf = (userId: string) => {\n\t\tconst name = members.byId(userId)?.displayName || userId;\n\t\treturn userId === me ? t(\"collections.access.you\", { name }) : name;\n\t};\n\tconst roster = grants.data ?? [];\n\tconst owner = roster.find((g) => g.level === \"owner\");\n\tconst granted = roster.filter((g) => g.level !== \"owner\");\n\n\t// Every member but the owner, who is never granted: someone granted\n\t// already stays offered, since granting them again changes their level.\n\tconst candidates = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\tmembers\n\t\t\t\t.list()\n\t\t\t\t.filter((m) => m.userId !== owner?.userId)\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.userId,\n\t\t\t\t\tlabel:\n\t\t\t\t\t\tm.userId === me\n\t\t\t\t\t\t\t? t(\"collections.access.you\", { name: m.displayName || m.userId })\n\t\t\t\t\t\t\t: m.displayName || m.userId,\n\t\t\t\t})),\n\t\t[members, owner, me, t],\n\t);\n\tconst levels = useMemo<BaseOption[]>(\n\t\t() => [\n\t\t\t{ id: \"viewer\", label: t(LEVEL_KEYS.viewer) },\n\t\t\t{ id: \"editor\", label: t(LEVEL_KEYS.editor) },\n\t\t],\n\t\t[t],\n\t);\n\n\tconst refused = (err: unknown) => {\n\t\tif (err instanceof RestrictionUnavailableError) {\n\t\t\tonRestrictionUnavailable();\n\t\t\tsetRefusal(t(\"collections.workspaceMode.title\"));\n\t\t} else if (err instanceof AccessDeniedError) {\n\t\t\tsetRefusal(t(\"collections.access.denied\"));\n\t\t} else if (err instanceof InvalidInputError) {\n\t\t\tsetRefusal(err.message);\n\t\t} else {\n\t\t\tsetRefusal(t(\"collections.access.failed\"));\n\t\t}\n\t};\n\tconst refresh = () =>\n\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.collectionGrants(id) });\n\n\tconst grant = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tif (!values.userId) {\n\t\t\tmethods.setError(\"userId\", { message: t(\"collections.access.personRequired\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait client.grantCollectionAccess({\n\t\t\t\tcollectionId: id,\n\t\t\t\tuserId: values.userId,\n\t\t\t\tlevel: values.level ?? \"viewer\",\n\t\t\t});\n\t\t\tmethods.reset(EMPTY);\n\t\t\tawait refresh();\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t}\n\t});\n\n\tconst revoke = async (g: CollectionGrant) => {\n\t\tsetRefusal(null);\n\t\tsetBusy(true);\n\t\ttry {\n\t\t\tawait client.revokeCollectionAccess({ collectionId: id, userId: g.userId });\n\t\t\tawait refresh();\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst loadError =\n\t\tgrants.error instanceof AccessDeniedError\n\t\t\t? t(\"collections.access.denied\")\n\t\t\t: unavailable\n\t\t\t\t? t(\"collections.workspaceMode.title\")\n\t\t\t\t: grants.isError\n\t\t\t\t\t? t(\"collections.access.loadError\")\n\t\t\t\t\t: null;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"collections.access.title\", { name: collection?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"collections.access.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t{loadError ? null : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tform=\"contenthub-collection-grant\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\t\tloading={methods.formState.isSubmitting}\n\t\t\t\t\t\t\tdisabled={!grants.isSuccess}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"collections.access.grant\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"collections.access.intro\")}\n\t\t\t\t</Text>\n\t\t\t\t{grants.isLoading ? <Spinner size=\"sm\" /> : null}\n\t\t\t\t{loadError ? <Alert status=\"error\" title={loadError} /> : null}\n\t\t\t\t{grants.isSuccess ? (\n\t\t\t\t\t<Stack gap=\"2\" aria-label={t(\"collections.access.roster\")} role=\"list\">\n\t\t\t\t\t\t{owner ? (\n\t\t\t\t\t\t\t<HStack role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(owner.userId)}</Text>\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t{t(LEVEL_KEYS.owner)}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{granted.map((g) => (\n\t\t\t\t\t\t\t<HStack key={g.userId} role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(g.userId)}</Text>\n\t\t\t\t\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t\t\t{t(LEVEL_KEYS[g.level])}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"collections.access.revokeOf\", { name: nameOf(g.userId) })}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void revoke(g)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{t(\"collections.access.revoke\")}\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{granted.length === 0 ? (\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"collections.access.nobody\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t\t{grants.isSuccess ? (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\t\t\tnoValidate\n\t\t\t\t\t\t\tid=\"contenthub-collection-grant\"\n\t\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tvoid grant();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t<BaseSelectField<GrantValues>\n\t\t\t\t\t\t\t\t\tname=\"userId\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"collections.access.person\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"collections.access.personHelp\")}\n\t\t\t\t\t\t\t\t\toptions={candidates}\n\t\t\t\t\t\t\t\t\tplaceholder={t(\"collections.access.personPlaceholder\")}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<BaseSelectField<GrantValues>\n\t\t\t\t\t\t\t\t\tname=\"level\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"collections.access.level\")}\n\t\t\t\t\t\t\t\t\toptions={levels}\n\t\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{picked && picked === me ? (\n\t\t\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"collections.access.breakGlass\")} />\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</FormProvider>\n\t\t\t\t) : null}\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, SwitchField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tCOLLECTION_NAME_MAX,\n\tInvalidInputError,\n\tNameTakenError,\n\tRestrictionUnavailableError,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection } from \"../types\";\nimport { collectionPath } from \"./collection-tree\";\n\n/** The parent picker's stand-in for the root, which has no id. */\nconst ROOT = \"__root__\";\n\n/** Each Collection as a place to put something: its path from the root. */\nexport function placeOptions(\n\tcollections: Collection[],\n\trootLabel: string,\n\texcept?: (c: Collection) => boolean,\n): BaseOption[] {\n\treturn [\n\t\t{ id: ROOT, label: rootLabel },\n\t\t...collections\n\t\t\t.filter((c) => !except?.(c))\n\t\t\t.map((c) => ({\n\t\t\t\tid: c.id,\n\t\t\t\tlabel: collectionPath(c.id, collections)\n\t\t\t\t\t.map((each) => each.name)\n\t\t\t\t\t.join(\" / \"),\n\t\t\t}))\n\t\t\t.sort((a, b) => a.label.localeCompare(b.label)),\n\t];\n}\n\n/** True for `id` and every Collection under it: where it can't move. */\nexport function isWithin(id: string, c: Collection, collections: Collection[]): boolean {\n\treturn collectionPath(c.id, collections).some((each) => each.id === id);\n}\n\ninterface NameValues {\n\tname: string;\n\tparent: string | null;\n\trestricted: boolean;\n}\n\nexport interface CollectionFormModalProps {\n\topen: boolean;\n\t/** A new Collection, or a rename of `collection`. */\n\tmode: \"create\" | \"rename\";\n\t/** The Collection renamed; ignored on create. */\n\tcollection: Collection | null;\n\t/** Every Collection, for the parent picker. */\n\tcollections: Collection[];\n\t/** Offer creating it restricted: false once workspace mode refused a restriction. */\n\tcanRestrict: boolean;\n\tonClose: () => void;\n\t/**\n\t * Sends it. A `NameTakenError` lands on the name, an `InvalidInputError`\n\t * or `RestrictionUnavailableError` above the form.\n\t */\n\tonSubmit: (input: { name: string; parentId: string; restricted: boolean }) => Promise<void>;\n}\n\n/**\n * Names a new Collection and where it sits (and whether it starts\n * Restricted, so its Content is never briefly open, ADR 0017), or renames\n * one. The service's name rule is checked first: trimmed, not blank, at most\n * 200 characters, one line.\n */\nexport function CollectionFormModal({\n\topen,\n\tmode,\n\tcollection,\n\tcollections,\n\tcanRestrict,\n\tonClose,\n\tonSubmit,\n}: CollectionFormModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst formId = `contenthub-collection-${mode}`;\n\tconst initial = useMemo<NameValues>(\n\t\t() => ({\n\t\t\tname: mode === \"rename\" ? (collection?.name ?? \"\") : \"\",\n\t\t\tparent: ROOT,\n\t\t\trestricted: false,\n\t\t}),\n\t\t[mode, collection],\n\t);\n\tconst methods = useForm<NameValues>({ defaultValues: initial });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(initial);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, initial, methods]);\n\n\tconst parents = useMemo(() => placeOptions(collections, t(\"collections.root\")), [collections, t]);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst name = values.name.trim();\n\t\tif (name === \"\") {\n\t\t\tmethods.setError(\"name\", { message: t(\"collections.form.nameRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tif ([...name].length > COLLECTION_NAME_MAX) {\n\t\t\tmethods.setError(\"name\", {\n\t\t\t\tmessage: t(\"collections.form.nameTooLong\", { max: COLLECTION_NAME_MAX }),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\tif (/[\\u0000-\\u001f\\u007f]/.test(name)) {\n\t\t\tmethods.setError(\"name\", { message: t(\"collections.form.oneLine\") });\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait onSubmit({\n\t\t\t\tname,\n\t\t\t\tparentId: !values.parent || values.parent === ROOT ? \"\" : values.parent,\n\t\t\t\trestricted: canRestrict && values.restricted,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"collections.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof RestrictionUnavailableError) {\n\t\t\t\tsetRefusal(t(\"collections.workspaceMode.title\"));\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"collections.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\n\t\t\t\tmode === \"create\" ? \"collections.form.createTitle\" : \"collections.form.renameTitle\",\n\t\t\t)}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={formId} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(\n\t\t\t\t\t\t\tmode === \"create\" ? \"collections.form.createSubmit\" : \"collections.form.renameSubmit\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid={formId}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<NameValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"collections.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"collections.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{mode === \"create\" ? (\n\t\t\t\t\t\t\t<BaseSelectField<NameValues>\n\t\t\t\t\t\t\t\tname=\"parent\"\n\t\t\t\t\t\t\t\tlabel={t(\"collections.form.parent\")}\n\t\t\t\t\t\t\t\toptions={parents}\n\t\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{mode === \"create\" && canRestrict ? (\n\t\t\t\t\t\t\t<SwitchField<NameValues>\n\t\t\t\t\t\t\t\tname=\"restricted\"\n\t\t\t\t\t\t\t\tlabel={t(\"collections.form.restrictedLabel\")}\n\t\t\t\t\t\t\t\thelperText={t(\"collections.form.restrictedHelp\")}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n\ninterface MoveValues {\n\tparent: string | null;\n}\n\nexport interface MoveCollectionModalProps {\n\topen: boolean;\n\tcollection: Collection | null;\n\tcollections: Collection[];\n\tonClose: () => void;\n\t/** Sends the move; \"\" for the root. Refusals show above the form. */\n\tonSubmit: (parentId: string) => Promise<void>;\n}\n\n/**\n * Moves a Collection, with everything under it, to the root or under\n * another. It offers no place under itself, which the service would refuse\n * as a cycle.\n */\nexport function MoveCollectionModal({\n\topen,\n\tcollection,\n\tcollections,\n\tonClose,\n\tonSubmit,\n}: MoveCollectionModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst initial = useMemo<MoveValues>(\n\t\t() => ({ parent: collection?.parentId ? collection.parentId : ROOT }),\n\t\t[collection],\n\t);\n\tconst methods = useForm<MoveValues>({ defaultValues: initial });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(initial);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, initial, methods]);\n\n\tconst places = useMemo(\n\t\t() =>\n\t\t\tplaceOptions(collections, t(\"collections.root\"), (c) =>\n\t\t\t\tcollection ? isWithin(collection.id, c, collections) : false,\n\t\t\t),\n\t\t[collections, collection, t],\n\t);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\ttry {\n\t\t\tawait onSubmit(!values.parent || values.parent === ROOT ? \"\" : values.parent);\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\t// A move sends no name, so the refusal names none: the moved one's own.\n\t\t\t\tsetRefusal(\n\t\t\t\t\tt(\"collections.form.nameTaken\", { name: err.takenName || (collection?.name ?? \"\") }),\n\t\t\t\t);\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"collections.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"collections.move.title\", { name: collection?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\tform=\"contenthub-collection-move\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tloading={submitting}\n\t\t\t\t\t>\n\t\t\t\t\t\t{t(\"collections.move.submit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid=\"contenthub-collection-move\"\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<BaseSelectField<MoveValues>\n\t\t\t\t\t\t\tname=\"parent\"\n\t\t\t\t\t\t\tlabel={t(\"collections.move.parent\")}\n\t\t\t\t\t\t\thelperText={t(\"collections.move.parentHelp\")}\n\t\t\t\t\t\t\toptions={places}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tDataTable,\n\tMenuCell,\n\tStatusBadgeCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { FolderInput, FolderTree, Lock, LockOpen, Pencil, Plus, Trash2, Users } from \"lucide-react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, RestrictionUnavailableError } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { Collection } from \"../types\";\nimport { CollectionAccessModal } from \"./collection-access-modal\";\nimport { CollectionFormModal, MoveCollectionModal } from \"./collection-modals\";\nimport { collectionPath } from \"./collection-tree\";\nimport { ConfirmModal } from \"./confirm-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype CollectionRow = Collection & Record<string, unknown>;\n\n/** The tree depth first, siblings in the service's order (by name). */\nfunction treeOrder(collections: Collection[]): CollectionRow[] {\n\tconst children = new Map<string, Collection[]>();\n\tconst ids = new Set(collections.map((c) => c.id));\n\tfor (const c of collections) {\n\t\t// A parent the caller can't see would orphan its children: show them at the root.\n\t\tconst parent = ids.has(c.parentId) ? c.parentId : \"\";\n\t\tchildren.set(parent, [...(children.get(parent) ?? []), c]);\n\t}\n\tconst out: CollectionRow[] = [];\n\tconst seen = new Set<string>();\n\tconst walk = (parent: string) => {\n\t\tfor (const c of children.get(parent) ?? []) {\n\t\t\tif (seen.has(c.id)) continue;\n\t\t\tseen.add(c.id);\n\t\t\tout.push({ ...c });\n\t\t\twalk(c.id);\n\t\t}\n\t};\n\twalk(\"\");\n\treturn out;\n}\n\ntype Confirming = { kind: \"restrict\" | \"unrestrict\" | \"remove\"; collection: Collection };\n\nexport interface CollectionsTabProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * The workspace's Collection tree as an admin manages it (ADR 0017; spec\n * #56, stories 64, 65, 67 and 107): a flush table in tree order, each row\n * named with the path above it; create from the tab's Toolbar; rename, move,\n * restrict or open again, manage access and remove from each row.\n *\n * Restricting and opening again are both confirmed: restricting makes the\n * admin its owner and hides its Content from everyone not granted, and\n * opening it again discloses that Content to every viewer and drops its\n * grants, so it is sent with the disclosure acknowledged only from the\n * confirmation. In `authz.mode: workspace` contenthub refuses every\n * restriction; no RPC says which mode runs, so the tab learns it from the\n * first refusal and then says so instead of offering restriction.\n */\nexport function CollectionsTab({ client }: CollectionsTabProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\tconst [creating, setCreating] = useState(false);\n\tconst [renaming, setRenaming] = useState<Collection | null>(null);\n\tconst [moving, setMoving] = useState<Collection | null>(null);\n\tconst [confirming, setConfirming] = useState<Confirming | null>(null);\n\tconst [managing, setManaging] = useState<Collection | null>(null);\n\tconst [restrictionUnavailable, setRestrictionUnavailable] = useState(false);\n\tconst markUnavailable = useCallback(() => setRestrictionUnavailable(true), []);\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.collections(),\n\t\tqueryFn: () => client.listCollections(),\n\t});\n\tconst collections = query.data ?? [];\n\tconst rows = useMemo(() => treeOrder(collections), [collections]);\n\t// Filing and the Library read the tree, and a removal unfiles Content.\n\tconst refresh = () =>\n\t\tPromise.all([\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.collections() }),\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.contents() }),\n\t\t]);\n\n\t/** Runs a write, learning workspace mode from its refusal before passing it on. */\n\tconst learning = async <T,>(write: () => Promise<T>): Promise<T> => {\n\t\ttry {\n\t\t\treturn await write();\n\t\t} catch (err) {\n\t\t\tif (err instanceof RestrictionUnavailableError) markUnavailable();\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst columns = useMemo<ColumnDef<CollectionRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"collections.columns.name\"),\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst above = collectionPath(row.original.parentId, collections);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\t\tvalue={row.original.name}\n\t\t\t\t\t\t\tsubText={\n\t\t\t\t\t\t\t\tabove.length > 0\n\t\t\t\t\t\t\t\t\t? t(\"collections.inPath\", { path: above.map((c) => c.name).join(\" / \") })\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"access\",\n\t\t\t\theader: t(\"collections.columns.access\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={t(row.original.restricted ? \"collections.restricted\" : \"collections.open\")}\n\t\t\t\t\t\tcolorMap={{ [t(\"collections.restricted\")]: \"orange\" }}\n\t\t\t\t\t\ticon={row.original.restricted ? <Lock size={12} /> : undefined}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"collections.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => {\n\t\t\t\t\tconst c = row.original;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<MenuCell\n\t\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t\t{ label: t(\"collections.rename\"), icon: Pencil, onClick: () => setRenaming(c) },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: t(\"collections.moveAction\"),\n\t\t\t\t\t\t\t\t\ticon: FolderInput,\n\t\t\t\t\t\t\t\t\tonClick: () => setMoving(c),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t...(c.restricted\n\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.manageAccess\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: Users,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled: restrictionUnavailable,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setManaging(c),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.unrestrict\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: LockOpen,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"unrestrict\", collection: c }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"collections.restrict\"),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: Lock,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled: restrictionUnavailable,\n\t\t\t\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"restrict\", collection: c }),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: t(\"collections.remove\"),\n\t\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\t\tonClick: () => setConfirming({ kind: \"remove\", collection: c }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[t, collections, restrictionUnavailable],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setCreating(true)}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"collections.create\")}\n\t\t</Button>\n\t);\n\n\tconst target = confirming?.collection;\n\tconst confirmText = {\n\t\trestrict: {\n\t\t\ttitle: t(\"collections.restrictDialog.title\"),\n\t\t\tmessage: t(\"collections.restrictDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.restrictDialog.confirm\"),\n\t\t\tfailed: t(\"collections.restrictDialog.failed\"),\n\t\t},\n\t\tunrestrict: {\n\t\t\ttitle: t(\"collections.unrestrictDialog.title\"),\n\t\t\tmessage: t(\"collections.unrestrictDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.unrestrictDialog.confirm\"),\n\t\t\tfailed: t(\"collections.unrestrictDialog.failed\"),\n\t\t},\n\t\tremove: {\n\t\t\ttitle: t(\"collections.removeDialog.title\"),\n\t\t\tmessage: t(\"collections.removeDialog.message\", { name: target?.name ?? \"\" }),\n\t\t\tconfirm: t(\"collections.removeDialog.confirm\"),\n\t\t\tfailed: t(\"collections.removeDialog.failed\"),\n\t\t},\n\t}[confirming?.kind ?? \"remove\"];\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Toolbar>\n\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t<Toolbar.Count>{t(\"collections.count\", { count: collections.length })}</Toolbar.Count>\n\t\t\t\t\t{createButton}\n\t\t\t\t</Toolbar.Right>\n\t\t\t</Toolbar>\n\t\t\t{restrictionUnavailable ? (\n\t\t\t\t<Alert status=\"info\" title={t(\"collections.workspaceMode.title\")} mx=\"8\" my=\"4\">\n\t\t\t\t\t{t(\"collections.workspaceMode.description\")}\n\t\t\t\t</Alert>\n\t\t\t) : null}\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"collections.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={rows}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<FolderTree size={32} />}\n\t\t\t\t\t\theader={t(\"collections.empty\")}\n\t\t\t\t\t\tdescription={t(\"collections.emptyHint\")}\n\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<CollectionFormModal\n\t\t\t\topen={creating}\n\t\t\t\tmode=\"create\"\n\t\t\t\tcollection={null}\n\t\t\t\tcollections={collections}\n\t\t\t\tcanRestrict={!restrictionUnavailable}\n\t\t\t\tonClose={() => setCreating(false)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tawait learning(() => client.createCollection(input));\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetCreating(false);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<CollectionFormModal\n\t\t\t\topen={renaming !== null}\n\t\t\t\tmode=\"rename\"\n\t\t\t\tcollection={renaming}\n\t\t\t\tcollections={collections}\n\t\t\t\tcanRestrict={false}\n\t\t\t\tonClose={() => setRenaming(null)}\n\t\t\t\tonSubmit={async ({ name }) => {\n\t\t\t\t\tif (!renaming) return;\n\t\t\t\t\tawait client.renameCollection({ id: renaming.id, name });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRenaming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<MoveCollectionModal\n\t\t\t\topen={moving !== null}\n\t\t\t\tcollection={moving}\n\t\t\t\tcollections={collections}\n\t\t\t\tonClose={() => setMoving(null)}\n\t\t\t\tonSubmit={async (parentId) => {\n\t\t\t\t\tif (!moving) return;\n\t\t\t\t\tawait client.moveCollection({ id: moving.id, parentId });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetMoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={confirming !== null}\n\t\t\t\ttitle={confirmText.title}\n\t\t\t\tmessage={confirmText.message}\n\t\t\t\tconfirmLabel={confirmText.confirm}\n\t\t\t\tdanger={confirming?.kind !== \"restrict\"}\n\t\t\t\tfailedMessage={confirmText.failed}\n\t\t\t\tonClose={() => setConfirming(null)}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!confirming) return;\n\t\t\t\t\tconst { kind, collection } = confirming;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (kind === \"remove\") {\n\t\t\t\t\t\t\tawait client.removeCollection({ id: collection.id });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tawait learning(() =>\n\t\t\t\t\t\t\t\tclient.setCollectionRestricted({\n\t\t\t\t\t\t\t\t\tid: collection.id,\n\t\t\t\t\t\t\t\t\trestricted: kind === \"restrict\",\n\t\t\t\t\t\t\t\t\t// Sent only from here: the admin has just read what it discloses.\n\t\t\t\t\t\t\t\t\tacknowledgeDisclosure: kind === \"unrestrict\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Workspace mode refused a restriction: the tab now says why, so the\n\t\t\t\t\t\t// dialog has nothing to add. Any other refusal is shown in the dialog.\n\t\t\t\t\t\tif (kind === \"restrict\" && err instanceof RestrictionUnavailableError) {\n\t\t\t\t\t\t\tsetConfirming(null);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetConfirming(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<CollectionAccessModal\n\t\t\t\topen={managing !== null}\n\t\t\t\tclient={client}\n\t\t\t\tcollection={managing}\n\t\t\t\tonClose={() => setManaging(null)}\n\t\t\t\tonRestrictionUnavailable={markUnavailable}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField, InputField, SwitchField, TextareaField } from \"@knkcs/anker/forms\";\nimport { Alert, HStack, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tBLUEPRINT_ACCESSOR_MAX,\n\tInvalidInputError,\n\tNameTakenError,\n\tREQUIRED_CHECK_NAME_MAX,\n} from \"../client/contenthub-client\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { CheckScope, RequiredCheck, RequiredCheckInput } from \"../types\";\n\nconst FORM_ID = \"contenthub-required-check\";\n\n/** Each scope's label key, for the picker and the table alike. */\nexport const SCOPE_LABELS: Record<CheckScope, string> = {\n\tbranch: \"requiredChecks.scope.branch\",\n\tchange_set: \"requiredChecks.scope.change_set\",\n};\n\ninterface CheckValues {\n\tname: string;\n\tscope: CheckScope | null;\n\teveryBlueprint: boolean;\n\t/** One Blueprint accessor per line. */\n\taccessors: string;\n\tindependent: boolean;\n}\n\nfunction valuesOf(check: RequiredCheck | null): CheckValues {\n\treturn {\n\t\tname: check?.name ?? \"\",\n\t\tscope: check?.scope ?? null,\n\t\teveryBlueprint: (check?.blueprintAccessors.length ?? 0) === 0,\n\t\taccessors: (check?.blueprintAccessors ?? []).join(\"\\n\"),\n\t\tindependent: check?.independent ?? false,\n\t};\n}\n\n/** The accessors a textarea holds: one a line, blank lines dropped. */\nconst accessorsOf = (text: string) =>\n\ttext\n\t\t.split(\"\\n\")\n\t\t.map((a) => a.trim())\n\t\t.filter((a) => a !== \"\");\n\nexport interface RequiredCheckModalProps {\n\topen: boolean;\n\t/** The check to edit; null to declare a new one. */\n\tcheck: RequiredCheck | null;\n\tonClose: () => void;\n\t/**\n\t * Sends the check. A `NameTakenError` lands on the name, an\n\t * `InvalidInputError` above the form with the service's guidance.\n\t */\n\tonSubmit: (input: RequiredCheckInput) => Promise<void>;\n}\n\n/**\n * Declares or edits a Required Check (ADR 0014; spec #56, story 39): its\n * name, its scope, the Blueprints it applies to by accessor or every one,\n * and whether it is independent. The form checks the service's rules first\n * (internal/workspaceconfig), so most mistakes are said before a request.\n *\n * Who may record it is said, not edited here: contenthub grants `recorder` to\n * every member when a check is created (ADR 0017's 2026-10-03 amendment),\n * and the tab's RequiredCheckRecordersModal narrows it.\n */\nexport function RequiredCheckModal({ open, check, onClose, onSubmit }: RequiredCheckModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst methods = useForm<CheckValues>({ defaultValues: valuesOf(check) });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst submitting = methods.formState.isSubmitting;\n\tconst everyBlueprint = methods.watch(\"everyBlueprint\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(valuesOf(check));\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, check, methods]);\n\n\tconst scopeOptions = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\t(Object.keys(SCOPE_LABELS) as CheckScope[]).map((id) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: t(SCOPE_LABELS[id]),\n\t\t\t})),\n\t\t[t],\n\t);\n\n\tconst submit = methods.handleSubmit(async (values) => {\n\t\tsetRefusal(null);\n\t\tconst name = values.name.trim();\n\t\tlet valid = true;\n\t\tconst fail = (field: keyof CheckValues, message: string) => {\n\t\t\tmethods.setError(field, { message });\n\t\t\tvalid = false;\n\t\t};\n\t\tif (name === \"\") fail(\"name\", t(\"requiredChecks.form.nameRequired\"));\n\t\telse if ([...name].length > REQUIRED_CHECK_NAME_MAX) {\n\t\t\tfail(\"name\", t(\"requiredChecks.form.nameTooLong\", { max: REQUIRED_CHECK_NAME_MAX }));\n\t\t}\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: the rule is exactly \"no control characters\"\n\t\telse if (/[\\u0000-\\u001f\\u007f]/.test(name)) fail(\"name\", t(\"requiredChecks.form.oneLine\"));\n\t\tif (!values.scope) fail(\"scope\", t(\"requiredChecks.form.scopeRequired\"));\n\t\tconst accessors = values.everyBlueprint ? [] : accessorsOf(values.accessors);\n\t\tif (!values.everyBlueprint && accessors.length === 0) {\n\t\t\tfail(\"accessors\", t(\"requiredChecks.form.accessorsRequired\"));\n\t\t} else if (accessors.some((a) => [...a].length > BLUEPRINT_ACCESSOR_MAX)) {\n\t\t\tfail(\"accessors\", t(\"requiredChecks.form.accessorTooLong\", { max: BLUEPRINT_ACCESSOR_MAX }));\n\t\t}\n\t\tif (!valid || !values.scope) return;\n\t\ttry {\n\t\t\tawait onSubmit({\n\t\t\t\tname,\n\t\t\t\tscope: values.scope,\n\t\t\t\tblueprintAccessors: [...new Set(accessors)],\n\t\t\t\tindependent: values.independent,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof NameTakenError) {\n\t\t\t\tmethods.setError(\"name\", {\n\t\t\t\t\tmessage: t(\"requiredChecks.form.nameTaken\", { name: err.takenName }),\n\t\t\t\t});\n\t\t\t} else if (err instanceof InvalidInputError) {\n\t\t\t\tsetRefusal(err.message);\n\t\t\t} else {\n\t\t\t\tsetRefusal(t(\"requiredChecks.form.failed\"));\n\t\t\t}\n\t\t}\n\t});\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(check ? \"requiredChecks.form.editTitle\" : \"requiredChecks.form.createTitle\")}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"common.cancel\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button type=\"submit\" form={FORM_ID} size=\"sm\" variant=\"solid\" loading={submitting}>\n\t\t\t\t\t\t{t(check ? \"requiredChecks.form.editSubmit\" : \"requiredChecks.form.createSubmit\")}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<FormProvider {...methods}>\n\t\t\t\t<form\n\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\tnoValidate\n\t\t\t\t\tid={FORM_ID}\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tvoid submit();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t<InputField<CheckValues>\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.name\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.nameHelp\")}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<BaseSelectField<CheckValues>\n\t\t\t\t\t\t\tname=\"scope\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.scope\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.scopeHelp\")}\n\t\t\t\t\t\t\toptions={scopeOptions}\n\t\t\t\t\t\t\tisClearable={false}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<SwitchField<CheckValues>\n\t\t\t\t\t\t\tname=\"everyBlueprint\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.everyBlueprint\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{everyBlueprint ? null : (\n\t\t\t\t\t\t\t<TextareaField<CheckValues>\n\t\t\t\t\t\t\t\tname=\"accessors\"\n\t\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.accessors\")}\n\t\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.accessorsHelp\")}\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<SwitchField<CheckValues>\n\t\t\t\t\t\t\tname=\"independent\"\n\t\t\t\t\t\t\tlabel={t(\"requiredChecks.form.independentLabel\")}\n\t\t\t\t\t\t\thelperText={t(\"requiredChecks.form.independentHelp\")}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Stack gap=\"1\">\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\">\n\t\t\t\t\t\t\t\t{t(\"requiredChecks.form.recorders\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t\t\t\t{t(\"requiredChecks.form.recordersHelp\")}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t\t\t</Stack>\n\t\t\t\t</form>\n\t\t\t</FormProvider>\n\t\t</Modal>\n\t);\n}\n","import type { BaseOption } from \"@knkcs/anker/atoms\";\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { BaseSelectField } from \"@knkcs/anker/forms\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, HStack, Spinner, Stack, Text } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n\tAccessDeniedError,\n\ttype ContenthubClient,\n\tGuardianModeRequiredError,\n\tInvalidInputError,\n} from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { RecorderGrant, RequiredCheck } from \"../types\";\n\ninterface AddValues {\n\tuserId: string | null;\n}\n\nconst EMPTY: AddValues = { userId: null };\n\n/** Don't ask again what the service refused for good: the mode, or the caller's rights. */\nexport function retryRecorders(failures: number, err: unknown): boolean {\n\treturn (\n\t\t!(err instanceof GuardianModeRequiredError || err instanceof AccessDeniedError) && failures < 3\n\t);\n}\n\nexport interface RequiredCheckRecordersModalProps {\n\topen: boolean;\n\tclient: ContenthubClient;\n\t/** The Required Check whose recorders are managed; null while closed. */\n\tcheck: RequiredCheck | null;\n\tonClose: () => void;\n\t/** Workspace mode refused it: the tab then says so and offers the editor no more. */\n\tonGuardianModeRequired: () => void;\n}\n\n/**\n * Who records a Required Check's results (ADR 0017's 2026-10-03 amendment):\n * every member of the workspace until an admin narrows it to named people.\n * Narrowing is adding the people, then removing every member; restoring is\n * adding every member back. People are the host's members\n * (`useHostIdentity().members`, ADR 0020), as for a Restricted Collection's\n * grants (CollectionAccessModal). An admin records a check only when\n * granted, so adding oneself is break-glass, announced like any grant, and\n * the picker says so.\n *\n * In `authz.mode: workspace` every member records every check and contenthub\n * refuses to narrow it: the tab is told, and stops offering this.\n */\nexport function RequiredCheckRecordersModal({\n\topen,\n\tclient,\n\tcheck,\n\tonClose,\n\tonGuardianModeRequired,\n}: RequiredCheckRecordersModalProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { userId: me, members } = useHostIdentity();\n\tconst queryClient = useQueryClient();\n\tconst id = check?.id ?? \"\";\n\tconst recorders = useQuery({\n\t\tqueryKey: contenthubKeys.requiredCheckRecorders(id),\n\t\tqueryFn: () => client.listRequiredCheckRecorders(id),\n\t\tenabled: open && id !== \"\",\n\t\tretry: retryRecorders,\n\t});\n\tconst methods = useForm<AddValues>({ defaultValues: EMPTY });\n\tconst [refusal, setRefusal] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst picked = methods.watch(\"userId\");\n\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tmethods.reset(EMPTY);\n\t\t\tsetRefusal(null);\n\t\t}\n\t}, [open, methods]);\n\n\tconst unavailable = recorders.error instanceof GuardianModeRequiredError;\n\tuseEffect(() => {\n\t\tif (unavailable) onGuardianModeRequired();\n\t}, [unavailable, onGuardianModeRequired]);\n\n\tconst nameOf = (userId: string) => {\n\t\tconst name = members.byId(userId)?.displayName || userId;\n\t\treturn userId === me ? t(\"requiredChecks.recorders.you\", { name }) : name;\n\t};\n\tconst everyMember = recorders.data?.everyMember ?? false;\n\tconst named = recorders.data?.userIds ?? [];\n\n\t// Every member not named already.\n\tconst candidates = useMemo<BaseOption[]>(\n\t\t() =>\n\t\t\tmembers\n\t\t\t\t.list()\n\t\t\t\t.filter((m) => !named.includes(m.userId))\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.userId,\n\t\t\t\t\tlabel:\n\t\t\t\t\t\tm.userId === me\n\t\t\t\t\t\t\t? t(\"requiredChecks.recorders.you\", { name: m.displayName || m.userId })\n\t\t\t\t\t\t\t: m.displayName || m.userId,\n\t\t\t\t})),\n\t\t[members, named, me, t],\n\t);\n\n\tconst refused = (err: unknown) => {\n\t\tif (err instanceof GuardianModeRequiredError) {\n\t\t\tonGuardianModeRequired();\n\t\t\tsetRefusal(t(\"requiredChecks.workspaceMode.title\"));\n\t\t} else if (err instanceof AccessDeniedError) {\n\t\t\tsetRefusal(t(\"requiredChecks.recorders.denied\"));\n\t\t} else if (err instanceof InvalidInputError) {\n\t\t\tsetRefusal(err.message);\n\t\t} else {\n\t\t\tsetRefusal(t(\"requiredChecks.recorders.failed\"));\n\t\t}\n\t};\n\tconst refresh = () =>\n\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.requiredCheckRecorders(id) });\n\n\tconst change = async (kind: \"grant\" | \"revoke\", recorder: RecorderGrant) => {\n\t\tsetRefusal(null);\n\t\tsetBusy(true);\n\t\ttry {\n\t\t\tconst input = { requiredCheckId: id, recorder };\n\t\t\tif (kind === \"grant\") await client.grantRequiredCheckRecorder(input);\n\t\t\telse await client.revokeRequiredCheckRecorder(input);\n\t\t\tawait refresh();\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\trefused(err);\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst add = methods.handleSubmit(async (values) => {\n\t\tif (!values.userId) {\n\t\t\tmethods.setError(\"userId\", { message: t(\"requiredChecks.recorders.personRequired\") });\n\t\t\treturn;\n\t\t}\n\t\tif (await change(\"grant\", { userId: values.userId })) methods.reset(EMPTY);\n\t});\n\n\tconst loadError =\n\t\trecorders.error instanceof AccessDeniedError\n\t\t\t? t(\"requiredChecks.recorders.denied\")\n\t\t\t: unavailable\n\t\t\t\t? t(\"requiredChecks.workspaceMode.title\")\n\t\t\t\t: recorders.isError\n\t\t\t\t\t? t(\"requiredChecks.recorders.loadError\")\n\t\t\t\t\t: null;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={onClose}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tsize=\"md\"\n\t\t\theader={t(\"requiredChecks.recorders.title\", { name: check?.name ?? \"\" })}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClose}>\n\t\t\t\t\t\t{t(\"requiredChecks.recorders.close\")}\n\t\t\t\t\t</Button>\n\t\t\t\t\t{loadError ? null : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tform=\"contenthub-required-check-recorder\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\t\tloading={methods.formState.isSubmitting}\n\t\t\t\t\t\t\tdisabled={!recorders.isSuccess || busy}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.add\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\">\n\t\t\t\t<Text fontSize=\"sm\" color=\"muted\">\n\t\t\t\t\t{t(\"requiredChecks.recorders.intro\")}\n\t\t\t\t</Text>\n\t\t\t\t{recorders.isLoading ? <Spinner size=\"sm\" /> : null}\n\t\t\t\t{loadError ? <Alert status=\"error\" title={loadError} /> : null}\n\t\t\t\t{recorders.isSuccess ? (\n\t\t\t\t\t<Stack gap=\"2\" aria-label={t(\"requiredChecks.recorders.roster\")} role=\"list\">\n\t\t\t\t\t\t{everyMember ? (\n\t\t\t\t\t\t\t<HStack role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{t(\"requiredChecks.recorders.everyMember\")}</Text>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\taria-label={t(\"requiredChecks.recorders.removeOf\", {\n\t\t\t\t\t\t\t\t\t\tname: t(\"requiredChecks.recorders.everyMember\"),\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\tonClick={() => void change(\"revoke\", { everyMember: true })}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.remove\")}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{named.map((userId) => (\n\t\t\t\t\t\t\t<HStack key={userId} role=\"listitem\" justify=\"space-between\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Text fontSize=\"sm\">{nameOf(userId)}</Text>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tcolorPalette=\"red\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\taria-label={t(\"requiredChecks.recorders.removeOf\", { name: nameOf(userId) })}\n\t\t\t\t\t\t\t\t\tonClick={() => void change(\"revoke\", { userId })}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.remove\")}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Stack>\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess && !everyMember && named.length === 0 ? (\n\t\t\t\t\t<Alert status=\"warning\" title={t(\"requiredChecks.recorders.nobody\")} />\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess && !everyMember ? (\n\t\t\t\t\t<HStack>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => void change(\"grant\", { everyMember: true })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(\"requiredChecks.recorders.restoreEveryMember\")}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</HStack>\n\t\t\t\t) : null}\n\t\t\t\t{recorders.isSuccess ? (\n\t\t\t\t\t<FormProvider {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t// The screen says what is missing in its own words, not the browser's.\n\t\t\t\t\t\t\tnoValidate\n\t\t\t\t\t\t\tid=\"contenthub-required-check-recorder\"\n\t\t\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tvoid add();\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Stack gap=\"4\">\n\t\t\t\t\t\t\t\t<BaseSelectField<AddValues>\n\t\t\t\t\t\t\t\t\tname=\"userId\"\n\t\t\t\t\t\t\t\t\tlabel={t(\"requiredChecks.recorders.person\")}\n\t\t\t\t\t\t\t\t\thelperText={t(\"requiredChecks.recorders.personHelp\")}\n\t\t\t\t\t\t\t\t\toptions={candidates}\n\t\t\t\t\t\t\t\t\tplaceholder={t(\"requiredChecks.recorders.personPlaceholder\")}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{picked && picked === me ? (\n\t\t\t\t\t\t\t\t\t<Alert status=\"warning\" title={t(\"requiredChecks.recorders.breakGlass\")} />\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</FormProvider>\n\t\t\t\t) : null}\n\t\t\t\t{refusal ? <Alert status=\"error\" title={refusal} /> : null}\n\t\t\t</Stack>\n\t\t</Modal>\n\t);\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tBooleanCell,\n\tDataTable,\n\tMenuCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { useHostIdentity } from \"@knkcs/anker/host\";\nimport { Alert, Stack } from \"@knkcs/anker/primitives\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { ListChecks, Pencil, Plus, Trash2, UserCheck } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { type ContenthubClient, GuardianModeRequiredError } from \"../client/contenthub-client\";\nimport { contenthubKeys } from \"../common/query-keys\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport type { RequiredCheck } from \"../types\";\nimport { ConfirmModal } from \"./confirm-modal\";\nimport { RequiredCheckModal, SCOPE_LABELS } from \"./required-check-modal\";\nimport { RequiredCheckRecordersModal, retryRecorders } from \"./required-check-recorders-modal\";\n\n// DataTable wants T extends Record<string, unknown>.\ntype CheckRow = RequiredCheck & Record<string, unknown>;\n\nexport interface RequiredChecksTabProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * Who records one check, read from contenthub: every member, the people\n * named, or nobody. In workspace mode every member records and contenthub\n * says so by refusing the read, which the tab is told.\n */\nfunction RecordersCell({\n\tclient,\n\tcheckId,\n\tworkspaceMode,\n\tonGuardianModeRequired,\n}: {\n\tclient: ContenthubClient;\n\tcheckId: string;\n\tworkspaceMode: boolean;\n\tonGuardianModeRequired: () => void;\n}) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst { members } = useHostIdentity();\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.requiredCheckRecorders(checkId),\n\t\tqueryFn: () => client.listRequiredCheckRecorders(checkId),\n\t\tenabled: !workspaceMode,\n\t\tretry: retryRecorders,\n\t});\n\tconst refused = query.error instanceof GuardianModeRequiredError;\n\tuseEffect(() => {\n\t\tif (refused) onGuardianModeRequired();\n\t}, [refused, onGuardianModeRequired]);\n\n\tlet value = \"\";\n\tif (workspaceMode || refused || query.data?.everyMember) value = t(\"requiredChecks.everyMember\");\n\telse if (query.data && query.data.userIds.length === 0) value = t(\"requiredChecks.nobody\");\n\telse if (query.data) {\n\t\tvalue = query.data.userIds.map((u) => members.byId(u)?.displayName || u).join(\", \");\n\t} else if (query.isError) value = t(\"requiredChecks.recordersUnknown\");\n\treturn <TruncatedTextCell value={value} />;\n}\n\n/**\n * The workspace's Required Checks (ADR 0014), a settings tab: a flush table,\n * declared and edited in a Modal opened from the tab's Toolbar (anker: no\n * inline create form above a DataTable; a tab's add goes in its Toolbar).\n * Every change is read back, so the table shows what contenthub holds.\n *\n * Who records each check is narrowed from its row (ADR 0017's 2026-10-03\n * amendment). In `authz.mode: workspace` every member records every check\n * and contenthub refuses to narrow it, with a typed refusal: the tab learns\n * the mode from the first one, says so, and offers no recorders editor.\n */\nexport function RequiredChecksTab({ client }: RequiredChecksTabProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst queryClient = useQueryClient();\n\t// null: closed; \"new\": declaring one; a check: editing it.\n\tconst [editing, setEditing] = useState<RequiredCheck | \"new\" | null>(null);\n\tconst [removing, setRemoving] = useState<RequiredCheck | null>(null);\n\tconst [narrowing, setNarrowing] = useState<RequiredCheck | null>(null);\n\tconst [workspaceMode, setWorkspaceMode] = useState(false);\n\tconst markWorkspaceMode = useCallback(() => {\n\t\tsetWorkspaceMode(true);\n\t\tsetNarrowing(null);\n\t}, []);\n\n\tconst query = useQuery({\n\t\tqueryKey: contenthubKeys.requiredChecks(),\n\t\tqueryFn: () => client.listRequiredChecks(),\n\t});\n\tconst checks = query.data ?? [];\n\t// The Change Set pages read which checks apply, so they ask again too.\n\tconst refresh = () =>\n\t\tPromise.all([\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.requiredChecks() }),\n\t\t\tqueryClient.invalidateQueries({ queryKey: contenthubKeys.changeSets() }),\n\t\t]);\n\n\tconst columns = useMemo<ColumnDef<CheckRow, unknown>[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: \"name\",\n\t\t\t\theader: t(\"requiredChecks.columns.name\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={row.original.name} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"scope\",\n\t\t\t\theader: t(\"requiredChecks.columns.scope\"),\n\t\t\t\tcell: ({ row }) => <TruncatedTextCell value={t(SCOPE_LABELS[row.original.scope])} />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"blueprints\",\n\t\t\t\theader: t(\"requiredChecks.columns.blueprints\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\trow.original.blueprintAccessors.length === 0\n\t\t\t\t\t\t\t\t? t(\"requiredChecks.everyBlueprint\")\n\t\t\t\t\t\t\t\t: row.original.blueprintAccessors.join(\", \")\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"independent\",\n\t\t\t\theader: t(\"requiredChecks.columns.independent\"),\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<BooleanCell\n\t\t\t\t\t\tvalue={row.original.independent}\n\t\t\t\t\t\ttrueLabel={t(\"requiredChecks.yes\")}\n\t\t\t\t\t\tfalseLabel={t(\"requiredChecks.no\")}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"recorders\",\n\t\t\t\theader: t(\"requiredChecks.columns.recorders\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<RecordersCell\n\t\t\t\t\t\tclient={client}\n\t\t\t\t\t\tcheckId={row.original.id}\n\t\t\t\t\t\tworkspaceMode={workspaceMode}\n\t\t\t\t\t\tonGuardianModeRequired={markWorkspaceMode}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: t(\"requiredChecks.columns.actions\"),\n\t\t\t\tenableSorting: false,\n\t\t\t\tcell: ({ row }) => (\n\t\t\t\t\t<MenuCell\n\t\t\t\t\t\tmenuThreshold={2}\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.edit\"),\n\t\t\t\t\t\t\t\ticon: Pencil,\n\t\t\t\t\t\t\t\tonClick: () => setEditing(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t// Not offered in workspace mode: nothing narrows it there.\n\t\t\t\t\t\t\t...(workspaceMode\n\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.manageRecorders\"),\n\t\t\t\t\t\t\t\t\t\t\ticon: UserCheck,\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => setNarrowing(row.original),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: t(\"requiredChecks.remove\"),\n\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\tonClick: () => setRemoving(row.original),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t},\n\t\t],\n\t\t[t, client, workspaceMode, markWorkspaceMode],\n\t);\n\n\tconst createButton = (\n\t\t<Button size=\"sm\" variant=\"solid\" onClick={() => setEditing(\"new\")}>\n\t\t\t<Plus size={16} />\n\t\t\t{t(\"requiredChecks.create\")}\n\t\t</Button>\n\t);\n\n\treturn (\n\t\t<Stack gap=\"0\">\n\t\t\t<Toolbar>\n\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t<Toolbar.Count>{t(\"requiredChecks.count\", { count: checks.length })}</Toolbar.Count>\n\t\t\t\t\t{createButton}\n\t\t\t\t</Toolbar.Right>\n\t\t\t</Toolbar>\n\t\t\t{query.isError ? (\n\t\t\t\t<Alert status=\"error\" title={t(\"requiredChecks.loadError\")} mx=\"8\" my=\"4\" />\n\t\t\t) : null}\n\t\t\t{workspaceMode ? (\n\t\t\t\t<Alert status=\"info\" title={t(\"requiredChecks.workspaceMode.title\")} mx=\"8\" my=\"4\">\n\t\t\t\t\t{t(\"requiredChecks.workspaceMode.description\")}\n\t\t\t\t</Alert>\n\t\t\t) : null}\n\t\t\t<DataTable\n\t\t\t\tcolumns={columns}\n\t\t\t\tdata={checks as CheckRow[]}\n\t\t\t\tloading={query.isLoading}\n\t\t\t\tgetRowId={(row) => row.id}\n\t\t\t\temptyState={\n\t\t\t\t\t<EmptyState\n\t\t\t\t\t\ticon={<ListChecks size={32} />}\n\t\t\t\t\t\theader={t(\"requiredChecks.empty\")}\n\t\t\t\t\t\tdescription={t(\"requiredChecks.emptyHint\")}\n\t\t\t\t\t\tactions={createButton}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<RequiredCheckModal\n\t\t\t\topen={editing !== null}\n\t\t\t\tcheck={editing === \"new\" ? null : editing}\n\t\t\t\tonClose={() => setEditing(null)}\n\t\t\t\tonSubmit={async (input) => {\n\t\t\t\t\tif (editing === \"new\") await client.createRequiredCheck(input);\n\t\t\t\t\telse if (editing) await client.updateRequiredCheck({ id: editing.id, ...input });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetEditing(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<RequiredCheckRecordersModal\n\t\t\t\topen={narrowing !== null}\n\t\t\t\tclient={client}\n\t\t\t\tcheck={narrowing}\n\t\t\t\tonClose={() => setNarrowing(null)}\n\t\t\t\tonGuardianModeRequired={markWorkspaceMode}\n\t\t\t/>\n\t\t\t<ConfirmModal\n\t\t\t\topen={removing !== null}\n\t\t\t\ttitle={t(\"requiredChecks.removeDialog.title\")}\n\t\t\t\tmessage={t(\"requiredChecks.removeDialog.message\", { name: removing?.name ?? \"\" })}\n\t\t\t\tconfirmLabel={t(\"requiredChecks.removeDialog.confirm\")}\n\t\t\t\tdanger\n\t\t\t\tfailedMessage={t(\"requiredChecks.removeDialog.failed\")}\n\t\t\t\tonClose={() => setRemoving(null)}\n\t\t\t\tonConfirm={async () => {\n\t\t\t\t\tif (!removing) return;\n\t\t\t\t\tawait client.deleteRequiredCheck({ id: removing.id });\n\t\t\t\t\tawait refresh();\n\t\t\t\t\tsetRemoving(null);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Stack>\n\t);\n}\n","import { Tabs } from \"@knkcs/anker/primitives\";\nimport { SettingsPageTemplate } from \"@knkcs/anker/templates\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSearchParams } from \"react-router\";\nimport type { ContenthubClient } from \"../client/contenthub-client\";\nimport { type ContenthubSettingsTab, useContenthubPaths } from \"../common/paths\";\nimport { CONTENTHUB_UI_NS } from \"../i18n/resources\";\nimport { BlockReasonsTab } from \"./block-reasons-settings\";\nimport { CollectionsTab } from \"./collections-tab\";\nimport { RequiredChecksTab } from \"./required-checks-tab\";\n\nconst TABS: ContenthubSettingsTab[] = [\"required-checks\", \"block-reasons\", \"collections\"];\nconst TAB_LABELS: Record<ContenthubSettingsTab, string> = {\n\t\"required-checks\": \"settings.tabs.requiredChecks\",\n\t\"block-reasons\": \"settings.tabs.blockReasons\",\n\tcollections: \"settings.tabs.collections\",\n};\n\nexport interface ContenthubSettingsProps {\n\tclient: ContenthubClient;\n}\n\n/**\n * contenthub's workspace configuration in one settings page (spec #56, story\n * 107): Required Checks, Block Reasons and the Collection tree with its\n * restriction and grants, each a tab chosen by `?tab=` so a host links\n * straight to one.\n *\n * Every tab is a flush DataTable whose rows are changed through Modals, so\n * the body is unpadded (`bodyPadding=\"none\"`, anker's rule for table tabs)\n * and there is no header Save: nothing here is a draft. Only the active tab\n * is mounted (nav-link tabs), so no two tabs' Modals or queries live at once.\n */\nexport function ContenthubSettings({ client }: ContenthubSettingsProps) {\n\tconst { t } = useTranslation(CONTENTHUB_UI_NS);\n\tconst paths = useContenthubPaths();\n\tconst [searchParams, setSearchParams] = useSearchParams();\n\tconst asked = searchParams.get(\"tab\") as ContenthubSettingsTab | null;\n\tconst tab: ContenthubSettingsTab = asked && TABS.includes(asked) ? asked : \"required-checks\";\n\n\tconst select = (next: ContenthubSettingsTab) => {\n\t\tconst params = new URLSearchParams(searchParams);\n\t\tparams.set(\"tab\", next);\n\t\tsetSearchParams(params);\n\t};\n\n\treturn (\n\t\t<SettingsPageTemplate\n\t\t\ttitle={t(\"settings.title\")}\n\t\t\tsubtitle={t(\"settings.subtitle\")}\n\t\t\tbreadcrumbs={[\n\t\t\t\t{ label: t(\"settings.section\"), to: paths.settings },\n\t\t\t\t{ label: t(\"settings.title\") },\n\t\t\t]}\n\t\t\tbodyPadding=\"none\"\n\t\t\tmaxBodyWidth=\"full\"\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root value={tab} onValueChange={(e) => select(e.value as ContenthubSettingsTab)}>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t{TABS.map((each) => (\n\t\t\t\t\t\t\t<Tabs.Trigger key={each} value={each}>\n\t\t\t\t\t\t\t\t{t(TAB_LABELS[each])}\n\t\t\t\t\t\t\t</Tabs.Trigger>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t{tab === \"required-checks\" ? <RequiredChecksTab client={client} /> : null}\n\t\t\t{tab === \"block-reasons\" ? <BlockReasonsTab client={client} /> : null}\n\t\t\t{tab === \"collections\" ? <CollectionsTab client={client} /> : null}\n\t\t</SettingsPageTemplate>\n\t);\n}\n\nContenthubSettings.displayName = \"ContenthubSettings\";\n"],"mappings":"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"}