@ash-qw/dsh-theme-prts 0.1.91
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/LICENSE +24 -0
- package/README.en.md +103 -0
- package/README.md +107 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/cordis.patch.yml +4 -0
- package/lib/client.js +7466 -0
- package/lib/index.js +3 -0
- package/package.json +64 -0
- package/src/assets/faction-emblems/lungmen.png +0 -0
- package/src/assets/faction-emblems/penguin-logistics.png +0 -0
- package/src/assets/faction-emblems/reunion.png +0 -0
- package/src/assets/faction-emblems/rhine-lab.png +0 -0
- package/src/assets/faction-emblems/rhodes-island.png +0 -0
- package/src/assets/prts-original-avatar.png +0 -0
- package/src/assets/rhodes-dsh.svg +6 -0
- package/src/assets/topographic-map.svg +72 -0
- package/src/assets/topographic-tech.svg +19 -0
- package/src/client/assistant-glass-adapter.js +231 -0
- package/src/client/composer-glass-adapter.js +210 -0
- package/src/client/conversation-control-adapter.js +109 -0
- package/src/client/conversation-scale-adapter.js +2243 -0
- package/src/client/facility-geometry.js +60 -0
- package/src/client/facility-vector.js +230 -0
- package/src/client/floating-glass-adapter.js +177 -0
- package/src/client/host-geometry-adapter.js +123 -0
- package/src/client/index.js +359 -0
- package/src/client/layout-stability-diagnostics.js +162 -0
- package/src/client/operations-shell-v2.js +248 -0
- package/src/client/particle-field-adapter.js +1840 -0
- package/src/client/preferences.js +239 -0
- package/src/client/rc7-adapter.js +83 -0
- package/src/client/resize-shield-adapter.js +64 -0
- package/src/client/settings-page.js +62 -0
- package/src/client/sidebar-control-adapter.js +317 -0
- package/src/client/startup-sequence.js +366 -0
- package/src/client/status-projection.js +79 -0
- package/src/client/terrain-motion-adapter.js +188 -0
- package/src/client/theme-controller-v2.js +134 -0
- package/src/client/theme-controller.js +119 -0
- package/src/client/theme-settings-workbench.js +583 -0
- package/src/client/to-bottom-adapter.js +85 -0
- package/src/client/ui-store.js +23 -0
- package/src/index.js +4 -0
- package/src/styles/conversation-scale.css +471 -0
- package/src/styles/facility-vector.css +292 -0
- package/src/styles/prts.css +1223 -0
- package/src/styles/refinement.css +429 -0
- package/src/styles/stabilization.css +161 -0
- package/src/styles/startup-sequence.css +496 -0
- package/src/styles/theme-settings-workbench.css +803 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const CONTROL_ATTRIBUTE = 'data-prts-glass-control'
|
|
2
|
+
const MENU_ATTRIBUTE = 'data-prts-glass-menu'
|
|
3
|
+
const FALLBACK_COMPOSER_ATTRIBUTE = 'data-prts-composer-fallback'
|
|
4
|
+
const COMPOSER_SIGNAL_ATTRIBUTE = 'data-prts-composer-signal'
|
|
5
|
+
const COMPOSER_RELEVANCE_SELECTOR = [
|
|
6
|
+
'[data-composer-card]',
|
|
7
|
+
'form textarea',
|
|
8
|
+
'button[aria-haspopup="menu"]',
|
|
9
|
+
'button[aria-haspopup="listbox"]',
|
|
10
|
+
'[role="menu"]',
|
|
11
|
+
'[role="listbox"]',
|
|
12
|
+
'[data-slot="conversation.input.overlay"]',
|
|
13
|
+
].join(', ')
|
|
14
|
+
const PRESET_TRIGGER_SELECTOR = [
|
|
15
|
+
'[data-slot="conversation.hero.agentPreset"] button[aria-haspopup="menu"]',
|
|
16
|
+
'button[class*="cubgiG_seat"][aria-haspopup="menu"]',
|
|
17
|
+
].join(', ')
|
|
18
|
+
|
|
19
|
+
function mark(node, attribute, value) {
|
|
20
|
+
if (node?.nodeType === 1) node.setAttribute(attribute, value)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function controlledPopup(document, trigger) {
|
|
24
|
+
const id = trigger.getAttribute('aria-controls')
|
|
25
|
+
if (!id) return null
|
|
26
|
+
return document.getElementById(id)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function localPopup(trigger) {
|
|
30
|
+
const selector = '[role="menu"], [role="listbox"], [class*="mufS8W_card"]'
|
|
31
|
+
const sibling = trigger.nextElementSibling
|
|
32
|
+
if (sibling?.matches(selector)) return sibling
|
|
33
|
+
return trigger.parentElement?.querySelector(`:scope > ${selector}`) ?? null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function overlayPopup(document) {
|
|
37
|
+
const overlay = document.querySelector('[data-slot="conversation.input.overlay"]')
|
|
38
|
+
if (!overlay) return null
|
|
39
|
+
return overlay.querySelector('[role="listbox"], [role="menu"], [class*="mufS8W_card"]')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function linkedMenu(document, trigger) {
|
|
43
|
+
return controlledPopup(document, trigger)
|
|
44
|
+
?? localPopup(trigger)
|
|
45
|
+
?? overlayPopup(document)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function markPopup(popup, kind) {
|
|
49
|
+
if (!popup) return
|
|
50
|
+
mark(popup, MENU_ATTRIBUTE, kind)
|
|
51
|
+
const card = popup.closest?.('[class*="mufS8W_card"]')
|
|
52
|
+
mark(card, MENU_ATTRIBUTE, kind)
|
|
53
|
+
for (const nested of popup.querySelectorAll?.('[role="menu"], [role="listbox"], [class*="mufS8W_card"]') ?? []) {
|
|
54
|
+
mark(nested, MENU_ATTRIBUTE, kind)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function createComposerGlassAdapter({ document, window }) {
|
|
59
|
+
let observer
|
|
60
|
+
let scanFrame
|
|
61
|
+
const ownedFallbacks = new Set()
|
|
62
|
+
const ownedSignals = new Set()
|
|
63
|
+
|
|
64
|
+
function ensureSignal(composer) {
|
|
65
|
+
let signal = composer.querySelector?.(`:scope > [${COMPOSER_SIGNAL_ATTRIBUTE}]`)
|
|
66
|
+
if (signal) return signal
|
|
67
|
+
signal = document.createElement('span')
|
|
68
|
+
signal.setAttribute(COMPOSER_SIGNAL_ATTRIBUTE, '')
|
|
69
|
+
signal.setAttribute('aria-hidden', 'true')
|
|
70
|
+
composer.append(signal)
|
|
71
|
+
ownedSignals.add(signal)
|
|
72
|
+
return signal
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function mutationTouchesComposer(mutation) {
|
|
76
|
+
if (mutation.target?.closest?.('[data-composer-card], [data-prts-composer-fallback], [data-slot="conversation.input.overlay"]')) return true
|
|
77
|
+
for (const node of [...(mutation.addedNodes ?? []), ...(mutation.removedNodes ?? [])]) {
|
|
78
|
+
if (node?.nodeType !== 1) continue
|
|
79
|
+
if (node.matches?.(COMPOSER_RELEVANCE_SELECTOR) || node.querySelector?.(COMPOSER_RELEVANCE_SELECTOR)) return true
|
|
80
|
+
}
|
|
81
|
+
return mutation.type === 'attributes' && (
|
|
82
|
+
mutation.target?.matches?.(COMPOSER_RELEVANCE_SELECTOR)
|
|
83
|
+
|| mutation.target?.closest?.(PRESET_TRIGGER_SELECTOR)
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function onMutations(mutations) {
|
|
88
|
+
if (mutations.some(mutationTouchesComposer)) queueScan()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function queueScan() {
|
|
92
|
+
if (scanFrame !== undefined) return
|
|
93
|
+
const requestFrame = window?.requestAnimationFrame?.bind(window) ?? (callback => window?.setTimeout?.(callback, 0))
|
|
94
|
+
scanFrame = requestFrame(() => {
|
|
95
|
+
scanFrame = undefined
|
|
96
|
+
scan()
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function scan() {
|
|
101
|
+
for (const signal of [...ownedSignals]) {
|
|
102
|
+
if (signal.isConnected) continue
|
|
103
|
+
signal.remove?.()
|
|
104
|
+
ownedSignals.delete(signal)
|
|
105
|
+
}
|
|
106
|
+
for (const form of [...ownedFallbacks]) {
|
|
107
|
+
if (!form.isConnected || form.hasAttribute('data-composer-card')) {
|
|
108
|
+
form.removeAttribute?.(FALLBACK_COMPOSER_ATTRIBUTE)
|
|
109
|
+
ownedFallbacks.delete(form)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const fallbackForms = new Set(
|
|
113
|
+
[...(document?.querySelectorAll?.('form textarea') ?? [])]
|
|
114
|
+
.map(textarea => textarea.closest('form'))
|
|
115
|
+
.filter(form => form && !form.querySelector('[data-composer-card]')),
|
|
116
|
+
)
|
|
117
|
+
for (const form of fallbackForms) {
|
|
118
|
+
form.setAttribute(FALLBACK_COMPOSER_ATTRIBUTE, '')
|
|
119
|
+
ownedFallbacks.add(form)
|
|
120
|
+
}
|
|
121
|
+
const composers = [
|
|
122
|
+
...(document?.querySelectorAll?.('[data-composer-card]') ?? []),
|
|
123
|
+
...fallbackForms,
|
|
124
|
+
]
|
|
125
|
+
for (const composer of composers) {
|
|
126
|
+
ensureSignal(composer)
|
|
127
|
+
for (const menu of composer.querySelectorAll('[role="menu"], [role="listbox"]')) markPopup(menu, 'action')
|
|
128
|
+
|
|
129
|
+
for (const trigger of composer.querySelectorAll('button[aria-haspopup="menu"], button[aria-haspopup="listbox"]')) {
|
|
130
|
+
const menu = linkedMenu(document, trigger)
|
|
131
|
+
?? trigger.parentElement?.querySelector('[role="menu"][aria-busy], [role="listbox"][aria-busy]')
|
|
132
|
+
const isModel = trigger.matches('[class*="_7KE1Ra_"]')
|
|
133
|
+
|| menu?.hasAttribute('aria-busy')
|
|
134
|
+
const isCommands = trigger.getAttribute('aria-haspopup') === 'listbox'
|
|
135
|
+
|| trigger.getAttribute('aria-label') === 'Commands'
|
|
136
|
+
|| trigger.matches('[class*="uV2eYG_add"]')
|
|
137
|
+
const kind = isModel ? 'model' : isCommands ? 'action' : 'action'
|
|
138
|
+
mark(trigger, CONTROL_ATTRIBUTE, kind)
|
|
139
|
+
markPopup(menu, kind)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const permissionCandidates = [
|
|
143
|
+
...composer.querySelectorAll('button.Sh0Q9G_trigger'),
|
|
144
|
+
...composer.querySelectorAll('button[class*="Sh0Q9G_"]'),
|
|
145
|
+
]
|
|
146
|
+
for (const trigger of new Set(permissionCandidates)) {
|
|
147
|
+
mark(trigger, CONTROL_ATTRIBUTE, 'permission')
|
|
148
|
+
markPopup(linkedMenu(document, trigger), 'permission')
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (const popup of document?.querySelectorAll?.(`[${MENU_ATTRIBUTE}="preset"]`) ?? []) {
|
|
153
|
+
popup.removeAttribute(MENU_ATTRIBUTE)
|
|
154
|
+
}
|
|
155
|
+
for (const trigger of document?.querySelectorAll?.(PRESET_TRIGGER_SELECTOR) ?? []) {
|
|
156
|
+
mark(trigger, CONTROL_ATTRIBUTE, 'preset')
|
|
157
|
+
if (trigger.getAttribute('aria-expanded') !== 'true') continue
|
|
158
|
+
const popup = controlledPopup(document, trigger)
|
|
159
|
+
?? localPopup(trigger)
|
|
160
|
+
markPopup(popup, 'preset')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const overlay = document?.querySelector?.('[data-slot="conversation.input.overlay"]')
|
|
164
|
+
if (overlay) {
|
|
165
|
+
for (const popup of overlay.querySelectorAll('[role="menu"], [role="listbox"], [class*="mufS8W_card"]')) {
|
|
166
|
+
markPopup(popup, popup.hasAttribute('aria-busy') ? 'model' : 'action')
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function removeMarkers() {
|
|
172
|
+
for (const node of document?.querySelectorAll?.(`[${CONTROL_ATTRIBUTE}], [${MENU_ATTRIBUTE}]`) ?? []) {
|
|
173
|
+
node.removeAttribute(CONTROL_ATTRIBUTE)
|
|
174
|
+
node.removeAttribute(MENU_ATTRIBUTE)
|
|
175
|
+
}
|
|
176
|
+
for (const form of ownedFallbacks) form.removeAttribute?.(FALLBACK_COMPOSER_ATTRIBUTE)
|
|
177
|
+
ownedFallbacks.clear()
|
|
178
|
+
for (const signal of ownedSignals) signal.remove?.()
|
|
179
|
+
ownedSignals.clear()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
start() {
|
|
184
|
+
if (!document || observer) return
|
|
185
|
+
scan()
|
|
186
|
+
const Observer = window?.MutationObserver
|
|
187
|
+
if (!Observer) return
|
|
188
|
+
const observationRoot = document.querySelector('[data-prts-region="operation"]')
|
|
189
|
+
?? document.querySelector('[data-slot="conversation"]')
|
|
190
|
+
if (!observationRoot) return
|
|
191
|
+
observer = new Observer(onMutations)
|
|
192
|
+
observer.observe(observationRoot, {
|
|
193
|
+
subtree: true,
|
|
194
|
+
childList: true,
|
|
195
|
+
attributes: true,
|
|
196
|
+
attributeFilter: ['aria-controls', 'aria-expanded', 'aria-busy', 'class', 'role'],
|
|
197
|
+
})
|
|
198
|
+
},
|
|
199
|
+
dispose() {
|
|
200
|
+
observer?.disconnect()
|
|
201
|
+
observer = undefined
|
|
202
|
+
if (scanFrame !== undefined) {
|
|
203
|
+
if (window?.cancelAnimationFrame) window.cancelAnimationFrame(scanFrame)
|
|
204
|
+
else window?.clearTimeout?.(scanFrame)
|
|
205
|
+
}
|
|
206
|
+
scanFrame = undefined
|
|
207
|
+
removeMarkers()
|
|
208
|
+
},
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export const CONVERSATION_CONTROL_ATTRIBUTE = 'data-prts-conversation-control'
|
|
2
|
+
|
|
3
|
+
function hasClassSuffix(node, suffix) {
|
|
4
|
+
return [...(node?.classList ?? [])].some(token => token.endsWith(suffix))
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function closestWithClassSuffix(node, suffix) {
|
|
8
|
+
for (let current = node; current?.nodeType === 1; current = current.parentElement) {
|
|
9
|
+
if (hasClassSuffix(current, suffix)) return current
|
|
10
|
+
}
|
|
11
|
+
return null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function classify(button, operation) {
|
|
15
|
+
if (button.tagName !== 'BUTTON' || !operation.contains(button)) return null
|
|
16
|
+
if (hasClassSuffix(button, '_sessionLogButton')) return 'header'
|
|
17
|
+
if (button.closest('[data-produced-files-row]') || hasClassSuffix(button, '_showFolder')) return 'utility'
|
|
18
|
+
if (closestWithClassSuffix(button, '_older')) return 'utility'
|
|
19
|
+
if (hasClassSuffix(button, '_inspectButton')) return 'inspect'
|
|
20
|
+
|
|
21
|
+
const approval = button.closest('[data-approval-key]')
|
|
22
|
+
if (approval) return hasClassSuffix(button, '_reject') ? 'danger' : 'cta'
|
|
23
|
+
if (hasClassSuffix(button, '_modalAction') || button.closest('[role="dialog"]')) return 'cta'
|
|
24
|
+
|
|
25
|
+
if (button.closest('[data-chat-flow-kind], [data-message-role]')) return 'micro'
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createConversationControlAdapter({ document, window }) {
|
|
30
|
+
let observer
|
|
31
|
+
let operation
|
|
32
|
+
const owned = new Set()
|
|
33
|
+
const pending = new Set()
|
|
34
|
+
|
|
35
|
+
function collectButtons(node) {
|
|
36
|
+
if (node?.nodeType !== 1) return
|
|
37
|
+
if (node.tagName === 'BUTTON') pending.add(node)
|
|
38
|
+
for (const button of node.querySelectorAll?.('button') ?? []) pending.add(button)
|
|
39
|
+
const closest = node.closest?.('button')
|
|
40
|
+
if (closest) pending.add(closest)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function process(button) {
|
|
44
|
+
const kind = button?.isConnected ? classify(button, operation) : null
|
|
45
|
+
if (!kind) {
|
|
46
|
+
button?.removeAttribute?.(CONVERSATION_CONTROL_ATTRIBUTE)
|
|
47
|
+
owned.delete(button)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
button.setAttribute(CONVERSATION_CONTROL_ATTRIBUTE, kind)
|
|
51
|
+
owned.add(button)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function scan() {
|
|
55
|
+
for (const button of pending) process(button)
|
|
56
|
+
pending.clear()
|
|
57
|
+
for (const button of [...owned]) {
|
|
58
|
+
if (!button.isConnected) process(button)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function queueScan() {
|
|
63
|
+
scan()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function onMutations(mutations) {
|
|
67
|
+
for (const mutation of mutations) {
|
|
68
|
+
if (mutation.type === 'attributes') collectButtons(mutation.target)
|
|
69
|
+
for (const node of mutation.addedNodes ?? []) collectButtons(node)
|
|
70
|
+
for (const node of mutation.removedNodes ?? []) {
|
|
71
|
+
if (node?.nodeType !== 1) continue
|
|
72
|
+
for (const button of owned) {
|
|
73
|
+
if (button === node || node.contains?.(button)) pending.add(button)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (pending.size) queueScan()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function clear() {
|
|
81
|
+
for (const button of owned) button.removeAttribute?.(CONVERSATION_CONTROL_ATTRIBUTE)
|
|
82
|
+
owned.clear()
|
|
83
|
+
pending.clear()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
start() {
|
|
88
|
+
if (!document) return
|
|
89
|
+
operation = document.querySelector('[data-prts-region="operation"]')
|
|
90
|
+
if (!operation) return
|
|
91
|
+
collectButtons(operation)
|
|
92
|
+
scan()
|
|
93
|
+
if (observer || !window?.MutationObserver) return
|
|
94
|
+
observer = new window.MutationObserver(onMutations)
|
|
95
|
+
observer.observe(operation, {
|
|
96
|
+
subtree: true,
|
|
97
|
+
childList: true,
|
|
98
|
+
attributes: true,
|
|
99
|
+
attributeFilter: ['class', 'data-approval-key'],
|
|
100
|
+
})
|
|
101
|
+
},
|
|
102
|
+
dispose() {
|
|
103
|
+
observer?.disconnect()
|
|
104
|
+
observer = undefined
|
|
105
|
+
clear()
|
|
106
|
+
operation = undefined
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
}
|