Status Update
Comments
lu...@gmail.com <lu...@gmail.com> #2
This is not a replication
plugin problem, but a PluginLoader
issue:
- The replication plugin exposes an
ApiModule
in master - The
ApiModule
is loaded into theapiInjector
of theServerPlugin
- All the plugins with an
ApiModule
andapiInjector
are chained together
Whilst the start()
was fully implemented, the stop()
was not, see below:
protected void stop(PluginGuiceEnvironment env) {
if (serverManager != null) {
RequestContext oldContext = env.enter(this);
try {
serverManager.stop();
} finally {
env.exit(oldContext);
}
serverManager = null;
sysInjector = null;
sshInjector = null;
httpInjector = null;
}
}
There isn't anything that manages the apiInjector
therefore the unloading keeps the injections as-is. When the plugin is reloaded, then boom the injections are duplicated.
I know how to fix it, leave it with me!
lu...@gmail.com <lu...@gmail.com> #3
@Saša see an initial fix here:
This formally works, BUT isn't ready yet because in addition to keeping the old interface definition (acceptable IMHO) it also references the old classes, making the new reloaded code unreachable.
It is late now, will resume the efforts tomorrow.
lu...@gmail.com <lu...@gmail.com> #4
I believe the overall issue here is that, after ApiModule
, which is the lightweight version of the libModule exposing just an API.
The ApiModule
are supposed to be loaded only once and used as base injector for all plugins. When replication became an ApiModule
has lost its ability to be dynamically reloaded.
The best solution would be to introduce a new target in the replication plugin to generate the ApiModule
as standalone jar (e.g. replication-api.jar
) and leave the replication.jar
as a regular plugin.
We can also amend the x-plugin support in future versions of Gerrit to allow reloadable ApiModule
, but that is a much more complex exercise, because it involves the construction of a full dependency graph of the dependencies and reload all the dependent plugins when an ApiModule
is reoaded.
lu...@gmail.com <lu...@gmail.com> #5
Switching back the component to replication
; I have a possible solution that allows:
- Keeping the ability to use x-plugin communication to extend the replication plugin with
ApiModule
- Allow reloading the
replication.jar
dynamically and provide new code - Keeping the initial replication API implementation across reloads
@Saša @Darek please have a look at
lu...@gmail.com <lu...@gmail.com> #6
I have also finalised the check on the x-plugin management of the PluginLoader
for preventing a plugin with ApiModule
to be stopped, unloaded, reloaded or restarted:
They should be both ready for review!
jo...@gmail.com <jo...@gmail.com> #7
fa...@gmail.com <fa...@gmail.com> #8
Branch: master
commit 5e33f8344e3855478914a5c530a327f888bd8c8e
Author: Luca Milanesio <luca.milanesio@gmail.com>
Date: Sat Feb 10 21:55:12 2024
Decouple replication-api.jar from the main replication plugin
The Change Ib7a04eea5 made the whole replication plugin an ApiModule
which becomes the base injector for all plugins and forbids reloads,
(see the Iac2851022ea for enforcing it at Gerrit level)
even when there is no intention to use th extension points.
All plugins that expose an ApiModule have the following limitations:
- Cannot add extra dependencies
- Cannot be reloaded
- Are the base injectors for all plugins
The above limitations aren't acceptable for the whole replication
plugin when used standalone without extensions.
Define a new replication-api target that generates the sole ApiModule
needed for extending the replication plugin functionality.
All the classes that are part of the replication-api are moved
into a separate c.g.g.p.replication.api package so that can be
included in the replication-api.jar plugin.
The gerrit.war will continue to include only the replication.jar which
will still work out of the box. Anyone willing to customise its behaviour
through the API will have to build the replication-api target.
Also fix the MergedConfigResource that was assuming that the ApiModule
was always installed and was binding DynamicItem<ReplicationConfigOverrides>.
Bug:
Release-Notes: Decouple replication-api.jar from the main replication plugin
Change-Id: Ic432fc77daf1162368abd65f64c463e4ef4f5d6d
M BUILD
M src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
M src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadRunnable.java
M src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadSecureCredentialsFactoryDecorator.java
M src/main/java/com/googlesource/gerrit/plugins/replication/CreateProjectTask.java
M src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java
M src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
M src/main/java/com/googlesource/gerrit/plugins/replication/MergedConfigResource.java
M src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
M src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImpl.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationDestinations.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationExtensionPointModule.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdater.java
M src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
M src/main/java/com/googlesource/gerrit/plugins/replication/SshHelper.java
M src/main/java/com/googlesource/gerrit/plugins/replication/api/ApiModule.java
M src/main/java/com/googlesource/gerrit/plugins/replication/api/ConfigResource.java
M src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfig.java
M src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfigOverrides.java
M src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationPushFilter.java
M src/main/resources/Documentation/extension-point.md
M src/test/java/com/googlesource/gerrit/plugins/replication/AbstractConfigTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecoratorTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/FanoutConfigResourceTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/FileConfigResourceTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/MergedConfigResourceTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImplTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdaterTest.java
M src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageDaemon.java
M src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageIT.java
M src/test/java/com/googlesource/gerrit/plugins/replication/TestReplicationModule.java
lu...@gmail.com <lu...@gmail.com> #9
Branch: stable-3.9
commit 7d4ace2c7718c9632ad1f2d9dcbbb0a035642bbb
Author: Luca Milanesio <luca.milanesio@gmail.com>
Date: Sat Feb 10 01:21:08 2024
Do not allow unload/restart plugins with ApiModule
The ApiModule from plugins is used for creating the
base injectors for all other plugins and cannot be
unloaded without potentially breaking all the other
plugins that depend on them.
Block the start of the new plugin for avoiding
leaving the overall Guice stack in an inconsistent
state. Plugins with ApiModule need to be effectively
considered mandatory.
Release-Notes: Prevent reload of plugins with ApiModule
Bug:
Change-Id: Iac2851022ea34e52014c519eeef70ce6028f4fda
M java/com/google/gerrit/server/plugins/DisablePlugin.java
M java/com/google/gerrit/server/plugins/PluginLoader.java
M java/com/google/gerrit/server/plugins/ServerPlugin.java
M java/com/google/gerrit/sshd/commands/PluginRemoveCommand.java
lu...@gmail.com <lu...@gmail.com> #10
I've deployed the fix on
ap...@google.com <ap...@google.com> #11
Branch: stable-3.9
commit a1948ebf970ef0accfbd390627ace5704703d61d
Author: Fabio Ponciroli <ponch78@gmail.com>
Date: Wed Jan 03 20:16:55 2024
Test comment linking of imported changes
When importing changes from another server, the user in the comment
might not match the one in the change message.
The same user on different Gerrit instances might have different
account Ids.
To consolidate it, an entry in the external-ids account reverse lookup
need to be added [1].
The update of external-ids is a "manual" process, and until it is done,
any reference to a "not identifiable" user will default to a
placeholder one.
If this consolidation hasn't happened yet, when rendering
the change detail page, links between comments and change messages
can be broken.
This manifests with comments not displayed at all in change
log entries. It will happen for the broken change and all the
ones following it chronologically.
This wasn't considered as part of Ia478b891 and the exit conditions.
This test demonstrates the breaking scenario.
[1]:
Bug:
Release-Notes: skip
Change-Id: I72e3af09abd63b0c758744d69bab83b8448b2c7f
M javatests/com/google/gerrit/server/restapi/change/ListChangeCommentsTest.java
ap...@google.com <ap...@google.com> #12
Branch: stable-3.9
commit 3a2a6be3b75fbf3a79c7f4d0f9e01d79f29cee94
Author: Fabio Ponciroli <ponch78@gmail.com>
Date: Wed Jan 03 20:25:25 2024
Fix comments rendering with imported changes
Resetting change message counter if no commments are matched.
Imported changes might lead to situations where change messages and
comments don't always match.
Only skip setting the changeMessageId for the broken message
and start checking from the beginning of the change messages.
This fixes the test added in I72e3af09.
Bug:
Release-Notes: Fix comments rendering with imported changes
Change-Id: Ia3d693ac7ea9d38578814872ef33dd442ec0fdc9
M java/com/google/gerrit/server/CommentsUtil.java
M javatests/com/google/gerrit/server/restapi/change/ListChangeCommentsTest.java
ma...@gmail.com <ma...@gmail.com> #13
thanks, this fix improves the situation but it seems some comments in
- David's comment on patchset 3 from Jun 14, 2022 8:13 AM
- Luca's comment on patchset 6 from Oct 13 6:37 PM
- my comment on patchset 6 from Oct 14 10:42 PM
- several comments from Marcin on patchsets 10, 12, 14
ap...@google.com <ap...@google.com> #14
Branch: stable-3.9
commit e48379be9f19ef2150a32e0b8080ad15db5542ca
Author: Fabio Ponciroli <ponch78@gmail.com>
Date: Mon Jan 08 19:19:25 2024
Avoid to always scan comments from the beginning
This change Ia3d693ac resets the search of comments from
the beginning of the array when something goes wrong.
Starting from the last successful match is enough.
No need to always start from the beginning.
Bug:
Release-Notes: skip
Change-Id: I5e159d12bf0fab847c5b494d96972fd7669e0935
M java/com/google/gerrit/server/CommentsUtil.java
ma...@gmail.com <ma...@gmail.com> #15
thanks, with this patch applied on eclipse.gerrithub.io the problem seems to be fixed. I can now see all comments of the change.
Thanks for the fix :-)
Description
GerritHub/GitHub projects names: eclipse-jgit/jgit
Full URL exhibiting the problem:
Expected behavior: I posted 3 comments on this change and they should be displayed
Observed behavior:
3 empty comments are shown
Timestamp when the error occurred (include timezone): 2023-12-30 13:59 CET, 14:02 CET, 14:08 CET
Has this worked before? If yes, when? This always worked.
If applicable: screenshot of erroneous UI element:
If applicable: JavaScript console log (chrome: F12 > Console):
```
initResin
gr-app.js:24586 Runtime Info
gr-app.js:24586 Gerrit UI (PolyGerrit)
gr-app.js:24586 Gerrit Server Version: 3.9.1-4-gb871735b5a
5Failed to decode downloaded font: <URL>
194140:1 Failed to decode downloaded font:
194140:1 Failed to decode downloaded font:
194140:1 Failed to decode downloaded font:
194140:1 Failed to decode downloaded font:
194140:1 Failed to decode downloaded font:
5OTS parsing error: invalid sfntVersion: 1008813135
194140:1 OTS parsing error: invalid sfntVersion: 1008813135
194140:1 OTS parsing error: invalid sfntVersion: 1008813135
194140:1 OTS parsing error: invalid sfntVersion: 1008813135
194140:1 OTS parsing error: invalid sfntVersion: 1008813135
194140:1 OTS parsing error: invalid sfntVersion: 1008813135
gr-app.js:24586
GET
_fetchWithXsrfToken @ gr-app.js:24586
fetch @ gr-app.js:24586
(anonymous) @ gr-app.js:4121
schedule @ gr-app.js:24586
(anonymous) @ gr-app.js:24586
next @ gr-app.js:24586
(anonymous) @ gr-app.js:24586
schedule @ gr-app.js:24586
schedule @ gr-app.js:4121
fetch @ gr-app.js:4121
fetchRawJSON @ gr-app.js:4121
fetchJSON @ gr-app.js:4121
fetchCacheURL @ gr-app.js:4121
_fetchSharedCacheURL @ gr-app.js:24586
getAccountDetails @ gr-app.js:24586
getAccount @ gr-app.js:4566
fillDetails @ gr-app.js:4566
updated @ gr-app.js:4649
_$AE @ gr-app.js:1747
performUpdate @ gr-app.js:1747
scheduleUpdate @ gr-app.js:1747
_$EP @ gr-app.js:1747
await in _$EP (async)
requestUpdate @ gr-app.js:1747
_$Ev @ gr-app.js:1747
uh @ gr-app.js:1747
ep @ gr-app.js:1747
yS @ gr-app.js:4697
u @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
T @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
Qh @ gr-app.js:1747
update @ gr-app.js:1747
performUpdate @ gr-app.js:1747
scheduleUpdate @ gr-app.js:1747
_$EP @ gr-app.js:1747
await in _$EP (async)
requestUpdate @ gr-app.js:1747
set @ gr-app.js:1747
j @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
Qh @ gr-app.js:1747
update @ gr-app.js:1747
performUpdate @ gr-app.js:1747
scheduleUpdate @ gr-app.js:1747
_$EP @ gr-app.js:1747
await in _$EP (async)
requestUpdate @ gr-app.js:1747
set @ gr-app.js:1747
(anonymous) @ gr-app.js:20808
update @ gr-app.js:2459
(anonymous) @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.nextInfiniteTimeWindow @ gr-app.js:2459
next @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.nextInfiniteTimeWindow @ gr-app.js:2459
next @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.nextInfiniteTimeWindow @ gr-app.js:2459
next @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
setState @ gr-app.js:2459
modifyState @ gr-app.js:10991
reloadComments @ gr-app.js:10991
await in reloadComments (async)
reloadAllComments @ gr-app.js:10991
(anonymous) @ gr-app.js:10991
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._subscribe @ gr-app.js:2459
e._trySubscribe @ gr-app.js:2459
t._trySubscribe @ gr-app.js:2459
e.subscribe @ gr-app.js:2459
(anonymous) @ gr-app.js:2459
e.subscribe @ gr-app.js:2459
aT @ gr-app.js:10991
(anonymous) @ gr-app.js:24586
(anonymous) @ gr-app.js:24586
get @ gr-app.js:2459
n @ gr-app.js:2459
Lf.showFindingsTab @ gr-app.js:20808
hostConnected @ gr-app.js:2459
(anonymous) @ gr-app.js:1747
connectedCallback @ gr-app.js:1747
connectedCallback @ gr-app.js:1747
connectedCallback @ gr-app.js:20808
k @ gr-app.js:1747
$ @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
p @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
Qh @ gr-app.js:1747
update @ gr-app.js:1747
performUpdate @ gr-app.js:1747
scheduleUpdate @ gr-app.js:1747
_$EP @ gr-app.js:1747
await in _$EP (async)
requestUpdate @ gr-app.js:1747
set @ gr-app.js:1747
(anonymous) @ gr-app.js:24436
update @ gr-app.js:2459
(anonymous) @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.nextInfiniteTimeWindow @ gr-app.js:2459
next @ gr-app.js:2459
t.__tryOrUnsub @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t._next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
t.next @ gr-app.js:2459
setState @ gr-app.js:2459
setState @ gr-app.js:24364
handleChangeRoute @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
Promise.then (async)
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
loadUserMiddleware @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
(anonymous) @ gr-app.js:24364
r @ gr-app.js:24364
dispatch @ gr-app.js:24364
replace @ gr-app.js:24364
start @ gr-app.js:24364
startRouter @ gr-app.js:24364
start @ gr-app.js:24364
connectedCallback @ gr-app.js:24436
k @ gr-app.js:1747
$ @ gr-app.js:1747
g @ gr-app.js:1747
_$AI @ gr-app.js:1747
Qh @ gr-app.js:1747
update @ gr-app.js:1747
performUpdate @ gr-app.js:1747
scheduleUpdate @ gr-app.js:1747
_$EP @ gr-app.js:1747
await in _$EP (async)
requestUpdate @ gr-app.js:1747
_$Ev @ gr-app.js:1747
uh @ gr-app.js:1747
ep @ gr-app.js:1747
JU @ gr-app.js:24586
(anonymous) @ gr-app.js:1918
XU @ gr-app.js:24586
(anonymous) @ gr-app.js:24586
syntax-worker.js:1 Deprecated as of 10.7.0. highlight(lang, code, ...args) has been deprecated.
syntax-worker.js:1 Deprecated as of 10.7.0. Please use highlight(code, options) instead.
194140:1 The resource
```
If applicable: Browser (name, version, operating system)
Chrome 120.0.6099.129 (Official Build) (arm64), MacOS 14.2
If using git command-line: output of "which git && git --version"