Skip to content

Store ordinary relationship keys as exact type ID pairs - #64788

Open
Jake Bailey (jakebailey) wants to merge 1 commit into
mainfrom
jakebailey/mem/exact-relation-keys
Open

Jake Bailey (jakebailey) wants to merge 1 commit into
mainfrom
jakebailey/mem/exact-relation-keys

Conversation

@jakebailey

@jakebailey Jake Bailey (jakebailey) commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Ordinary comparisons only need two 32-bit type IDs, but each cached result stored a 128-bit hash.

  • Stores ordinary comparisons as exact 64-bit ID pairs; generic normalization keeps its full-width hash.
  • VS Code measurements showed 0.94% less retained heap and 1.29% fewer allocated bytes.

@typescript-automation typescript-automation Bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Oct 13, 2026
@jakebailey
Jake Bailey (jakebailey) added this pull request to stack #64792 October 13, 2026 17:37
@jakebailey Jake Bailey (jakebailey) changed the title Store ordinary relationship keys as exact type ID pairs Store ordinary relationship keys as exact type ID pairs Ordinary comparisons only need two 32-bit type IDs, but each cached result stored a 128-bit hash. - Stores ordinary comparisons as exact 64-bit ID pairs; generic normalization keeps its full-width hash. - VS Code measurements showed **0.94% less retained heap** and **1.29% fewer allocated bytes**. Oct 13, 2026
@jakebailey Jake Bailey (jakebailey) changed the title Store ordinary relationship keys as exact type ID pairs Ordinary comparisons only need two 32-bit type IDs, but each cached result stored a 128-bit hash. - Stores ordinary comparisons as exact 64-bit ID pairs; generic normalization keeps its full-width hash. - VS Code measurements showed **0.94% less retained heap** and **1.29% fewer allocated bytes**. Store ordinary relationship keys as exact type ID pairs Oct 13, 2026
@jakebailey
Jake Bailey (jakebailey) marked this pull request as ready for review October 13, 2026 17:42
Copilot AI balanced review requested due to automatic review settings October 13, 2026 17:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused cache representation change preserves existing semantics and has comprehensive unit coverage.

0 open findings

What changed in this PR

Optimizes relationship caching by storing ordinary comparisons as exact 64-bit type-ID pairs while preserving generic hashes.

Changes:

  • Splits ordinary and generic relation caches.
  • Packs ordinary type IDs into collision-free keys.
  • Adds coverage for key states, namespaces, and generic normalization.
File Description
tsc/​internal/​checker/​checker.go Generates packed ordinary keys and hashed generic keys.
tsc/​internal/​checker/​relater.go Implements separate relation caches.
tsc/​internal/​checker/​types_test.go Tests relation-key behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/indexed-type-node-caches branch from 6360afc to e7a1293 Compare October 13, 2026 18:36
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 98420cf to 46ffb18 Compare October 13, 2026 18:36
@jakebailey
Jake Bailey (jakebailey) marked this pull request as draft October 13, 2026 19:41
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/indexed-type-node-caches branch from e7a1293 to e46e706 Compare October 13, 2026 20:06
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 46ffb18 to 3b5631d Compare October 13, 2026 20:06
Base automatically changed from jakebailey/mem/indexed-type-node-caches to jakebailey/mem/compact-member-indexes October 13, 2026 20:06
@jakebailey
Jake Bailey (jakebailey) removed this pull request from stack #64792 October 13, 2026 20:15
@jakebailey
Jake Bailey (jakebailey) added this pull request to stack #64805 October 13, 2026 20:16
@jakebailey
Jake Bailey (jakebailey) removed this pull request from stack #64805 October 13, 2026 20:49
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from 5aa1029 to 621e8f2 Compare October 13, 2026 20:50
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 3b5631d to 2b8f9af Compare October 13, 2026 20:50
@jakebailey
Jake Bailey (jakebailey) added this pull request to stack #64806 October 13, 2026 20:50
@jakebailey
Jake Bailey (jakebailey) requested a balanced review from Copilot October 13, 2026 21:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The cache representation remains behaviorally equivalent and is well covered by focused tests.

