Repository: linkerd/linkerd2
Pull request #14242 (2025-07-14 03:45:41)

build(deps): bump golang.org/x/tools from 0.34.0 to 0.35.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.34.0 to 0.35.0.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/golang/tools/commit/50ec2f15fda46d8960c1d871856265127b4dcce5"><code>50ec2f1</code></a> go.mod: update golang.org/x dependencies</li>
<li><a href="https://github.com/golang/tools/commit/197c6c1b47160df25b9cd6598d88525c27a01e5a"><code>197c6c1</code></a> gopls/internal/mcp: more tuning of tools and prompts</li>
<li><a href="https://github.com/golang/tools/commit/9563af690255d5b5f7802773c0853f1176130da4"><code>9563af6</code></a> gopls/internal/mcp: include module paths in workspace summaries</li>
<li><a href="https://github.com/golang/tools/commit/88a4eb3018821e07f501b483e0f6f4eac4146198"><code>88a4eb3</code></a> gopls/internal/cmd: wait for startup log in TestMCPCommandHTTP</li>
<li><a href="https://github.com/golang/tools/commit/4738c7c0b1a53ae0c0fa248a8c31d2a07922dc9b"><code>4738c7c</code></a> gopls/internal/cmd: avoid the use of channels in the sessions API</li>
<li><a href="https://github.com/golang/tools/commit/ae1841752658d1d164b5926e72b2b0751fe5db17"><code>ae18417</code></a> gopls/internal/filewatcher: skip test for unsupported OS</li>
<li><a href="https://github.com/golang/tools/commit/8391b17713e95ac9bc23d8de7c0303b11c4a190b"><code>8391b17</code></a> gopls/doc: document Zed editor</li>
<li><a href="https://github.com/golang/tools/commit/778fe21d5d9f021763cced9defde671c6329d921"><code>778fe21</code></a> gopls/internal/util/tokeninternal: move from internal/tokeninternal</li>
<li><a href="https://github.com/golang/tools/commit/0343b7064dcefd5b28e53395fa70768990cc71fb"><code>0343b70</code></a> internal/jsonrpc2/stack: move from internal/stack</li>
<li><a href="https://github.com/golang/tools/commit/8c9f4cc0c2a00d508755a558cf73e0dab8d78863"><code>8c9f4cc</code></a> gopls/internal/filewatcher: refactor filewatcher to pass in handler func</li>
<li>Additional commits viewable in <a href="https://github.com/golang/tools/compare/v0.34.0...v0.35.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/tools&package-manager=go_modules&previous-version=0.34.0&new-version=0.35.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 4f480ad29..84ca0598f 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -9,7 +9,7 @@ jobs:
     runs-on: ubuntu-24.04
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
-      - uses: tj-actions/changed-files@5f66af5912c4f9c360c03a612f98606fb0f83790
+      - uses: tj-actions/changed-files@055970845dd036d7345da7399b7e89f2e10f2b04
         id: changed
         with:
           files: |
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 8f62a08eb..371acc825 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -29,7 +29,7 @@ jobs:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
       - id: tag
         run: echo "tag=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> "$GITHUB_OUTPUT"
-      - uses: tj-actions/changed-files@5f66af5912c4f9c360c03a612f98606fb0f83790
+      - uses: tj-actions/changed-files@055970845dd036d7345da7399b7e89f2e10f2b04
         id: core
         with:
           files: |
diff --git a/.gitignore b/.gitignore
index 55ceac7c1..31b2b6d21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,6 @@ web/app/js/locales/_build
 web/app/js/locales/**/*.js
 web/app/yarn-error.log
 vendor
-**/*.gogen*
 **/*.swp
 **/charts/**/charts
 package-lock.json
diff --git a/Cargo.lock b/Cargo.lock
index 1f9abb302..e01b140c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -410,9 +410,29 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
 
 [[package]]
 name = "delegate"
