Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
98c16659c9 | ||
![]() |
5644063fc7 | ||
![]() |
85b8050cc5 | ||
![]() |
60d3bf1718 | ||
![]() |
b8e1b1f3ad | ||
![]() |
57432b9779 | ||
![]() |
156073a407 | ||
![]() |
f676a20332 | ||
![]() |
63af29d345 | ||
![]() |
69a1b74e05 | ||
![]() |
163dbd47d4 | ||
![]() |
08889adfa5 | ||
![]() |
aaf4943fa3 | ||
![]() |
4fd18d1b3e | ||
![]() |
f8cf19cae9 | ||
![]() |
6540c5460e | ||
![]() |
dc95cf3447 | ||
![]() |
1ca985aa4a | ||
![]() |
bc9c8f7ee2 | ||
![]() |
3eacd6f07b | ||
![]() |
afa929b2a2 | ||
![]() |
370c9a643f | ||
![]() |
22c57c8f4a | ||
![]() |
eef9662195 | ||
![]() |
69a7b1f2b5 | ||
![]() |
3b11b1d9d3 | ||
![]() |
b778035854 | ||
![]() |
92c2a42edf | ||
![]() |
7cadc3de52 | ||
![]() |
336b7222de | ||
![]() |
4d0ebf5ac5 | ||
![]() |
949e9ae03a | ||
![]() |
b5151bda5a | ||
![]() |
8157c84d11 |
@ -73,6 +73,8 @@ export const getDefaultAppState = (): Omit<
|
|||||||
zenModeEnabled: false,
|
zenModeEnabled: false,
|
||||||
zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } },
|
zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } },
|
||||||
viewModeEnabled: false,
|
viewModeEnabled: false,
|
||||||
|
networkSpeed: 0,
|
||||||
|
networkPing: 0,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,6 +155,8 @@ const APP_STATE_STORAGE_CONF = (<
|
|||||||
zenModeEnabled: { browser: true, export: false },
|
zenModeEnabled: { browser: true, export: false },
|
||||||
zoom: { browser: true, export: false },
|
zoom: { browser: true, export: false },
|
||||||
viewModeEnabled: { browser: false, export: false },
|
viewModeEnabled: { browser: false, export: false },
|
||||||
|
networkSpeed: { browser: false, export: false },
|
||||||
|
networkPing: { browser: false, export: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
const _clearAppStateForStorage = <ExportType extends "export" | "browser">(
|
const _clearAppStateForStorage = <ExportType extends "export" | "browser">(
|
||||||
|
@ -51,6 +51,7 @@ import {
|
|||||||
GRID_SIZE,
|
GRID_SIZE,
|
||||||
LINE_CONFIRM_THRESHOLD,
|
LINE_CONFIRM_THRESHOLD,
|
||||||
MIME_TYPES,
|
MIME_TYPES,
|
||||||
|
NETWORK_TIMEOUT_MS,
|
||||||
POINTER_BUTTON,
|
POINTER_BUTTON,
|
||||||
TAP_TWICE_TIMEOUT,
|
TAP_TWICE_TIMEOUT,
|
||||||
TEXT_TO_CENTER_SNAP_THRESHOLD,
|
TEXT_TO_CENTER_SNAP_THRESHOLD,
|
||||||
@ -183,6 +184,7 @@ import LayerUI from "./LayerUI";
|
|||||||
import { Stats } from "./Stats";
|
import { Stats } from "./Stats";
|
||||||
import { Toast } from "./Toast";
|
import { Toast } from "./Toast";
|
||||||
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
||||||
|
import { getNetworkSpeed, getNetworkPing } from "../networkStats";
|
||||||
|
|
||||||
const { history } = createHistory();
|
const { history } = createHistory();
|
||||||
|
|
||||||
@ -205,6 +207,9 @@ const gesture: Gesture = {
|
|||||||
initialScale: null,
|
initialScale: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldEnableNetworkStats = !!(
|
||||||
|
typeof process !== "undefined" && process.env?.REACT_APP_SOCKET_SERVER_URL
|
||||||
|
);
|
||||||
export type PointerDownState = Readonly<{
|
export type PointerDownState = Readonly<{
|
||||||
// The first position at which pointerDown happened
|
// The first position at which pointerDown happened
|
||||||
origin: Readonly<{ x: number; y: number }>;
|
origin: Readonly<{ x: number; y: number }>;
|
||||||
@ -289,6 +294,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
height: window.innerHeight,
|
height: window.innerHeight,
|
||||||
};
|
};
|
||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
|
private networkSpeedIntervalId?: any;
|
||||||
|
private networkPingIntervalId?: any;
|
||||||
constructor(props: ExcalidrawProps) {
|
constructor(props: ExcalidrawProps) {
|
||||||
super(props);
|
super(props);
|
||||||
const defaultAppState = getDefaultAppState();
|
const defaultAppState = getDefaultAppState();
|
||||||
@ -469,6 +476,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
setAppState={this.setAppState}
|
setAppState={this.setAppState}
|
||||||
elements={this.scene.getElements()}
|
elements={this.scene.getElements()}
|
||||||
onClose={this.toggleStats}
|
onClose={this.toggleStats}
|
||||||
|
isCollaborating={this.props.isCollaborating}
|
||||||
|
shouldEnableNetworkStats={shouldEnableNetworkStats}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.state.toastMessage !== null && (
|
{this.state.toastMessage !== null && (
|
||||||
@ -748,6 +757,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
this.removeEventListeners();
|
this.removeEventListeners();
|
||||||
this.scene.destroy();
|
this.scene.destroy();
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
clearTimeout(this.networkSpeedIntervalId);
|
||||||
touchTimeout = 0;
|
touchTimeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,6 +884,34 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
gridSize: this.props.gridModeEnabled ? GRID_SIZE : null,
|
gridSize: this.props.gridModeEnabled ? GRID_SIZE : null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
shouldEnableNetworkStats &&
|
||||||
|
(prevState.showStats !== this.state.showStats ||
|
||||||
|
prevProps.isCollaborating !== this.props.isCollaborating)
|
||||||
|
) {
|
||||||
|
const navigator: Navigator & {
|
||||||
|
connection?: {
|
||||||
|
addEventListener: Function;
|
||||||
|
removeEventListener: Function;
|
||||||
|
};
|
||||||
|
} = window.navigator;
|
||||||
|
|
||||||
|
if (this.state.showStats && this.props.isCollaborating) {
|
||||||
|
this.calculateNetStats();
|
||||||
|
|
||||||
|
navigator?.connection?.addEventListener(
|
||||||
|
"change",
|
||||||
|
this.calculateNetStats,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
navigator?.connection?.removeEventListener(
|
||||||
|
"change",
|
||||||
|
this.calculateNetStats,
|
||||||
|
);
|
||||||
|
clearTimeout(this.networkSpeedIntervalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector(".excalidraw")
|
.querySelector(".excalidraw")
|
||||||
?.classList.toggle("Appearance_dark", this.state.appearance === "dark");
|
?.classList.toggle("Appearance_dark", this.state.appearance === "dark");
|
||||||
@ -999,6 +1037,42 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private calculateNetStats = () => {
|
||||||
|
this.checkNetworkPing();
|
||||||
|
this.checkNetworkSpeed();
|
||||||
|
};
|
||||||
|
|
||||||
|
private checkNetworkPing = async () => {
|
||||||
|
if (!this.state.showStats || !this.props.isCollaborating) {
|
||||||
|
clearTimeout(this.networkPingIntervalId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const networkPing = await getNetworkPing();
|
||||||
|
this.setState({ networkPing });
|
||||||
|
if (this.networkPingIntervalId) {
|
||||||
|
clearTimeout(this.networkPingIntervalId);
|
||||||
|
}
|
||||||
|
this.networkPingIntervalId = setTimeout(
|
||||||
|
this.checkNetworkPing,
|
||||||
|
NETWORK_TIMEOUT_MS,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
private checkNetworkSpeed = async () => {
|
||||||
|
if (!this.state.showStats || !this.props.isCollaborating) {
|
||||||
|
clearTimeout(this.networkSpeedIntervalId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const networkSpeed = await getNetworkSpeed();
|
||||||
|
this.setState({ networkSpeed });
|
||||||
|
if (this.networkSpeedIntervalId) {
|
||||||
|
clearTimeout(this.networkSpeedIntervalId);
|
||||||
|
}
|
||||||
|
this.networkSpeedIntervalId = setTimeout(
|
||||||
|
this.checkNetworkSpeed,
|
||||||
|
NETWORK_TIMEOUT_MS,
|
||||||
|
);
|
||||||
|
};
|
||||||
// Copy/paste
|
// Copy/paste
|
||||||
|
|
||||||
private onCut = withBatchedUpdates((event: ClipboardEvent) => {
|
private onCut = withBatchedUpdates((event: ClipboardEvent) => {
|
||||||
|
@ -11,7 +11,13 @@ import { t } from "../i18n";
|
|||||||
import useIsMobile from "../is-mobile";
|
import useIsMobile from "../is-mobile";
|
||||||
import { getTargetElements } from "../scene";
|
import { getTargetElements } from "../scene";
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { debounce, getVersion, nFormatter } from "../utils";
|
import {
|
||||||
|
debounce,
|
||||||
|
formatSpeedBits,
|
||||||
|
formatTime,
|
||||||
|
getVersion,
|
||||||
|
nFormatter,
|
||||||
|
} from "../utils";
|
||||||
import { close } from "./icons";
|
import { close } from "./icons";
|
||||||
import { Island } from "./Island";
|
import { Island } from "./Island";
|
||||||
import "./Stats.scss";
|
import "./Stats.scss";
|
||||||
@ -30,6 +36,8 @@ export const Stats = (props: {
|
|||||||
setAppState: React.Component<any, AppState>["setState"];
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
elements: readonly NonDeletedExcalidrawElement[];
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
isCollaborating?: boolean;
|
||||||
|
shouldEnableNetworkStats: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const [storageSizes, setStorageSizes] = useState<StorageSizes>({
|
const [storageSizes, setStorageSizes] = useState<StorageSizes>({
|
||||||
@ -170,6 +178,37 @@ export const Stats = (props: {
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
|
{props.shouldEnableNetworkStats && props.isCollaborating ? (
|
||||||
|
<>
|
||||||
|
<tr>
|
||||||
|
<th colSpan={2}>{t("stats.collaboration")}</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("stats.collaborators")}</td>
|
||||||
|
<td>{props.appState.collaborators.size}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("stats.ping")}</td>
|
||||||
|
<td>
|
||||||
|
{props.appState.networkPing === 0
|
||||||
|
? "…"
|
||||||
|
: props.appState.networkPing > 0
|
||||||
|
? formatTime(props.appState.networkPing)
|
||||||
|
: t("stats.error")}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("stats.speed")}</td>
|
||||||
|
<td>
|
||||||
|
{props.appState.networkSpeed === 0
|
||||||
|
? "…"
|
||||||
|
: props.appState.networkSpeed > 0
|
||||||
|
? formatSpeedBits(props.appState.networkSpeed)
|
||||||
|
: t("stats.error")}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
<tr>
|
<tr>
|
||||||
<th colSpan={2}>{t("stats.version")}</th>
|
<th colSpan={2}>{t("stats.version")}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -8,6 +8,8 @@ export const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
|
|||||||
export const ELEMENT_TRANSLATE_AMOUNT = 1;
|
export const ELEMENT_TRANSLATE_AMOUNT = 1;
|
||||||
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
||||||
export const SHIFT_LOCKING_ANGLE = Math.PI / 12;
|
export const SHIFT_LOCKING_ANGLE = Math.PI / 12;
|
||||||
|
export const NETWORK_TIMEOUT_MS = 4000;
|
||||||
|
|
||||||
export const CURSOR_TYPE = {
|
export const CURSOR_TYPE = {
|
||||||
TEXT: "text",
|
TEXT: "text",
|
||||||
CROSSHAIR: "crosshair",
|
CROSSHAIR: "crosshair",
|
||||||
|
@ -227,11 +227,16 @@
|
|||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"angle": "Angle",
|
"angle": "Angle",
|
||||||
|
"collaboration": "Collaboration",
|
||||||
|
"collaborators": "Collaborators",
|
||||||
"element": "Element",
|
"element": "Element",
|
||||||
"elements": "Elements",
|
"elements": "Elements",
|
||||||
|
"error": "Error",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
|
"ping": "Ping",
|
||||||
"scene": "Scene",
|
"scene": "Scene",
|
||||||
"selected": "Selected",
|
"selected": "Selected",
|
||||||
|
"speed": "Speed",
|
||||||
"storage": "Storage",
|
"storage": "Storage",
|
||||||
"title": "Stats for nerds",
|
"title": "Stats for nerds",
|
||||||
"total": "Total",
|
"total": "Total",
|
||||||
|
64
src/networkStats.ts
Normal file
64
src/networkStats.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { getAverage } from "./utils";
|
||||||
|
|
||||||
|
const IMAGE_URL = `${process.env.REACT_APP_SOCKET_SERVER_URL}/test256.png`;
|
||||||
|
const IMAGE_SIZE_BITS = 141978 * 8;
|
||||||
|
const AVERAGE_MAX = 4;
|
||||||
|
|
||||||
|
const speedHistory: number[] = [];
|
||||||
|
|
||||||
|
const pushSpeed = (speed: number): void => {
|
||||||
|
speedHistory.push(speed);
|
||||||
|
if (speedHistory.length > AVERAGE_MAX) {
|
||||||
|
speedHistory.shift();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSpeedBits = (
|
||||||
|
imageSize: number,
|
||||||
|
startTime: number,
|
||||||
|
endTime: number,
|
||||||
|
): number => {
|
||||||
|
const duration = (endTime - startTime) / 1000;
|
||||||
|
if (duration > 0) {
|
||||||
|
return imageSize / duration;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processImage = (): Promise<number> => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const image = new Image();
|
||||||
|
let endTime: number;
|
||||||
|
image.onload = () => {
|
||||||
|
endTime = new Date().getTime();
|
||||||
|
const speed = getSpeedBits(IMAGE_SIZE_BITS, startTime, endTime);
|
||||||
|
pushSpeed(speed);
|
||||||
|
resolve(getAverage(speedHistory));
|
||||||
|
};
|
||||||
|
|
||||||
|
image.onerror = () => {
|
||||||
|
resolve(-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
image.src = `${IMAGE_URL}?t=${startTime}`;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getNetworkSpeed = async (): Promise<number> => {
|
||||||
|
return await processImage();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getNetworkPing = async () => {
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
try {
|
||||||
|
await fetch(process.env.REACT_APP_SOCKET_SERVER_URL, {
|
||||||
|
mode: "no-cors",
|
||||||
|
method: "HEAD",
|
||||||
|
});
|
||||||
|
const endTime = new Date().getTime();
|
||||||
|
return endTime - startTime;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
@ -40,6 +40,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -500,6 +502,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -966,6 +970,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -1741,6 +1747,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -1944,6 +1952,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -2401,6 +2411,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -2653,6 +2665,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -2816,6 +2830,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -3292,6 +3308,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -3599,6 +3617,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -3802,6 +3822,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -4045,6 +4067,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -4296,6 +4320,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -4678,6 +4704,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -4972,6 +5000,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -5278,6 +5308,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -5485,6 +5517,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -5648,6 +5682,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -6100,6 +6136,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -6417,6 +6455,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -8450,6 +8490,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -8811,6 +8853,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -9065,6 +9109,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -9317,6 +9363,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -9631,6 +9679,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -9794,6 +9844,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -9957,6 +10009,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -10120,6 +10174,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -10313,6 +10369,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -10506,6 +10564,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -10699,6 +10759,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -10892,6 +10954,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -11055,6 +11119,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -11218,6 +11284,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -11411,6 +11479,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -11574,6 +11644,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -11767,6 +11839,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -12482,6 +12556,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -12734,6 +12810,8 @@ Object {
|
|||||||
"lastPointerDownWith": "touch",
|
"lastPointerDownWith": "touch",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -12835,6 +12913,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -12934,6 +13014,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -13097,6 +13179,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -13404,6 +13488,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -13711,6 +13797,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -13874,6 +13962,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -14069,6 +14159,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -14317,6 +14409,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -14640,6 +14734,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -15478,6 +15574,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -15785,6 +15883,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -16092,6 +16192,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -16470,6 +16572,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -16636,6 +16740,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -16956,6 +17062,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -17194,6 +17302,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -17448,6 +17558,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -17774,6 +17886,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -17873,6 +17987,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -18036,6 +18152,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -18856,6 +18974,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -18955,6 +19075,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -19708,6 +19830,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -20112,6 +20236,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -20384,6 +20510,8 @@ Object {
|
|||||||
"lastPointerDownWith": "touch",
|
"lastPointerDownWith": "touch",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -20485,6 +20613,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -20982,6 +21112,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
@ -21081,6 +21213,8 @@ Object {
|
|||||||
"lastPointerDownWith": "mouse",
|
"lastPointerDownWith": "mouse",
|
||||||
"multiElement": null,
|
"multiElement": null,
|
||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
|
"networkPing": 0,
|
||||||
|
"networkSpeed": 0,
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
@ -88,6 +88,8 @@ export type AppState = {
|
|||||||
appearance: "light" | "dark";
|
appearance: "light" | "dark";
|
||||||
gridSize: number | null;
|
gridSize: number | null;
|
||||||
viewModeEnabled: boolean;
|
viewModeEnabled: boolean;
|
||||||
|
networkSpeed: number;
|
||||||
|
networkPing: number;
|
||||||
|
|
||||||
/** top-most selected groups (i.e. does not include nested groups) */
|
/** top-most selected groups (i.e. does not include nested groups) */
|
||||||
selectedGroupIds: { [groupId: string]: boolean };
|
selectedGroupIds: { [groupId: string]: boolean };
|
||||||
|
21
src/utils.ts
21
src/utils.ts
@ -363,6 +363,17 @@ export const nFormatter = (num: number, digits: number): string => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const formatSpeedBits = (speed: number): string => {
|
||||||
|
// source: https://en.wikipedia.org/wiki/Data-rate_units#Conversion_table
|
||||||
|
const suffix = ["bps", "kbps", "Mbps", "Gbps"];
|
||||||
|
let index = 0;
|
||||||
|
while (speed > 1000) {
|
||||||
|
index++;
|
||||||
|
speed = speed / 1000;
|
||||||
|
}
|
||||||
|
return `${speed.toFixed(index > 1 ? 1 : 0)} ${suffix[index]}`;
|
||||||
|
};
|
||||||
|
|
||||||
export const getVersion = () => {
|
export const getVersion = () => {
|
||||||
return (
|
return (
|
||||||
document.querySelector<HTMLMetaElement>('meta[name="version"]')?.content ||
|
document.querySelector<HTMLMetaElement>('meta[name="version"]')?.content ||
|
||||||
@ -370,6 +381,16 @@ export const getVersion = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const formatTime = (mseconds: number): string => {
|
||||||
|
return mseconds < 1000
|
||||||
|
? `${mseconds} ms`
|
||||||
|
: `${(mseconds / 1000).toFixed(1)} s`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAverage = (arr: Array<number>): number => {
|
||||||
|
return arr.reduce((sum, currentVal) => sum + currentVal) / arr.length;
|
||||||
|
};
|
||||||
|
|
||||||
// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js
|
// Adapted from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/emoji.js
|
||||||
export const supportsEmoji = () => {
|
export const supportsEmoji = () => {
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user