WIP new TS template for files page, htmlPage wrapper

7f8822801a7701fa9a39828da5e9048b112672b5

Tucker McKnight | Mon Dec 15 2025

WIP new TS template for files page, htmlPage wrapper
js_templates/common/htmlPage.ts:0
Before
0
After
0
import { type ReposConfiguration } from '../../src/configTypes.ts'
import { type Repository } from '../../src/dataTypes.ts'
import { NavHelper } from '../helpers/nav.ts'

export const branchesListItems = (branches: Array<{name: string, href: string, date: string}>, defaultBranch: string): string => {
  return branches.map((branch) => {
    const badge = defaultBranch === branch.name ? '<div class="badge rounded-pill bg-primary ms-2">default</div>' : ''
    return `<a href='${branch.href}' class='dropdown-item my-1'><span class="branch-dropdown-branch-name">${branch.name}</span>${badge}<span class="text-body d-block ms-2">updated ${branch.date}</span></a>`
  }).join('')
}

export default async (reposConfig: ReposConfiguration, eleventyConfig: any, pageContent: Function) => {
  return async (data) => {
    if (data.currentRepo === '') {
      return
    }

    const repo: Repository = data.currentRepo
    const branch: Repository['branches'][0] = data.currentBranch

    const slugify = eleventyConfig.getFilter("slugify")
    const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

    const branchesWithHrefs = repo.branches.map((branch) => {
      return {
        name: branch.name,
        href: nav.repoBranchHome(branch.name),
        date: repo.commits.get(branch.head).date.toDateString(),
      }
    })

    return `
      <!doctype html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>${repo.name}</title>
          <link rel="stylesheet" href="/css/design-board.css">
          <link href="https://unpkg.com/prismjs@1.20.0/themes/prism.css" rel="stylesheet" />
          <script>
            window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
            window.defaultBranch = "${repo.defaultBranch}";
            window.cloneUrl = "${repo.cloneUrl}";
          </script>
          <script src="${nav.rootPath()}frontend/top.js"></script>
        </head>
        <body>
          <div class="container">
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.rootPath()}">&larr; All repositories</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="#">${repo.name}</a>
                    </li>
                    <li class="nav-item">
                      <span class="nav-link d-inline-block">Branch:</span>
                      <div class="branch-selector dropdown-center d-inline-block">
                        <button class="branches nav-link d-inline-block btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                          ${branch.name}
                        </button>
                        <div class="dropdown-menu">
                          <form class="mx-3 my-1">
                            <input type="text" class="form-control" id="dropdownBranchSearch" placeholder="Search branches...">
                            <div>
                              <div class="row mt-3">
                                <div class="col">
                                  <label class="form-label">Sort by:</label>
                                </div>
                              </div>
                              <div class="sortRadioButtons">
                                <div class="sortRadioButton pe-1">
                                  <input class="form-check-input" type="radio" name="branchSort" id="branchSortByDate" checked>
                                  <label class="form-check-label" for="branchSortByDate">
                                    Last commit
                                  </label>
                                </div>
                                <div class="sortRadioButton ps-1">
                                  <input class="form-check-input" type="radio" name="branchSort" id="branchSortByName">
                                  <label class="form-check-label" for="branchSortByName">
                                    Name
                                  </label>
                                </div>
                              </div>
                            </div>
                          </form>
                          <div class="dropdown-divider"></div>
                          <div id="dropdown-branches-results" class="dropdown-branches">
                            ${branchesListItems(branchesWithHrefs, repo.defaultBranch)}
                          </div>
                        </div>
                      </div>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="main-nav navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link active" aria-current="page" href="${nav.repoCurrentBranchHome()}">Home</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchFiles()}">Files</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchCommits()}">Commits</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchBranches()}">Branches</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="#">Tags</a>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>

            <div class="row">
              <div class="col-12">
                ${await pageContent(eleventyConfig, data)}
              </div>
            </div>

          </div>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
          <script src="${nav.rootPath()}frontend/main-frontend.bundle.js"></script>
        </body>
      </html>
      `
  }
}
js_templates/files.ts:0
Before
0
After
0
export default async (eleventyConfig: any, data: any) => {
  const branch: Repository['branches'][0] = data.currentBranch
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const slugify = eleventyConfig.getFilter("slugify")

  const files = topLevelFilesOnly('', branch.fileList)

  return `
    <div class="row">
      <div class="col">
        <ul class="list-group">
        ${files.map(files) => {
            return `
              <li class="list-group-item">
                ${file.isDirectory ? '<i class="bi bi-folder-fill"></i>' : '<i class="bi bi-file-earmark"></i>'
                <a href="${data.reposPath}/${slugify(data.branchInfo.repoName)}/branches/${slugify(branchInfo.branchName)}/files/${slugify(file.fullPath)}.html">${file.name}</a>
              </li>
            `
        }}
        </ul>
      </div>
    </div>
  `
}
js_templates/repo.ts:1
Before
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import { NavHelper } from './helpers/nav.ts'
export const branchesListItems = (branches: Array<{name: string, href: string, date: string}>, defaultBranch: string): string => {
  return branches.map((branch) => {
    const badge = defaultBranch === branch.name ? '<div class="badge rounded-pill bg-primary ms-2">default</div>' : ''
    return `<a href='${branch.href}' class='dropdown-item my-1'><span class="branch-dropdown-branch-name">${branch.name}</span>${badge}<span class="text-body d-block ms-2">updated ${branch.date}</span></a>`
  }).join('')
}

export default async (reposConfig: ReposConfiguration, eleventyConfig: any) => {
  return async (data) => {
    if (data.currentRepo === '') {
      return
    }
    const repo: Repository = data.currentRepo
    const branch: Repository['branches'][0] = data.currentBranch

    const slugify = eleventyConfig.getFilter("slugify")
    const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
    const getReadMe = eleventyConfig.getFilter("getReadMe")

    const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

    const branchesWithHrefs = repo.branches.map((branch) => {
      return {
        name: branch.name,
        href: nav.repoBranchHome(branch.name),
        date: repo.commits.get(branch.head).date.toDateString(),
      }
    })

    return `
      <!doctype html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>${repo.name}</title>
          <link rel="stylesheet" href="/css/design-board.css">
          <link href="https://unpkg.com/prismjs@1.20.0/themes/prism.css" rel="stylesheet" />
          <script>
            window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
            window.defaultBranch = "${repo.defaultBranch}";
            window.cloneUrl = "${repo.cloneUrl}";
          </script>
          <script src="${nav.rootPath()}frontend/top.js"></script>
        </head>
        <body>
          <div class="container">
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.rootPath()}">&larr; All repositories</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="#">${repo.name}</a>
                    </li>
                    <li class="nav-item">
                      <span class="nav-link d-inline-block">Branch:</span>
                      <div class="branch-selector dropdown-center d-inline-block">
                        <button class="branches nav-link d-inline-block btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                          ${branch.name}
                        </button>
                        <div class="dropdown-menu">
                          <form class="mx-3 my-1">
                            <input type="text" class="form-control" id="dropdownBranchSearch" placeholder="Search branches...">
                            <div>
                              <div class="row mt-3">
                                <div class="col">
                                  <label class="form-label">Sort by:</label>
                                </div>
                              </div>
                              <div class="sortRadioButtons">
                                <div class="sortRadioButton pe-1">
                                  <input class="form-check-input" type="radio" name="branchSort" id="branchSortByDate" checked>
                                  <label class="form-check-label" for="branchSortByDate">
                                    Last commit
                                  </label>
                                </div>
                                <div class="sortRadioButton ps-1">
                                  <input class="form-check-input" type="radio" name="branchSort" id="branchSortByName">
                                  <label class="form-check-label" for="branchSortByName">
                                    Name
                                  </label>
                                </div>
                              </div>
                            </div>
                          </form>
                          <div class="dropdown-divider"></div>
                          <div id="dropdown-branches-results" class="dropdown-branches">
                            ${branchesListItems(branchesWithHrefs, repo.defaultBranch)}
                          </div>
                        </div>
                      </div>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="main-nav navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link active" aria-current="page" href="${nav.repoCurrentBranchHome()}">Home</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchFiles()}">Files</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchCommits()}">Commits</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchBranches()}">Branches</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="#">Tags</a>
                    </li>
                  </ul>
                </nav>
              </div>

            <div class="row">
              <div class="col">
                <div class="px-4 pt-3 bezel">
                    <div class="col-12 col-xl-6">
                      <h1 class="display-2 text-white"><em>${repo.name}</em></h1>
                      ${repo.description ? '<p class="text-white fs-5">' + repo.description + '</p>' : ''}
                    </div>
                    <div class="col-12 col-xl-6 d-flex flex-column">
                      <div class="row py-3 flex-grow-1 align-items-center">
                        <div class="col-12">
                          <div class="row">
                            <div class="col-12 language-percentages">
                              <span style="width: 25%;" class="language-name text-light font-monospace">HTML</span>
                              <span style="width: 15%;" class="language-name text-light font-monospace">CSS</span>
                              <span style="width: 10%;" class="language-name text-light font-monospace">Rust</span>
                              <span style="width: 33%;" class="language-name text-light font-monospace">Typescript</span>
                              <span style="width: 17%;" class="language-name text-light font-monospace">Bash</span>
                            </div>
                          </div>
                          <div class="row">
                            <div class="col-12 language-percentages">
                              <div style="background: #E273FA; width: 25%;" class="language-percent"></div>
                              <div style="background: #852CDF; width: 15%;" class="language-percent"></div>
                              <div style="background: #E273FA; width: 10%;" class="language-percent"></div>
                              <div style="background: #852CDF; width: 33%;" class="language-percent"></div>
                              <div style="background: #E273FA; width: 17%;" class="language-percent"></div>
                            </div>
                          </div>
                        </div>
                      </div>
                      <div class="row flex-grow-1 align-items-center">
                        <div class="col-md col-fluid py-3">
                          <button class="w-100 btn btn-info btn-lg dropdown-toggle" id="clone-popover-btn">Clone</button>
                        </div>
                        <div class="col-md col-fluid py-3">
                          <button class="w-100 btn btn-outline-info shadow-none btn-lg">Setup Instructions</button>
                        </div>
                      </div>
                  <noscript>
                    <div class=&quot;row mt-2"&gt;
                      <div class="col">
                        <p class="font-monospace text-white">
                          Clone URL: ${repo.cloneUrl}
                        </p>
                      </div>
                    </div>
                  </noscript>
                  <div class="row mt-2">
                    <div class="col">
                      <p class="font-monospace text-white">
                        Latest commit: ${repo.commits.get(branch.head).hash.substr(0, 6)} ${repo.commits.get(branch.head).date.toDateString()} - ${repo.commits.get(branch.head).message}
                      </p>

            <div class="row my-4 mx-1">
                ${await renderContentIfAvailable(await getReadMe(repo.name, branch.name), "md")}

          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js&quot; integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"&gt;</script>

          <script src="${nav.rootPath()}frontend/main-frontend.bundle.js&quot;&gt;</script>
        </body>
      </html>
      `
  }
After
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
export default async (eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const branch: Repository['branches'][0] = data.currentBranch
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  return `
    <div class="row">
      <div class="col">
        <div class="px-4 pt-3 bezel">
          <div class="row">
            <div class="col-12 col-xl-6">
              <h1 class="display-2 text-white"><em>${repo.name}</em></h1>
              ${repo.description ? '<p class="text-white fs-5">' + repo.description + '</p>' : ''}
            <div class="col-12 col-xl-6 d-flex flex-column">
              <div class="row py-3 flex-grow-1 align-items-center">
                <div class="col-12">
                    <div class="col-12 language-percentages">
                      <span style="width: 25%;" class="language-name text-light font-monospace">HTML</span>
                      <span style="width: 15%;" class="language-name text-light font-monospace">CSS</span>
                      <span style="width: 10%;" class="language-name text-light font-monospace">Rust</span>
                      <span style="width: 33%;" class="language-name text-light font-monospace">Typescript</span>
                      <span style="width: 17%;" class="language-name text-light font-monospace">Bash</span>
                  <div class="row">
                    <div class="col-12 language-percentages">
                      <div style="background: #E273FA; width: 25%;" class="language-percent"></div>
                      <div style="background: #852CDF; width: 15%;" class="language-percent"></div>
                      <div style="background: #E273FA; width: 10%;" class="language-percent"></div>
                      <div style="background: #852CDF; width: 33%;" class="language-percent"></div>
                      <div style="background: #E273FA; width: 17%;" class="language-percent"></div>
              <div class="row flex-grow-1 align-items-center">
                <div class="col-md col-fluid py-3">
                  <button class="w-100 btn btn-info btn-lg dropdown-toggle" id="clone-popover-btn">Clone</button>
                </div>
                <div class="col-md col-fluid py-3">
                  <button class="w-100 btn btn-outline-info shadow-none btn-lg">Setup Instructions</button>
                </div>
              </div>
          </div>
          <noscript>
            <div class="row mt-2">
                <p class="font-monospace text-white">
                  Clone URL: ${repo.cloneUrl}
                </p>
          </noscript>
          <div class="row mt-2">
            <div class="col">
              <p class="font-monospace text-white">
                Latest commit: ${repo.commits.get(branch.head).hash.substr(0, 6)} ${repo.commits.get(branch.head).date.toDateString()} - ${repo.commits.get(branch.head).message}
              </p>
            </div>
        </div>
      </div>
    </div>
    <div class="row my-4 mx-1">
      <div class="col">
        ${await renderContentIfAvailable(await getReadMe(repo.name, branch.name), "md")}
      </div>
    </div>
  `
main.ts:11
Before
11
After
11
import htmlPage from './js_templates/common/htmlPage.ts'
main.ts:414
Before
414
  const template = repoJsTemplate(reposConfiguration, eleventyConfig)
After
414
  const template = htmlPage(reposConfiguration, eleventyConfig, repoJsTemplate)
package-lock.json:20
Before
20
        "webpack": "^5.103.0"
After
20
        "webpack": "^5.103.0",
        "webpack-cli": "^6.0.1"
      }
    },
    "node_modules/@discoveryjs/json-ext": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
      "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=14.17.0"
package-lock.json:677
Before
677
After
677
    "node_modules/@webpack-cli/configtest": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz",
      "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=18.12.0"
      },
      "peerDependencies": {
        "webpack": "^5.82.0",
        "webpack-cli": "6.x.x"
      }
    },
    "node_modules/@webpack-cli/info": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz",
      "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=18.12.0"
      },
      "peerDependencies": {
        "webpack": "^5.82.0",
        "webpack-cli": "6.x.x"
      }
    },
    "node_modules/@webpack-cli/serve": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz",
      "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=18.12.0"
      },
      "peerDependencies": {
        "webpack": "^5.82.0",
        "webpack-cli": "6.x.x"
      },
      "peerDependenciesMeta": {
        "webpack-dev-server": {
          "optional": true
        }
      }
    },