-version = "0.13.3"
+version = "0.13.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21"
+checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "derive_more"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -646,9 +666,9 @@ dependencies = [
 
 [[package]]
 name = "gateway-api"
-version = "0.15.0"
+version = "0.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ea401eaa9802293115029b448ef0f13ebc39cccfd9651aa2abac084aa4f4bef"
+checksum = "4369c3e046bbeb9c1eadb2a3e954ba7f0fbdbea165c96b7a0e698ac381b736d4"
 dependencies = [
  "delegate",
  "k8s-openapi",
@@ -1120,23 +1140,22 @@ dependencies = [
 
 [[package]]
 name = "k8s-openapi"
-version = "0.24.0"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c75b990324f09bef15e791606b7b7a296d02fc88a344f6eba9390970a870ad5"
+checksum = "aa60a41b57ae1a0a071af77dbcf89fc9819cfe66edaf2beeb204c34459dcf0b2"
 dependencies = [
  "base64",
  "chrono",
  "schemars",
  "serde",
- "serde-value",
  "serde_json",
 ]
 
 [[package]]
 name = "kube"
-version = "0.99.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a4eb20010536b48abe97fec37d23d43069bcbe9686adcf9932202327bc5ca6e"
+checksum = "778f98664beaf4c3c11372721e14310d1ae00f5e2d9aabcf8906c881aa4e9f51"
 dependencies = [
  "k8s-openapi",
  "kube-client",
@@ -1147,9 +1166,9 @@ dependencies = [
 
 [[package]]
 name = "kube-client"
-version = "0.99.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fc2ed952042df20d15ac2fe9614d0ec14b6118eab89633985d4b36e688dccf1"
+checksum = "7cb276b85b6e94ded00ac8ea2c68fcf4697ea0553cb25fddc35d4a0ab718db8d"
 dependencies = [
  "base64",
  "bytes",
@@ -1187,11 +1206,12 @@ dependencies = [
 
 [[package]]
 name = "kube-core"
-version = "0.99.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff0d0793db58e70ca6d689489183816cb3aa481673e7433dc618cf7e8007c675"
+checksum = "e3c56ff45deb0031f2a476017eed60c06872251f271b8387ad8020b8fef60960"
 dependencies = [
  "chrono",
+ "derive_more",
  "form_urlencoded",
  "http",
  "json-patch",
@@ -1205,9 +1225,9 @@ dependencies = [
 
 [[package]]
 name = "kube-derive"
-version = "0.99.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c562f58dc9f7ca5feac8a6ee5850ca221edd6f04ce0dd2ee873202a88cd494c9"
+checksum = "079fc8c1c397538628309cfdee20696ebdcc26745f9fb17f89b78782205bd995"
 dependencies = [
  "darling",
  "proc-macro2",
@@ -1219,14 +1239,13 @@ dependencies = [
 
 [[package]]
 name = "kube-runtime"
-version = "0.99.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88f34cfab9b4bd8633062e0e85edb81df23cb09f159f2e31c60b069ae826ffdc"
+checksum = "2f1326e946fadf6248febdf8a1c001809c3899ccf48cb9768cbc536b741040dc"
 dependencies = [
  "ahash",
  "async-broadcast",
  "async-stream",
- "async-trait",
  "backon",
  "educe",
  "futures",
@@ -1247,9 +1266,9 @@ dependencies = [
 
 [[package]]
 name = "kubert"
-version = "0.24.0"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92cbeb0adfdf2706c4f85f0d63e01b6535d44e150f5963289cd4b8bc0115fe5"
+checksum = "6c9f0a6d5aea62e120a6875be7d06f74c2ff4e8f33c40cfc331b4adee2f93a76"
 dependencies = [
  "ahash",
  "backon",
diff --git a/Cargo.toml b/Cargo.toml
index 745024017..71e21b744 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,12 +15,12 @@ members = [
 lto = "thin"
 
 [workspace.dependencies]
-gateway-api = "0.15"
+gateway-api = "0.16"
 http = "1"
 hyper = "1"
-k8s-openapi = { version = "0.24", features = ["v1_32"] }
-kube = { version = "0.99", default-features = false }
-kubert = { version = "0.24", default-features = false }
+k8s-openapi = { version = "0.25", features = ["v1_33"] }
+kube = { version = "1.1", default-features = false }
+kubert = { version = "0.25", default-features = false }
 prometheus-client = { version = "0.23", default-features = false }
 tonic = { version = "0.12", default-features = false }
 tower = { version = "0.5", default-features = false }
diff --git a/bin/build-cli-bin b/bin/build-cli-bin
index 892dc6648..44d9500ad 100755
--- a/bin/build-cli-bin
+++ b/bin/build-cli-bin
@@ -17,12 +17,7 @@ rootdir=$( cd "$bindir"/.. && pwd )
     cd "$rootdir"
     cd "$(pwd -P)"
     target=target/cli/$(os)/linkerd
-     # TODO: `go generate` does not honor -mod=readonly
-    GO111MODULE=on go generate -mod=readonly ./pkg/charts/static
-    GO111MODULE=on go generate -mod=readonly ./jaeger/static
-    GO111MODULE=on go generate -mod=readonly ./multicluster/static
-    GO111MODULE=on go generate -mod=readonly ./viz/static
-    
+
     root_tag=$("$bindir"/root-tag)
     GO111MODULE=on CGO_ENABLED=0 go build -o "$target" -tags prod -mod=readonly -ldflags "-s -w -X github.com/linkerd/linkerd2/pkg/version.Version=$root_tag" ./cli
     echo "$target"
diff --git a/charts/templates.go b/charts/templates.go
new file mode 100644
index 000000000..3e5761bbc
--- /dev/null
+++ b/charts/templates.go
@@ -0,0 +1,8 @@
+package charts
+
+import (
+	"embed"
+)
+
+//go:embed linkerd-control-plane linkerd-crds linkerd2-cni all:partials patch
+var Templates embed.FS
diff --git a/cli/Dockerfile b/cli/Dockerfile
index c81073702..e2077eed2 100644
--- a/cli/Dockerfile
+++ b/cli/Dockerfile
@@ -22,13 +22,6 @@ COPY controller/api controller/api
 COPY controller/gen controller/gen
 COPY pkg pkg
 
-# Generate static templates
-# TODO: `go generate` does not honor -mod=readonly
-RUN go generate -mod=readonly ./pkg/charts/static
-RUN go generate -mod=readonly ./jaeger/static
-RUN go generate -mod=readonly ./multicluster/static
-RUN go generate -mod=readonly ./viz/static
-
 RUN mkdir -p /out
 
 FROM go-gen AS linux-amd64-full
diff --git a/cli/cmd/install-cni-plugin.go b/cli/cmd/install-cni-plugin.go
index 1b1906e60..eb8e19698 100644
--- a/cli/cmd/install-cni-plugin.go
+++ b/cli/cmd/install-cni-plugin.go
@@ -6,9 +6,9 @@ import (
 	"os"
 	"strings"
 
-	"github.com/linkerd/linkerd2/pkg/charts"
+	"github.com/linkerd/linkerd2/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	cnicharts "github.com/linkerd/linkerd2/pkg/charts/cni"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
 	"github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/version"
@@ -249,13 +249,13 @@ func renderCNIPlugin(w io.Writer, valOpts values.Options, config *cniPluginOptio
 		{Name: "templates/cni-plugin.yaml"},
 	}
 
-	ch := &charts.Chart{
+	ch := &chartspkg.Chart{
 		Name:      helmCNIDefaultChartName,
 		Dir:       helmCNIDefaultChartDir,
 		Namespace: defaultCNINamespace,
 		Values:    mergedValues,
 		Files:     files,
-		Fs:        static.Templates,
+		Fs:        charts.Templates,
 	}
 
 	buf, err := ch.RenderCNI()
diff --git a/cli/cmd/install.go b/cli/cmd/install.go
index 7060b954d..1889368d5 100644
--- a/cli/cmd/install.go
+++ b/cli/cmd/install.go
@@ -13,10 +13,10 @@ import (
 	"text/template"
 	"time"
 
+	"github.com/linkerd/linkerd2/charts"
 	"github.com/linkerd/linkerd2/cli/flag"
-	"github.com/linkerd/linkerd2/pkg/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	flagspkg "github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/healthcheck"
@@ -331,14 +331,11 @@ func isRunAsRoot(values map[string]interface{}) bool {
 // them into a buffer. The coalesced values are also returned so that they may be rendered via
 // `renderOverrides` if appropriate.
 func renderChartToBuffer(files []*loader.BufferedFile, values map[string]interface{}, valuesOverrides map[string]interface{}) (*bytes.Buffer, chartutil.Values, error) {
-	// Load the partials in addition to the main chart.
-	var partials []*loader.BufferedFile
-	for _, template := range charts.L5dPartials {
-		partials = append(partials, &loader.BufferedFile{Name: template})
-	}
-	if err := charts.FilesReader(static.Templates, "", partials); err != nil {
+	partials, err := chartspkg.LoadPartials()
+	if err != nil {
 		return nil, nil, err
 	}
+
 	chart, err := loader.LoadFiles(append(files, partials...))
 	if err != nil {
 		return nil, nil, err
@@ -435,13 +432,13 @@ func renderCRDs(ctx context.Context, k *k8s.KubernetesAPI, w io.Writer, options
 	for _, template := range TemplatesCrdFiles {
 		files = append(files, &loader.BufferedFile{Name: template})
 	}
-	if err := charts.FilesReader(static.Templates, l5dcharts.HelmChartDirCrds+"/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, l5dcharts.HelmChartDirCrds+"/", files); err != nil {
 		return err
 	}
 
 	// Load defaults from values.yaml
 	valuesFile := &loader.BufferedFile{Name: l5dcharts.HelmChartDirCrds + "/values.yaml"}
-	if err := charts.ReadFile(static.Templates, "/", valuesFile); err != nil {
+	if err := chartspkg.ReadFile(charts.Templates, "", valuesFile); err != nil {
 		return err
 	}
 	// Ensure the map is not nil, even if the default `values.yaml` is empty ---
@@ -470,7 +467,7 @@ func renderCRDs(ctx context.Context, k *k8s.KubernetesAPI, w io.Writer, options
 		}
 
 		defaultValues = updateDefaultValues(installed, defaultValues)
-		finalValues := charts.MergeMaps(defaultValues, valuesOverrides)
+		finalValues := chartspkg.MergeMaps(defaultValues, valuesOverrides)
 
 		if err := validateFinalValues(installed, finalValues); err != nil {
 			return err
@@ -492,7 +489,7 @@ func renderControlPlane(w io.Writer, values *l5dcharts.Values, valuesOverrides m
 	for _, template := range TemplatesControlPlane {
 		files = append(files, &loader.BufferedFile{Name: template})
 	}
-	if err := charts.FilesReader(static.Templates, l5dcharts.HelmChartDirCP+"/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, l5dcharts.HelmChartDirCP+"/", files); err != nil {
 		return err
 	}
 
diff --git a/controller/Dockerfile b/controller/Dockerfile
index 283bd8969..986277143 100644
--- a/controller/Dockerfile
+++ b/controller/Dockerfile
@@ -14,14 +14,12 @@ FROM go-deps AS golang
 WORKDIR /linkerd-build
 COPY controller/gen controller/gen
 COPY pkg pkg
+COPY charts charts
 COPY controller controller
 COPY charts/patch charts/patch
 COPY charts/partials charts/partials
 COPY multicluster multicluster
 
-# Generate static templates
-# TODO: `go generate` does not honor -mod=readonly
-RUN go generate -mod=readonly ./pkg/charts/static
 ARG TARGETARCH
 RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o /out/controller -tags prod -mod=readonly -ldflags "-s -w" ./controller/cmd
 
diff --git a/go.mod b/go.mod
index 710f6d432..84512283d 100644
--- a/go.mod
+++ b/go.mod
@@ -36,7 +36,7 @@ require (
 	github.com/spf13/pflag v1.0.6
 	go.opencensus.io v0.24.0
 	golang.org/x/net v0.42.0
-	golang.org/x/tools v0.34.0
+	golang.org/x/tools v0.35.0
 	google.golang.org/grpc v1.73.0
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
 	google.golang.org/protobuf v1.36.6
@@ -135,13 +135,14 @@ require (
 	go.yaml.in/yaml/v2 v2.4.2 // indirect
 	go.yaml.in/yaml/v3 v3.0.3 // indirect
 	golang.org/x/crypto v0.40.0 // indirect
-	golang.org/x/mod v0.25.0 // indirect
+	golang.org/x/mod v0.26.0 // indirect
 	golang.org/x/oauth2 v0.30.0 // indirect
 	golang.org/x/sync v0.16.0 // indirect
 	golang.org/x/sys v0.34.0 // indirect
 	golang.org/x/term v0.33.0 // indirect
 	golang.org/x/text v0.27.0 // indirect
 	golang.org/x/time v0.9.0 // indirect
+	golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
 	google.golang.org/api v0.143.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
diff --git a/go.sum b/go.sum
index bec3c54e2..08d9d7da8 100644
--- a/go.sum
+++ b/go.sum
@@ -492,8 +492,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
-golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
+golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
+golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -607,8 +607,12 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
-golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
+golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
+golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
+golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY=
+golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
+golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
+golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/jaeger/charts/templates.go b/jaeger/charts/templates.go
new file mode 100644
index 000000000..7a24a2f31
--- /dev/null
+++ b/jaeger/charts/templates.go
@@ -0,0 +1,8 @@
+package charts
+
+import (
+	"embed"
+)
+
+//go:embed linkerd-jaeger
+var Templates embed.FS
diff --git a/jaeger/cmd/install.go b/jaeger/cmd/install.go
index 58f05dc75..d310f5a1e 100644
--- a/jaeger/cmd/install.go
+++ b/jaeger/cmd/install.go
@@ -8,9 +8,8 @@ import (
 	"path"
 	"time"
 
-	"github.com/linkerd/linkerd2/jaeger/static"
-	"github.com/linkerd/linkerd2/pkg/charts"
-	partials "github.com/linkerd/linkerd2/pkg/charts/static"
+	"github.com/linkerd/linkerd2/jaeger/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/healthcheck"
@@ -126,20 +125,13 @@ func render(w io.Writer, valuesOverrides map[string]interface{}, registry string
 		)
 	}
 
-	var partialFiles []*loader.BufferedFile
-	for _, template := range charts.L5dPartials {
-		partialFiles = append(partialFiles,
-			&loader.BufferedFile{Name: template},
-		)
-	}
-
 	// Load all jaeger chart files into buffer
-	if err := charts.FilesReader(static.Templates, "linkerd-jaeger/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, "linkerd-jaeger/", files); err != nil {
 		return err
 	}
 
-	// Load all partial chart files into buffer
-	if err := charts.FilesReader(partials.Templates, "", partialFiles); err != nil {
+	partialFiles, err := chartspkg.LoadPartials()
+	if err != nil {
 		return err
 	}
 
@@ -154,7 +146,7 @@ func render(w io.Writer, valuesOverrides map[string]interface{}, registry string
 		return err
 	}
 
-	vals, err = charts.InsertVersionValues(vals)
+	vals, err = chartspkg.InsertVersionValues(vals)
 	if err != nil {
 		return err
 	}
diff --git a/jaeger/static/generate.go b/jaeger/static/generate.go
deleted file mode 100644
index cb0637209..000000000
--- a/jaeger/static/generate.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build ignore
-
-package main
-
-import (
-	"github.com/linkerd/linkerd2/jaeger/static"
-	"github.com/shurcooL/vfsgen"
-	log "github.com/sirupsen/logrus"
-)
-
-func main() {
-	err := vfsgen.Generate(static.Templates, vfsgen.Options{
-		Filename:     "generated_jaeger_templates.gogen.go",
-		PackageName:  "static",
-		BuildTags:    "prod",
-		VariableName: "Templates",
-	})
-	if err != nil {
-		log.Fatalln(err)
-	}
-}
diff --git a/jaeger/static/templates.go b/jaeger/static/templates.go
deleted file mode 100644
index a132ddda4..000000000
--- a/jaeger/static/templates.go
+++ /dev/null
@@ -1,15 +0,0 @@
-//go:generate go run generate.go
-//go:build !prod
-
-package static
-
-import (
-	"net/http"
-	"path"
-
-	"github.com/linkerd/linkerd2/pkg/charts/static"
-)
-
-// Templates that will be rendered by `linkerd install`. This is only used on
-// dev builds.
-var Templates http.FileSystem = http.Dir(path.Join(static.GetRepoRoot(), "jaeger/charts"))
diff --git a/multicluster/charts/templates.go b/multicluster/charts/templates.go
new file mode 100644
index 000000000..1c6ee6d1f
--- /dev/null
+++ b/multicluster/charts/templates.go
@@ -0,0 +1,8 @@
+package charts
+
+import (
+	"embed"
+)
+
+//go:embed linkerd-multicluster linkerd-multicluster-link
+var Templates embed.FS
diff --git a/multicluster/cmd/allow.go b/multicluster/cmd/allow.go
index 5d955c879..760593d42 100644
--- a/multicluster/cmd/allow.go
+++ b/multicluster/cmd/allow.go
@@ -5,9 +5,9 @@ import (
 	"errors"
 	"fmt"
 
-	"github.com/linkerd/linkerd2/multicluster/static"
+	"github.com/linkerd/linkerd2/multicluster/charts"
 	mccharts "github.com/linkerd/linkerd2/multicluster/values"
-	"github.com/linkerd/linkerd2/pkg/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"github.com/linkerd/linkerd2/pkg/version"
@@ -59,13 +59,13 @@ func newAllowCommand() *cobra.Command {
 				{Name: "templates/remote-access-service-mirror-rbac.yaml"},
 			}
 
-			chart := &charts.Chart{
-				Name:      helmMulticlusterDefaultChartName,
-				Dir:       helmMulticlusterDefaultChartName,
+			chart := &chartspkg.Chart{
+				Name:      mccharts.HelmDefaultChartDir,
+				Dir:       mccharts.HelmDefaultChartDir,
 				Namespace: opts.namespace,
 				RawValues: rawValues,
 				Files:     files,
-				Fs:        static.Templates,
+				Fs:        charts.Templates,
 			}
 			buf, err := chart.Render()
 			if err != nil {
diff --git a/multicluster/cmd/install.go b/multicluster/cmd/install.go
index 8365b4ccc..a90b0dc96 100644
--- a/multicluster/cmd/install.go
+++ b/multicluster/cmd/install.go
@@ -11,10 +11,9 @@ import (
 	"strings"
 	"time"
 
-	"github.com/linkerd/linkerd2/multicluster/static"
+	"github.com/linkerd/linkerd2/multicluster/charts"
 	multicluster "github.com/linkerd/linkerd2/multicluster/values"
-	"github.com/linkerd/linkerd2/pkg/charts"
-	partials "github.com/linkerd/linkerd2/pkg/charts/static"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/healthcheck"
@@ -137,7 +136,7 @@ func install(ctx context.Context, w io.Writer, options *multiclusterInstallOptio
 	}
 
 	if ha {
-		valuesOverrides, err = charts.OverrideFromFile(valuesOverrides, static.Templates, helmMulticlusterDefaultChartName, "values-ha.yaml")
+		valuesOverrides, err = chartspkg.OverrideFromFile(valuesOverrides, charts.Templates, multicluster.HelmDefaultChartDir, "values-ha.yaml")
 		if err != nil {
 			return err
 		}
@@ -156,20 +155,13 @@ func render(w io.Writer, values *multicluster.Values, valuesOverrides map[string
 		files = append(files, &loader.BufferedFile{Name: template})
 	}
 
-	var partialFiles []*loader.BufferedFile
-	for _, template := range charts.L5dPartials {
-		partialFiles = append(partialFiles,
-			&loader.BufferedFile{Name: template},
-		)
-	}
-
 	// Load all multicluster install chart files into buffer
-	if err := charts.FilesReader(static.Templates, helmMulticlusterDefaultChartName+"/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, multicluster.HelmDefaultChartDir+"/", files); err != nil {
 		return err
 	}
 
-	// Load all partial chart files into buffer
-	if err := charts.FilesReader(partials.Templates, "", partialFiles); err != nil {
+	partialFiles, err := chartspkg.LoadPartials()
+	if err != nil {
 		return err
 	}
 
diff --git a/multicluster/cmd/link.go b/multicluster/cmd/link.go
index 3511b39db..d21476504 100644
--- a/multicluster/cmd/link.go
+++ b/multicluster/cmd/link.go
@@ -10,10 +10,9 @@ import (
 	"strings"
 
 	"github.com/linkerd/linkerd2/controller/gen/apis/link/v1alpha3"
-	"github.com/linkerd/linkerd2/multicluster/static"
+	"github.com/linkerd/linkerd2/multicluster/charts"
 	multicluster "github.com/linkerd/linkerd2/multicluster/values"
-	"github.com/linkerd/linkerd2/pkg/charts"
-	partials "github.com/linkerd/linkerd2/pkg/charts/static"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/k8s"
@@ -346,10 +345,10 @@ A full list of configurable values can be found at https://github.com/linkerd/li
 			}
 
 			if opts.ha {
-				if valuesOverrides, err = charts.OverrideFromFile(
+				if valuesOverrides, err = chartspkg.OverrideFromFile(
 					valuesOverrides,
-					static.Templates,
-					helmMulticlusterLinkDefaultChartName,
+					charts.Templates,
+					multicluster.HelmDefaultLinkChartDir,
 					"values-ha.yaml",
 				); err != nil {
 					return err
@@ -415,20 +414,13 @@ func renderServiceMirror(values *multicluster.Values, valuesOverrides map[string
 		{Name: "templates/gateway-mirror.yaml"},
 	}
 
-	var partialFiles []*chartloader.BufferedFile
-	for _, template := range charts.L5dPartials {
-		partialFiles = append(partialFiles,
-			&chartloader.BufferedFile{Name: template},
-		)
-	}
-
 	// Load all multicluster link chart files into buffer
-	if err := charts.FilesReader(static.Templates, helmMulticlusterLinkDefaultChartName+"/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, multicluster.HelmDefaultLinkChartDir+"/", files); err != nil {
 		return nil, err
 	}
 
-	// Load all partial chart files into buffer
-	if err := charts.FilesReader(partials.Templates, "", partialFiles); err != nil {
+	partialFiles, err := chartspkg.LoadPartials()
+	if err != nil {
 		return nil, err
 	}
 
diff --git a/multicluster/cmd/root.go b/multicluster/cmd/root.go
index a420c2842..a2d2e6930 100644
--- a/multicluster/cmd/root.go
+++ b/multicluster/cmd/root.go
@@ -17,7 +17,6 @@ const (
 	defaultLinkerdNamespace              = "linkerd"
 	defaultMulticlusterNamespace         = "linkerd-multicluster"
 	defaultGatewayName                   = "linkerd-gateway"
-	helmMulticlusterDefaultChartName     = "linkerd-multicluster"
 	helmMulticlusterLinkDefaultChartName = "linkerd-multicluster-link"
 	tokenKey                             = "token"
 
@@ -30,6 +29,8 @@ const (
 )
 
 var (
+	HelmMulticlusterDefaultChartName = "linkerd-multicluster"
+
 	apiAddr               string // An empty value means "use the Kubernetes configuration"
 	controlPlaneNamespace string
 	kubeconfigPath        string
diff --git a/multicluster/static/generate.go b/multicluster/static/generate.go
deleted file mode 100644
index cd8049a28..000000000
--- a/multicluster/static/generate.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build ignore
-
-package main
-
-import (
-	"github.com/linkerd/linkerd2/multicluster/static"
-	"github.com/shurcooL/vfsgen"
-	log "github.com/sirupsen/logrus"
-)
-
-func main() {
-	err := vfsgen.Generate(static.Templates, vfsgen.Options{
-		Filename:     "generated_multicluster_templates.gogen.go",
-		PackageName:  "static",
-		BuildTags:    "prod",
-		VariableName: "Templates",
-	})
-	if err != nil {
-		log.Fatalln(err)
-	}
-}
diff --git a/multicluster/static/templates.go b/multicluster/static/templates.go
deleted file mode 100644
index c85a765da..000000000
--- a/multicluster/static/templates.go
+++ /dev/null
@@ -1,15 +0,0 @@
-//go:generate go run generate.go
-//go:build !prod
-
-package static
-
-import (
-	"net/http"
-	"path"
-
-	"github.com/linkerd/linkerd2/pkg/charts/static"
-)
-
-// Templates that will be rendered by `linkerd install`. This is only used on
-// dev builds.
-var Templates http.FileSystem = http.Dir(path.Join(static.GetRepoRoot(), "multicluster/charts"))
diff --git a/multicluster/values/values.go b/multicluster/values/values.go
index 65cd8eabd..84aa6af79 100644
--- a/multicluster/values/values.go
+++ b/multicluster/values/values.go
@@ -3,8 +3,8 @@ package values
 import (
 	"fmt"
 
-	"github.com/linkerd/linkerd2/multicluster/static"
-	"github.com/linkerd/linkerd2/pkg/charts"
+	"github.com/linkerd/linkerd2/multicluster/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	"github.com/linkerd/linkerd2/pkg/charts/linkerd2"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"helm.sh/helm/v3/pkg/chart/loader"
@@ -13,9 +13,9 @@ import (
 	"sigs.k8s.io/yaml"
 )
 
-const (
-	helmDefaultChartDir     = "linkerd-multicluster"
-	helmDefaultLinkChartDir = "linkerd-multicluster-link"
+var (
+	HelmDefaultChartDir     = "linkerd-multicluster"
+	HelmDefaultLinkChartDir = "linkerd-multicluster-link"
 )
 
 // Values contains the top-level elements in the Helm charts
@@ -113,7 +113,7 @@ type ControllerDefaultsProbe struct {
 
 // NewInstallValues returns a new instance of the Values type.
 func NewInstallValues() (*Values, error) {
-	chartDir := fmt.Sprintf("%s/", helmDefaultChartDir)
+	chartDir := fmt.Sprintf("%s/", HelmDefaultChartDir)
 	v, err := readDefaults(chartDir)
 	if err != nil {
 		return nil, err
@@ -125,7 +125,7 @@ func NewInstallValues() (*Values, error) {
 
 // NewLinkValues returns a new instance of the Values type.
 func NewLinkValues() (*Values, error) {
-	chartDir := fmt.Sprintf("%s/", helmDefaultLinkChartDir)
+	chartDir := fmt.Sprintf("%s/", HelmDefaultLinkChartDir)
 	v, err := readDefaults(chartDir)
 	if err != nil {
 		return nil, err
@@ -141,11 +141,11 @@ func readDefaults(chartDir string) (*Values, error) {
 	file := &loader.BufferedFile{
 		Name: chartutil.ValuesfileName,
 	}
-	if err := charts.ReadFile(static.Templates, chartDir, file); err != nil {
+	if err := chartspkg.ReadFile(charts.Templates, chartDir, file); err != nil {
 		return nil, err
 	}
 	values := Values{}
-	if err := yaml.Unmarshal(charts.InsertVersion(file.Data), &values); err != nil {
+	if err := yaml.Unmarshal(chartspkg.InsertVersion(file.Data), &values); err != nil {
 		return nil, err
 	}
 	return &values, nil
diff --git a/pkg/charts/charts.go b/pkg/charts/charts.go
index 7b7f16e39..9ce576c63 100644
--- a/pkg/charts/charts.go
+++ b/pkg/charts/charts.go
@@ -2,12 +2,12 @@ package charts
 
 import (
 	"bytes"
+	"embed"
 	"errors"
-	"net/http"
 	"path"
 	"strings"
 
-	"github.com/linkerd/linkerd2/pkg/charts/static"
+	"github.com/linkerd/linkerd2/charts"
 	"github.com/linkerd/linkerd2/pkg/version"
 	"helm.sh/helm/v3/pkg/chart/loader"
 	"helm.sh/helm/v3/pkg/chartutil"
@@ -19,25 +19,25 @@ const versionPlaceholder = "linkerdVersionValue"
 
 var (
 	// L5dPartials is the list of templates in partials chart
-	// Keep this slice synced with the contents of /charts/partials
+	// Keep this slice synced with the contents of charts/partials
 	L5dPartials = []string{
-		"charts/partials/" + chartutil.ChartfileName,
-		"charts/partials/templates/_affinity.tpl",
-		"charts/partials/templates/_capabilities.tpl",
-		"charts/partials/templates/_debug.tpl",
-		"charts/partials/templates/_helpers.tpl",
-		"charts/partials/templates/_metadata.tpl",
-		"charts/partials/templates/_nodeselector.tpl",
-		"charts/partials/templates/_network-validator.tpl",
-		"charts/partials/templates/_proxy-config-ann.tpl",
-		"charts/partials/templates/_proxy-init.tpl",
-		"charts/partials/templates/_proxy.tpl",
-		"charts/partials/templates/_pull-secrets.tpl",
-		"charts/partials/templates/_resources.tpl",
-		"charts/partials/templates/_tolerations.tpl",
-		"charts/partials/templates/_trace.tpl",
-		"charts/partials/templates/_validate.tpl",
-		"charts/partials/templates/_volumes.tpl",
+		"partials/" + chartutil.ChartfileName,
+		"partials/templates/_affinity.tpl",
+		"partials/templates/_capabilities.tpl",
+		"partials/templates/_debug.tpl",
+		"partials/templates/_helpers.tpl",
+		"partials/templates/_metadata.tpl",
+		"partials/templates/_nodeselector.tpl",
+		"partials/templates/_network-validator.tpl",
+		"partials/templates/_proxy-config-ann.tpl",
+		"partials/templates/_proxy-init.tpl",
+		"partials/templates/_proxy.tpl",
+		"partials/templates/_pull-secrets.tpl",
+		"partials/templates/_resources.tpl",
+		"partials/templates/_tolerations.tpl",
+		"partials/templates/_trace.tpl",
+		"partials/templates/_validate.tpl",
+		"partials/templates/_volumes.tpl",
 	}
 )
 
@@ -56,7 +56,7 @@ type Chart struct {
 	Values map[string]any
 
 	Files []*loader.BufferedFile
-	Fs    http.FileSystem
+	Fs    embed.FS
 }
 
 func (c *Chart) render(partialsFiles []*loader.BufferedFile) (bytes.Buffer, error) {
@@ -64,11 +64,6 @@ func (c *Chart) render(partialsFiles []*loader.BufferedFile) (bytes.Buffer, erro
 		return bytes.Buffer{}, err
 	}
 
-	// static.Templates is used as partials are always available there
-	if err := FilesReader(static.Templates, "", partialsFiles); err != nil {
-		return bytes.Buffer{}, err
-	}
-
 	// Create chart and render templates
 	chart, err := loader.LoadFiles(append(c.Files, partialsFiles...))
 	if err != nil {
@@ -119,36 +114,40 @@ func (c *Chart) render(partialsFiles []*loader.BufferedFile) (bytes.Buffer, erro
 // Render returns a bytes buffer with the result of rendering a Helm chart
 func (c *Chart) Render() (bytes.Buffer, error) {
 
-	l5dPartials := []*loader.BufferedFile{}
-	for _, template := range L5dPartials {
-		l5dPartials = append(l5dPartials, &loader.BufferedFile{
-			Name: template,
-		})
+	partials, err := LoadPartials()
+	if err != nil {
+		return bytes.Buffer{}, err
 	}
 
-	return c.render(l5dPartials)
+	return c.render(partials)
 }
 
 // RenderCNI returns a bytes buffer with the result of rendering a Helm chart
 func (c *Chart) RenderCNI() (bytes.Buffer, error) {
 	cniPartials := []*loader.BufferedFile{
-		{Name: "charts/partials/" + chartutil.ChartfileName},
-		{Name: "charts/partials/templates/_helpers.tpl"},
-		{Name: "charts/partials/templates/_metadata.tpl"},
-		{Name: "charts/partials/templates/_pull-secrets.tpl"},
-		{Name: "charts/partials/templates/_tolerations.tpl"},
-		{Name: "charts/partials/templates/_resources.tpl"},
+		{Name: "partials/" + chartutil.ChartfileName},
+		{Name: "partials/templates/_helpers.tpl"},
+		{Name: "partials/templates/_metadata.tpl"},
+		{Name: "partials/templates/_pull-secrets.tpl"},
+		{Name: "partials/templates/_tolerations.tpl"},
+		{Name: "partials/templates/_resources.tpl"},
+	}
+
+	// Load all partial chart files into buffer
+	if err := FilesReader(charts.Templates, "", cniPartials); err != nil {
+		return bytes.Buffer{}, err
+	}
+
+	// The partials files must have the "charts/" prefix to be loaded correctly.
+	for i, f := range cniPartials {
+		cniPartials[i].Name = path.Join("charts", f.Name)
 	}
 	return c.render(cniPartials)
 }
 
 // ReadFile updates the buffered file with the data read from disk
-func ReadFile(fs http.FileSystem, dir string, f *loader.BufferedFile) error {
-	filename := dir + f.Name
-	if dir == "" {
-		filename = filename[7:]
-	}
-	file, err := fs.Open(filename)
+func ReadFile(fs embed.FS, dir string, f *loader.BufferedFile) error {
+	file, err := fs.Open(dir + f.Name)
 	if err != nil {
 		return err
 	}
@@ -164,7 +163,7 @@ func ReadFile(fs http.FileSystem, dir string, f *loader.BufferedFile) error {
 }
 
 // FilesReader reads all the files from a directory
-func FilesReader(fs http.FileSystem, dir string, files []*loader.BufferedFile) error {
+func FilesReader(fs embed.FS, dir string, files []*loader.BufferedFile) error {
 	for _, f := range files {
 		if err := ReadFile(fs, dir, f); err != nil {
 			return err
@@ -173,6 +172,26 @@ func FilesReader(fs http.FileSystem, dir string, files []*loader.BufferedFile) e
 	return nil
 }
 
+func LoadPartials() ([]*loader.BufferedFile, error) {
+	var partialFiles []*loader.BufferedFile
+	for _, template := range L5dPartials {
+		partialFiles = append(partialFiles,
+			&loader.BufferedFile{Name: template},
+		)
+	}
+
+	// Load all partial chart files into buffer
+	if err := FilesReader(charts.Templates, "", partialFiles); err != nil {
+		return nil, err
+	}
+
+	// The partials files must have the "charts/" prefix to be loaded correctly.
+	for i, f := range partialFiles {
+		partialFiles[i].Name = path.Join("charts", f.Name)
+	}
+	return partialFiles, nil
+}
+
 // InsertVersion returns the chart values file contents passed in
 // with the version placeholder replaced with the current version
 func InsertVersion(data []byte) []byte {
@@ -191,7 +210,7 @@ func InsertVersionValues(values chartutil.Values) (chartutil.Values, error) {
 }
 
 // OverrideFromFile overrides the given map with the given file from FS
-func OverrideFromFile(values map[string]interface{}, fs http.FileSystem, chartName, name string) (map[string]interface{}, error) {
+func OverrideFromFile(values map[string]interface{}, fs embed.FS, chartName, name string) (map[string]interface{}, error) {
 	// Load Values file
 	valuesOverride := loader.BufferedFile{
 		Name: name,
diff --git a/pkg/charts/cni/values.go b/pkg/charts/cni/values.go
index 935cd331c..46b56d531 100644
--- a/pkg/charts/cni/values.go
+++ b/pkg/charts/cni/values.go
@@ -3,8 +3,8 @@ package cni
 import (
 	"fmt"
 
-	"github.com/linkerd/linkerd2/pkg/charts"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
+	"github.com/linkerd/linkerd2/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"helm.sh/helm/v3/pkg/chart/loader"
 	"helm.sh/helm/v3/pkg/chartutil"
@@ -111,11 +111,11 @@ func readDefaults(chartDir string) (*Values, error) {
 	file := &loader.BufferedFile{
 		Name: chartutil.ValuesfileName,
 	}
-	if err := charts.ReadFile(static.Templates, chartDir, file); err != nil {
+	if err := chartspkg.ReadFile(charts.Templates, chartDir, file); err != nil {
 		return nil, err
 	}
 	values := Values{}
-	if err := yaml.Unmarshal(charts.InsertVersion(file.Data), &values); err != nil {
+	if err := yaml.Unmarshal(chartspkg.InsertVersion(file.Data), &values); err != nil {
 		return nil, err
 	}
 	return &values, nil
diff --git a/pkg/charts/linkerd2/values.go b/pkg/charts/linkerd2/values.go
index 6c7e3c263..48b3f4d56 100644
--- a/pkg/charts/linkerd2/values.go
+++ b/pkg/charts/linkerd2/values.go
@@ -5,8 +5,8 @@ import (
 	"fmt"
 
 	"github.com/imdario/mergo"
-	"github.com/linkerd/linkerd2/pkg/charts"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
+	"github.com/linkerd/linkerd2/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"github.com/linkerd/linkerd2/pkg/version"
 	"helm.sh/helm/v3/pkg/chart/loader"
@@ -15,7 +15,7 @@ import (
 	"sigs.k8s.io/yaml"
 )
 
-const (
+var (
 	// HelmChartDirCrds is the directory name for the linkerd-crds chart
 	HelmChartDirCrds = "linkerd-crds"
 
@@ -443,12 +443,12 @@ func MergeHAValues(values *Values) error {
 // readDefaults read all the default variables from filename.
 func readDefaults(filename string) (*Values, error) {
 	valuesFile := &loader.BufferedFile{Name: filename}
-	if err := charts.ReadFile(static.Templates, "/", valuesFile); err != nil {
+	if err := chartspkg.ReadFile(charts.Templates, "", valuesFile); err != nil {
 		return nil, err
 	}
 
 	var values Values
-	err := yaml.Unmarshal(charts.InsertVersion(valuesFile.Data), &values)
+	err := yaml.Unmarshal(chartspkg.InsertVersion(valuesFile.Data), &values)
 
 	return &values, err
 }
diff --git a/pkg/charts/static/generate.go b/pkg/charts/static/generate.go
deleted file mode 100644
index ae84c0735..000000000
--- a/pkg/charts/static/generate.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build ignore
-
-package main
-
-import (
-	"github.com/linkerd/linkerd2/pkg/charts/static"
-	"github.com/shurcooL/vfsgen"
-	log "github.com/sirupsen/logrus"
-)
-
-func main() {
-	err := vfsgen.Generate(static.Templates, vfsgen.Options{
-		Filename:     "generated_linkerd_templates.gogen.go",
-		PackageName:  "static",
-		BuildTags:    "prod",
-		VariableName: "Templates",
-	})
-	if err != nil {
-		log.Fatalln(err)
-	}
-}
diff --git a/pkg/charts/static/helpers.go b/pkg/charts/static/helpers.go
deleted file mode 100644
index b88dea365..000000000
--- a/pkg/charts/static/helpers.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package static
-
-import (
-	"path"
-	"path/filepath"
-	"runtime"
-)
-
-// GetRepoRoot returns the full path to the root of the repo. We assume this
-// function is only called from the `Templates` var above, and that this source
-// file lives at `pkg/charts/static`, relative to the root of the repo.
-func GetRepoRoot() string {
-	// /foo/bar/linkerd2/pkg/charts/static/templates.go
-	_, filename, _, _ := runtime.Caller(0)
-
-	// /foo/bar/linkerd2/pkg/charts/static
-	dir := filepath.Dir(filename)
-
-	// filepath.Dir returns the parent directory, so that combined with joining
-	// ".." walks 3 levels up the tree:
-	// /foo/bar/linkerd2
-	return filepath.Dir(path.Join(dir, "../.."))
-}
diff --git a/pkg/charts/static/templates.go b/pkg/charts/static/templates.go
deleted file mode 100644
index e613ec36a..000000000
--- a/pkg/charts/static/templates.go
+++ /dev/null
@@ -1,13 +0,0 @@
-//go:generate go run generate.go
-//go:build !prod
-
-package static
-
-import (
-	"net/http"
-	"path"
-)
-
-// Templates that will be rendered by `linkerd install`. This is only used on
-// dev builds.
-var Templates http.FileSystem = http.Dir(path.Join(GetRepoRoot(), "charts"))
diff --git a/pkg/inject/inject.go b/pkg/inject/inject.go
index 28e016c70..2291339f1 100644
--- a/pkg/inject/inject.go
+++ b/pkg/inject/inject.go
@@ -16,9 +16,9 @@ import (
 	"time"
 
 	jsonfilter "github.com/clarketm/json"
-	"github.com/linkerd/linkerd2/pkg/charts"
+	"github.com/linkerd/linkerd2/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"github.com/linkerd/linkerd2/pkg/util"
 	log "github.com/sirupsen/logrus"
@@ -704,13 +704,13 @@ func GetPodPatch(conf *ResourceConfig, injectProxy bool, values *OverriddenValue
 		{Name: "templates/patch.json"},
 	}
 
-	chart := &charts.Chart{
+	chart := &chartspkg.Chart{
 		Name:      "patch",
 		Dir:       "patch",
 		Namespace: conf.namespace,
 		RawValues: rawValues,
 		Files:     files,
-		Fs:        static.Templates,
+		Fs:        charts.Templates,
 	}
 	buf, err := chart.Render()
 	if err != nil {
diff --git a/viz/charts/templates.go b/viz/charts/templates.go
new file mode 100644
index 000000000..7eb9af74a
--- /dev/null
+++ b/viz/charts/templates.go
@@ -0,0 +1,8 @@
+package charts
+
+import (
+	"embed"
+)
+
+//go:embed linkerd-viz
+var Templates embed.FS
diff --git a/viz/cmd/allow-scrapes.go b/viz/cmd/allow-scrapes.go
index 54a8d408e..76922b410 100644
--- a/viz/cmd/allow-scrapes.go
+++ b/viz/cmd/allow-scrapes.go
@@ -121,7 +121,7 @@ func newCmdAllowScrapes() *cobra.Command {
 	output := "yaml"
 	options := templateOptions{
 		ExtensionName: ExtensionName,
-		ChartName:     vizChartName,
+		ChartName:     VizChartName,
 		Version:       version.Version,
 		VizNs:         defaultNamespace,
 	}
diff --git a/viz/cmd/install.go b/viz/cmd/install.go
index 0e07338a3..f4dc2cd0c 100644
--- a/viz/cmd/install.go
+++ b/viz/cmd/install.go
@@ -7,12 +7,11 @@ import (
 	"path"
 	"time"
 
-	"github.com/linkerd/linkerd2/pkg/charts"
-	partials "github.com/linkerd/linkerd2/pkg/charts/static"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/flags"
 	"github.com/linkerd/linkerd2/pkg/healthcheck"
-	"github.com/linkerd/linkerd2/viz/static"
+	"github.com/linkerd/linkerd2/viz/charts"
 	"github.com/spf13/cobra"
 	"helm.sh/helm/v3/pkg/chart/loader"
 	"helm.sh/helm/v3/pkg/chartutil"
@@ -112,7 +111,7 @@ func install(w io.Writer, options values.Options, ha, cniEnabled bool, format st
 	}
 
 	if ha {
-		valuesOverrides, err = charts.OverrideFromFile(valuesOverrides, static.Templates, vizChartName, "values-ha.yaml")
+		valuesOverrides, err = chartspkg.OverrideFromFile(valuesOverrides, charts.Templates, VizChartName, "values-ha.yaml")
 		if err != nil {
 			return err
 		}
@@ -140,20 +139,13 @@ func render(w io.Writer, valuesOverrides map[string]interface{}, format string)
 		)
 	}
 
-	var partialFiles []*loader.BufferedFile
-	for _, template := range charts.L5dPartials {
-		partialFiles = append(partialFiles,
-			&loader.BufferedFile{Name: template},
-		)
-	}
-
 	// Load all Viz chart files into buffer
-	if err := charts.FilesReader(static.Templates, vizChartName+"/", files); err != nil {
+	if err := chartspkg.FilesReader(charts.Templates, VizChartName+"/", files); err != nil {
 		return err
 	}
 
-	// Load all partial chart files into buffer
-	if err := charts.FilesReader(partials.Templates, "", partialFiles); err != nil {
+	partialFiles, err := chartspkg.LoadPartials()
+	if err != nil {
 		return err
 	}
 
@@ -168,7 +160,7 @@ func render(w io.Writer, valuesOverrides map[string]interface{}, format string)
 		return err
 	}
 
-	vals, err = charts.InsertVersionValues(vals)
+	vals, err = chartspkg.InsertVersionValues(vals)
 	if err != nil {
 		return err
 	}
diff --git a/viz/cmd/root.go b/viz/cmd/root.go
index 5213f5edd..85b273220 100644
--- a/viz/cmd/root.go
+++ b/viz/cmd/root.go
@@ -19,7 +19,6 @@ const (
 	// until 15d1809bd043192bb21cacbc96112cce35bf384f
 	LegacyExtensionName = "linkerd-viz"
 
-	vizChartName            = "linkerd-viz"
 	defaultNamespace        = "linkerd-viz"
 	defaultLinkerdNamespace = "linkerd"
 	maxRps                  = 100.0
@@ -31,6 +30,8 @@ const (
 )
 
 var (
+	VizChartName = "linkerd-viz"
+
 	// special handling for Windows, on all other platforms these resolve to
 	// os.Stdout and os.Stderr, thanks to https://github.com/mattn/go-colorable
 	stdout = color.Output
diff --git a/viz/static/generate.go b/viz/static/generate.go
deleted file mode 100644
index 28785ffbc..000000000
--- a/viz/static/generate.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build ignore
-
-package main
-
-import (
-	"github.com/linkerd/linkerd2/viz/static"
-	"github.com/shurcooL/vfsgen"
-	log "github.com/sirupsen/logrus"
-)
-
-func main() {
-	err := vfsgen.Generate(static.Templates, vfsgen.Options{
-		Filename:     "generated_viz_templates.gogen.go",
-		PackageName:  "static",
-		BuildTags:    "prod",
-		VariableName: "Templates",
-	})
-	if err != nil {
-		log.Fatalln(err)
-	}
-}
diff --git a/viz/static/templates.go b/viz/static/templates.go
deleted file mode 100644
index c240343e5..000000000
--- a/viz/static/templates.go
+++ /dev/null
@@ -1,15 +0,0 @@
-//go:generate go run generate.go
-//go:build !prod
-
-package static
-
-import (
-	"net/http"
-	"path"
-
-	"github.com/linkerd/linkerd2/pkg/charts/static"
-)
-
-// Templates that will be rendered by `linkerd viz install`. This is only used on
-// dev builds.
-var Templates http.FileSystem = http.Dir(path.Join(static.GetRepoRoot(), "viz/charts"))
diff --git a/web/Dockerfile b/web/Dockerfile
index b32abbf03..f557dbf84 100644
--- a/web/Dockerfile
+++ b/web/Dockerfile
@@ -43,6 +43,7 @@ COPY viz/pkg viz/pkg
 COPY viz/tap/gen/tap viz/tap/gen/tap
 COPY viz/tap/pkg viz/tap/pkg
 COPY pkg pkg
+COPY charts charts
 ARG TARGETARCH
 RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -mod=readonly -o web/web -ldflags "-s -w" ./web
 
diff --git a/web/app/package.json b/web/app/package.json
index 96e79af7f..132eade13 100644
--- a/web/app/package.json
+++ b/web/app/package.json
@@ -16,7 +16,7 @@
     "@material-ui/icons": "4.11.3",
     "@material-ui/lab": "^4.0.0-alpha.61",
     "classnames": "2.5.1",
-    "core-js": "^3.43.0",
+    "core-js": "^3.44.0",
     "css-mediaquery": "^0.1.2",
     "d3-drag": "3.0.0",
     "d3-force": "3.0.0",
@@ -29,7 +29,7 @@
     "make-plural": "^7.4.0",
     "path": "0.12.7",
     "prop-types": "15.8.1",
-    "query-string": "^9.2.1",
+    "query-string": "^9.2.2",
     "react": "16.14.0",
     "react-dom": "16.14.0",
     "react-linkify": "1.0.0-alpha",
@@ -44,12 +44,12 @@
     "@babel/core": "^7.28.0",
     "@babel/eslint-parser": "^7.28.0",
     "@babel/plugin-proposal-class-properties": "^7.17.12",
-    "@babel/preset-env": "^7.27.2",
+    "@babel/preset-env": "^7.28.0",
     "@babel/preset-react": "^7.27.1",
     "@babel/runtime": "^7.27.6",
     "@lingui/cli": "3.17.2",
     "babel-core": "^7.0.0-bridge.0",
-    "babel-jest": "^30.0.2",
+    "babel-jest": "^30.0.4",
     "babel-loader": "^10.0.0",
     "babel-plugin-import": "^1.13.8",
     "babel-plugin-macros": "^3.1.0",
diff --git a/web/app/yarn.lock b/web/app/yarn.lock
index eb3e7b014..2d3c782eb 100644
--- a/web/app/yarn.lock
+++ b/web/app/yarn.lock
@@ -35,10 +35,10 @@
     js-tokens "^4.0.0"
     picocolors "^1.1.1"
 
-"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.27.2":
-  version "7.27.2"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.2.tgz#4183f9e642fd84e74e3eea7ffa93a412e3b102c9"
-  integrity sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==
+"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790"
+  integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==
 
 "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.28.0":
   version "7.28.0"
@@ -102,7 +102,14 @@
   dependencies:
     "@babel/types" "^7.27.1"
 
-"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2":
+"@babel/helper-annotate-as-pure@^7.27.3":
+  version "7.27.3"
+  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
+  integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==
+  dependencies:
+    "@babel/types" "^7.27.3"
+
+"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2":
   version "7.27.2"
   resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d"
   integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==
@@ -156,27 +163,16 @@
     regexpu-core "^6.2.0"
     semver "^6.3.1"
 
-"@babel/helper-define-polyfill-provider@^0.6.1":
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz#fadc63f0c2ff3c8d02ed905dcea747c5b0fb74fd"
-  integrity sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==
-  dependencies:
-    "@babel/helper-compilation-targets" "^7.22.6"
-    "@babel/helper-plugin-utils" "^7.22.5"
-    debug "^4.1.1"
-    lodash.debounce "^4.0.8"
-    resolve "^1.14.2"
-
-"@babel/helper-define-polyfill-provider@^0.6.3":
-  version "0.6.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz#f4f2792fae2ef382074bc2d713522cf24e6ddb21"
-  integrity sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==
+"@babel/helper-define-polyfill-provider@^0.6.5":
+  version "0.6.5"
+  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753"
+  integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==
   dependencies:
-    "@babel/helper-compilation-targets" "^7.22.6"
-    "@babel/helper-plugin-utils" "^7.22.5"
-    debug "^4.1.1"
+    "@babel/helper-compilation-targets" "^7.27.2"
+    "@babel/helper-plugin-utils" "^7.27.1"
+    debug "^4.4.1"
     lodash.debounce "^4.0.8"
-    resolve "^1.14.2"
+    resolve "^1.22.10"
 
 "@babel/helper-environment-visitor@^7.18.6":
   version "7.18.6"
@@ -249,7 +245,7 @@
   dependencies:
     "@babel/types" "^7.27.1"
 
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0":
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0":
   version "7.27.1"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c"
   integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==
@@ -537,14 +533,14 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/plugin-transform-async-generator-functions@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz#ca433df983d68e1375398e7ca71bf2a4f6fd89d7"
-  integrity sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==
+"@babel/plugin-transform-async-generator-functions@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2"
+  integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
     "@babel/helper-remap-async-to-generator" "^7.27.1"
-    "@babel/traverse" "^7.27.1"
+    "@babel/traverse" "^7.28.0"
 
 "@babel/plugin-transform-async-to-generator@^7.27.1":
   version "7.27.1"
@@ -562,10 +558,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/plugin-transform-block-scoping@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.1.tgz#bc0dbe8ac6de5602981ba58ef68c6df8ef9bfbb3"
-  integrity sha512-QEcFlMl9nGTgh1rn2nIeU5bkfb9BAjaQcWbiP4LvKxUot52ABcTkpcyJ7f2Q2U2RuQ84BNLgts3jRme2dTx6Fw==
+"@babel/plugin-transform-block-scoping@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz#e7c50cbacc18034f210b93defa89638666099451"
+  integrity sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
@@ -585,17 +581,17 @@
     "@babel/helper-create-class-features-plugin" "^7.27.1"
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/plugin-transform-classes@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz#03bb04bea2c7b2f711f0db7304a8da46a85cced4"
-  integrity sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==
+"@babel/plugin-transform-classes@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz#12fa46cffc32a6e084011b650539e880add8a0f8"
+  integrity sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==
   dependencies:
-    "@babel/helper-annotate-as-pure" "^7.27.1"
-    "@babel/helper-compilation-targets" "^7.27.1"
+    "@babel/helper-annotate-as-pure" "^7.27.3"
+    "@babel/helper-compilation-targets" "^7.27.2"
+    "@babel/helper-globals" "^7.28.0"
     "@babel/helper-plugin-utils" "^7.27.1"
     "@babel/helper-replace-supers" "^7.27.1"
-    "@babel/traverse" "^7.27.1"
-    globals "^11.1.0"
+    "@babel/traverse" "^7.28.0"
 
 "@babel/plugin-transform-computed-properties@^7.27.1":
   version "7.27.1"
@@ -605,12 +601,13 @@
     "@babel/helper-plugin-utils" "^7.27.1"
     "@babel/template" "^7.27.1"
 
-"@babel/plugin-transform-destructuring@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.1.tgz#d5916ef7089cb254df0418ae524533c1b72ba656"
-  integrity sha512-ttDCqhfvpE9emVkXbPD8vyxxh4TWYACVybGkDj+oReOGwnp066ITEivDlLwe0b1R0+evJ13IXQuLNB5w1fhC5Q==
+"@babel/plugin-transform-destructuring@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz#0f156588f69c596089b7d5b06f5af83d9aa7f97a"
+  integrity sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
+    "@babel/traverse" "^7.28.0"
 
 "@babel/plugin-transform-dotall-regex@^7.27.1":
   version "7.27.1"
@@ -642,6 +639,14 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
+"@babel/plugin-transform-explicit-resource-management@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a"
+  integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.27.1"
+    "@babel/plugin-transform-destructuring" "^7.28.0"
+
 "@babel/plugin-transform-exponentiation-operator@^7.27.1":
   version "7.27.1"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz#fc497b12d8277e559747f5a3ed868dd8064f83e1"
@@ -764,15 +769,16 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/plugin-transform-object-rest-spread@^7.27.2":
-  version "7.27.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.2.tgz#67f9ab822347aa2bcee91e8996763da79bdea973"
-  integrity sha512-AIUHD7xJ1mCrj3uPozvtngY3s0xpv7Nu7DoUSnzNY6Xam1Cy4rUznR//pvMHOhQ4AvbCexhbqXCtpxGHOGOO6g==
+"@babel/plugin-transform-object-rest-spread@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz#d23021857ffd7cd809f54d624299b8086402ed8d"
+  integrity sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==
   dependencies:
     "@babel/helper-compilation-targets" "^7.27.2"
     "@babel/helper-plugin-utils" "^7.27.1"
-    "@babel/plugin-transform-destructuring" "^7.27.1"
-    "@babel/plugin-transform-parameters" "^7.27.1"
+    "@babel/plugin-transform-destructuring" "^7.28.0"
+    "@babel/plugin-transform-parameters" "^7.27.7"
+    "@babel/traverse" "^7.28.0"
 
 "@babel/plugin-transform-object-super@^7.27.1":
   version "7.27.1"
@@ -797,10 +803,10 @@
     "@babel/helper-plugin-utils" "^7.27.1"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
 
-"@babel/plugin-transform-parameters@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz#80334b54b9b1ac5244155a0c8304a187a618d5a7"
-  integrity sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==
+"@babel/plugin-transform-parameters@^7.27.7":
+  version "7.27.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a"
+  integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
@@ -861,10 +867,10 @@
     "@babel/helper-annotate-as-pure" "^7.27.1"
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/plugin-transform-regenerator@^7.27.1":
-  version "7.27.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.1.tgz#0a471df9213416e44cd66bf67176b66f65768401"
-  integrity sha512-B19lbbL7PMrKr52BNPjCqg1IyNUIjTcxKj8uX9zHO+PmWN93s19NDr/f69mIkEp2x9nmDJ08a7lgHaTTzvW7mw==
+"@babel/plugin-transform-regenerator@^7.28.0":
+  version "7.28.1"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.1.tgz#bde80603442ff4bb4e910bc8b35485295d556ab1"
+  integrity sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.27.1"
 
@@ -950,12 +956,12 @@
     "@babel/helper-create-regexp-features-plugin" "^7.27.1"
     "@babel/helper-plugin-utils" "^7.27.1"
 
-"@babel/preset-env@^7.27.2":
-  version "7.27.2"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.27.2.tgz#106e6bfad92b591b1f6f76fd4cf13b7725a7bf9a"
-  integrity sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==
+"@babel/preset-env@^7.28.0":
+  version "7.28.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.0.tgz#d23a6bc17b43227d11db77081a0779c706b5569c"
+  integrity sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg==
   dependencies:
-    "@babel/compat-data" "^7.27.2"
+    "@babel/compat-data" "^7.28.0"
     "@babel/helper-compilation-targets" "^7.27.2"
     "@babel/helper-plugin-utils" "^7.27.1"
     "@babel/helper-validator-option" "^7.27.1"
@@ -969,19 +975,20 @@
     "@babel/plugin-syntax-import-attributes" "^7.27.1"
     "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
     "@babel/plugin-transform-arrow-functions" "^7.27.1"
-    "@babel/plugin-transform-async-generator-functions" "^7.27.1"
+    "@babel/plugin-transform-async-generator-functions" "^7.28.0"
     "@babel/plugin-transform-async-to-generator" "^7.27.1"
     "@babel/plugin-transform-block-scoped-functions" "^7.27.1"
-    "@babel/plugin-transform-block-scoping" "^7.27.1"
+    "@babel/plugin-transform-block-scoping" "^7.28.0"
     "@babel/plugin-transform-class-properties" "^7.27.1"
     "@babel/plugin-transform-class-static-block" "^7.27.1"
-    "@babel/plugin-transform-classes" "^7.27.1"
+    "@babel/plugin-transform-classes" "^7.28.0"
     "@babel/plugin-transform-computed-properties" "^7.27.1"
-    "@babel/plugin-transform-destructuring" "^7.27.1"
+    "@babel/plugin-transform-destructuring" "^7.28.0"
     "@babel/plugin-transform-dotall-regex" "^7.27.1"
     "@babel/plugin-transform-duplicate-keys" "^7.27.1"
     "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1"
     "@babel/plugin-transform-dynamic-import" "^7.27.1"
+    "@babel/plugin-transform-explicit-resource-management" "^7.28.0"
     "@babel/plugin-transform-exponentiation-operator" "^7.27.1"
     "@babel/plugin-transform-export-namespace-from" "^7.27.1"
     "@babel/plugin-transform-for-of" "^7.27.1"
@@ -998,15 +1005,15 @@
     "@babel/plugin-transform-new-target" "^7.27.1"
     "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1"
     "@babel/plugin-transform-numeric-separator" "^7.27.1"
-    "@babel/plugin-transform-object-rest-spread" "^7.27.2"
+    "@babel/plugin-transform-object-rest-spread" "^7.28.0"
     "@babel/plugin-transform-object-super" "^7.27.1"
     "@babel/plugin-transform-optional-catch-binding" "^7.27.1"
     "@babel/plugin-transform-optional-chaining" "^7.27.1"
-    "@babel/plugin-transform-parameters" "^7.27.1"
+    "@babel/plugin-transform-parameters" "^7.27.7"
     "@babel/plugin-transform-private-methods" "^7.27.1"
     "@babel/plugin-transform-private-property-in-object" "^7.27.1"
     "@babel/plugin-transform-property-literals" "^7.27.1"
-    "@babel/plugin-transform-regenerator" "^7.27.1"
+    "@babel/plugin-transform-regenerator" "^7.28.0"
     "@babel/plugin-transform-regexp-modifiers" "^7.27.1"
     "@babel/plugin-transform-reserved-words" "^7.27.1"
     "@babel/plugin-transform-shorthand-properties" "^7.27.1"
@@ -1019,10 +1026,10 @@
     "@babel/plugin-transform-unicode-regex" "^7.27.1"
     "@babel/plugin-transform-unicode-sets-regex" "^7.27.1"
     "@babel/preset-modules" "0.1.6-no-external-plugins"
-    babel-plugin-polyfill-corejs2 "^0.4.10"
-    babel-plugin-polyfill-corejs3 "^0.11.0"
-    babel-plugin-polyfill-regenerator "^0.6.1"
-    core-js-compat "^3.40.0"
+    babel-plugin-polyfill-corejs2 "^0.4.14"
+    babel-plugin-polyfill-corejs3 "^0.13.0"
+    babel-plugin-polyfill-regenerator "^0.6.5"
+    core-js-compat "^3.43.0"
     semver "^6.3.1"
 
 "@babel/preset-modules@0.1.6-no-external-plugins":
@@ -1469,27 +1476,6 @@
     jest-haste-map "30.0.2"
     slash "^3.0.0"
 
-"@jest/transform@30.0.2":
-  version "30.0.2"
-  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.0.2.tgz#62ba84fcc2389ab751e7ec923958c9b1163d90c3"
-  integrity sha512-kJIuhLMTxRF7sc0gPzPtCDib/V9KwW3I2U25b+lYCYMVqHHSrcZopS8J8H+znx9yixuFv+Iozl8raLt/4MoxrA==
-  dependencies:
-    "@babel/core" "^7.27.4"
-    "@jest/types" "30.0.1"
-    "@jridgewell/trace-mapping" "^0.3.25"
-    babel-plugin-istanbul "^7.0.0"
-    chalk "^4.1.2"
-    convert-source-map "^2.0.0"
-    fast-json-stable-stringify "^2.1.0"
-    graceful-fs "^4.2.11"
-    jest-haste-map "30.0.2"
-    jest-regex-util "30.0.1"
-    jest-util "30.0.2"
-    micromatch "^4.0.8"
-    pirates "^4.0.7"
-    slash "^3.0.0"
-    write-file-atomic "^5.0.1"
-
 "@jest/transform@30.0.4":
   version "30.0.4"
   resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.0.4.tgz#a06f8c6fc2a04985241b483096f821bafb99cc93"
@@ -2881,7 +2867,7 @@ babel-core@^7.0.0-bridge.0:
   resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
   integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
 
-babel-jest@30.0.4:
+babel-jest@30.0.4, babel-jest@^30.0.4:
   version "30.0.4"
   resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.0.4.tgz#63945c1b27227312fc687689073124dba5b28282"
   integrity sha512-UjG2j7sAOqsp2Xua1mS/e+ekddkSu3wpf4nZUSvXNHuVWdaOUXQ77+uyjJLDE9i0atm5x4kds8K9yb5lRsRtcA==
@@ -2894,19 +2880,6 @@ babel-jest@30.0.4:
     graceful-fs "^4.2.11"
     slash "^3.0.0"
 
-babel-jest@^30.0.2:
-  version "30.0.2"
-  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.0.2.tgz#f627dc5afc3bd5795fc84735b4f1d74f9d4b8e91"
-  integrity sha512-A5kqR1/EUTidM2YC2YMEUDP2+19ppgOwK0IAd9Swc3q2KqFb5f9PtRUXVeZcngu0z5mDMyZ9zH2huJZSOMLiTQ==
-  dependencies:
-    "@jest/transform" "30.0.2"
-    "@types/babel__core" "^7.20.5"
-    babel-plugin-istanbul "^7.0.0"
-    babel-preset-jest "30.0.1"
-    chalk "^4.1.2"
-    graceful-fs "^4.2.11"
-    slash "^3.0.0"
-
 babel-loader@^10.0.0:
   version "10.0.0"
   resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-10.0.0.tgz#b9743714c0e1e084b3e4adef3cd5faee33089977"
@@ -2950,29 +2923,29 @@ babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0:
     cosmiconfig "^7.0.0"
     resolve "^1.19.0"
 
-babel-plugin-polyfill-corejs2@^0.4.10:
-  version "0.4.10"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz#276f41710b03a64f6467433cab72cbc2653c38b1"
-  integrity sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==
+babel-plugin-polyfill-corejs2@^0.4.14:
+  version "0.4.14"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f"
+  integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==
   dependencies:
-    "@babel/compat-data" "^7.22.6"
-    "@babel/helper-define-polyfill-provider" "^0.6.1"
+    "@babel/compat-data" "^7.27.7"
+    "@babel/helper-define-polyfill-provider" "^0.6.5"
     semver "^6.3.1"
 
-babel-plugin-polyfill-corejs3@^0.11.0:
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz#4e4e182f1bb37c7ba62e2af81d8dd09df31344f6"
-  integrity sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==
+babel-plugin-polyfill-corejs3@^0.13.0:
+  version "0.13.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164"
+  integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==
   dependencies:
-    "@babel/helper-define-polyfill-provider" "^0.6.3"
-    core-js-compat "^3.40.0"
+    "@babel/helper-define-polyfill-provider" "^0.6.5"
+    core-js-compat "^3.43.0"
 
-babel-plugin-polyfill-regenerator@^0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz#4f08ef4c62c7a7f66a35ed4c0d75e30506acc6be"
-  integrity sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==
+babel-plugin-polyfill-regenerator@^0.6.5:
+  version "0.6.5"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5"
+  integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==
   dependencies:
-    "@babel/helper-define-polyfill-provider" "^0.6.1"
+    "@babel/helper-define-polyfill-provider" "^0.6.5"
 
 babel-plugin-transform-react-remove-prop-types@0.4.24:
   version "0.4.24"
@@ -3104,7 +3077,7 @@ braces@^3.0.1, braces@^3.0.2, braces@^3.0.3, braces@~3.0.2:
   dependencies:
     fill-range "^7.1.1"
 
-browserslist@^4.24.0, browserslist@^4.24.3:
+browserslist@^4.24.0:
   version "4.24.4"
   resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
   integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
@@ -3114,6 +3087,16 @@ browserslist@^4.24.0, browserslist@^4.24.3:
     node-releases "^2.0.19"
     update-browserslist-db "^1.1.1"
 
+browserslist@^4.25.1:
+  version "4.25.1"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111"
+  integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
+  dependencies:
+    caniuse-lite "^1.0.30001726"
+    electron-to-chromium "^1.5.173"
+    node-releases "^2.0.19"
+    update-browserslist-db "^1.1.3"
+
 bser@2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
@@ -3254,6 +3237,11 @@ caniuse-lite@^1.0.30001688:
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz#a102cf330d153bf8c92bfb5be3cd44c0a89c8c12"
   integrity sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==
 
+caniuse-lite@^1.0.30001726:
+  version "1.0.30001727"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85"
+  integrity sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==
+
 chai@4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8"
@@ -3576,17 +3564,17 @@ cookie@0.7.1:
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
   integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
 
-core-js-compat@^3.40.0:
-  version "3.40.0"
-  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.40.0.tgz#7485912a5a4a4315c2fdb2cbdc623e6881c88b38"
-  integrity sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==
+core-js-compat@^3.43.0:
+  version "3.44.0"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.44.0.tgz#62b9165b97e4cbdb8bca16b14818e67428b4a0f8"
+  integrity sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==
   dependencies:
-    browserslist "^4.24.3"
+    browserslist "^4.25.1"
 
-core-js@^3.43.0:
-  version "3.43.0"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.43.0.tgz#f7258b156523208167df35dea0cfd6b6ecd4ee88"
-  integrity sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==
+core-js@^3.44.0:
+  version "3.44.0"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.44.0.tgz#db4fd4fa07933c1d6898c8b112a1119a9336e959"
+  integrity sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==
 
 core-util-is@~1.0.0:
   version "1.0.3"
@@ -3827,7 +3815,7 @@ debug@2.6.9:
   dependencies:
     ms "2.0.0"
 
-debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
+debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1:
   version "4.4.1"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
   integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
@@ -4091,6 +4079,11 @@ ee-first@1.1.1:
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
   integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
 
+electron-to-chromium@^1.5.173:
+  version "1.5.182"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz#4ab73104f893938acb3ab9c28d7bec170c116b3e"
+  integrity sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==
+
 electron-to-chromium@^1.5.73:
   version "1.5.96"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz#afa3bf1608c897a7c7e33f22d4be1596dd5a4f3e"
@@ -5438,11 +5431,6 @@ glob@^7.0.3, glob@^7.1.3, glob@^7.1.4:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-globals@^11.1.0:
-  version "11.12.0"
-  resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
-  integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
 globals@^13.19.0:
   version "13.19.0"
   resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8"
@@ -6016,7 +6004,7 @@ is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.4:
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
   integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
 
-is-core-module@^2.13.0, is-core-module@^2.16.1:
+is-core-module@^2.13.0, is-core-module@^2.16.0, is-core-module@^2.16.1:
   version "2.16.1"
   resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
   integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
@@ -8161,10 +8149,10 @@ query-string@^7.0.0:
     split-on-first "^1.0.0"
     strict-uri-encode "^2.0.0"
 
-query-string@^9.2.1:
-  version "9.2.1"
-  resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.2.1.tgz#67bd95f6e2cb64eafecfb0504be7cc38bcd4dd11"
-  integrity sha512-3jTGGLRzlhu/1ws2zlr4Q+GVMLCQTLFOj8CMX5x44cdZG9FQE07x2mQhaNxaKVPNmIDu0mvJ/cEwtY7Pim7hqA==
+query-string@^9.2.2:
+  version "9.2.2"
+  resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.2.2.tgz#a0104824edfdd2c1db2f18af71cef7abf6a3b20f"
+  integrity sha512-pDSIZJ9sFuOp6VnD+5IkakSVf+rICAuuU88Hcsr6AKL0QtxSIfVuKiVP2oahFI7tk3CRSexwV+Ya6MOoTxzg9g==
   dependencies:
     decode-uri-component "^0.4.1"
     filter-obj "^5.1.0"
@@ -8545,7 +8533,7 @@ resolve-pathname@^3.0.0:
   resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
   integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
 
-resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.4:
+resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.4:
   version "1.22.8"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
   integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@@ -8554,6 +8542,15 @@ resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.4:
     path-parse "^1.0.7"
     supports-preserve-symlinks-flag "^1.0.0"
 
+resolve@^1.22.10:
+  version "1.22.10"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
+  integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
+  dependencies:
+    is-core-module "^2.16.0"
+    path-parse "^1.0.7"
+    supports-preserve-symlinks-flag "^1.0.0"
+
 resolve@^2.0.0-next.5:
   version "2.0.0-next.5"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
@@ -9802,6 +9799,14 @@ update-browserslist-db@^1.1.1:
     escalade "^3.2.0"
     picocolors "^1.1.1"
 
+update-browserslist-db@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
+  integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
+  dependencies:
+    escalade "^3.2.0"
+    picocolors "^1.1.1"
+
 uri-js@^4.2.2:
   version "4.4.1"
   resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"


Test patch:
diff --git a/cli/cmd/install_helm_test.go b/cli/cmd/install_helm_test.go
index c1ee4cdf2..b963460df 100644
--- a/cli/cmd/install_helm_test.go
+++ b/cli/cmd/install_helm_test.go
@@ -5,9 +5,9 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/linkerd/linkerd2/pkg/charts"
+	"github.com/linkerd/linkerd2/charts"
+	chartspkg "github.com/linkerd/linkerd2/pkg/charts"
 	l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
-	"github.com/linkerd/linkerd2/pkg/charts/static"
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	"github.com/linkerd/linkerd2/testutil"
 	"helm.sh/helm/v3/pkg/chart"
@@ -227,7 +227,7 @@ func chartCrds(t *testing.T) *chart.Chart {
 
 	// Load defaults from values.yaml
 	valuesFile := &loader.BufferedFile{Name: l5dcharts.HelmChartDirCrds + "/values.yaml"}
-	if err := charts.ReadFile(static.Templates, "/", valuesFile); err != nil {
+	if err := chartspkg.ReadFile(charts.Templates, "", valuesFile); err != nil {
 		t.Fatal(err)
 	}
 	defaultValues := make(map[string]interface{})