@peachy/hooks 0.0.9 → 0.0.11

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @peachy/hooks
2
2
 
3
+ ## 0.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 3e37e37: Improve types for useBinding hook
8
+
9
+ ## 0.0.10
10
+
11
+ ### Patch Changes
12
+
13
+ - b74728b: Add useDarkMode and useAccentColor hook
14
+
3
15
  ## 0.0.9
4
16
 
5
17
  ## 0.0.8
package/README.md CHANGED
@@ -24,11 +24,7 @@ import { useNetworkMonitor } from "@peachy/hooks";
24
24
  const App = () => {
25
25
  const { connected } = useNetworkMonitor();
26
26
 
27
- return (
28
- <Gtk.Label>
29
- {connected ? "Connected" : "Disconnected"}
30
- </Gtk.Label>
31
- );
27
+ return <Gtk.Label>{connected ? "Connected" : "Disconnected"}</Gtk.Label>;
32
28
  };
33
29
  ```
34
30
 
@@ -51,12 +47,8 @@ const App = () => {
51
47
 
52
48
  return (
53
49
  <Gtk.Box>
54
- <Gtk.Label>
55
- Theme: {value}
56
- </Gtk.Label>
57
- <Gtk.Button onClick={() => changeValue("Adwaita-dark")}>
58
- Change Theme
59
- </Gtk.Button>
50
+ <Gtk.Label>Theme: {value}</Gtk.Label>
51
+ <Gtk.Button onClick={() => changeValue("Adwaita-dark")}>Change Theme</Gtk.Button>
60
52
  </Gtk.Box>
61
53
  );
62
54
  };
@@ -68,6 +60,8 @@ const App = () => {
68
60
 
69
61
  Bind to a property, and listen for changes.
70
62
 
63
+ NOTE: You can provide a default value for the hook as third parameter
64
+
71
65
  ```tsx
72
66
  import Adw from "gi://Adw?version=1";
73
67
 
@@ -81,14 +75,34 @@ const App = () => {
81
75
 
82
76
  return (
83
77
  <Gtk.Box>
84
- <Gtk.Label>
85
- Theme: {darkMode ? "Dark" : "Light"}
86
- </Gtk.Label>
87
-
88
- <Gtk.Label>
89
- Accent Color: {accentColor}
90
- </Gtk.Label>
78
+ <Gtk.Label>Theme: {darkMode ? "Dark" : "Light"}</Gtk.Label>
79
+
80
+ <Gtk.Label>Accent Color: {accentColor}</Gtk.Label>
91
81
  </Gtk.Box>
92
82
  );
93
83
  };
94
84
  ```
85
+
86
+ ### Adwaita
87
+
88
+ #### `useDarkMode`
89
+
90
+ Allows checking the current dark mode state and setting it.
91
+
92
+ ```ts
93
+ import { useDarkMode } from "@peachy/hooks";
94
+
95
+ const [darkMode, setDarkMode] = useDarkMode();
96
+ ```
97
+
98
+ #### `useAccentColor`
99
+
100
+ Allows checking the current accent color if set.
101
+
102
+ ```ts
103
+ import { useAccentColor } from "@peachy/hooks";
104
+
105
+ const [accentColor] = useAccentColor();
106
+
107
+ // NOTE: returns `null` if accent colors are unsupported
108
+ ```
@@ -0,0 +1,3 @@
1
+ import { useAccentColor } from "./use-accent-color.mjs";
2
+ import { useDarkMode } from "./use-dark-mode.mjs";
3
+ export { useAccentColor, useDarkMode };
@@ -0,0 +1,4 @@
1
+ import { useAccentColor } from "./use-accent-color.mjs";
2
+ import { useDarkMode } from "./use-dark-mode.mjs";
3
+
4
+ export { useAccentColor, useDarkMode };
@@ -0,0 +1,8 @@
1
+ //#region src/adw/use-accent-color.d.ts
2
+ /**
3
+ * Query the system's accent color if supported
4
+ * @returns [accentColor] - accent color or null
5
+ */
6
+ declare function useAccentColor(): any[];
7
+ //#endregion
8
+ export { useAccentColor };
@@ -0,0 +1,19 @@
1
+ import { useBinding } from "../gobject/use-binding.mjs";
2
+ import "../gobject/index.mjs";
3
+ import { useRef } from "react";
4
+ import Adw from "gi://Adw?version=1";
5
+
6
+ //#region src/adw/use-accent-color.ts
7
+ /**
8
+ * Query the system's accent color if supported
9
+ * @returns [accentColor] - accent color or null
10
+ */
11
+ function useAccentColor() {
12
+ const styleManager = useRef(Adw.StyleManager.get_default());
13
+ const [accentColor] = useBinding(styleManager, "accent-color");
14
+ const [systemSupportsAccentColors] = useBinding(styleManager, "system-supports-accent-colors");
15
+ return [systemSupportsAccentColors ? accentColor : null];
16
+ }
17
+
18
+ //#endregion
19
+ export { useAccentColor };
@@ -0,0 +1,4 @@
1
+ //#region src/adw/use-dark-mode.d.ts
2
+ declare function useDarkMode(): any[];
3
+ //#endregion
4
+ export { useDarkMode };
@@ -0,0 +1,16 @@
1
+ import { useBinding } from "../gobject/use-binding.mjs";
2
+ import "../gobject/index.mjs";
3
+ import { useCallback, useRef } from "react";
4
+ import Adw from "gi://Adw?version=1";
5
+
6
+ //#region src/adw/use-dark-mode.ts
7
+ function useDarkMode() {
8
+ const styleManager = useRef(Adw.StyleManager.get_default());
9
+ const [isDark] = useBinding(styleManager, "dark");
10
+ return [isDark, useCallback((value) => {
11
+ styleManager.current.set_color_scheme(value ? Adw.ColorScheme.PREFER_DARK : Adw.ColorScheme.PREFER_LIGHT);
12
+ }, [styleManager])];
13
+ }
14
+
15
+ //#endregion
16
+ export { useDarkMode };
@@ -1,26 +1,27 @@
1
- import { useCallback, useEffect, useState } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import Gio from "gi://Gio?version=2.0";
3
3
 
4
4
  //#region src/gio/use-network-monitor.ts
5
5
  function useNetworkMonitor() {
6
- const monitor = Gio.NetworkMonitor.get_default();
6
+ const monitor = useRef(Gio.NetworkMonitor.get_default());
7
7
  const [state, setState] = useState(() => calculateState());
8
8
  const calculateState = useCallback(() => {
9
9
  return {
10
- available: monitor.network_available,
11
- connected: monitor.connectivity === Gio.NetworkConnectivity.FULL,
12
- state: monitor.connectivity,
13
- metered: monitor.network_metered
10
+ available: monitor.current.networkAvailable,
11
+ connected: monitor.current.connectivity === Gio.NetworkConnectivity.FULL,
12
+ state: monitor.current.connectivity,
13
+ metered: monitor.current.networkMetered
14
14
  };
15
- }, []);
15
+ }, [monitor]);
16
16
  useEffect(() => {
17
- const id = monitor.connect("network-changed", () => {
17
+ const monitorObj = monitor.current;
18
+ const id = monitorObj.connect("network-changed", () => {
18
19
  setState(calculateState());
19
20
  });
20
21
  return () => {
21
- monitor.disconnect(id);
22
+ monitorObj.disconnect(id);
22
23
  };
23
- }, []);
24
+ }, [calculateState]);
24
25
  return state;
25
26
  }
26
27
 
@@ -1,21 +1,25 @@
1
- import { useEffect, useState } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import Gio from "gi://Gio?version=2.0";
3
3
 
4
4
  //#region src/gio/use-setting.ts
5
5
  function useSetting(schema, key) {
6
- const settings = Gio.Settings.new(schema);
7
- const getValue = () => settings.get_value(key).recursiveUnpack();
6
+ const settings = useRef(Gio.Settings.new(schema));
7
+ const getValue = useCallback(() => settings.current.get_value(key).recursiveUnpack(), [key, settings]);
8
8
  const [value, setValue] = useState(() => getValue());
9
9
  useEffect(() => {
10
- const handler = settings.connect("changed::" + key, () => {
10
+ let settingsObj = settings.current;
11
+ const handler = settingsObj.connect(`changed::${key}`, () => {
11
12
  setValue(getValue());
12
13
  });
13
- return () => settings.disconnect(handler);
14
- }, [settings, key]);
15
- const changeValue = (newValue) => {
16
- settings.set_value(key, newValue);
17
- };
18
- return [value, changeValue];
14
+ return () => settingsObj.disconnect(handler);
15
+ }, [
16
+ settings,
17
+ key,
18
+ getValue
19
+ ]);
20
+ return [value, useCallback(() => (newValue) => {
21
+ settings.current.set_value(key, newValue);
22
+ }, [key])];
19
23
  }
20
24
 
21
25
  //#endregion
@@ -2,8 +2,10 @@ import { RefObject } from "react";
2
2
  import GObject from "gi://GObject?version=2.0";
3
3
 
4
4
  //#region src/gobject/use-binding.d.ts
5
- type NonFunctionKeys<T> = { [K in keyof T]: T[K] extends Function ? never : K extends Symbol ? never : K extends number ? never : K }[keyof T];
6
- declare function useBinding<T extends GObject.Object, Prop extends NonFunctionKeys<T>>(object: T | RefObject<T>, property: Prop, defaultValue?: T[Prop], converter?: undefined): [T[Prop]];
7
- declare function useBinding<T extends GObject.Object, Prop extends NonFunctionKeys<T>, Converter extends (value: T[Prop]) => any>(object: T | RefObject<T>, property: Prop, defaultValue: T[Prop] | undefined, converter: Converter): [ReturnType<Converter>];
5
+ type PropertyOf<T extends GObject.Object> = Extract<keyof T["$readableProperties"], string>;
6
+ type PropertyType<T, Prop extends keyof T> = T["$readableProperties"][Prop];
7
+ declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T>, property: Prop, defaultValue?: null): [PropType];
8
+ declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T | null>, property: Prop, defaultValue: PropType): [PropType];
9
+ declare function useBinding<T extends GObject.Object, Prop extends PropertyOf<T>, PropType extends PropertyType<T, Prop>>(object: T | RefObject<T | null>, property: Prop, defaultValue?: null): [PropType | null];
8
10
  //#endregion
9
11
  export { useBinding };
@@ -3,31 +3,23 @@ import "../base/index.mjs";
3
3
  import { useEffect, useState } from "react";
4
4
 
5
5
  //#region src/gobject/use-binding.ts
6
- function useBinding(object, _property, defaultValue, converter) {
7
- const property = toKebabCase(_property);
6
+ function useBinding(object, property, defaultValue) {
8
7
  const value = useReference(object);
9
8
  const [result, setResult] = useState(() => {
10
- if (!value) return defaultValue;
11
- const initialResult = value[property];
12
- return converter ? converter(initialResult) : initialResult;
9
+ if (!value) return defaultValue ?? null;
10
+ return value[property];
13
11
  });
14
12
  useEffect(() => {
15
- if (!value) {
16
- console.error(`Object is null or undefined`);
17
- return;
18
- }
13
+ if (!value) return;
19
14
  const id = value.connect(`notify::${property}`, () => {
20
15
  setResult(value[property]);
21
16
  });
22
17
  return () => {
23
18
  value.disconnect(id);
24
19
  };
25
- }, []);
20
+ }, [value, property]);
26
21
  return [result];
27
22
  }
28
- function toKebabCase(str) {
29
- return str.replace(/([A-Z])/g, "-$1").replace(/_/g, "-").toLowerCase();
30
- }
31
23
 
32
24
  //#endregion
33
25
  export { useBinding };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,7 @@
1
+ import { useAccentColor } from "./adw/use-accent-color.mjs";
2
+ import { useDarkMode } from "./adw/use-dark-mode.mjs";
1
3
  import { useReference } from "./base/use-reference.mjs";
2
4
  import "./base/index.mjs";
3
5
  import { useBinding } from "./gobject/use-binding.mjs";
4
6
  import "./gobject/index.mjs";
5
- export { useBinding, useReference };
7
+ export { useAccentColor, useBinding, useDarkMode, useReference };
package/dist/index.mjs CHANGED
@@ -2,5 +2,8 @@ import { useReference } from "./base/use-reference.mjs";
2
2
  import "./base/index.mjs";
3
3
  import { useBinding } from "./gobject/use-binding.mjs";
4
4
  import "./gobject/index.mjs";
5
+ import { useAccentColor } from "./adw/use-accent-color.mjs";
6
+ import { useDarkMode } from "./adw/use-dark-mode.mjs";
7
+ import "./adw/index.mjs";
5
8
 
6
- export { useBinding, useReference };
9
+ export { useAccentColor, useBinding, useDarkMode, useReference };
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "@peachy/hooks",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "",
5
+ "license": "MIT",
6
+ "author": "",
5
7
  "main": "./dist/index.mjs",
6
8
  "exports": {
7
9
  ".": {
@@ -13,14 +15,12 @@
13
15
  "types": "./dist/*/index.d.mts"
14
16
  }
15
17
  },
16
- "author": "",
17
- "license": "MIT",
18
18
  "devDependencies": {
19
- "@types/react": "^19.2.8",
20
- "react": "^19.2.3",
21
- "tsdown": "0.20.0-beta.4",
19
+ "@types/react": "^19.2.13",
20
+ "react": "^19.2.4",
21
+ "tsdown": "0.20.3",
22
22
  "typescript": "^5.9.3",
23
- "@peachy/react": "0.0.9"
23
+ "@peachy/react": "0.0.11"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "react": "^19.2.0"
@@ -0,0 +1,2 @@
1
+ export * from "./use-accent-color";
2
+ export * from "./use-dark-mode";
@@ -0,0 +1,18 @@
1
+ import Adw from "gi://Adw?version=1";
2
+
3
+ import { useRef } from "react";
4
+
5
+ import { useBinding } from "../gobject";
6
+
7
+ /**
8
+ * Query the system's accent color if supported
9
+ * @returns [accentColor] - accent color or null
10
+ */
11
+ export function useAccentColor() {
12
+ const styleManager = useRef(Adw.StyleManager.get_default());
13
+
14
+ const [accentColor] = useBinding(styleManager, "accent-color");
15
+ const [systemSupportsAccentColors] = useBinding(styleManager, "system-supports-accent-colors");
16
+
17
+ return [systemSupportsAccentColors ? accentColor : null];
18
+ }
@@ -0,0 +1,21 @@
1
+ import Adw from "gi://Adw?version=1";
2
+
3
+ import { useCallback, useRef } from "react";
4
+
5
+ import { useBinding } from "../gobject";
6
+
7
+ export function useDarkMode() {
8
+ const styleManager = useRef(Adw.StyleManager.get_default());
9
+
10
+ const [isDark] = useBinding(styleManager, "dark");
11
+ const setDarkMode = useCallback(
12
+ (value: boolean) => {
13
+ styleManager.current.set_color_scheme(
14
+ value ? Adw.ColorScheme.PREFER_DARK : Adw.ColorScheme.PREFER_LIGHT,
15
+ );
16
+ },
17
+ [styleManager],
18
+ );
19
+
20
+ return [isDark, setDarkMode];
21
+ }
@@ -3,10 +3,7 @@ import { RefObject, useEffect, useState } from "react";
3
3
  /**
4
4
  * Returns the value inside a `ref`, correctly checking it after the initial render
5
5
  */
6
- export function useReference<T>(
7
- value: T | RefObject<T>,
8
- defaultValue?: T,
9
- ): T | null {
6
+ export function useReference<T>(value: T | RefObject<T>, defaultValue?: T): T | null {
10
7
  const [result, setResult] = useState<T | null>(() => {
11
8
  return getValue(value) ?? (defaultValue || null);
12
9
  });
@@ -1,5 +1,6 @@
1
1
  import Gio from "gi://Gio?version=2.0";
2
- import { useCallback, useEffect, useState } from "react";
2
+
3
+ import { useCallback, useEffect, useRef, useState } from "react";
3
4
 
4
5
  interface NetworkMonitor {
5
6
  connected: boolean;
@@ -9,27 +10,29 @@ interface NetworkMonitor {
9
10
  }
10
11
 
11
12
  export function useNetworkMonitor(): NetworkMonitor {
12
- const monitor = Gio.NetworkMonitor.get_default();
13
+ const monitor = useRef(Gio.NetworkMonitor.get_default());
13
14
  const [state, setState] = useState(() => calculateState());
14
15
 
15
16
  const calculateState = useCallback(() => {
16
17
  return {
17
- available: monitor.network_available,
18
- connected: monitor.connectivity === Gio.NetworkConnectivity.FULL,
19
- state: monitor.connectivity,
20
- metered: monitor.network_metered,
18
+ available: monitor.current.networkAvailable,
19
+ connected: monitor.current.connectivity === Gio.NetworkConnectivity.FULL,
20
+ state: monitor.current.connectivity,
21
+ metered: monitor.current.networkMetered,
21
22
  } as NetworkMonitor;
22
- }, []);
23
+ }, [monitor]);
23
24
 
24
25
  useEffect(() => {
25
- const id = monitor.connect("network-changed", () => {
26
+ const monitorObj = monitor.current;
27
+
28
+ const id = monitorObj.connect("network-changed", () => {
26
29
  setState(calculateState());
27
30
  });
28
31
 
29
32
  return () => {
30
- monitor.disconnect(id);
33
+ monitorObj.disconnect(id);
31
34
  };
32
- }, []);
35
+ }, [calculateState]);
33
36
 
34
37
  return state;
35
38
  }
@@ -1,25 +1,34 @@
1
1
  import Gio from "gi://Gio?version=2.0";
2
2
  import GLib from "gi://GLib?version=2.0";
3
- import { useEffect, useState } from "react";
3
+
4
+ import { useCallback, useEffect, useRef, useState } from "react";
4
5
 
5
6
  export function useSetting<T = unknown>(schema: string, key: string) {
6
- const settings = Gio.Settings.new(schema);
7
+ const settings = useRef(Gio.Settings.new(schema));
7
8
 
8
- const getValue = () => settings.get_value(key).recursiveUnpack() as T;
9
+ const getValue = useCallback(
10
+ () => settings.current.get_value(key).recursiveUnpack() as T,
11
+ [key, settings],
12
+ );
9
13
 
10
14
  const [value, setValue] = useState<T>(() => getValue());
11
15
 
12
16
  useEffect(() => {
13
- const handler = settings.connect("changed::" + key, () => {
17
+ let settingsObj = settings.current;
18
+
19
+ const handler = settingsObj.connect(`changed::${key}`, () => {
14
20
  setValue(getValue());
15
21
  });
16
22
 
17
- return () => settings.disconnect(handler);
18
- }, [settings, key]);
23
+ return () => settingsObj.disconnect(handler);
24
+ }, [settings, key, getValue]);
19
25
 
20
- const changeValue = (newValue: GLib.Variant) => {
21
- settings.set_value(key, newValue);
22
- };
26
+ const changeValue = useCallback(
27
+ () => (newValue: GLib.Variant) => {
28
+ settings.current.set_value(key, newValue);
29
+ },
30
+ [key],
31
+ );
23
32
 
24
33
  return [value, changeValue] as [T, (newValue: GLib.Variant) => void];
25
34
  }
@@ -1,62 +1,52 @@
1
1
  import GObject from "gi://GObject?version=2.0";
2
+
2
3
  import { RefObject, useEffect, useState } from "react";
4
+
3
5
  import { useReference } from "../base";
4
6
 
5
- type NonFunctionKeys<T> = {
6
- [K in keyof T]: T[K] extends Function
7
- ? never
8
- : K extends Symbol
9
- ? never
10
- : K extends number
11
- ? never
12
- : K;
13
- }[keyof T];
7
+ type PropertyOf<T extends GObject.Object> = Extract<keyof T["$readableProperties"], string>;
14
8
 
9
+ /// @ts-expect-error broken
10
+ type PropertyType<T, Prop extends keyof T> = T["$readableProperties"][Prop];
11
+
12
+ // when your ref is non-nullable, the result is never null
15
13
  export function useBinding<
16
14
  T extends GObject.Object,
17
- Prop extends NonFunctionKeys<T>,
18
- >(
19
- object: T | RefObject<T>,
20
- property: Prop,
21
- defaultValue?: T[Prop],
22
- converter?: undefined,
23
- ): [T[Prop]];
15
+ Prop extends PropertyOf<T>,
16
+ PropType extends PropertyType<T, Prop>,
17
+ >(object: T | RefObject<T>, property: Prop, defaultValue?: null): [PropType];
18
+ // when the ref is nullable but you provided a default value, the result is never null
24
19
  export function useBinding<
25
20
  T extends GObject.Object,
26
- Prop extends NonFunctionKeys<T>,
27
- Converter extends (value: T[Prop]) => any,
28
- >(
29
- object: T | RefObject<T>,
30
- property: Prop,
31
- defaultValue: T[Prop] | undefined,
32
- converter: Converter,
33
- ): [ReturnType<Converter>];
21
+ Prop extends PropertyOf<T>,
22
+ PropType extends PropertyType<T, Prop>,
23
+ >(object: T | RefObject<T | null>, property: Prop, defaultValue: PropType): [PropType];
24
+ // when you didn't provide a default value, the result can be null
34
25
  export function useBinding<
35
26
  T extends GObject.Object,
36
- Prop extends NonFunctionKeys<T>,
37
- Converter extends (value: T[Prop]) => any,
38
- >(
39
- object: T | RefObject<T>,
40
- _property: Prop,
41
- defaultValue?: any,
42
- converter?: Converter,
43
- ): any {
44
- const property = toKebabCase(_property);
27
+ Prop extends PropertyOf<T>,
28
+ PropType extends PropertyType<T, Prop>,
29
+ >(object: T | RefObject<T | null>, property: Prop, defaultValue?: null): [PropType | null];
30
+ // base implementation
31
+ export function useBinding<
32
+ T extends GObject.Object,
33
+ Prop extends PropertyOf<T>,
34
+ PropType extends PropertyType<T, Prop>,
35
+ >(object: T | RefObject<T>, property: Prop, defaultValue?: PropType): any {
45
36
  const value = useReference(object);
46
37
 
47
38
  const [result, setResult] = useState(() => {
48
- if (!value) return defaultValue;
49
- const initialResult = value[property];
50
- return converter ? converter(initialResult) : initialResult;
39
+ if (!value) return defaultValue ?? null;
40
+ return value[property];
51
41
  });
52
42
 
53
43
  // run this on initial render
54
44
  useEffect(() => {
55
45
  if (!value) {
56
- console.error(`Object is null or undefined`);
57
46
  return;
58
47
  }
59
48
 
49
+ // @ts-expect-error trust me, we are listening to a property
60
50
  const id = value.connect(`notify::${property}`, () => {
61
51
  setResult(value[property]);
62
52
  });
@@ -64,14 +54,7 @@ export function useBinding<
64
54
  return () => {
65
55
  value.disconnect(id);
66
56
  };
67
- }, []);
57
+ }, [value, property]);
68
58
 
69
59
  return [result] as const;
70
60
  }
71
-
72
- function toKebabCase(str: string): string {
73
- return str
74
- .replace(/([A-Z])/g, "-$1")
75
- .replace(/_/g, "-")
76
- .toLowerCase();
77
- }
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./base";
2
2
  export * from "./gobject";
3
+ export * from "./adw";
package/tsconfig.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "extends": "@peachy/react/tsconfig",
2
+ "extends": "@peachy/react/tsconfig"
3
3
  }
package/dist/types.d.mts DELETED
@@ -1 +0,0 @@
1
- export { };
package/dist/types.mjs DELETED
@@ -1 +0,0 @@
1
- export { };
package/src/types.ts DELETED
File without changes