0 open findings

🧠 Review effort: Balanced

@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 2b8f9af to f7addbf Compare October 13, 2026 21:39
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch 2 times, most recently from 0f3d124 to 11f0df8 Compare October 13, 2026 22:00
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from f7addbf to 2a5167f Compare October 13, 2026 22:00
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 2a5167f to 51be58b Compare October 13, 2026 22:25
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from 11f0df8 to 48d2bb2 Compare October 13, 2026 22:25
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 51be58b to f34f38a Compare October 13, 2026 23:08
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from 48d2bb2 to f2431d1 Compare October 13, 2026 23:08
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from f34f38a to e59a4dd Compare October 13, 2026 23:16
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch 2 times, most recently from d1038c7 to da3177f Compare October 13, 2026 23:18
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch 2 times, most recently from a15ee39 to a94e6ec Compare October 14, 2026 01:07
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from bf46f3e to c4938e8 Compare October 14, 2026 02:23
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch 2 times, most recently from 59c8a48 to ad1de82 Compare October 14, 2026 02:27
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from c4938e8 to 22ec779 Compare October 14, 2026 02:27
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from ad1de82 to 354885c Compare October 14, 2026 03:47
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from 22ec779 to 3654528 Compare October 14, 2026 03:47
@ahejlsberg
Anders Hejlsberg (ahejlsberg) force-pushed the jakebailey/mem/exact-relation-keys branch from 354885c to 0e30e19 Compare October 14, 2026 14:14
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 0e30e19 to 8455c76 Compare October 14, 2026 14:17
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/compact-member-indexes branch from 7265ad1 to 04c2a42 Compare October 14, 2026 14:17
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 8455c76 to 953c7fb Compare October 14, 2026 16:02
Ordinary type comparisons need only two 32-bit IDs and intersection
context, but retained a 128-bit hash for every cached result. Hashing
and storing twice the necessary key width wastes allocations and memory.

Keep exact 64-bit pairs in separate maps for the four intersection
states. Generic-reference normalization still uses its original
full-width hash. An explicit key tag separates both namespaces,
including recursion guards, without sacrificing hash bits or changing
constrained generic behavior.

Six fresh-process interleaved VS Code comparisons against the parent
commit, using normal GC, reduce retained heap 0.94% (roughly 33 MiB) and
total allocated bytes 1.29%. GC scanning, allocation events, and
instruction counts are not statistically different.

Tests cover directional and identity comparisons, all intersection
contexts, result replacement, exact high-bit IDs, namespace isolation,
generic parameter normalization, and constrained versus unconstrained
recursion keys.
Production diagnostics
and all semantic counts match exactly.

goos: linux
goarch: amd64
pkg: github.com/microsoft/TypeScript/tsc/internal/checker
cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz
                   │ vscode-relation-before-6.txt │       vscode-relation-6.txt        │
                   │          retained-B          │  retained-B   vs base              │
ExternalProgram-20                   3.456Gi ± 0%   3.424Gi ± 0%  -0.94% (p=0.002 n=6)

                   │ vscode-relation-before-6.txt │     vscode-relation-6.txt     │
                   │            scan-B            │    scan-B     vs base         │
ExternalProgram-20                   2.998Gi ± 0%   2.997Gi ± 0%  ~ (p=0.310 n=6)

                   │ vscode-relation-before-6.txt │       vscode-relation-6.txt        │
                   │             B/op             │     B/op      vs base              │
ExternalProgram-20                   5.021Gi ± 0%   4.956Gi ± 0%  -1.29% (p=0.002 n=6)

                   │ vscode-relation-before-6.txt │    vscode-relation-6.txt     │
                   │          allocs/op           │  allocs/op   vs base         │
ExternalProgram-20                    31.08M ± 0%   31.07M ± 0%  ~ (p=0.240 n=6)

                        │ relation-before-instructions.txt │    relation-instructions.txt     │
                        │         instructions/op          │ instructions/op  vs base         │
ExternalInstructions-20                        269.3G ± 2%       270.0G ± 3%  ~ (p=0.937 n=6)
@jakebailey
Jake Bailey (jakebailey) removed this pull request from stack #64806 October 14, 2026 16:55
@jakebailey
Jake Bailey (jakebailey) changed the base branch from jakebailey/mem/compact-member-indexes to main October 14, 2026 16:56
@jakebailey
Jake Bailey (jakebailey) force-pushed the jakebailey/mem/exact-relation-keys branch from 953c7fb to 8f3ee02 Compare October 14, 2026 16:56
@jakebailey
Jake Bailey (jakebailey) marked this pull request as ready for review October 14, 2026 16:58
@jakebailey

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) perf test this faster

@typescript-automation

typescript-automation Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
perf test this faster ✅ Started 👀 Results

@typescript-automation

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - native
Errors 41 41 ~ ~ ~ p=1.000 n=12
Symbols 115,276 115,276 ~ ~ ~ p=1.000 n=12
Types 79,613 79,613 ~ ~ ~ p=1.000 n=12
Memory Used 113,545k (± 0.07%) 109,969k (± 0.07%) 🟩-3,576k (- 3.15%) 109,808k 110,176k p=0.000 n=12
Memory Allocs 2,212,432 (± 0.00%) 2,212,662 (± 0.00%) +230 (+ 0.01%) 2,212,441 2,212,934 p=0.002 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.049s (± 3.59%) 0.048s (± 2.51%) ~ 0.046s 0.052s p=0.452 n=12
Bind Time 0.018s (± 9.02%) 0.018s (± 9.28%) ~ 0.014s 0.022s p=1.000 n=12
Check Time 0.580s (± 0.61%) 0.575s (± 0.39%) -0.006s (- 0.99%) 0.568s 0.580s p=0.013 n=12
Emit Time 0.327s (± 1.81%) 0.329s (± 2.11%) ~ 0.312s 0.348s p=0.701 n=12
Total Time 0.982s (± 0.70%) 0.978s (± 0.81%) ~ 0.962s 1.004s p=0.312 n=12
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=12
Symbols 847,226 (± 0.07%) 846,950 (± 0.08%) ~ 844,926 848,574 p=0.724 n=12
Types 247,031 (± 0.00%) 247,032 (± 0.00%) ~ 247,030 247,033 p=0.509 n=12
Memory Used 596,432k (± 0.02%) 595,377k (± 0.03%) -1,055k (- 0.18%) 595,026k 595,749k p=0.000 n=12
Memory Allocs 13,139,398 (± 0.03%) 13,137,888 (± 0.02%) ~ 13,134,614 13,149,070 p=0.443 n=12
Config Time 0.021s (± 5.35%) 0.021s (± 5.80%) ~ 0.020s 0.025s p=0.328 n=12
Parse Time 0.280s (± 2.70%) 0.299s (± 4.16%) 🔻+0.019s (+ 6.76%) 0.272s 0.331s p=0.010 n=12
Bind Time 0.112s (±11.33%) 0.110s (±14.11%) ~ 0.079s 0.140s p=0.919 n=12
Check Time 0s 0s ~ ~ ~ p=1.000 n=12
Emit Time 1.870s (± 1.54%) 1.950s (± 2.58%) 🔻+0.080s (+ 4.30%) 1.809s 2.113s p=0.006 n=12
Total Time 2.304s (± 1.60%) 2.400s (± 2.45%) 🔻+0.095s (+ 4.14%) 2.230s 2.564s p=0.006 n=12
mui-docs - native
Errors 11,405 11,405 ~ ~ ~ p=1.000 n=12
Symbols 4,331,835 4,331,835 ~ ~ ~ p=1.000 n=12
Types 1,370,520 1,370,520 ~ ~ ~ p=1.000 n=12
Memory Used 2,627,092k (± 0.05%) 2,613,311k (± 0.07%) -13,781k (- 0.52%) 2,609,490k 2,618,886k p=0.000 n=12
Memory Allocs 27,719,041 (± 0.04%) 27,701,574 (± 0.08%) ~ 27,642,825 27,783,172 p=0.052 n=12
Config Time 0.020s (± 1.21%) 0.020s (± 1.21%) ~ 0.020s 0.021s p=1.000 n=12
Parse Time 0.581s (± 2.64%) 0.582s (± 2.85%) ~ 0.538s 0.635s p=0.876 n=12
Bind Time 0.003s (±10.34%) 0.003s (±12.54%) ~ 0.002s 0.003s p=0.667 n=12
Check Time 8.784s (± 0.20%) 8.797s (± 0.46%) ~ 8.683s 8.907s p=0.561 n=12
Emit Time 0.733s (± 9.03%) 0.671s (±12.07%) ~ 0.506s 0.797s p=0.104 n=12
Total Time 11.040s (± 0.74%) 11.001s (± 0.92%) ~ 10.738s 11.296s p=0.235 n=12
strada-build-src - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,388,669 1,388,669 ~ ~ ~ p=1.000 n=12
Types 441,862 441,862 ~ ~ ~ p=1.000 n=12
Memory Used 1,306,717k (± 0.32%) 1,310,410k (± 0.53%) ~ 1,289,634k 1,330,242k p=0.319 n=12
Memory Allocs 78,222,085 (± 0.13%) 78,177,455 (± 0.12%) ~ 77,885,090 78,354,044 p=0.198 n=12
Config Time 0.004s (± 8.27%) 0.004s (± 9.39%) ~ 0.003s 0.004s p=0.131 n=12
Parse Time 0.258s (± 2.54%) 0.250s (± 2.63%) ~ 0.238s 0.270s p=0.066 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.757s (± 0.49%) 1.771s (± 0.57%) +0.015s (+ 0.83%) 1.747s 1.799s p=0.045 n=12
Emit Time 0.299s (± 4.45%) 0.298s (± 3.79%) ~ 0.261s 0.320s p=0.944 n=12
Total Time 20.641s (± 0.48%) 20.709s (± 0.42%) ~ 20.447s 20.899s p=0.410 n=12
strada-compiler - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 334,953 334,953 ~ ~ ~ p=1.000 n=12
Types 197,616 197,616 ~ ~ ~ p=1.000 n=12
Memory Used 247,539k (± 0.03%) 245,597k (± 0.02%) -1,942k (- 0.78%) 245,476k 245,724k p=0.000 n=12
Memory Allocs 4,329,761 (± 0.01%) 4,330,187 (± 0.01%) ~ 4,328,435 4,331,284 p=0.132 n=12
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=12
Parse Time 0.109s (± 5.49%) 0.113s (± 3.93%) ~ 0.101s 0.125s p=0.213 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 0.999s (± 0.63%) 1.005s (± 0.53%) ~ 0.993s 1.020s p=0.097 n=12
Emit Time 0.155s (± 3.81%) 0.152s (± 4.58%) ~ 0.134s 0.172s p=0.560 n=12
Total Time 1.319s (± 0.82%) 1.324s (± 0.76%) ~ 1.297s 1.354s p=0.599 n=12
ts-pre-modules - native
Errors 87 87 ~ ~ ~ p=1.000 n=12
Symbols 303,834 303,834 ~ ~ ~ p=1.000 n=12
Types 181,663 181,663 ~ ~ ~ p=1.000 n=12
Memory Used 215,216k (± 0.02%) 214,134k (± 0.03%) -1,082k (- 0.50%) 213,948k 214,313k p=0.000 n=12
Memory Allocs 1,401,471 (± 0.01%) 1,402,038 (± 0.04%) +567 (+ 0.04%) 1,401,424 1,405,006 p=0.003 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.095s (± 3.93%) 0.095s (± 3.26%) ~ 0.087s 0.102s p=0.921 n=12
Bind Time 0.041s (± 9.24%) 0.037s (± 8.30%) ~ 0.030s 0.047s p=0.116 n=12
Check Time 0.783s (± 0.58%) 0.797s (± 0.96%) +0.014s (+ 1.82%) 0.780s 0.815s p=0.007 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 0.935s (± 0.63%) 0.945s (± 0.52%) +0.010s (+ 1.09%) 0.933s 0.958s p=0.015 n=12
vscode - native
Errors 396 396 ~ ~ ~ p=1.000 n=12
Symbols 11,687,315 11,687,315 ~ ~ ~ p=1.000 n=12
Types 3,851,234 3,851,234 ~ ~ ~ p=1.000 n=12
Memory Used 5,515,025k (± 0.03%) 5,486,559k (± 0.01%) -28,466k (- 0.52%) 5,485,301k 5,489,348k p=0.000 n=12
Memory Allocs 56,199,448 (± 0.03%) 56,194,715 (± 0.02%) ~ 56,183,903 56,244,181 p=1.000 n=12
Config Time 0.075s (± 0.33%) 0.075s (± 0.38%) ~ 0.074s 0.075s p=1.000 n=12
Parse Time 1.751s (± 2.31%) 1.733s (± 2.25%) ~ 1.663s 1.887s p=0.590 n=12
Bind Time 0.634s (±12.35%) 0.670s (±12.33%) ~ 0.467s 0.843s p=0.590 n=12
Check Time 13.395s (± 0.96%) 13.292s (± 0.96%) -0.104s (- 0.77%) 13.111s 13.666s p=0.039 n=12
Emit Time 5.502s (± 6.95%) 5.524s (± 7.20%) ~ 4.329s 6.205s p=0.843 n=12
Total Time 21.448s (± 1.40%) 21.388s (± 1.43%) ~ 20.503s 21.921s p=0.671 n=12
webpack - native
Errors 584 584 ~ ~ ~ p=1.000 n=12
Symbols 1,299,351 1,299,351 ~ ~ ~ p=1.000 n=12
Types 598,360 598,360 ~ ~ ~ p=1.000 n=12
Memory Used 789,463k (± 0.02%) 784,952k (± 0.02%) -4,511k (- 0.57%) 784,639k 785,384k p=0.000 n=12
Memory Allocs 6,052,667 (± 0.02%) 6,053,819 (± 0.03%) ~ 6,050,780 6,059,881 p=0.378 n=12
Config Time 0.008s (± 4.38%) 0.007s (± 4.22%) ~ 0.007s 0.008s p=0.680 n=12
Parse Time 0.234s (± 2.93%) 0.238s (± 3.13%) ~ 0.218s 0.257s p=0.369 n=12
Bind Time 0.058s (± 8.39%) 0.059s (± 5.50%) ~ 0.054s 0.072s p=0.307 n=12
Check Time 1.636s (± 0.68%) 1.640s (± 0.31%) ~ 1.628s 1.652s p=1.000 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.965s (± 0.59%) 1.973s (± 0.53%) ~ 1.950s 2.002s p=0.325 n=12
xstate-main - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,062,854 1,062,854 ~ ~ ~ p=1.000 n=12
Types 390,845 390,845 ~ ~ ~ p=1.000 n=12
Memory Used 472,365k (± 0.03%) 470,658k (± 0.03%) -1,706k (- 0.36%) 470,291k 471,007k p=0.000 n=12
Memory Allocs 4,224,654 (± 0.06%) 4,224,527 (± 0.09%) ~ 4,215,223 4,236,159 p=0.887 n=12
Config Time 0.003s (±10.34%) 0.003s (± 6.23%) ~ 0.002s 0.003s p=0.590 n=12
Parse Time 0.138s (± 2.97%) 0.140s (± 2.69%) ~ 0.130s 0.147s p=0.557 n=12
Bind Time 0.043s (±14.09%) 0.040s (±11.46%) ~ 0.033s 0.050s p=0.501 n=12
Check Time 1.009s (± 0.95%) 1.009s (± 1.16%) ~ 0.985s 1.042s p=0.899 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.202s (± 0.96%) 1.200s (± 1.14%) ~ 1.169s 1.233s p=0.766 n=12
System info unknown
Hosts
  • native
Scenarios
  • Compiler-Unions - native
  • angular-1 - native
  • mui-docs - native
  • strada-build-src - native
  • strada-compiler - native
  • ts-pre-modules - native
  • vscode - native
  • webpack - native
  • xstate-main - native
Benchmark Name Iterations
Current pr 12
Baseline baseline 12

Developer Information:

Download Benchmarks

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants