tgui-core 1.1.0 → 1.1.2

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.
@@ -1,4 +1,4 @@
1
- import { Middleware } from './common/redux';
1
+ import { Middleware } from './redux';
2
2
 
3
3
  export declare const resolveAsset: (name: string) => string;
4
4
  export declare const assetMiddleware: Middleware;
@@ -7,4 +7,27 @@ export declare class EventEmitter {
7
7
  emit(name: string, ...params: any[]): void;
8
8
  clear(): void;
9
9
  }
10
+ export declare const globalEvents: EventEmitter;
11
+ export declare const setupGlobalEvents: (options?: {
12
+ ignoreWindowFocus?: boolean;
13
+ }) => void;
14
+ export declare function canStealFocus(node: HTMLElement): boolean;
15
+ export declare function addScrollableNode(node: HTMLElement): void;
16
+ export declare function removeScrollableNode(node: HTMLElement): void;
17
+ export declare class KeyEvent {
18
+ event: KeyboardEvent;
19
+ type: 'keydown' | 'keyup';
20
+ code: number;
21
+ ctrl: boolean;
22
+ shift: boolean;
23
+ alt: boolean;
24
+ repeat: boolean;
25
+ _str?: string;
26
+ constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean);
27
+ hasModifierKeys(): boolean;
28
+ isModifierKey(): boolean;
29
+ isDown(): boolean;
30
+ isUp(): boolean;
31
+ toString(): string;
32
+ }
10
33
  export {};
@@ -1,32 +1,147 @@
1
- var h = Object.defineProperty;
2
- var c = (e, s, t) => s in e ? h(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
3
- var n = (e, s, t) => c(e, typeof s != "symbol" ? s + "" : s, t);
4
- class u {
1
+ var _ = Object.defineProperty;
2
+ var v = (t, e, s) => e in t ? _(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
3
+ var i = (t, e, s) => v(t, typeof e != "symbol" ? e + "" : e, s);
4
+ import { KEY_CTRL as F, KEY_SHIFT as L, KEY_ALT as b, KEY_F1 as K, KEY_F12 as S } from "./keycodes.js";
5
+ class C {
5
6
  constructor() {
6
- n(this, "listeners");
7
+ i(this, "listeners");
7
8
  this.listeners = {};
8
9
  }
9
- on(s, t) {
10
- this.listeners[s] = this.listeners[s] || [], this.listeners[s].push(t);
11
- }
12
- off(s, t) {
13
- const r = this.listeners[s];
14
- if (!r)
15
- throw new Error(`There is no listeners for "${s}"`);
16
- this.listeners[s] = r.filter((i) => i !== t);
17
- }
18
- emit(s, ...t) {
19
- const r = this.listeners[s];
20
- if (r)
21
- for (let i = 0, l = r.length; i < l; i += 1) {
22
- const o = r[i];
23
- o(...t);
10
+ on(e, s) {
11
+ this.listeners[e] = this.listeners[e] || [], this.listeners[e].push(s);
12
+ }
13
+ off(e, s) {
14
+ const n = this.listeners[e];
15
+ if (!n)
16
+ throw new Error(`There is no listeners for "${e}"`);
17
+ this.listeners[e] = n.filter((l) => l !== s);
18
+ }
19
+ emit(e, ...s) {
20
+ const n = this.listeners[e];
21
+ if (n)
22
+ for (let l = 0, k = n.length; l < k; l += 1) {
23
+ const g = n[l];
24
+ g(...s);
24
25
  }
25
26
  }
26
27
  clear() {
27
28
  this.listeners = {};
28
29
  }
29
30
  }
31
+ const o = new C();
32
+ let m = !1;
33
+ const W = (t = {}) => {
34
+ m = !!t.ignoreWindowFocus;
35
+ };
36
+ let d, f = !0;
37
+ function u(t, e) {
38
+ if (m) {
39
+ f = !0;
40
+ return;
41
+ }
42
+ if (d && (clearTimeout(d), d = null), e) {
43
+ d = setTimeout(() => u(t));
44
+ return;
45
+ }
46
+ f !== t && (f = t, o.emit(t ? "window-focus" : "window-blur"), o.emit("window-focus-change", t));
47
+ }
48
+ let r = null;
49
+ function E(t) {
50
+ const e = String(t.tagName).toLowerCase();
51
+ return e === "input" || e === "textarea";
52
+ }
53
+ function T(t) {
54
+ a(), r = t, r.addEventListener("blur", a);
55
+ }
56
+ function a() {
57
+ r && (r.removeEventListener("blur", a), r = null);
58
+ }
59
+ let w = null, c = null;
60
+ const h = [];
61
+ function A(t) {
62
+ h.push(t);
63
+ }
64
+ function B(t) {
65
+ const e = h.indexOf(t);
66
+ e >= 0 && h.splice(e, 1);
67
+ }
68
+ function N(t) {
69
+ if (r || !f)
70
+ return;
71
+ const e = document.body;
72
+ for (; t && t !== e; ) {
73
+ if (h.includes(t)) {
74
+ if (t.contains(w))
75
+ return;
76
+ w = t, t.focus();
77
+ return;
78
+ }
79
+ t = t.parentElement;
80
+ }
81
+ }
82
+ window.addEventListener("mousemove", (t) => {
83
+ const e = t.target;
84
+ e !== c && (c = e, N(e));
85
+ });
86
+ window.addEventListener("focusin", (t) => {
87
+ c = null, w = t.target, u(!0), E(t.target) && T(t.target);
88
+ });
89
+ window.addEventListener("focusout", () => {
90
+ c = null, u(!1, !0);
91
+ });
92
+ window.addEventListener("blur", () => {
93
+ c = null, u(!1, !0);
94
+ });
95
+ window.addEventListener("beforeunload", () => {
96
+ u(!1);
97
+ });
98
+ const y = {};
99
+ class p {
100
+ constructor(e, s, n) {
101
+ i(this, "event");
102
+ i(this, "type");
103
+ i(this, "code");
104
+ i(this, "ctrl");
105
+ i(this, "shift");
106
+ i(this, "alt");
107
+ i(this, "repeat");
108
+ i(this, "_str");
109
+ this.event = e, this.type = s, this.code = e.keyCode, this.ctrl = e.ctrlKey, this.shift = e.shiftKey, this.alt = e.altKey, this.repeat = !!n;
110
+ }
111
+ hasModifierKeys() {
112
+ return this.ctrl || this.alt || this.shift;
113
+ }
114
+ isModifierKey() {
115
+ return this.code === F || this.code === L || this.code === b;
116
+ }
117
+ isDown() {
118
+ return this.type === "keydown";
119
+ }
120
+ isUp() {
121
+ return this.type === "keyup";
122
+ }
123
+ toString() {
124
+ return this._str ? this._str : (this._str = "", this.ctrl && (this._str += "Ctrl+"), this.alt && (this._str += "Alt+"), this.shift && (this._str += "Shift+"), this.code >= 48 && this.code <= 90 ? this._str += String.fromCharCode(this.code) : this.code >= K && this.code <= S ? this._str += "F" + (this.code - 111) : this._str += "[" + this.code + "]", this._str);
125
+ }
126
+ }
127
+ document.addEventListener("keydown", (t) => {
128
+ if (E(t.target))
129
+ return;
130
+ const e = t.keyCode, s = new p(t, "keydown", y[e]);
131
+ o.emit("keydown", s), o.emit("key", s), y[e] = !0;
132
+ });
133
+ document.addEventListener("keyup", (t) => {
134
+ if (E(t.target))
135
+ return;
136
+ const e = t.keyCode, s = new p(t, "keyup");
137
+ o.emit("keyup", s), o.emit("key", s), y[e] = !1;
138
+ });
30
139
  export {
31
- u as EventEmitter
140
+ C as EventEmitter,
141
+ p as KeyEvent,
142
+ A as addScrollableNode,
143
+ E as canStealFocus,
144
+ o as globalEvents,
145
+ B as removeScrollableNode,
146
+ W as setupGlobalEvents
32
147
  };
@@ -1,5 +1,5 @@
1
- import { KEY_ESCAPE as K, KEY_ENTER as E, KEY_SPACE as p, KEY_TAB as h, KEY_CTRL as d, KEY_SHIFT as g, KEY_UP as S, KEY_DOWN as Y, KEY_LEFT as _, KEY_RIGHT as b, KEY_F5 as B } from "./common/keycodes.js";
2
1
  import { globalEvents as l } from "./events.js";
2
+ import { KEY_ESCAPE as K, KEY_ENTER as E, KEY_SPACE as p, KEY_TAB as h, KEY_CTRL as d, KEY_SHIFT as g, KEY_UP as S, KEY_DOWN as Y, KEY_LEFT as _, KEY_RIGHT as b, KEY_F5 as B } from "./keycodes.js";
3
3
  const m = {}, c = [
4
4
  K,
5
5
  E,
@@ -10,7 +10,7 @@
10
10
  * @url https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
11
11
  * @usage
12
12
  * ```ts
13
- * import { KEY } from 'tgui/common/keys';
13
+ * import { KEY } from 'tgui/keys';
14
14
  *
15
15
  * if (event.key === KEY.Enter) {
16
16
  * // do something
@@ -3,7 +3,7 @@ var _ = (e, t, s) => t in e ? g(e, t, { enumerable: !0, configurable: !0, writab
3
3
  var l = (e, t, s) => _(e, typeof t != "symbol" ? t + "" : t, s);
4
4
  import { jsxs as d, jsx as h } from "react/jsx-runtime";
5
5
  import { Component as v, createRef as $ } from "react";
6
- import { resolveAsset as p } from "../assets.js";
6
+ import { resolveAsset as p } from "../common/assets.js";
7
7
  import { Image as f } from "./Image.js";
8
8
  var b = /* @__PURE__ */ ((e) => (e.Chest = "chest", e.Eyes = "eyes", e.Groin = "groin", e.Head = "head", e.LeftArm = "l_arm", e.LeftLeg = "l_leg", e.Mouth = "mouth", e.RightArm = "r_arm", e.RightLeg = "r_leg", e))(b || {});
9
9
  const C = (e, t) => {
@@ -1,6 +1,6 @@
1
1
  import { createElement as y } from "react";
2
- import { classes as b } from "../common/react.js";
3
- import { CSS_COLORS as u } from "../constants.js";
2
+ import { CSS_COLORS as b } from "../common/constants.js";
3
+ import { classes as u } from "../common/react.js";
4
4
  function p(o) {
5
5
  if (typeof o == "string")
6
6
  return o.endsWith("px") ? parseFloat(o) / 12 + "rem" : o;
@@ -17,7 +17,7 @@ function x(o) {
17
17
  return !a(o);
18
18
  }
19
19
  function a(o) {
20
- return typeof o == "string" && u.includes(o);
20
+ return typeof o == "string" && b.includes(o);
21
21
  }
22
22
  const m = (o) => (t, i) => {
23
23
  (typeof i == "number" || typeof i == "string") && (t[o] = i);
@@ -108,7 +108,7 @@ function S(o) {
108
108
  }
109
109
  function d(o) {
110
110
  const t = o.textColor || o.color, i = o.backgroundColor;
111
- return b([
111
+ return u([
112
112
  a(t) && "color-" + t,
113
113
  a(i) && "color-bg-" + i
114
114
  ]);
@@ -1,7 +1,7 @@
1
1
  import { jsx as s } from "react/jsx-runtime";
2
+ import { Component as a, createRef as c } from "react";
2
3
  import { shallowDiffers as r } from "../common/react.js";
3
- import { debounce as a } from "../common/timer.js";
4
- import { Component as c, createRef as m } from "react";
4
+ import { debounce as m } from "../common/timer.js";
5
5
  import { computeBoxProps as l } from "./Box.js";
6
6
  const o = [];
7
7
  function h(t) {
@@ -37,10 +37,10 @@ function u(t) {
37
37
  ]
38
38
  };
39
39
  }
40
- class U extends c {
40
+ class U extends a {
41
41
  constructor(n) {
42
42
  var e;
43
- super(n), this.containerRef = m(), this.byondUiElement = h((e = n.params) == null ? void 0 : e.id), this.handleResize = a(() => {
43
+ super(n), this.containerRef = c(), this.byondUiElement = h((e = n.params) == null ? void 0 : e.id), this.handleResize = m(() => {
44
44
  this.forceUpdate();
45
45
  }, 100);
46
46
  }
@@ -1,7 +1,7 @@
1
1
  import { jsx as $ } from "react/jsx-runtime";
2
2
  import { useState as R, useEffect as d } from "react";
3
- import { resolveAsset as j } from "../assets.js";
4
- import { fetchRetry as v } from "../http.js";
3
+ import { resolveAsset as j } from "../common/assets.js";
4
+ import { fetchRetry as v } from "../common/http.js";
5
5
  import { Image as x } from "./Image.js";
6
6
  let e;
7
7
  function b(n) {
@@ -1,5 +1,5 @@
1
1
  import { Component } from 'react';
2
- import { KeyEvent } from '../events';
2
+ import { KeyEvent } from '../common/events';
3
3
 
4
4
  type KeyListenerProps = Partial<{
5
5
  onKey: (key: KeyEvent) => void;
@@ -2,7 +2,7 @@ var t = Object.defineProperty;
2
2
  var e = (s, o, p) => o in s ? t(s, o, { enumerable: !0, configurable: !0, writable: !0, value: p }) : s[o] = p;
3
3
  var i = (s, o, p) => e(s, typeof o != "symbol" ? o + "" : o, p);
4
4
  import { Component as r } from "react";
5
- import { listenForKeyEvents as h } from "../hotkeys.js";
5
+ import { listenForKeyEvents as h } from "../common/hotkeys.js";
6
6
  class d extends r {
7
7
  constructor(p) {
8
8
  super(p);
@@ -1,7 +1,7 @@
1
1
  import { jsxs as g, jsx as n } from "react/jsx-runtime";
2
- import { keyOfMatchingRange as v, toFixed as y, scale as N, clamp01 as _ } from "../common/math.js";
2
+ import { CSS_COLORS as v } from "../common/constants.js";
3
+ import { keyOfMatchingRange as y, toFixed as N, scale as _, clamp01 as B } from "../common/math.js";
3
4
  import { classes as m } from "../common/react.js";
4
- import { CSS_COLORS as B } from "../constants.js";
5
5
  import { s as o } from "../ProgressBar.module-BkAFfFy0.js";
6
6
  import { computeBoxProps as S, computeBoxClassName as O } from "./Box.js";
7
7
  function w(d) {
@@ -14,14 +14,14 @@ function w(d) {
14
14
  ranges: h = {},
15
15
  children: l,
16
16
  ...t
17
- } = d, a = N(r, u, p), x = l !== void 0, s = C || v(r, h) || "default", e = S(t), c = [
17
+ } = d, a = _(r, u, p), x = l !== void 0, s = C || y(r, h) || "default", e = S(t), c = [
18
18
  o.progressBar,
19
19
  f,
20
20
  O(t)
21
21
  ], i = {
22
- width: _(a) * 100 + "%"
22
+ width: B(a) * 100 + "%"
23
23
  };
24
- return B.includes(s) || s === "default" ? c.push(o["color__" + s]) : (e.style = { ...e.style, borderColor: s }, i.backgroundColor = s), /* @__PURE__ */ g("div", { className: m(c), ...e, children: [
24
+ return v.includes(s) || s === "default" ? c.push(o["color__" + s]) : (e.style = { ...e.style, borderColor: s }, i.backgroundColor = s), /* @__PURE__ */ g("div", { className: m(c), ...e, children: [
25
25
  /* @__PURE__ */ n(
26
26
  "div",
27
27
  {
@@ -29,7 +29,7 @@ function w(d) {
29
29
  style: i
30
30
  }
31
31
  ),
32
- /* @__PURE__ */ n("div", { className: o.content, children: x ? l : y(a * 100) + "%" })
32
+ /* @__PURE__ */ n("div", { className: o.content, children: x ? l : N(a * 100) + "%" })
33
33
  ] });
34
34
  }
35
35
  export {
@@ -1,7 +1,7 @@
1
1
  import { jsxs as r, jsx as s } from "react/jsx-runtime";
2
2
  import { forwardRef as S, useEffect as j } from "react";
3
- import { classes as z, canRender as m } from "../common/react.js";
4
- import { addScrollableNode as B, removeScrollableNode as H } from "../events.js";
3
+ import { addScrollableNode as z, removeScrollableNode as B } from "../common/events.js";
4
+ import { classes as H, canRender as m } from "../common/react.js";
5
5
  import { s as t } from "../Section.module-CLVHJ4yA.js";
6
6
  import { computeBoxClassName as T, computeBoxProps as y } from "./Box.js";
7
7
  const q = S(
@@ -21,14 +21,14 @@ const q = S(
21
21
  } = a, x = m(n) || m(c);
22
22
  return j(() => {
23
23
  if (l != null && l.current && !(!i && !e))
24
- return B(l.current), () => {
25
- l != null && l.current && H(l.current);
24
+ return z(l.current), () => {
25
+ l != null && l.current && B(l.current);
26
26
  };
27
27
  }, []), /* @__PURE__ */ r(
28
28
  "div",
29
29
  {
30
30
  id: v || "",
31
- className: z([
31
+ className: H([
32
32
  t.section,
33
33
  N && t.fill,
34
34
  b && t.fitted,
@@ -1,5 +1,5 @@
1
1
  import { Component as r } from "react";
2
- import { formatTime as u } from "../format.js";
2
+ import { formatTime as u } from "../common/format.js";
3
3
  function s(e) {
4
4
  return typeof e == "number" && Number.isFinite(e) && !Number.isNaN(e);
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tgui-core",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "TGUI core component library",
5
5
  "keywords": [
6
6
  "TGUI",
@@ -11,17 +11,13 @@
11
11
  "dist"
12
12
  ],
13
13
  "exports": {
14
- "./common/*": {
15
- "import": "./dist/*.js",
16
- "require": "./dist/*.cjs"
17
- },
18
14
  "./components": {
19
15
  "import": "./dist/components/index.js",
20
16
  "require": "./dist/components/index.cjs"
21
17
  },
22
18
  "./*": {
23
- "import": "./dist/*.js",
24
- "require": "./dist/*.cjs"
19
+ "import": "./dist/common/*.js",
20
+ "require": "./dist/common/*.cjs"
25
21
  }
26
22
  },
27
23
  "repository": {
package/dist/events.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import { EventEmitter } from './common/events';
2
-
3
- export declare const globalEvents: EventEmitter;
4
- export declare const setupGlobalEvents: (options?: {
5
- ignoreWindowFocus?: boolean;
6
- }) => void;
7
- export declare function canStealFocus(node: HTMLElement): boolean;
8
- export declare function addScrollableNode(node: HTMLElement): void;
9
- export declare function removeScrollableNode(node: HTMLElement): void;
10
- export declare class KeyEvent {
11
- event: KeyboardEvent;
12
- type: 'keydown' | 'keyup';
13
- code: number;
14
- ctrl: boolean;
15
- shift: boolean;
16
- alt: boolean;
17
- repeat: boolean;
18
- _str?: string;
19
- constructor(e: KeyboardEvent, type: 'keydown' | 'keyup', repeat?: boolean);
20
- hasModifierKeys(): boolean;
21
- isModifierKey(): boolean;
22
- isDown(): boolean;
23
- isUp(): boolean;
24
- toString(): string;
25
- }
package/dist/events.js DELETED
@@ -1,128 +0,0 @@
1
- var p = Object.defineProperty;
2
- var k = (t, e, i) => e in t ? p(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i;
3
- var s = (t, e, i) => k(t, typeof e != "symbol" ? e + "" : e, i);
4
- import { EventEmitter as _ } from "./common/events.js";
5
- import { KEY_CTRL as g, KEY_SHIFT as v, KEY_ALT as F, KEY_F1 as L, KEY_F12 as b } from "./common/keycodes.js";
6
- /**
7
- * Normalized browser focus events and BYOND-specific focus helpers.
8
- *
9
- * @file
10
- * @copyright 2020 Aleksej Komarov
11
- * @license MIT
12
- */
13
- const o = new _();
14
- let y = !1;
15
- const Y = (t = {}) => {
16
- y = !!t.ignoreWindowFocus;
17
- };
18
- let d, u = !0;
19
- function c(t, e) {
20
- if (y) {
21
- u = !0;
22
- return;
23
- }
24
- if (d && (clearTimeout(d), d = null), e) {
25
- d = setTimeout(() => c(t));
26
- return;
27
- }
28
- u !== t && (u = t, o.emit(t ? "window-focus" : "window-blur"), o.emit("window-focus-change", t));
29
- }
30
- let n = null;
31
- function w(t) {
32
- const e = String(t.tagName).toLowerCase();
33
- return e === "input" || e === "textarea";
34
- }
35
- function K(t) {
36
- f(), n = t, n.addEventListener("blur", f);
37
- }
38
- function f() {
39
- n && (n.removeEventListener("blur", f), n = null);
40
- }
41
- let a = null, r = null;
42
- const l = [];
43
- function x(t) {
44
- l.push(t);
45
- }
46
- function W(t) {
47
- const e = l.indexOf(t);
48
- e >= 0 && l.splice(e, 1);
49
- }
50
- function S(t) {
51
- if (n || !u)
52
- return;
53
- const e = document.body;
54
- for (; t && t !== e; ) {
55
- if (l.includes(t)) {
56
- if (t.contains(a))
57
- return;
58
- a = t, t.focus();
59
- return;
60
- }
61
- t = t.parentElement;
62
- }
63
- }
64
- window.addEventListener("mousemove", (t) => {
65
- const e = t.target;
66
- e !== r && (r = e, S(e));
67
- });
68
- window.addEventListener("focusin", (t) => {
69
- r = null, a = t.target, c(!0), w(t.target) && K(t.target);
70
- });
71
- window.addEventListener("focusout", () => {
72
- r = null, c(!1, !0);
73
- });
74
- window.addEventListener("blur", () => {
75
- r = null, c(!1, !0);
76
- });
77
- window.addEventListener("beforeunload", () => {
78
- c(!1);
79
- });
80
- const h = {};
81
- class m {
82
- constructor(e, i, E) {
83
- s(this, "event");
84
- s(this, "type");
85
- s(this, "code");
86
- s(this, "ctrl");
87
- s(this, "shift");
88
- s(this, "alt");
89
- s(this, "repeat");
90
- s(this, "_str");
91
- this.event = e, this.type = i, this.code = e.keyCode, this.ctrl = e.ctrlKey, this.shift = e.shiftKey, this.alt = e.altKey, this.repeat = !!E;
92
- }
93
- hasModifierKeys() {
94
- return this.ctrl || this.alt || this.shift;
95
- }
96
- isModifierKey() {
97
- return this.code === g || this.code === v || this.code === F;
98
- }
99
- isDown() {
100
- return this.type === "keydown";
101
- }
102
- isUp() {
103
- return this.type === "keyup";
104
- }
105
- toString() {
106
- return this._str ? this._str : (this._str = "", this.ctrl && (this._str += "Ctrl+"), this.alt && (this._str += "Alt+"), this.shift && (this._str += "Shift+"), this.code >= 48 && this.code <= 90 ? this._str += String.fromCharCode(this.code) : this.code >= L && this.code <= b ? this._str += "F" + (this.code - 111) : this._str += "[" + this.code + "]", this._str);
107
- }
108
- }
109
- document.addEventListener("keydown", (t) => {
110
- if (w(t.target))
111
- return;
112
- const e = t.keyCode, i = new m(t, "keydown", h[e]);
113
- o.emit("keydown", i), o.emit("key", i), h[e] = !0;
114
- });
115
- document.addEventListener("keyup", (t) => {
116
- if (w(t.target))
117
- return;
118
- const e = t.keyCode, i = new m(t, "keyup");
119
- o.emit("keyup", i), o.emit("key", i), h[e] = !1;
120
- });
121
- export {
122
- m as KeyEvent,
123
- x as addScrollableNode,
124
- w as canStealFocus,
125
- o as globalEvents,
126
- W as removeScrollableNode,
127
- Y as setupGlobalEvents
128
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes