create-astrale-domain 0.3.0-beta.63 → 0.3.0-beta.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/index.js +9 -26
- package/package.json +4 -4
- package/template/.variants/custom/README.md +10 -8
- package/template/.variants/custom/application.ts +10 -2
- package/template/.variants/custom/{views/application/app → frontend}/main.ts +1 -1
- package/template/.variants/custom/frontend/package.json +11 -0
- package/template/.variants/custom/frontend/tsconfig.json +17 -0
- package/template/.variants/custom/views/application/index.ts +1 -0
- package/template/.variants/custom/views/index.ts +1 -1
- package/template/.variants/custom/vite.config.ts +11 -2
- package/template/.variants/none/README.md +3 -1
- package/template/.variants/react/README.md +9 -7
- package/template/.variants/react/application.ts +10 -2
- package/template/CLAUDE.md +6 -0
- package/template/.variants/custom/views/application/__tests__/routes.test.ts +0 -7
- package/template/.variants/custom/views/application/routes.ts +0 -12
- package/template/.variants/react/views/application/__tests__/routes.test.ts +0 -7
- package/template/.variants/react/views/application/routes.ts +0 -12
- package/template/.variants/react/views/index.ts +0 -1
- /package/template/.variants/custom/{views/application/app → frontend}/index.html +0 -0
- /package/template/.variants/custom/{views/application/app → frontend}/public/favicon.svg +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.0-beta.65](https://github.com/astrale-os/sdk/compare/create-astrale-domain-v0.3.0-beta.64...create-astrale-domain-v0.3.0-beta.65) (2026-08-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add coordinated Domain development sessions ([#300](https://github.com/astrale-os/sdk/issues/300)) ([102104f](https://github.com/astrale-os/sdk/commit/102104f1ed55333f5892db23c036578aa0ffd2e1))
|
|
9
|
+
* **tooling:** keep frontend composition application-owned ([#310](https://github.com/astrale-os/sdk/issues/310)) ([31e9bb6](https://github.com/astrale-os/sdk/commit/31e9bb6de256ef9cdbcdb0296abb973086f11ff0))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Dependencies
|
|
13
|
+
|
|
14
|
+
* The following workspace dependencies were updated
|
|
15
|
+
* dependencies
|
|
16
|
+
* @astrale-os/adapter-astrale bumped to 0.5.0-beta.65
|
|
17
|
+
* @astrale-os/adapter-cloudflare bumped to 0.5.0-beta.72
|
|
18
|
+
* devDependencies
|
|
19
|
+
* @astrale-os/sdk bumped to 0.5.0-beta.69
|
|
20
|
+
|
|
21
|
+
## [0.3.0-beta.64](https://github.com/astrale-os/sdk/compare/create-astrale-domain-v0.3.0-beta.63...create-astrale-domain-v0.3.0-beta.64) (2026-08-28)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Dependencies
|
|
25
|
+
|
|
26
|
+
* The following workspace dependencies were updated
|
|
27
|
+
* dependencies
|
|
28
|
+
* @astrale-os/adapter-astrale bumped to 0.5.0-beta.64
|
|
29
|
+
* @astrale-os/adapter-cloudflare bumped to 0.5.0-beta.71
|
|
30
|
+
* devDependencies
|
|
31
|
+
* @astrale-os/sdk bumped to 0.5.0-beta.68
|
|
32
|
+
|
|
3
33
|
## [0.3.0-beta.63](https://github.com/astrale-os/sdk/compare/create-astrale-domain-v0.3.0-beta.62...create-astrale-domain-v0.3.0-beta.63) (2026-08-28)
|
|
4
34
|
|
|
5
35
|
|
package/dist/index.js
CHANGED
|
@@ -781,7 +781,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
781
781
|
|
|
782
782
|
// src/index.ts
|
|
783
783
|
import { existsSync as existsSync2 } from "node:fs";
|
|
784
|
-
import {
|
|
784
|
+
import { relative as relative2, resolve as resolve2 } from "node:path";
|
|
785
785
|
|
|
786
786
|
// src/scaffold/index.ts
|
|
787
787
|
import { signingIdentity } from "@astrale-os/adapter-cloudflare/build";
|
|
@@ -795,7 +795,7 @@ var HERE = dirname(fileURLToPath(import.meta.url));
|
|
|
795
795
|
var CREATE_PACKAGE_ROOT = owningPackageRoot(HERE, "create-astrale-domain");
|
|
796
796
|
var SDK_ROOT = sdkCheckoutRoot(CREATE_PACKAGE_ROOT);
|
|
797
797
|
var ORIGIN_PLACEHOLDER = "astrale-domain.example.dev";
|
|
798
|
-
var
|
|
798
|
+
var INSTANCE_DECLARATION = "const targetInstance: string | undefined = undefined";
|
|
799
799
|
var LINK_PACKAGES = /* @__PURE__ */ new Set([
|
|
800
800
|
"@astrale-os/sdk",
|
|
801
801
|
"@astrale-os/adapter-cloudflare",
|
|
@@ -1031,7 +1031,7 @@ async function materializeAdapter(opts) {
|
|
|
1031
1031
|
await cp(join(templateDir(ADAPTER_PACKAGES[opts.adapter]), "astrale.config.ts"), config);
|
|
1032
1032
|
await addAdapterDependency(opts.dir, ADAPTER_PACKAGES[opts.adapter]);
|
|
1033
1033
|
if (opts.adapter === "astrale" && opts.instance) {
|
|
1034
|
-
await replaceInFile(config, `
|
|
1034
|
+
await replaceInFile(config, INSTANCE_DECLARATION, `const targetInstance = '${opts.instance}'`);
|
|
1035
1035
|
}
|
|
1036
1036
|
}
|
|
1037
1037
|
async function addAdapterDependency(dir, adapter) {
|
|
@@ -1058,6 +1058,10 @@ var PREPACK_COMMANDS = {
|
|
|
1058
1058
|
};
|
|
1059
1059
|
async function materializePackageManagerInstructions(dir, packageManager) {
|
|
1060
1060
|
const replacements = [
|
|
1061
|
+
[
|
|
1062
|
+
"pnpm dev --host <origin> --port <port>",
|
|
1063
|
+
packageManagerScript(packageManager, "dev", "--host <origin> --port <port>")
|
|
1064
|
+
],
|
|
1061
1065
|
["pnpm run deploy prod", packageManagerScript(packageManager, "deploy", "prod")],
|
|
1062
1066
|
["pnpm deploy prod", packageManagerScript(packageManager, "deploy", "prod")],
|
|
1063
1067
|
["pnpm prod", packageManagerScript(packageManager, "deploy", "prod")],
|
|
@@ -1150,12 +1154,6 @@ function localPackageRoot(dependency) {
|
|
|
1150
1154
|
|
|
1151
1155
|
// src/index.ts
|
|
1152
1156
|
var PMS = ["pnpm", "npm", "yarn", "bun"];
|
|
1153
|
-
var DLX = {
|
|
1154
|
-
pnpm: "pnpm dlx",
|
|
1155
|
-
npm: "npx",
|
|
1156
|
-
yarn: "yarn dlx",
|
|
1157
|
-
bun: "bunx"
|
|
1158
|
-
};
|
|
1159
1157
|
var ADAPTERS = [
|
|
1160
1158
|
{
|
|
1161
1159
|
value: "astrale",
|
|
@@ -1326,7 +1324,6 @@ async function main() {
|
|
|
1326
1324
|
`cd ${cdTarget}`,
|
|
1327
1325
|
`${pm} install`,
|
|
1328
1326
|
devStep(pm),
|
|
1329
|
-
installStep(pm),
|
|
1330
1327
|
deployStep(pm, adapter, instance)
|
|
1331
1328
|
].join("\n"),
|
|
1332
1329
|
"Next"
|
|
@@ -1342,26 +1339,12 @@ async function main() {
|
|
|
1342
1339
|
Se(`\u2713 ${slug} ready`);
|
|
1343
1340
|
return 0;
|
|
1344
1341
|
}
|
|
1345
|
-
var devStep = (pm) => `${packageManagerScript(pm, "dev")} #
|
|
1342
|
+
var devStep = (pm) => `${packageManagerScript(pm, "dev")} # complete development session`;
|
|
1346
1343
|
var deployStep = (pm, adapter, instance) => {
|
|
1347
1344
|
const hint = adapter === "astrale" ? `# managed deploy \u2192 installs on ${instance ? `"${instance}"` : "your instance"}` : "# deploy production \u2192 prints a URL";
|
|
1348
1345
|
return `${deployCommand(pm)} ${hint}`;
|
|
1349
1346
|
};
|
|
1350
1347
|
var deployCommand = (pm) => packageManagerScript(pm, "deploy", "prod");
|
|
1351
|
-
function installStep(pm) {
|
|
1352
|
-
if (astraleOnPath()) return "astrale domain install <url> --direct # mount it on an instance";
|
|
1353
|
-
return [
|
|
1354
|
-
"# astrale CLI not found on PATH \u2014 run it on demand (no install):",
|
|
1355
|
-
`${DLX[pm]} @astrale-os/cli domain install <url> --direct`,
|
|
1356
|
-
"# or install it globally: npm i -g @astrale-os/cli"
|
|
1357
|
-
].join("\n");
|
|
1358
|
-
}
|
|
1359
|
-
function astraleOnPath() {
|
|
1360
|
-
const path = process.env.PATH;
|
|
1361
|
-
if (!path) return false;
|
|
1362
|
-
const names = process.platform === "win32" ? ["astrale.cmd", "astrale.exe", "astrale.bat", "astrale"] : ["astrale"];
|
|
1363
|
-
return path.split(delimiter).some((d3) => d3.length > 0 && names.some((n) => existsSync2(join2(d3, n))));
|
|
1364
|
-
}
|
|
1365
1348
|
function detectPm() {
|
|
1366
1349
|
const name = process.env.npm_config_user_agent?.split("/")[0];
|
|
1367
1350
|
return PMS.find((p2) => p2 === name);
|
|
@@ -1408,7 +1391,7 @@ Arguments:
|
|
|
1408
1391
|
Options:
|
|
1409
1392
|
--adapter <id> deployment adapter \u2014 astrale (managed, default) | cloudflare
|
|
1410
1393
|
--frontend <id> react (default) | custom | none
|
|
1411
|
-
--instance <slug> target instance for managed
|
|
1394
|
+
--instance <slug> target instance for managed development and deploys
|
|
1412
1395
|
--pm <pm> pnpm | npm | yarn | bun (default: detected, else pnpm)
|
|
1413
1396
|
--dir <path> target directory (default: ./<slug>)
|
|
1414
1397
|
--origin <fqdn> domain identity origin (default: <slug>.example.dev)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-astrale-domain",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.65",
|
|
4
4
|
"description": "Scaffold a standalone Astrale domain — npm create astrale-domain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astrale",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"registry": "https://registry.npmjs.org/"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@astrale-os/adapter-astrale": "0.5.0-beta.
|
|
34
|
-
"@astrale-os/adapter-cloudflare": "0.5.0-beta.
|
|
33
|
+
"@astrale-os/adapter-astrale": "0.5.0-beta.65",
|
|
34
|
+
"@astrale-os/adapter-cloudflare": "0.5.0-beta.72",
|
|
35
35
|
"@clack/prompts": "^0.11.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@astrale-os/ox": "0.1.3",
|
|
39
|
-
"@astrale-os/sdk": "0.5.0-beta.
|
|
39
|
+
"@astrale-os/sdk": "0.5.0-beta.69",
|
|
40
40
|
"@types/node": "^22.0.0",
|
|
41
41
|
"esbuild": "^0.28.2",
|
|
42
42
|
"oxfmt": "0.63.0",
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# Astrale Domain
|
|
2
2
|
|
|
3
|
-
This project uses the framework-neutral frontend escape hatch. `
|
|
4
|
-
|
|
5
|
-
framework; `ui/` owns presentation assets. The starter route uses
|
|
6
|
-
as a plain hosted app. Change that route to `handshake: 'shell'`
|
|
7
|
-
boots the Shell protocol.
|
|
3
|
+
This project uses the framework-neutral frontend escape hatch. `application.ts` binds declared
|
|
4
|
+
Schema Views to `defineFrontend`; `vite.config.ts` owns the ordinary `frontend/` Vite root you can
|
|
5
|
+
replace with any framework; `ui/` owns presentation assets. The starter route uses
|
|
6
|
+
`handshake: 'none'`, so it mounts as a plain hosted app. Change that route to `handshake: 'shell'`
|
|
7
|
+
only after your browser entrypoint boots the Shell protocol.
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
10
|
schema/ public Domain contract, including View declarations
|
|
11
11
|
runtime.ts Actions, Workflows, Integrations, Providers, and initialization
|
|
12
12
|
application.ts Schema, Runtime, and frontend composition
|
|
13
|
-
views/
|
|
14
|
-
|
|
13
|
+
views/application/ application View projection and mount behavior
|
|
14
|
+
frontend/ browser entrypoint and assets
|
|
15
15
|
ui/application/ application presentation, tokens, and styles
|
|
16
16
|
tests/ cross-layer executable journeys
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Run `pnpm dev` for
|
|
19
|
+
Run `pnpm dev` for Worker and browser hot reload. With the managed Astrale adapter, it also creates
|
|
20
|
+
temporary public ingress, installs each ready revision on the selected (or active) instance, and
|
|
21
|
+
opens its View. Run `pnpm build` to build both Worker and browser assets.
|
|
20
22
|
Domain projects intentionally own no `.spec` trees and import authoring contracts only through
|
|
21
23
|
semantic `@astrale-os/sdk/*` subpaths.
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { defineApplication } from '@astrale-os/sdk/application'
|
|
1
|
+
import { defineApplication, defineFrontend, vite } from '@astrale-os/sdk/application'
|
|
2
2
|
|
|
3
3
|
import { schema } from '#schema'
|
|
4
|
-
import { frontend } from '#views'
|
|
5
4
|
|
|
6
5
|
import runtime from './runtime.js'
|
|
7
6
|
|
|
7
|
+
/** Framework-neutral escape hatch: swap Vite or the browser implementation without changing Views. */
|
|
8
|
+
const frontend = defineFrontend({
|
|
9
|
+
schema,
|
|
10
|
+
source: vite(),
|
|
11
|
+
routes: {
|
|
12
|
+
application: { handshake: 'none' },
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
8
16
|
/** Build and publication composition; provider effects live in astrale.config.ts. */
|
|
9
17
|
export const application = defineApplication({ schema, runtime, frontend })
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"paths": {
|
|
8
|
+
"#views/*": ["../views/*/index.ts"]
|
|
9
|
+
},
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"skipLibCheck": false,
|
|
14
|
+
"verbatimModuleSyntax": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["main.ts"]
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { mountApplication } from './application.view.js'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { mountApplication } from './application/index.js'
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
1
2
|
import { defineConfig } from 'vite'
|
|
2
3
|
|
|
3
4
|
export default defineConfig({
|
|
4
|
-
root: '
|
|
5
|
+
root: 'frontend',
|
|
6
|
+
resolve: {
|
|
7
|
+
alias: [
|
|
8
|
+
{
|
|
9
|
+
find: /^#views\//,
|
|
10
|
+
replacement: fileURLToPath(new URL('./views/', import.meta.url)),
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
},
|
|
5
14
|
build: {
|
|
6
|
-
outDir: '
|
|
15
|
+
outDir: '../dist/frontend',
|
|
7
16
|
emptyOutDir: true,
|
|
8
17
|
},
|
|
9
18
|
})
|
|
@@ -9,6 +9,8 @@ application.ts Schema and Runtime composition
|
|
|
9
9
|
tests/ cross-layer executable journeys
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Run `pnpm dev` for
|
|
12
|
+
Run `pnpm dev` for Worker hot reload. With the managed Astrale adapter, it also creates temporary
|
|
13
|
+
public ingress and installs each ready revision on the selected (or active) instance; it simply
|
|
14
|
+
skips browser startup because this Domain declares no frontend. Run `pnpm build` to qualify its deploy bundle. Add `views/` and
|
|
13
15
|
`ui/` later only when the schema gains declared Views. Domain projects intentionally own no `.spec`
|
|
14
16
|
trees and import authoring contracts only through semantic `@astrale-os/sdk/*` subpaths.
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
# Astrale Domain
|
|
2
2
|
|
|
3
|
-
This project is an ordinary Vite React application. `
|
|
4
|
-
|
|
5
|
-
presentation. It has no mandatory Shell runtime: add
|
|
6
|
-
the application genuinely needs Shell sessions, graph
|
|
3
|
+
This project is an ordinary Vite React application. `application.ts` owns the small Worker-safe,
|
|
4
|
+
Schema-bound frontend deployment contract; `frontend/` owns TanStack Router and browser
|
|
5
|
+
composition; `ui/` owns reusable presentation. It has no mandatory Shell runtime: add
|
|
6
|
+
`@astrale-os/shell-react` independently when the application genuinely needs Shell sessions, graph
|
|
7
|
+
context, or View-stage integration.
|
|
7
8
|
|
|
8
9
|
```text
|
|
9
10
|
schema/ public Domain contract, including View declarations
|
|
10
11
|
runtime.ts Actions, Workflows, Integrations, Providers, and initialization
|
|
11
12
|
application.ts Schema, Runtime, and frontend composition
|
|
12
|
-
views/ schema-bound frontend declaration
|
|
13
13
|
frontend/ Vite, file-based TanStack Router, and Tailwind entrypoint
|
|
14
14
|
ui/ styles and pure presentation components
|
|
15
15
|
tests/ cross-layer executable journeys
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
Run `pnpm dev` for one Worker-facing URL with Vite HMR
|
|
19
|
-
|
|
18
|
+
Run `pnpm dev` for one Worker-facing URL with Vite HMR. With the managed Astrale adapter, that same
|
|
19
|
+
command also creates a temporary public ingress, installs each ready revision on the selected (or
|
|
20
|
+
active) instance, and opens its View. Run `pnpm build` to qualify Worker and frontend output, and
|
|
21
|
+
`pnpm run deploy prod` to deploy through the selected adapter. Add semantic `rules/`, `queries/`,
|
|
20
22
|
`mutations/`, and `actions/` modules only when the Domain gains those responsibilities.
|
|
21
23
|
|
|
22
24
|
Domain projects intentionally own no `.spec` trees. Import authoring contracts through semantic
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { defineApplication } from '@astrale-os/sdk/application'
|
|
1
|
+
import { defineApplication, defineFrontend, vite } from '@astrale-os/sdk/application'
|
|
2
2
|
|
|
3
3
|
import { schema } from '#schema'
|
|
4
|
-
import { frontend } from '#views'
|
|
5
4
|
|
|
6
5
|
import runtime from './runtime.js'
|
|
7
6
|
|
|
7
|
+
/** The complete deploy contract; Vite and the browser application stay author-owned. */
|
|
8
|
+
const frontend = defineFrontend({
|
|
9
|
+
schema,
|
|
10
|
+
source: vite(),
|
|
11
|
+
routes: {
|
|
12
|
+
application: { handshake: 'none' },
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
8
16
|
/** Build and publication composition; provider effects live in astrale.config.ts. */
|
|
9
17
|
export const application = defineApplication({ schema, runtime, frontend })
|
package/template/CLAUDE.md
CHANGED
|
@@ -27,6 +27,12 @@ Schema contract at the package root. Runtime, handlers, Providers, frontend code
|
|
|
27
27
|
adapters remain implementation inputs and are not published. Do not add a parallel build or
|
|
28
28
|
declaration-rewrite script.
|
|
29
29
|
|
|
30
|
+
`pnpm dev` owns the complete development session. With the managed Astrale adapter it acquires
|
|
31
|
+
private ingress, starts Worker and optional Vite hot reload, reconciles the Domain installation on
|
|
32
|
+
the configured or active instance, and opens the View when one exists. Stop closes only local
|
|
33
|
+
processes; it retains the installation and local reconciliation evidence for the next run. Do not
|
|
34
|
+
add a parallel tunnel, install loop, frontend watcher, or automatic shutdown uninstall.
|
|
35
|
+
|
|
30
36
|
Domain projects do not contain `.spec` directories. Do not add one: public SDK types, package
|
|
31
37
|
facades, the Domain knowledge rules, and executable tests are the contract guardrails. Import Core
|
|
32
38
|
and DSL authoring values only from the matching `@astrale-os/sdk/*` semantic subpath; never import
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { defineFrontend, vite } from '@astrale-os/sdk/view'
|
|
2
|
-
|
|
3
|
-
import { schema } from '#schema'
|
|
4
|
-
|
|
5
|
-
/** Framework-neutral escape hatch: swap Vite or the browser implementation without changing Views. */
|
|
6
|
-
export const frontend = defineFrontend({
|
|
7
|
-
schema,
|
|
8
|
-
source: vite(),
|
|
9
|
-
routes: {
|
|
10
|
-
application: { handshake: 'none' },
|
|
11
|
-
},
|
|
12
|
-
})
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { defineFrontend, vite } from '@astrale-os/sdk/view'
|
|
2
|
-
|
|
3
|
-
import { schema } from '#schema'
|
|
4
|
-
|
|
5
|
-
/** The complete deploy contract; Vite and the browser application stay author-owned. */
|
|
6
|
-
export const frontend = defineFrontend({
|
|
7
|
-
schema,
|
|
8
|
-
source: vite(),
|
|
9
|
-
routes: {
|
|
10
|
-
application: { handshake: 'none' },
|
|
11
|
-
},
|
|
12
|
-
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { frontend } from './application/routes.js'
|
|
File without changes
|
|
File without changes
|