package-lock.json:929
Before
929
After
929
    "node_modules/clone-deep": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "is-plain-object": "^2.0.4",
        "kind-of": "^6.0.2",
        "shallow-clone": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
package-lock.json:949
Before
949
After
949
    "node_modules/colorette": {
      "version": "2.0.20",
      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
      "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
      "dev": true,
      "license": "MIT"
    },
package-lock.json:1041
Before
1041
After
1041
    "node_modules/envinfo": {
      "version": "7.21.0",
      "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz",
      "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==",
      "dev": true,
      "license": "MIT",
      "bin": {
        "envinfo": "dist/cli.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
package-lock.json:1130
Before
1130
After
1130
    "node_modules/fastest-levenshtein": {
      "version": "1.0.16",
      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 4.9.1"
      }
    },
package-lock.json:1143
Before
1143
After
1143
    "node_modules/find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/flat": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
      "dev": true,
      "license": "BSD-3-Clause",
      "bin": {
        "flat": "cli.js"
      }
    },
package-lock.json:1160
Before
1160
After
1160
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
      "dev": true,
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
package-lock.json:1205
Before
1205
After
1205
    "node_modules/hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/import-local": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
      "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "pkg-dir": "^4.2.0",
        "resolve-cwd": "^3.0.0"
      },
      "bin": {
        "import-local-fixture": "fixtures/cli.js"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/interpret": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
      "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/is-core-module": {
      "version": "2.16.1",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
      "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
package-lock.json:1254
Before
1254
After
1254
    "node_modules/is-plain-object": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "isobject": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
package-lock.json:1261
Before
1261
After
1261
    "node_modules/isobject": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=0.10.0"
      }
    },
package-lock.json:1316
Before
1316
After
1316
    "node_modules/kind-of": {
      "version": "6.0.3",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=0.10.0"
      }
    },
package-lock.json:1338
Before
1338
After
1338
    "node_modules/locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "p-locate": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
package-lock.json:1479
Before
1479
After
1479
    "node_modules/p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "p-limit": "^2.2.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=6"
      }
    },
package-lock.json:1486
Before
1486
After
1486
    "node_modules/path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
package-lock.json:1496
Before
1496
After
1496
    "node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true,
      "license": "MIT"
    },
package-lock.json:1532
Before
1532
After
1532
    "node_modules/pkg-dir": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "find-up": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
package-lock.json:1563
Before
1563
After
1563
    "node_modules/rechoir": {
      "version": "0.8.0",
      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
      "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "resolve": "^1.20.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      }
    },
package-lock.json:1572
Before
1572
After
1572
    "node_modules/resolve": {
      "version": "1.22.11",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
      "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "is-core-module": "^2.16.1",
        "path-parse": "^1.0.7",
        "supports-preserve-symlinks-flag": "^1.0.0"
      },
      "bin": {
        "resolve": "bin/resolve"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/resolve-cwd": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
      "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "resolve-from": "^5.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/resolve-from": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
package-lock.json:1650
Before
1650
After
1650
    "node_modules/shallow-clone": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "kind-of": "^6.0.2"
      },
      "engines": {
        "node": ">=8"
      }
    },
package-lock.json:1833
Before
1833
After
1833
    "node_modules/supports-preserve-symlinks-flag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
package-lock.json:2103
Before
2103
After
2103
    "node_modules/webpack-cli": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz",
      "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "@discoveryjs/json-ext": "^0.6.1",
        "@webpack-cli/configtest": "^3.0.1",
        "@webpack-cli/info": "^3.0.1",
        "@webpack-cli/serve": "^3.0.1",
        "colorette": "^2.0.14",
        "commander": "^12.1.0",
        "cross-spawn": "^7.0.3",
        "envinfo": "^7.14.0",
        "fastest-levenshtein": "^1.0.12",
        "import-local": "^3.0.2",
        "interpret": "^3.1.1",
        "rechoir": "^0.8.0",
        "webpack-merge": "^6.0.1"
      },
      "bin": {
        "webpack-cli": "bin/cli.js"
      },
      "engines": {
        "node": ">=18.12.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^5.82.0"
      },
      "peerDependenciesMeta": {
        "webpack-bundle-analyzer": {
          "optional": true
        },
        "webpack-dev-server": {
          "optional": true
        }
      }
    },
    "node_modules/webpack-cli/node_modules/commander": {
      "version": "12.1.0",
      "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
      "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/webpack-merge": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
      "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "clone-deep": "^4.0.1",
        "flat": "^5.0.2",
        "wildcard": "^2.0.1"
      },
      "engines": {
        "node": ">=18.0.0"
      }
    },
package-lock.json:2128
Before
2128
After
2128
    "node_modules/wildcard": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
      "dev": true,
      "license": "MIT"
    },
package.json:23
Before
23
    "webpack": "^5.103.0"
After
23
    "webpack": "^5.103.0",
    "webpack-cli": "^6.0.1"