merged develop
This commit is contained in:
commit
a1c96b0524
178 changed files with 6744 additions and 3541 deletions
|
@ -34,14 +34,15 @@ module.exports = {
|
|||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"no-throw-literal": "error",
|
||||
// TODO: remove those ignored rules and write a stronger code!
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/restrict-plus-operands": "off",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off"
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/no-unsafe-argument": "off",
|
||||
},
|
||||
"settings": {
|
||||
"svelte3/typescript": true,
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
src/Messages/generated
|
||||
src/Messages/JsonMessages
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
FROM node:14.15.4-buster-slim@sha256:cbae886186467bbfd274b82a234a1cdfbbd31201c2a6ee63a6893eefcf3c6e76 as builder
|
||||
WORKDIR /usr/src
|
||||
COPY messages .
|
||||
RUN yarn install && yarn proto
|
||||
RUN yarn install && yarn ts-proto
|
||||
|
||||
# we are rebuilding on each deploy to cope with the PUSHER_URL environment URL
|
||||
FROM thecodingmachine/nodejs:14-apache
|
||||
|
||||
COPY --chown=docker:docker front .
|
||||
COPY --from=builder --chown=docker:docker /usr/src/generated /var/www/html/src/Messages/generated
|
||||
COPY --from=builder --chown=docker:docker /usr/src/ts-proto-generated/protos /var/www/html/src/Messages/ts-proto-generated
|
||||
RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' /var/www/html/src/Messages/ts-proto-generated/messages.ts
|
||||
COPY --from=builder --chown=docker:docker /usr/src/JsonMessages /var/www/html/src/Messages/JsonMessages
|
||||
|
||||
# Removing the iframe.html file from the final image as this adds a XSS attack.
|
||||
# iframe.html is only in dev mode to circumvent a limitation
|
||||
|
|
2
front/dist/.htaccess
vendored
2
front/dist/.htaccess
vendored
|
@ -20,7 +20,7 @@ RewriteBase /
|
|||
# We only want to let Apache serve files and not directories.
|
||||
# Rewrite all other queries starting with _ to index.ts.
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule "^[_@]/" "/index.html" [L]
|
||||
RewriteRule "^[_@*]/" "/index.html" [L]
|
||||
RewriteRule "^register/" "/index.html" [L]
|
||||
RewriteRule "^login" "/index.html" [L]
|
||||
RewriteRule "^jwt" "/index.html" [L]
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
"@types/quill": "^1.3.7",
|
||||
"@types/uuidv4": "^5.0.0",
|
||||
"@types/webpack-dev-server": "^3.11.4",
|
||||
"@typescript-eslint/eslint-plugin": "^4.23.0",
|
||||
"@typescript-eslint/parser": "^4.23.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||
"@typescript-eslint/parser": "^5.6.0",
|
||||
"css-loader": "^5.2.4",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"fork-ts-checker-webpack-plugin": "^6.2.9",
|
||||
"fork-ts-checker-webpack-plugin": "^6.5.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"jasmine": "^3.5.0",
|
||||
"lint-staged": "^11.0.0",
|
||||
|
@ -32,10 +32,10 @@
|
|||
"svelte-check": "^2.1.0",
|
||||
"svelte-loader": "^3.1.1",
|
||||
"svelte-preprocess": "^4.7.3",
|
||||
"ts-loader": "^9.1.2",
|
||||
"ts-node": "^9.1.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node": "^10.4.0",
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"typescript": "^4.2.4",
|
||||
"typescript": "^4.5.3",
|
||||
"webpack": "^5.37.0",
|
||||
"webpack-cli": "^4.7.0",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
|
@ -47,6 +47,7 @@
|
|||
"@types/socket.io-client": "^1.4.32",
|
||||
"axios": "^0.21.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"deep-copy-ts": "^0.5.0",
|
||||
"generic-type-guard": "^3.2.0",
|
||||
"google-protobuf": "^3.13.0",
|
||||
"phaser": "^3.54.0",
|
||||
|
@ -61,6 +62,7 @@
|
|||
"simple-peer": "^9.11.0",
|
||||
"socket.io-client": "^2.3.0",
|
||||
"standardized-audio-context": "^25.2.4",
|
||||
"ts-proto": "^1.96.0",
|
||||
"uuidv4": "^6.2.10"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -18,64 +18,84 @@ class AnalyticsClient {
|
|||
}
|
||||
|
||||
identifyUser(uuid: string, email: string | null) {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.identify(uuid, { uuid, email, wa: true });
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.identify(uuid, { uuid, email, wa: true });
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
loggedWithSso() {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-logged-sso");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-logged-sso");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
loggedWithToken() {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-logged-token");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-logged-token");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
enteredRoom(roomId: string, roomGroup: string | null) {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("$pageView", { roomId, roomGroup });
|
||||
posthog.capture("enteredRoom");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("$pageView", { roomId, roomGroup });
|
||||
posthog.capture("enteredRoom");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
openedMenu() {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-opened-menu");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-opened-menu");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
launchEmote(emote: string) {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-emote-launch", { emote });
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-emote-launch", { emote });
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
enteredJitsi(roomName: string, roomId: string) {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-entered-jitsi", { roomName, roomId });
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-entered-jitsi", { roomName, roomId });
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
validationName() {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-name-validation");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-name-validation");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
validationWoka(scene: string) {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-woka-validation", { scene });
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-woka-validation", { scene });
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
validationVideo() {
|
||||
this.posthogPromise?.then((posthog) => {
|
||||
posthog.capture("wa-video-validation");
|
||||
});
|
||||
this.posthogPromise
|
||||
?.then((posthog) => {
|
||||
posthog.capture("wa-video-validation");
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
export const analyticsClient = new AnalyticsClient();
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
import { AdminMessageEventTypes, adminMessagesService } from "../Connexion/AdminMessagesService";
|
||||
import { textMessageContentStore, textMessageVisibleStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||
import { UPLOADER_URL } from "../Enum/EnvironmentVariable";
|
||||
import { banMessageContentStore, banMessageVisibleStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
|
||||
class UserMessageManager {
|
||||
receiveBannedMessageListener!: Function;
|
||||
|
||||
constructor() {
|
||||
adminMessagesService.messageStream.subscribe((event) => {
|
||||
textMessageVisibleStore.set(false);
|
||||
banMessageVisibleStore.set(false);
|
||||
if (event.type === AdminMessageEventTypes.admin) {
|
||||
textMessageContentStore.set(event.text);
|
||||
textMessageVisibleStore.set(true);
|
||||
textMessageStore.addMessage(event.text);
|
||||
} else if (event.type === AdminMessageEventTypes.audio) {
|
||||
soundPlayingStore.playSound(UPLOADER_URL + event.text);
|
||||
} else if (event.type === AdminMessageEventTypes.ban) {
|
||||
banMessageContentStore.set(event.text);
|
||||
banMessageVisibleStore.set(true);
|
||||
banMessageStore.addMessage(event.text);
|
||||
} else if (event.type === AdminMessageEventTypes.banned) {
|
||||
banMessageContentStore.set(event.text);
|
||||
banMessageVisibleStore.set(true);
|
||||
banMessageStore.addMessage(event.text);
|
||||
this.receiveBannedMessageListener();
|
||||
}
|
||||
});
|
||||
|
|
13
front/src/Api/Events/ColorEvent.ts
Normal file
13
front/src/Api/Events/ColorEvent.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import * as tg from "generic-type-guard";
|
||||
|
||||
export const isColorEvent = new tg.IsInterface()
|
||||
.withProperties({
|
||||
red: tg.isNumber,
|
||||
green: tg.isNumber,
|
||||
blue: tg.isNumber,
|
||||
})
|
||||
.get();
|
||||
/**
|
||||
* A message sent from the iFrame to the game to dynamically set the outline of the player.
|
||||
*/
|
||||
export type ColorEvent = tg.GuardedType<typeof isColorEvent>;
|
|
@ -34,6 +34,7 @@ import type { ChangeZoneEvent } from "./ChangeZoneEvent";
|
|||
import type { CameraSetPositionEvent } from "./CameraSetPositionEvent";
|
||||
import type { CameraFocusOnEvent } from "./CameraFocusOnEvent";
|
||||
import type { CameraFollowPlayerEvent } from "./CameraFollowPlayerEvent";
|
||||
import { isColorEvent } from "./ColorEvent";
|
||||
|
||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||
data: T;
|
||||
|
@ -162,6 +163,14 @@ export const iframeQueryMapTypeGuards = {
|
|||
query: isCreateEmbeddedWebsiteEvent,
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
setPlayerOutline: {
|
||||
query: isColorEvent,
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
removePlayerOutline: {
|
||||
query: tg.isUndefined,
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
getPlayerPosition: {
|
||||
query: tg.isUndefined,
|
||||
answer: isPlayerPosition,
|
||||
|
|
|
@ -26,7 +26,7 @@ export class ActionMessage {
|
|||
this.message = actionMessageOptions.message;
|
||||
this.type = actionMessageOptions.type ?? "message";
|
||||
this.callback = actionMessageOptions.callback;
|
||||
this.create();
|
||||
this.create().catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
private async create() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import { Subject } from "rxjs";
|
||||
import type { WasCameraUpdatedEvent, WasCameraUpdatedEventCallback } from "../Events/WasCameraUpdatedEvent";
|
||||
import type { WasCameraUpdatedEvent } from "../Events/WasCameraUpdatedEvent";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import { isWasCameraUpdatedEvent } from "../Events/WasCameraUpdatedEvent";
|
||||
|
||||
|
@ -38,12 +38,12 @@ export class WorkAdventureCameraCommands extends IframeApiContribution<WorkAdven
|
|||
});
|
||||
}
|
||||
|
||||
onCameraUpdate(callback: WasCameraUpdatedEventCallback): void {
|
||||
moveStream.subscribe(callback);
|
||||
onCameraUpdate(): Subject<WasCameraUpdatedEvent> {
|
||||
sendToWorkadventure({
|
||||
type: "onCameraUpdate",
|
||||
data: null,
|
||||
});
|
||||
return moveStream;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,24 @@ export class WorkadventurePlayerCommands extends IframeApiContribution<Workadven
|
|||
}
|
||||
return userRoomToken;
|
||||
}
|
||||
|
||||
public setOutlineColor(red: number, green: number, blue: number): Promise<void> {
|
||||
return queryWorkadventure({
|
||||
type: "setPlayerOutline",
|
||||
data: {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public removeOutlineColor(): Promise<void> {
|
||||
return queryWorkadventure({
|
||||
type: "removePlayerOutline",
|
||||
data: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export type Position = {
|
||||
|
|
|
@ -95,7 +95,7 @@ export function createState(target: "global" | "player"): WorkadventureStateComm
|
|||
set(target: WorkadventureStateCommands, p: PropertyKey, value: unknown, receiver: unknown): boolean {
|
||||
// Note: when using "set", there is no way to wait, so we ignore the return of the promise.
|
||||
// User must use WA.state.saveVariable to have error message.
|
||||
target.saveVariable(p.toString(), value);
|
||||
target.saveVariable(p.toString(), value).catch((e) => console.error(e));
|
||||
return true;
|
||||
},
|
||||
has(target: WorkadventureStateCommands, p: PropertyKey): boolean {
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
import { chatVisibilityStore } from "../Stores/ChatStore";
|
||||
import { helpCameraSettingsVisibleStore } from "../Stores/HelpCameraSettingsStore";
|
||||
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
||||
import { showLimitRoomModalStore, showShareLinkMapModalStore } from "../Stores/ModalStore";
|
||||
import LimitRoomModal from "./Modal/LimitRoomModal.svelte";
|
||||
import ShareLinkMapModal from "./Modal/ShareLinkMapModal.svelte";
|
||||
import AudioPlaying from "./UI/AudioPlaying.svelte";
|
||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||
import ErrorDialog from "./UI/ErrorDialog.svelte";
|
||||
|
@ -30,10 +33,10 @@
|
|||
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
||||
import VideoOverlay from "./Video/VideoOverlay.svelte";
|
||||
import { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
||||
import AdminMessage from "./TypeMessage/BanMessage.svelte";
|
||||
import TextMessage from "./TypeMessage/TextMessage.svelte";
|
||||
import { banMessageVisibleStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { textMessageVisibleStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import BanMessageContainer from "./TypeMessage/BanMessageContainer.svelte";
|
||||
import TextMessageContainer from "./TypeMessage/TextMessageContainer.svelte";
|
||||
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { warningContainerStore } from "../Stores/MenuStore";
|
||||
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
||||
import { layoutManagerVisibilityStore } from "../Stores/LayoutManagerStore";
|
||||
|
@ -42,6 +45,9 @@
|
|||
import AudioManager from "./AudioManager/AudioManager.svelte";
|
||||
import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore";
|
||||
import ReportMenu from "./ReportMenu/ReportMenu.svelte";
|
||||
import { followStateStore } from "../Stores/FollowStore";
|
||||
import { peerStore } from "../Stores/PeerStore";
|
||||
import FollowMenu from "./FollowMenu/FollowMenu.svelte";
|
||||
|
||||
export let game: Game;
|
||||
</script>
|
||||
|
@ -72,14 +78,13 @@
|
|||
<EnableCameraScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $banMessageVisibleStore}
|
||||
{#if $banMessageStore.length > 0}
|
||||
<div>
|
||||
<AdminMessage />
|
||||
<BanMessageContainer />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $textMessageVisibleStore}
|
||||
{:else if $textMessageStore.length > 0}
|
||||
<div>
|
||||
<TextMessage />
|
||||
<TextMessageContainer />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $soundPlayingStore}
|
||||
|
@ -102,6 +107,11 @@
|
|||
<ReportMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $followStateStore !== "off" || $peerStore.size > 0}
|
||||
<div>
|
||||
<FollowMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $menuIconVisiblilityStore}
|
||||
<div>
|
||||
<MenuIcon />
|
||||
|
@ -129,6 +139,16 @@
|
|||
<HelpCameraSettingsPopup />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showLimitRoomModalStore}
|
||||
<div>
|
||||
<LimitRoomModal />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showShareLinkMapModalStore}
|
||||
<div>
|
||||
<ShareLinkMapModal />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $requestVisitCardsStore}
|
||||
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
||||
{/if}
|
||||
|
|
|
@ -19,12 +19,13 @@
|
|||
audioManagerVolumeStore.setVolume(volume);
|
||||
audioManagerVolumeStore.setMuted(localUserStore.getAudioPlayerMuted());
|
||||
|
||||
unsubscriberFileStore = audioManagerFileStore.subscribe(() => {
|
||||
unsubscriberFileStore = audioManagerFileStore.subscribe((src) => {
|
||||
HTMLAudioPlayer.pause();
|
||||
HTMLAudioPlayer.src = src;
|
||||
HTMLAudioPlayer.loop = get(audioManagerVolumeStore).loop;
|
||||
HTMLAudioPlayer.volume = get(audioManagerVolumeStore).volume;
|
||||
HTMLAudioPlayer.muted = get(audioManagerVolumeStore).muted;
|
||||
HTMLAudioPlayer.play();
|
||||
void HTMLAudioPlayer.play();
|
||||
});
|
||||
unsubscriberVolumeStore = audioManagerVolumeStore.subscribe((audioManager: audioManagerVolume) => {
|
||||
const reduceVolume = audioManager.talking && audioManager.decreaseWhileTalking;
|
||||
|
@ -148,9 +149,7 @@
|
|||
</label>
|
||||
<section class="audio-manager-file">
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<audio class="audio-manager-audioplayer" bind:this={HTMLAudioPlayer}>
|
||||
<source src={$audioManagerFileStore} />
|
||||
</audio>
|
||||
<audio class="audio-manager-audioplayer" bind:this={HTMLAudioPlayer} />
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
.messagePart {
|
||||
flex-grow: 1;
|
||||
max-width: 100%;
|
||||
user-select: text;
|
||||
|
||||
span.date {
|
||||
font-size: 80%;
|
||||
|
|
197
front/src/Components/FollowMenu/FollowMenu.svelte
Normal file
197
front/src/Components/FollowMenu/FollowMenu.svelte
Normal file
|
@ -0,0 +1,197 @@
|
|||
<!--
|
||||
vim: ft=typescript
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
import followImg from "../images/follow.svg";
|
||||
|
||||
import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
|
||||
|
||||
const gameScene = gameManager.getCurrentGameScene();
|
||||
|
||||
function name(userId: number): string | undefined {
|
||||
return gameScene.MapPlayersByKey.get(userId)?.PlayerValue;
|
||||
}
|
||||
|
||||
function sendFollowRequest() {
|
||||
gameScene.CurrentPlayer.sendFollowRequest();
|
||||
}
|
||||
|
||||
function acceptFollowRequest() {
|
||||
gameScene.CurrentPlayer.startFollowing();
|
||||
}
|
||||
|
||||
function abortEnding() {
|
||||
followStateStore.set("active");
|
||||
}
|
||||
|
||||
function reset() {
|
||||
gameScene.connection?.emitFollowAbort();
|
||||
followUsersStore.stopFollowing();
|
||||
}
|
||||
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
{#if $followStateStore === "requesting" && $followRoleStore === "follower"}
|
||||
<div class="interact-menu nes-container is-rounded">
|
||||
<section class="interact-menu-title">
|
||||
<h2>Do you want to follow {name($followUsersStore[0])}?</h2>
|
||||
</section>
|
||||
<section class="interact-menu-action">
|
||||
<button type="button" class="nes-btn is-success" on:click|preventDefault={acceptFollowRequest}>Yes</button>
|
||||
<button type="button" class="nes-btn is-error" on:click|preventDefault={reset}>No</button>
|
||||
</section>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "ending"}
|
||||
<div class="interact-menu nes-container is-rounded">
|
||||
<section class="interact-menu-title">
|
||||
<h2>Interaction</h2>
|
||||
</section>
|
||||
{#if $followRoleStore === "follower"}
|
||||
<section class="interact-menu-question">
|
||||
<p>Do you want to stop following {name($followUsersStore[0])}?</p>
|
||||
</section>
|
||||
{:else if $followRoleStore === "leader"}
|
||||
<section class="interact-menu-question">
|
||||
<p>Do you want to stop leading the way?</p>
|
||||
</section>
|
||||
{/if}
|
||||
<section class="interact-menu-action">
|
||||
<button type="button" class="nes-btn is-success" on:click|preventDefault={reset}>Yes</button>
|
||||
<button type="button" class="nes-btn is-error" on:click|preventDefault={abortEnding}>No</button>
|
||||
</section>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "active" || $followStateStore === "ending"}
|
||||
<div class="interact-status nes-container is-rounded">
|
||||
<section class="interact-status">
|
||||
{#if $followRoleStore === "follower"}
|
||||
<p>Following {name($followUsersStore[0])}</p>
|
||||
{:else if $followUsersStore.length === 0}
|
||||
<p>Waiting for followers' confirmation</p>
|
||||
{:else if $followUsersStore.length === 1}
|
||||
<p>{name($followUsersStore[0])} is following you</p>
|
||||
{:else if $followUsersStore.length === 2}
|
||||
<p>{name($followUsersStore[0])} and {name($followUsersStore[1])} are following you</p>
|
||||
{:else}
|
||||
<p>
|
||||
{$followUsersStore.slice(0, -1).map(name).join(", ")} and {name(
|
||||
$followUsersStore[$followUsersStore.length - 1]
|
||||
)} are following you
|
||||
</p>
|
||||
{/if}
|
||||
</section>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "off"}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-primary follow-menu-button"
|
||||
on:click|preventDefault={sendFollowRequest}
|
||||
title="Ask others to follow"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "active" || $followStateStore === "ending"}
|
||||
{#if $followRoleStore === "follower"}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-error follow-menu-button"
|
||||
on:click|preventDefault={reset}
|
||||
title="Stop following"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-error follow-menu-button"
|
||||
on:click|preventDefault={reset}
|
||||
title="Stop leading the way"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.interact-status {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
height: 2.7em;
|
||||
width: 40vw;
|
||||
top: 87vh;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.interact-menu {
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
width: 60vw;
|
||||
top: 60vh;
|
||||
margin: auto;
|
||||
|
||||
section.interact-menu-title {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
section.interact-menu-question {
|
||||
margin: 4px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
p {
|
||||
font-size: 1.05em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
section.interact-menu-action {
|
||||
display: grid;
|
||||
grid-gap: 10%;
|
||||
grid-template-columns: 45% 45%;
|
||||
margin-bottom: 20px;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-menu-button {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.interact-status {
|
||||
width: 100vw;
|
||||
top: 78vh;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
div.interact-menu {
|
||||
height: 21vh;
|
||||
width: 100vw;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -6,11 +6,14 @@
|
|||
|
||||
let expandedMapCopyright = false;
|
||||
let expandedTilesetCopyright = false;
|
||||
let expandedAudioCopyright = false;
|
||||
|
||||
let mapName: string = "";
|
||||
let mapLink: string = "";
|
||||
let mapDescription: string = "";
|
||||
let mapCopyright: string = "The map creator did not declare a copyright for the map.";
|
||||
let tilesetCopyright: string[] = [];
|
||||
let audioCopyright: string[] = [];
|
||||
|
||||
onMount(() => {
|
||||
if (gameScene.mapFile.properties !== undefined) {
|
||||
|
@ -18,6 +21,10 @@
|
|||
if (propertyName !== undefined && typeof propertyName.value === "string") {
|
||||
mapName = propertyName.value;
|
||||
}
|
||||
const propertyLink = gameScene.mapFile.properties.find((property) => property.name === "mapLink");
|
||||
if (propertyLink !== undefined && typeof propertyLink.value === "string") {
|
||||
mapLink = propertyLink.value;
|
||||
}
|
||||
const propertyDescription = gameScene.mapFile.properties.find(
|
||||
(property) => property.name === "mapDescription"
|
||||
);
|
||||
|
@ -36,7 +43,18 @@
|
|||
(property) => property.name === "tilesetCopyright"
|
||||
);
|
||||
if (propertyTilesetCopyright !== undefined && typeof propertyTilesetCopyright.value === "string") {
|
||||
tilesetCopyright = [...tilesetCopyright, propertyTilesetCopyright.value]; //Assignment needed to trigger Svelte's reactivity
|
||||
// Assignment needed to trigger Svelte's reactivity
|
||||
tilesetCopyright = [...tilesetCopyright, propertyTilesetCopyright.value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const layer of gameScene.mapFile.layers) {
|
||||
if (layer.type && layer.type === "tilelayer" && layer.properties) {
|
||||
const propertyAudioCopyright = layer.properties.find((property) => property.name === "audioCopyright");
|
||||
if (propertyAudioCopyright !== undefined && typeof propertyAudioCopyright.value === "string") {
|
||||
// Assignment needed to trigger Svelte's reactivity
|
||||
audioCopyright = [...audioCopyright, propertyAudioCopyright.value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +66,9 @@
|
|||
<section class="container-overflow">
|
||||
<h3>{mapName}</h3>
|
||||
<p class="string-HTML">{mapDescription}</p>
|
||||
{#if mapLink}
|
||||
<p class="string-HTML">> <a href={mapLink} target="_blank">link to this map</a> <</p>
|
||||
{/if}
|
||||
<h3 class="nes-pointer hoverable" on:click={() => (expandedMapCopyright = !expandedMapCopyright)}>
|
||||
Copyrights of the map
|
||||
</h3>
|
||||
|
@ -60,8 +81,21 @@
|
|||
<p class="string-HTML">{copyright}</p>
|
||||
{:else}
|
||||
<p>
|
||||
The map creator did not declare a copyright for the tilesets. Warning, This doesn't mean that those
|
||||
tilesets have no license.
|
||||
The map creator did not declare a copyright for the tilesets. This doesn't mean that those tilesets
|
||||
have no license.
|
||||
</p>
|
||||
{/each}
|
||||
</section>
|
||||
<h3 class="nes-pointer hoverable" on:click={() => (expandedAudioCopyright = !expandedAudioCopyright)}>
|
||||
Copyrights of audio files
|
||||
</h3>
|
||||
<section hidden={!expandedAudioCopyright}>
|
||||
{#each audioCopyright as copyright}
|
||||
<p class="string-HTML">{copyright}</p>
|
||||
{:else}
|
||||
<p>
|
||||
The map creator did not declare a copyright for audio files. This doesn't mean that those tilesets
|
||||
have no license.
|
||||
</p>
|
||||
{/each}
|
||||
</section>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
const selectedFile = inputAudio.files ? inputAudio.files[0] : null;
|
||||
if (!selectedFile) {
|
||||
errorFile = true;
|
||||
throw "no file selected";
|
||||
throw new Error("no file selected");
|
||||
}
|
||||
|
||||
const fd = new FormData();
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
uploadAudioActive = true;
|
||||
}
|
||||
|
||||
function send() {
|
||||
async function send(): Promise<void> {
|
||||
if (inputSendTextActive) {
|
||||
handleSendText.sendTextMessage(broadcastToWorld);
|
||||
return handleSendText.sendTextMessage(broadcastToWorld);
|
||||
}
|
||||
if (uploadAudioActive) {
|
||||
handleSendAudio.sendAudioMessage(broadcastToWorld);
|
||||
return handleSendAudio.sendAudioMessage(broadcastToWorld);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
<div class="guest-main">
|
||||
<section class="container-overflow">
|
||||
<section class="share-url not-mobile">
|
||||
<h3>Share the link of the room !</h3>
|
||||
<h3>Share the link of the room!</h3>
|
||||
<input type="text" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={copyLink}>Copy</button>
|
||||
</section>
|
||||
<section class="is-mobile">
|
||||
<h3>Share the link of the room !</h3>
|
||||
<h3>Share the link of the room!</h3>
|
||||
<input type="hidden" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={shareLink}>Share</button>
|
||||
</section>
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else throw "There is no menu called " + menu;
|
||||
} else throw new Error("There is no menu called " + menu);
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
<script lang="typescript">
|
||||
import logoTalk from "../images/logo-message-pixel.png";
|
||||
import logoWA from "../images/logo-WA-pixel.png";
|
||||
import logoInvite from "../images/logo-invite-pixel.png";
|
||||
import logoRegister from "../images/logo-register-pixel.png";
|
||||
import { menuVisiblilityStore } from "../../Stores/MenuStore";
|
||||
import { chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
import { limitMapStore } from "../../Stores/GameStore";
|
||||
import { get } from "svelte/store";
|
||||
import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
|
||||
import { showShareLinkMapModalStore } from "../../Stores/ModalStore";
|
||||
|
||||
function showMenu() {
|
||||
menuVisiblilityStore.set(!get(menuVisiblilityStore));
|
||||
|
@ -11,13 +16,25 @@
|
|||
function showChat() {
|
||||
chatVisibilityStore.set(true);
|
||||
}
|
||||
|
||||
function register() {
|
||||
window.open(`${ADMIN_URL}/second-step-register`, "_self");
|
||||
}
|
||||
function showInvite() {
|
||||
showShareLinkMapModalStore.set(true);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window />
|
||||
|
||||
<main class="menuIcon">
|
||||
<img src={logoWA} alt="open menu" class="nes-pointer" on:click|preventDefault={showMenu} />
|
||||
<img src={logoTalk} alt="open menu" class="nes-pointer" on:click|preventDefault={showChat} />
|
||||
{#if $limitMapStore}
|
||||
<img src={logoInvite} alt="open menu" class="nes-pointer" on:click|preventDefault={showInvite} />
|
||||
<img src={logoRegister} alt="open menu" class="nes-pointer" on:click|preventDefault={register} />
|
||||
{:else}
|
||||
<img src={logoWA} alt="open menu" class="nes-pointer" on:click|preventDefault={showMenu} />
|
||||
<img src={logoTalk} alt="open menu" class="nes-pointer" on:click|preventDefault={showChat} />
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
async function logOut() {
|
||||
disableMenuStores();
|
||||
loginSceneVisibleStore.set(true);
|
||||
connectionManager.logout();
|
||||
return connectionManager.logout();
|
||||
}
|
||||
|
||||
function getProfileUrl() {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
let fullscreen: boolean = localUserStore.getFullscreen();
|
||||
let notification: boolean = localUserStore.getNotification() === "granted";
|
||||
let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger();
|
||||
let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests();
|
||||
let valueGame: number = localUserStore.getGameQualityValue();
|
||||
let valueVideo: number = localUserStore.getVideoQualityValue();
|
||||
let previewValueGame = valueGame;
|
||||
|
@ -32,9 +33,9 @@
|
|||
const body = HtmlUtils.querySelectorOrFail("body");
|
||||
if (body) {
|
||||
if (document.fullscreenElement !== null && !fullscreen) {
|
||||
document.exitFullscreen();
|
||||
document.exitFullscreen().catch((e) => console.error(e));
|
||||
} else {
|
||||
body.requestFullscreen();
|
||||
body.requestFullscreen().catch((e) => console.error(e));
|
||||
}
|
||||
localUserStore.setFullscreen(fullscreen);
|
||||
}
|
||||
|
@ -44,14 +45,16 @@
|
|||
if (Notification.permission === "granted") {
|
||||
localUserStore.setNotification(notification ? "granted" : "denied");
|
||||
} else {
|
||||
Notification.requestPermission().then((response) => {
|
||||
if (response === "granted") {
|
||||
localUserStore.setNotification(notification ? "granted" : "denied");
|
||||
} else {
|
||||
localUserStore.setNotification("denied");
|
||||
notification = false;
|
||||
}
|
||||
});
|
||||
Notification.requestPermission()
|
||||
.then((response) => {
|
||||
if (response === "granted") {
|
||||
localUserStore.setNotification(notification ? "granted" : "denied");
|
||||
} else {
|
||||
localUserStore.setNotification("denied");
|
||||
notification = false;
|
||||
}
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +62,10 @@
|
|||
localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger);
|
||||
}
|
||||
|
||||
function changeIgnoreFollowRequests() {
|
||||
localUserStore.setIgnoreFollowRequests(ignoreFollowRequests);
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
|
@ -123,6 +130,15 @@
|
|||
/>
|
||||
<span>Always ask before opening websites and Jitsi Meet rooms</span>
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="nes-checkbox is-dark"
|
||||
bind:checked={ignoreFollowRequests}
|
||||
on:change={changeIgnoreFollowRequests}
|
||||
/>
|
||||
<span>Ignore requests to follow other users</span>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
|
47
front/src/Components/Modal/LimitRoomModal.svelte
Normal file
47
front/src/Components/Modal/LimitRoomModal.svelte
Normal file
|
@ -0,0 +1,47 @@
|
|||
<script lang="typescript">
|
||||
import { fly } from "svelte/transition";
|
||||
import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
function register() {
|
||||
window.open(`${ADMIN_URL}/second-step-register`, "_self");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="limit-map nes-container" transition:fly={{ y: -900, duration: 500 }}>
|
||||
<section>
|
||||
<h2>Limit of your room</h2>
|
||||
<p>Register your account!</p>
|
||||
<p>
|
||||
This map is limited in the time and to continue to use WorkAdventure, you must register your account in our
|
||||
back office.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<button class="nes-btn is-primary" on:click|preventDefault={register}>Register</button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.limit-map {
|
||||
pointer-events: auto;
|
||||
background: #eceeee;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10vh;
|
||||
max-height: 80vh;
|
||||
max-width: 80vw;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
section {
|
||||
p {
|
||||
margin: 15px;
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
90
front/src/Components/Modal/ShareLinkMapModal.svelte
Normal file
90
front/src/Components/Modal/ShareLinkMapModal.svelte
Normal file
|
@ -0,0 +1,90 @@
|
|||
<script lang="typescript">
|
||||
import { fly } from "svelte/transition";
|
||||
import { showShareLinkMapModalStore } from "../../Stores/ModalStore";
|
||||
|
||||
interface ExtNavigator extends Navigator {
|
||||
canShare?(data?: ShareData): Promise<boolean>;
|
||||
}
|
||||
|
||||
const myNavigator: ExtNavigator = window.navigator;
|
||||
const haveNavigatorSharingFeature: boolean =
|
||||
myNavigator && myNavigator.canShare != null && myNavigator.share != null;
|
||||
|
||||
let copied: boolean = false;
|
||||
|
||||
function copyLink() {
|
||||
try {
|
||||
const input: HTMLInputElement = document.getElementById("input-share-link") as HTMLInputElement;
|
||||
input.focus();
|
||||
input.select();
|
||||
document.execCommand("copy");
|
||||
copied = true;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
copied = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function shareLink() {
|
||||
const shareData = { url: location.toString() };
|
||||
|
||||
try {
|
||||
await myNavigator.share(shareData);
|
||||
} catch (err) {
|
||||
console.error("Error: " + err);
|
||||
copyLink();
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
showShareLinkMapModalStore.set(false);
|
||||
copied = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="share-link-map nes-container" transition:fly={{ y: -900, duration: 500 }}>
|
||||
<section>
|
||||
<h2>Invite your friends or colleagues</h2>
|
||||
<p>Share the link of the room!</p>
|
||||
</section>
|
||||
<section>
|
||||
{#if haveNavigatorSharingFeature}
|
||||
<input type="hidden" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={shareLink}>Share</button>
|
||||
{:else}
|
||||
<input type="text" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={copyLink}>Copy</button>
|
||||
{/if}
|
||||
{#if copied}
|
||||
<p>Copied!</p>
|
||||
{/if}
|
||||
</section>
|
||||
<section>
|
||||
<button class="nes-btn" on:click|preventDefault={close}>Close</button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.share-link-map {
|
||||
pointer-events: auto;
|
||||
background: #eceeee;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10vh;
|
||||
max-height: 80vh;
|
||||
max-width: 80vw;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
section {
|
||||
p {
|
||||
margin: 15px;
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -6,12 +6,11 @@
|
|||
import type { Unsubscriber } from "svelte/store";
|
||||
import { playersStore } from "../../Stores/PlayersStore";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
import { GameConnexionTypes } from "../../Url/UrlManager";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
let blockActive = true;
|
||||
let reportActive = !blockActive;
|
||||
let anonymous: boolean = false;
|
||||
let disableReport: boolean = false;
|
||||
let userUUID: string | undefined = playersStore.getPlayerById(get(showReportScreenStore).userId)?.userUuid;
|
||||
let userName = "No name";
|
||||
let unsubscriber: Unsubscriber;
|
||||
|
@ -26,7 +25,7 @@
|
|||
}
|
||||
}
|
||||
});
|
||||
anonymous = connectionManager.getConnexionType === GameConnexionTypes.anonymous;
|
||||
disableReport = !connectionManager.currentRoom?.canReport ?? true;
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
|
@ -65,7 +64,7 @@
|
|||
<button type="button" class="nes-btn" on:click|preventDefault={close}>X</button>
|
||||
</section>
|
||||
</section>
|
||||
<section class="report-menu-action {anonymous ? 'hidden' : ''}">
|
||||
<section class="report-menu-action {disableReport ? 'hidden' : ''}">
|
||||
<section class="justify-center">
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { fly } from "svelte/transition";
|
||||
import { banMessageVisibleStore, banMessageContentStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { fly, fade } from "svelte/transition";
|
||||
import { onMount } from "svelte";
|
||||
import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
|
||||
import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
|
||||
export let message: Message;
|
||||
|
||||
const text = $banMessageContentStore;
|
||||
const NAME_BUTTON = "Ok";
|
||||
let nbSeconds = 10;
|
||||
let nameButton = "";
|
||||
|
@ -25,17 +27,21 @@
|
|||
}
|
||||
|
||||
function closeBanMessage() {
|
||||
banMessageVisibleStore.set(false);
|
||||
banMessageStore.clearMessageById(message.id);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="main-ban-message nes-container is-rounded" transition:fly={{ y: -1000, duration: 500 }}>
|
||||
<div
|
||||
class="main-ban-message nes-container is-rounded"
|
||||
in:fly={{ y: -1000, duration: 500, delay: 250 }}
|
||||
out:fade={{ duration: 200 }}
|
||||
>
|
||||
<h2 class="title-ban-message">
|
||||
<img src="resources/logos/report.svg" alt="***" /> Important message
|
||||
<img src="resources/logos/report.svg" alt="***" />
|
||||
</h2>
|
||||
<div class="content-ban-message">
|
||||
<p>{text}</p>
|
||||
<p>{message.text}</p>
|
||||
</div>
|
||||
<div class="footer-ban-message">
|
||||
<button
|
||||
|
|
13
front/src/Components/TypeMessage/BanMessageContainer.svelte
Normal file
13
front/src/Components/TypeMessage/BanMessageContainer.svelte
Normal file
|
@ -0,0 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { flip } from "svelte/animate";
|
||||
import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
import BanMessage from "./BanMessage.svelte";
|
||||
</script>
|
||||
|
||||
<div class="main-ban-message-container">
|
||||
{#each $banMessageStore.slice(0, 1) as message (message.id)}
|
||||
<div animate:flip={{ duration: 250 }}>
|
||||
<BanMessage {message} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
|
@ -1,14 +1,17 @@
|
|||
<script lang="ts">
|
||||
import { fly } from "svelte/transition";
|
||||
import { textMessageContentStore, textMessageVisibleStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { fly, fade } from "svelte/transition";
|
||||
import { QuillDeltaToHtmlConverter } from "quill-delta-to-html";
|
||||
import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
|
||||
import { textMessageStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||
|
||||
const content = JSON.parse($textMessageContentStore);
|
||||
export let message: Message;
|
||||
|
||||
const content = JSON.parse(message.text);
|
||||
const converter = new QuillDeltaToHtmlConverter(content.ops, { inlineStyles: true });
|
||||
const NAME_BUTTON = "Ok";
|
||||
|
||||
function closeTextMessage() {
|
||||
textMessageVisibleStore.set(false);
|
||||
textMessageStore.clearMessageById(message.id);
|
||||
}
|
||||
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
|
@ -20,7 +23,11 @@
|
|||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="main-text-message nes-container is-rounded" transition:fly={{ x: -1000, duration: 500 }}>
|
||||
<div
|
||||
class="main-text-message nes-container is-rounded"
|
||||
in:fly={{ x: -1000, duration: 500, delay: 250 }}
|
||||
out:fade={{ duration: 250 }}
|
||||
>
|
||||
<div class="content-text-message">
|
||||
{@html converter.convert()}
|
||||
</div>
|
||||
|
@ -40,6 +47,8 @@
|
|||
width: 80vw;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
margin-bottom: 16px;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
|
||||
pointer-events: auto;
|
||||
|
|
21
front/src/Components/TypeMessage/TextMessageContainer.svelte
Normal file
21
front/src/Components/TypeMessage/TextMessageContainer.svelte
Normal file
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts">
|
||||
import { flip } from "svelte/animate";
|
||||
import TextMessage from "./TextMessage.svelte";
|
||||
import { textMessageStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||
|
||||
const MAX_MESSAGES = 3;
|
||||
</script>
|
||||
|
||||
<div class="main-text-message-container">
|
||||
{#each $textMessageStore.slice(0, MAX_MESSAGES) as message (message.id)}
|
||||
<div animate:flip={{ duration: 250 }}>
|
||||
<TextMessage {message} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.main-text-message-container {
|
||||
padding-top: 16px;
|
||||
}
|
||||
</style>
|
|
@ -12,7 +12,7 @@
|
|||
}
|
||||
|
||||
afterUpdate(() => {
|
||||
audio.play();
|
||||
audio.play().catch((e) => console.error(e));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
<script lang="typescript">
|
||||
import { fly } from "svelte/transition";
|
||||
import { userIsAdminStore } from "../../Stores/GameStore";
|
||||
import { userIsAdminStore, limitMapStore } from "../../Stores/GameStore";
|
||||
import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
const upgradeLink = ADMIN_URL + "/pricing";
|
||||
const registerLink = ADMIN_URL + "/second-step-register";
|
||||
</script>
|
||||
|
||||
<main class="warningMain" transition:fly={{ y: -200, duration: 500 }}>
|
||||
<h2>Warning!</h2>
|
||||
{#if $userIsAdminStore}
|
||||
<h2>Warning!</h2>
|
||||
<p>
|
||||
This world is close to its limit!. You can upgrade its capacity <a href={upgradeLink} target="_blank"
|
||||
>here</a
|
||||
>
|
||||
</p>
|
||||
{:else if $limitMapStore}
|
||||
<p>
|
||||
This map is available for 2 days. You can register your domain <a href={registerLink}>here</a>!
|
||||
</p>
|
||||
{:else}
|
||||
<h2>Warning!</h2>
|
||||
<p>This world is close to its limit!</p>
|
||||
{/if}
|
||||
</main>
|
||||
|
|
1
front/src/Components/images/follow.svg
Normal file
1
front/src/Components/images/follow.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24"><rect fill="none" height="24" width="24"/><path d="M9.5,5.5c1.1,0,2-0.9,2-2s-0.9-2-2-2s-2,0.9-2,2S8.4,5.5,9.5,5.5z M5.75,8.9L3,23h2.1l1.75-8L9,17v6h2v-7.55L8.95,13.4 l0.6-3C10.85,12,12.8,13,15,13v-2c-1.85,0-3.45-1-4.35-2.45L9.7,6.95C9.35,6.35,8.7,6,8,6C7.75,6,7.5,6.05,7.25,6.15L2,8.3V13h2 V9.65L5.75,8.9 M13,2v7h3.75v14h1.5V9H22V2H13z M18.01,8V6.25H14.5v-1.5h3.51V3l2.49,2.5L18.01,8z"/></svg>
|
After Width: | Height: | Size: 510 B |
BIN
front/src/Components/images/logo-invite-pixel.png
Normal file
BIN
front/src/Components/images/logo-invite-pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
front/src/Components/images/logo-register-pixel.png
Normal file
BIN
front/src/Components/images/logo-register-pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 977 B |
|
@ -1,5 +1,5 @@
|
|||
import { Subject } from "rxjs";
|
||||
import type { BanUserMessage, SendUserMessage } from "../Messages/generated/messages_pb";
|
||||
import type { BanUserMessage, SendUserMessage } from "../Messages/ts-proto-generated/messages";
|
||||
|
||||
export enum AdminMessageEventTypes {
|
||||
admin = "message",
|
||||
|
@ -26,8 +26,8 @@ class AdminMessagesService {
|
|||
|
||||
onSendusermessage(message: SendUserMessage | BanUserMessage) {
|
||||
this._messageStream.next({
|
||||
type: message.getType() as unknown as AdminMessageEventTypes,
|
||||
text: message.getMessage(),
|
||||
type: message.type as unknown as AdminMessageEventTypes,
|
||||
text: message.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Axios from "axios";
|
||||
import { PUSHER_URL, START_ROOM_URL } from "../Enum/EnvironmentVariable";
|
||||
import { PUSHER_URL } from "../Enum/EnvironmentVariable";
|
||||
import { RoomConnection } from "./RoomConnection";
|
||||
import type { OnConnectInterface, PositionInterface, ViewportInterface } from "./ConnexionModels";
|
||||
import { GameConnexionTypes, urlManager } from "../Url/UrlManager";
|
||||
|
@ -8,9 +8,14 @@ import { CharacterTexture, LocalUser } from "./LocalUser";
|
|||
import { Room } from "./Room";
|
||||
import { _ServiceWorker } from "../Network/ServiceWorker";
|
||||
import { loginSceneVisibleIframeStore } from "../Stores/LoginSceneStore";
|
||||
import { userIsConnected } from "../Stores/MenuStore";
|
||||
import { userIsConnected, warningContainerStore } from "../Stores/MenuStore";
|
||||
import { analyticsClient } from "../Administration/AnalyticsClient";
|
||||
import { axiosWithRetry } from "./AxiosUtils";
|
||||
import axios from "axios";
|
||||
import { isRegisterData } from "../Messages/JsonMessages/RegisterData";
|
||||
import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
|
||||
import { limitMapStore } from "../Stores/GameStore";
|
||||
import { showLimitRoomModalStore } from "../Stores/ModalStore";
|
||||
|
||||
class ConnectionManager {
|
||||
private localUser!: LocalUser;
|
||||
|
@ -101,10 +106,10 @@ class ConnectionManager {
|
|||
const code = urlParams.get("code");
|
||||
const state = urlParams.get("state");
|
||||
if (!state || !localUserStore.verifyState(state)) {
|
||||
throw "Could not validate state!";
|
||||
throw new Error("Could not validate state!");
|
||||
}
|
||||
if (!code) {
|
||||
throw "No Auth code provided";
|
||||
throw new Error("No Auth code provided");
|
||||
}
|
||||
localUserStore.setCode(code);
|
||||
}
|
||||
|
@ -125,6 +130,10 @@ class ConnectionManager {
|
|||
const data = await Axios.post(`${PUSHER_URL}/register`, { organizationMemberToken }).then(
|
||||
(res) => res.data
|
||||
);
|
||||
if (!isRegisterData(data)) {
|
||||
console.error("Invalid data received from /register route. Data: ", data);
|
||||
throw new Error("Invalid data received from /register route.");
|
||||
}
|
||||
this.localUser = new LocalUser(data.userUuid, data.textures, data.email);
|
||||
this.authToken = data.authToken;
|
||||
localUserStore.saveUser(this.localUser);
|
||||
|
@ -145,11 +154,7 @@ class ConnectionManager {
|
|||
)
|
||||
);
|
||||
urlManager.pushRoomIdToUrl(this._currentRoom);
|
||||
} else if (
|
||||
connexionType === GameConnexionTypes.organization ||
|
||||
connexionType === GameConnexionTypes.anonymous ||
|
||||
connexionType === GameConnexionTypes.empty
|
||||
) {
|
||||
} else if (connexionType === GameConnexionTypes.room || connexionType === GameConnexionTypes.empty) {
|
||||
this.authToken = localUserStore.getAuthToken();
|
||||
|
||||
let roomPath: string;
|
||||
|
@ -163,6 +168,9 @@ class ConnectionManager {
|
|||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
if (err instanceof Error) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const query = urlParams.toString();
|
||||
|
@ -181,7 +189,7 @@ class ConnectionManager {
|
|||
|
||||
//Set last room visited! (connected or nor, must to be saved in localstorage and cache API)
|
||||
//use href to keep # value
|
||||
localUserStore.setLastRoomUrl(this._currentRoom.href);
|
||||
await localUserStore.setLastRoomUrl(this._currentRoom.href);
|
||||
|
||||
//todo: add here some kind of warning if authToken has expired.
|
||||
if (!this.authToken && !this._currentRoom.authenticationMandatory) {
|
||||
|
@ -192,11 +200,13 @@ class ConnectionManager {
|
|||
analyticsClient.loggedWithSso();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
//if user must to be connect in current room or pusher error is not openid provier access error
|
||||
//try to connected with function loadOpenIDScreen
|
||||
// if the user must be connected in the current room or if the pusher error is not openid provider access error
|
||||
// try to connect with function loadOpenIDScreen
|
||||
if (
|
||||
this._currentRoom.authenticationMandatory ||
|
||||
(err.response?.data && err.response.data !== "User cannot to be connected on openid provier")
|
||||
(axios.isAxiosError(err) &&
|
||||
err.response?.data &&
|
||||
err.response.data !== "User cannot to be connected on openid provider")
|
||||
) {
|
||||
this.loadOpenIDScreen();
|
||||
return Promise.reject(new Error("You will be redirect on login page"));
|
||||
|
@ -228,6 +238,17 @@ class ConnectionManager {
|
|||
analyticsClient.identifyUser(this.localUser.uuid, this.localUser.email);
|
||||
}
|
||||
|
||||
//if limit room active test headband
|
||||
if (this._currentRoom.expireOn !== undefined) {
|
||||
warningContainerStore.activateWarningContainer();
|
||||
limitMapStore.set(true);
|
||||
|
||||
//check time of map
|
||||
if (new Date() > this._currentRoom.expireOn) {
|
||||
showLimitRoomModalStore.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
this.serviceWorker = new _ServiceWorker();
|
||||
return Promise.resolve(this._currentRoom);
|
||||
}
|
||||
|
@ -271,7 +292,7 @@ class ConnectionManager {
|
|||
reject(error);
|
||||
});
|
||||
|
||||
connection.onConnectingError((event: CloseEvent) => {
|
||||
connection.connectionErrorStream.subscribe((event: CloseEvent) => {
|
||||
console.log("An error occurred while connecting to socket server. Retrying");
|
||||
reject(
|
||||
new Error(
|
||||
|
@ -283,7 +304,7 @@ class ConnectionManager {
|
|||
);
|
||||
});
|
||||
|
||||
connection.onConnect((connect: OnConnectInterface) => {
|
||||
connection.roomJoinedMessageStream.subscribe((connect: OnConnectInterface) => {
|
||||
resolve(connect);
|
||||
});
|
||||
}).catch((err) => {
|
||||
|
@ -292,7 +313,7 @@ class ConnectionManager {
|
|||
this.reconnectingTimeout = setTimeout(() => {
|
||||
//todo: allow a way to break recursion?
|
||||
//todo: find a way to avoid recursive function. Otherwise, the call stack will grow indefinitely.
|
||||
this.connectToRoomSocket(roomUrl, name, characterLayers, position, viewport, companion).then(
|
||||
void this.connectToRoomSocket(roomUrl, name, characterLayers, position, viewport, companion).then(
|
||||
(connection) => resolve(connection)
|
||||
);
|
||||
}, 4000 + Math.floor(Math.random() * 2000));
|
||||
|
@ -315,15 +336,17 @@ class ConnectionManager {
|
|||
|
||||
if (!token) {
|
||||
if (!state || !localUserStore.verifyState(state)) {
|
||||
throw "Could not validate state!";
|
||||
throw new Error("Could not validate state!");
|
||||
}
|
||||
if (!code) {
|
||||
throw "No Auth code provided";
|
||||
throw new Error("No Auth code provided");
|
||||
}
|
||||
}
|
||||
const { authToken, userUuid, textures, email } = await Axios.get(`${PUSHER_URL}/login-callback`, {
|
||||
params: { code, nonce, token, playUri: this.currentRoom?.key },
|
||||
}).then((res) => res.data);
|
||||
}).then((res) => {
|
||||
return res.data;
|
||||
});
|
||||
localUserStore.setAuthToken(authToken);
|
||||
this.localUser = new LocalUser(userUuid, textures, email);
|
||||
localUserStore.saveUser(this.localUser);
|
||||
|
|
|
@ -1,43 +1,12 @@
|
|||
import type { SignalData } from "simple-peer";
|
||||
import type { RoomConnection } from "./RoomConnection";
|
||||
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
|
||||
|
||||
export enum EventMessage {
|
||||
CONNECT = "connect",
|
||||
WEBRTC_SIGNAL = "webrtc-signal",
|
||||
WEBRTC_SCREEN_SHARING_SIGNAL = "webrtc-screen-sharing-signal",
|
||||
WEBRTC_START = "webrtc-start",
|
||||
//START_ROOM = "start-room", // From server to client: list of all room users/groups/items
|
||||
JOIN_ROOM = "join-room", // bi-directional
|
||||
USER_POSITION = "user-position", // From client to server
|
||||
USER_MOVED = "user-moved", // From server to client
|
||||
USER_LEFT = "user-left", // From server to client
|
||||
MESSAGE_ERROR = "message-error",
|
||||
WEBRTC_DISCONNECT = "webrtc-disconect",
|
||||
GROUP_CREATE_UPDATE = "group-create-update",
|
||||
GROUP_DELETE = "group-delete",
|
||||
SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id.
|
||||
ITEM_EVENT = "item-event",
|
||||
|
||||
CONNECT_ERROR = "connect_error",
|
||||
CONNECTING_ERROR = "connecting_error",
|
||||
SET_SILENT = "set_silent", // Set or unset the silent mode for this user.
|
||||
SET_VIEWPORT = "set-viewport",
|
||||
BATCH = "batch",
|
||||
|
||||
PLAY_GLOBAL_MESSAGE = "play-global-message",
|
||||
STOP_GLOBAL_MESSAGE = "stop-global-message",
|
||||
|
||||
TELEPORT = "teleport",
|
||||
USER_MESSAGE = "user-message",
|
||||
START_JITSI_ROOM = "start-jitsi-room",
|
||||
SET_VARIABLE = "set-variable",
|
||||
}
|
||||
import { PositionMessage_Direction } from "../Messages/ts-proto-generated/messages";
|
||||
|
||||
export interface PointInterface {
|
||||
x: number;
|
||||
y: number;
|
||||
direction: string;
|
||||
direction: string; // TODO: modify this to the enum from ts-proto
|
||||
moving: boolean;
|
||||
}
|
||||
|
||||
|
@ -64,6 +33,7 @@ export interface MessageUserJoined {
|
|||
visitCardUrl: string | null;
|
||||
companion: string | null;
|
||||
userUuid: string;
|
||||
outlineColor: number | undefined;
|
||||
}
|
||||
|
||||
export interface PositionInterface {
|
||||
|
@ -102,6 +72,12 @@ export interface ItemEventMessageInterface {
|
|||
parameters: unknown;
|
||||
}
|
||||
|
||||
export interface PlayerDetailsUpdatedMessageInterface {
|
||||
userId: number;
|
||||
outlineColor: number;
|
||||
removeOutlineColor: boolean;
|
||||
}
|
||||
|
||||
export interface RoomJoinedMessageInterface {
|
||||
//users: MessageUserPositionInterface[],
|
||||
//groups: GroupCreatedUpdatedMessageInterface[],
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { Subject } from "rxjs";
|
||||
|
||||
interface EmoteEvent {
|
||||
userId: number;
|
||||
emote: string;
|
||||
}
|
||||
|
||||
class EmoteEventStream {
|
||||
private _stream: Subject<EmoteEvent> = new Subject();
|
||||
public stream = this._stream.asObservable();
|
||||
|
||||
fire(userId: number, emote: string) {
|
||||
this._stream.next({ userId, emote });
|
||||
}
|
||||
}
|
||||
|
||||
export const emoteEventStream = new EmoteEventStream();
|
|
@ -14,6 +14,7 @@ const audioPlayerMuteKey = "audioMute";
|
|||
const helpCameraSettingsShown = "helpCameraSettingsShown";
|
||||
const fullscreenKey = "fullscreen";
|
||||
const forceCowebsiteTriggerKey = "forceCowebsiteTrigger";
|
||||
const ignoreFollowRequests = "ignoreFollowRequests";
|
||||
const lastRoomUrl = "lastRoomUrl";
|
||||
const authToken = "authToken";
|
||||
const state = "state";
|
||||
|
@ -128,13 +129,23 @@ class LocalUserStore {
|
|||
return localStorage.getItem(forceCowebsiteTriggerKey) === "true";
|
||||
}
|
||||
|
||||
setLastRoomUrl(roomUrl: string): void {
|
||||
setIgnoreFollowRequests(value: boolean): void {
|
||||
localStorage.setItem(ignoreFollowRequests, value.toString());
|
||||
}
|
||||
getIgnoreFollowRequests(): boolean {
|
||||
return localStorage.getItem(ignoreFollowRequests) === "true";
|
||||
}
|
||||
|
||||
async setLastRoomUrl(roomUrl: string): Promise<void> {
|
||||
localStorage.setItem(lastRoomUrl, roomUrl.toString());
|
||||
if ("caches" in window) {
|
||||
caches.open(cacheAPIIndex).then((cache) => {
|
||||
try {
|
||||
const cache = await caches.open(cacheAPIIndex);
|
||||
const stringResponse = new Response(JSON.stringify({ roomUrl }));
|
||||
cache.put(`/${lastRoomUrl}`, stringResponse);
|
||||
});
|
||||
await cache.put(`/${lastRoomUrl}`, stringResponse);
|
||||
} catch (e) {
|
||||
console.error("Could not store last room url in Browser cache. Are you using private browser mode?", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
getLastRoomUrl(): string {
|
||||
|
|
|
@ -5,6 +5,8 @@ import type { CharacterTexture } from "./LocalUser";
|
|||
import { localUserStore } from "./LocalUserStore";
|
||||
import axios from "axios";
|
||||
import { axiosWithRetry } from "./AxiosUtils";
|
||||
import { isMapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
|
||||
import { isRoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
|
||||
|
||||
export class MapDetail {
|
||||
constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {}
|
||||
|
@ -16,7 +18,10 @@ export interface RoomRedirect {
|
|||
|
||||
export class Room {
|
||||
public readonly id: string;
|
||||
public readonly isPublic: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
private readonly isPublic: boolean;
|
||||
private _authenticationMandatory: boolean = DISABLE_ANONYMOUS;
|
||||
private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER;
|
||||
private _mapUrl: string | undefined;
|
||||
|
@ -25,6 +30,8 @@ export class Room {
|
|||
private readonly _search: URLSearchParams;
|
||||
private _contactPage: string | undefined;
|
||||
private _group: string | null = null;
|
||||
private _expireOn: Date | undefined;
|
||||
private _canReport: boolean = false;
|
||||
|
||||
private constructor(private roomUrl: URL) {
|
||||
this.id = roomUrl.pathname;
|
||||
|
@ -32,7 +39,7 @@ export class Room {
|
|||
if (this.id.startsWith("/")) {
|
||||
this.id = this.id.substr(1);
|
||||
}
|
||||
if (this.id.startsWith("_/")) {
|
||||
if (this.id.startsWith("_/") || this.id.startsWith("*/")) {
|
||||
this.isPublic = true;
|
||||
} else if (this.id.startsWith("@/")) {
|
||||
this.isPublic = false;
|
||||
|
@ -80,13 +87,11 @@ export class Room {
|
|||
const currentRoom = new Room(baseUrl);
|
||||
let instance: string = "global";
|
||||
if (currentRoom.isPublic) {
|
||||
instance = currentRoom.instance as string;
|
||||
instance = currentRoom.getInstance();
|
||||
}
|
||||
|
||||
baseUrl.pathname = "/_/" + instance + "/" + absoluteExitSceneUrl.host + absoluteExitSceneUrl.pathname;
|
||||
if (absoluteExitSceneUrl.hash) {
|
||||
baseUrl.hash = absoluteExitSceneUrl.hash;
|
||||
}
|
||||
baseUrl.hash = absoluteExitSceneUrl.hash;
|
||||
|
||||
return baseUrl;
|
||||
}
|
||||
|
@ -101,27 +106,41 @@ export class Room {
|
|||
});
|
||||
|
||||
const data = result.data;
|
||||
if (data.redirectUrl) {
|
||||
return {
|
||||
redirectUrl: data.redirectUrl as string,
|
||||
};
|
||||
|
||||
if (data.authenticationMandatory !== undefined) {
|
||||
data.authenticationMandatory = Boolean(data.authenticationMandatory);
|
||||
}
|
||||
|
||||
if (isRoomRedirect(data)) {
|
||||
return {
|
||||
redirectUrl: data.redirectUrl,
|
||||
};
|
||||
} else if (isMapDetailsData(data)) {
|
||||
console.log("Map ", this.id, " resolves to URL ", data.mapUrl);
|
||||
this._mapUrl = data.mapUrl;
|
||||
this._textures = data.textures;
|
||||
this._group = data.group;
|
||||
this._authenticationMandatory =
|
||||
data.authenticationMandatory != null ? data.authenticationMandatory : DISABLE_ANONYMOUS;
|
||||
this._iframeAuthentication = data.iframeAuthentication || OPID_LOGIN_SCREEN_PROVIDER;
|
||||
this._contactPage = data.contactPage || CONTACT_URL;
|
||||
if (data.expireOn) {
|
||||
this._expireOn = new Date(data.expireOn);
|
||||
}
|
||||
this._canReport = data.canReport ?? false;
|
||||
return new MapDetail(data.mapUrl, data.textures);
|
||||
} else {
|
||||
throw new Error("Data received by the /map endpoint of the Pusher is not in a valid format.");
|
||||
}
|
||||
console.log("Map ", this.id, " resolves to URL ", data.mapUrl);
|
||||
this._mapUrl = data.mapUrl;
|
||||
this._textures = data.textures;
|
||||
this._group = data.group;
|
||||
this._authenticationMandatory =
|
||||
data.authenticationMandatory != null ? data.authenticationMandatory : DISABLE_ANONYMOUS;
|
||||
this._iframeAuthentication = data.iframeAuthentication || OPID_LOGIN_SCREEN_PROVIDER;
|
||||
this._contactPage = data.contactPage || CONTACT_URL;
|
||||
return new MapDetail(data.mapUrl, data.textures);
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e) && e.response?.status == 401 && e.response?.data === "Token decrypted error") {
|
||||
console.warn("JWT token sent could not be decrypted. Maybe it expired?");
|
||||
localUserStore.setAuthToken(null);
|
||||
window.location.assign("/login");
|
||||
} else {
|
||||
} else if (axios.isAxiosError(e)) {
|
||||
console.error("Error => getMapDetail", e, e.response);
|
||||
} else {
|
||||
console.error("Error => getMapDetail", e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -131,6 +150,8 @@ export class Room {
|
|||
* Instance name is:
|
||||
* - In a public URL: the second part of the URL ( _/[instance]/map.json)
|
||||
* - In a private URL: [organizationId/worldId]
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public getInstance(): string {
|
||||
if (this.instance !== undefined) {
|
||||
|
@ -138,7 +159,7 @@ export class Room {
|
|||
}
|
||||
|
||||
if (this.isPublic) {
|
||||
const match = /_\/([^/]+)\/.+/.exec(this.id);
|
||||
const match = /[_*]\/([^/]+)\/.+/.exec(this.id);
|
||||
if (!match) throw new Error('Could not extract instance from "' + this.id + '"');
|
||||
this.instance = match[1];
|
||||
return this.instance;
|
||||
|
@ -210,4 +231,12 @@ export class Room {
|
|||
get group(): string | null {
|
||||
return this._group;
|
||||
}
|
||||
|
||||
get expireOn(): Date | undefined {
|
||||
return this._expireOn;
|
||||
}
|
||||
|
||||
get canReport(): boolean {
|
||||
return this._canReport;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,12 +0,0 @@
|
|||
import { Subject } from "rxjs";
|
||||
|
||||
class WorldFullMessageStream {
|
||||
private _stream: Subject<string | null> = new Subject<string | null>();
|
||||
public stream = this._stream.asObservable();
|
||||
|
||||
onMessage(message?: string) {
|
||||
this._stream.next(message);
|
||||
}
|
||||
}
|
||||
|
||||
export const worldFullMessageStream = new WorldFullMessageStream();
|
1
front/src/Messages/.gitignore
vendored
1
front/src/Messages/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/generated/
|
2
front/src/Messages/JsonMessages/.gitignore
vendored
Normal file
2
front/src/Messages/JsonMessages/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
1
front/src/Messages/ts-proto-generated/.gitignore
vendored
Normal file
1
front/src/Messages/ts-proto-generated/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*
|
|
@ -1,21 +1,21 @@
|
|||
import { PositionMessage } from "../Messages/generated/messages_pb";
|
||||
import Direction = PositionMessage.Direction;
|
||||
import { PositionMessage, PositionMessage_Direction } from "../Messages/ts-proto-generated/messages";
|
||||
|
||||
import type { PointInterface } from "../Connexion/ConnexionModels";
|
||||
|
||||
export class ProtobufClientUtils {
|
||||
public static toPointInterface(position: PositionMessage): PointInterface {
|
||||
let direction: string;
|
||||
switch (position.getDirection()) {
|
||||
case Direction.UP:
|
||||
switch (position.direction) {
|
||||
case PositionMessage_Direction.UP:
|
||||
direction = "up";
|
||||
break;
|
||||
case Direction.DOWN:
|
||||
case PositionMessage_Direction.DOWN:
|
||||
direction = "down";
|
||||
break;
|
||||
case Direction.LEFT:
|
||||
case PositionMessage_Direction.LEFT:
|
||||
direction = "left";
|
||||
break;
|
||||
case Direction.RIGHT:
|
||||
case PositionMessage_Direction.RIGHT:
|
||||
direction = "right";
|
||||
break;
|
||||
default:
|
||||
|
@ -24,10 +24,10 @@ export class ProtobufClientUtils {
|
|||
|
||||
// sending to all clients in room except sender
|
||||
return {
|
||||
x: position.getX(),
|
||||
y: position.getY(),
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
direction,
|
||||
moving: position.getMoving(),
|
||||
moving: position.moving,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,13 +41,15 @@ export class Companion extends Container {
|
|||
this.companionName = name;
|
||||
this._pictureStore = writable(undefined);
|
||||
|
||||
texturePromise.then((resource) => {
|
||||
this.addResource(resource);
|
||||
this.invisible = false;
|
||||
return this.getSnapshot().then((htmlImageElementSrc) => {
|
||||
this._pictureStore.set(htmlImageElementSrc);
|
||||
});
|
||||
});
|
||||
texturePromise
|
||||
.then((resource) => {
|
||||
this.addResource(resource);
|
||||
this.invisible = false;
|
||||
return this.getSnapshot().then((htmlImageElementSrc) => {
|
||||
this._pictureStore.set(htmlImageElementSrc);
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
|
||||
this.scene.physics.world.enableBody(this);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { COMPANION_RESOURCES, CompanionResourceDescriptionInterface } from "./Co
|
|||
|
||||
export const getAllCompanionResources = (loader: LoaderPlugin): CompanionResourceDescriptionInterface[] => {
|
||||
COMPANION_RESOURCES.forEach((resource: CompanionResourceDescriptionInterface) => {
|
||||
lazyLoadCompanionResource(loader, resource.name);
|
||||
lazyLoadCompanionResource(loader, resource.name).catch((e) => console.error(e));
|
||||
});
|
||||
|
||||
return COMPANION_RESOURCES;
|
||||
|
|
|
@ -72,9 +72,11 @@ export class Loader {
|
|||
if (this.loadingText) {
|
||||
this.loadingText.destroy();
|
||||
}
|
||||
promiseLoadLogoTexture.then((resLoadingImage: Phaser.GameObjects.Image) => {
|
||||
resLoadingImage.destroy();
|
||||
});
|
||||
promiseLoadLogoTexture
|
||||
.then((resLoadingImage: Phaser.GameObjects.Image) => {
|
||||
resLoadingImage.destroy();
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
this.progress.destroy();
|
||||
this.progressContainer.destroy();
|
||||
if (this.scene instanceof DirtyScene) {
|
||||
|
|
|
@ -13,7 +13,8 @@ import { isSilentStore } from "../../Stores/MediaStore";
|
|||
import { lazyLoadPlayerCharacterTextures, loadAllDefaultModels } from "./PlayerTexturesLoadingManager";
|
||||
import { TexturesHelper } from "../Helpers/TexturesHelper";
|
||||
import type { PictureStore } from "../../Stores/PictureStore";
|
||||
import { Writable, writable } from "svelte/store";
|
||||
import { Unsubscriber, Writable, writable } from "svelte/store";
|
||||
import { createColorStore } from "../../Stores/OutlineColorStore";
|
||||
|
||||
const playerNameY = -25;
|
||||
|
||||
|
@ -32,7 +33,7 @@ export abstract class Character extends Container {
|
|||
private readonly playerName: Text;
|
||||
public PlayerValue: string;
|
||||
public sprites: Map<string, Sprite>;
|
||||
private lastDirection: PlayerAnimationDirections = PlayerAnimationDirections.Down;
|
||||
protected lastDirection: PlayerAnimationDirections = PlayerAnimationDirections.Down;
|
||||
//private teleportation: Sprite;
|
||||
private invisible: boolean;
|
||||
public companion?: Companion;
|
||||
|
@ -40,6 +41,8 @@ export abstract class Character extends Container {
|
|||
private emoteTween: Phaser.Tweens.Tween | null = null;
|
||||
scene: GameScene;
|
||||
private readonly _pictureStore: Writable<string | undefined>;
|
||||
private readonly outlineColorStore = createColorStore();
|
||||
private readonly outlineColorStoreUnsubscribe: Unsubscriber;
|
||||
|
||||
constructor(
|
||||
scene: GameScene,
|
||||
|
@ -97,18 +100,26 @@ export abstract class Character extends Container {
|
|||
});
|
||||
|
||||
this.on("pointerover", () => {
|
||||
this.getOutlinePlugin()?.add(this.playerName, {
|
||||
thickness: 2,
|
||||
outlineColor: 0xffff00,
|
||||
});
|
||||
this.scene.markDirty();
|
||||
this.outlineColorStore.pointerOver();
|
||||
});
|
||||
this.on("pointerout", () => {
|
||||
this.getOutlinePlugin()?.remove(this.playerName);
|
||||
this.scene.markDirty();
|
||||
this.outlineColorStore.pointerOut();
|
||||
});
|
||||
}
|
||||
|
||||
this.outlineColorStoreUnsubscribe = this.outlineColorStore.subscribe((color) => {
|
||||
if (color === undefined) {
|
||||
this.getOutlinePlugin()?.remove(this.playerName);
|
||||
} else {
|
||||
this.getOutlinePlugin()?.remove(this.playerName);
|
||||
this.getOutlinePlugin()?.add(this.playerName, {
|
||||
thickness: 2,
|
||||
outlineColor: color,
|
||||
});
|
||||
}
|
||||
this.scene.markDirty();
|
||||
});
|
||||
|
||||
scene.add.existing(this);
|
||||
|
||||
this.scene.physics.world.enableBody(this);
|
||||
|
@ -266,24 +277,20 @@ export abstract class Character extends Container {
|
|||
|
||||
body.setVelocity(x, y);
|
||||
|
||||
// up or down animations are prioritized over left and right
|
||||
if (body.velocity.y < 0) {
|
||||
//moving up
|
||||
this.lastDirection = PlayerAnimationDirections.Up;
|
||||
this.playAnimation(PlayerAnimationDirections.Up, true);
|
||||
} else if (body.velocity.y > 0) {
|
||||
//moving down
|
||||
this.lastDirection = PlayerAnimationDirections.Down;
|
||||
this.playAnimation(PlayerAnimationDirections.Down, true);
|
||||
} else if (body.velocity.x > 0) {
|
||||
//moving right
|
||||
this.lastDirection = PlayerAnimationDirections.Right;
|
||||
this.playAnimation(PlayerAnimationDirections.Right, true);
|
||||
} else if (body.velocity.x < 0) {
|
||||
//moving left
|
||||
this.lastDirection = PlayerAnimationDirections.Left;
|
||||
this.playAnimation(PlayerAnimationDirections.Left, true);
|
||||
if (Math.abs(body.velocity.x) > Math.abs(body.velocity.y)) {
|
||||
if (body.velocity.x < 0) {
|
||||
this.lastDirection = PlayerAnimationDirections.Left;
|
||||
} else if (body.velocity.x > 0) {
|
||||
this.lastDirection = PlayerAnimationDirections.Right;
|
||||
}
|
||||
} else {
|
||||
if (body.velocity.y < 0) {
|
||||
this.lastDirection = PlayerAnimationDirections.Up;
|
||||
} else if (body.velocity.y > 0) {
|
||||
this.lastDirection = PlayerAnimationDirections.Down;
|
||||
}
|
||||
}
|
||||
this.playAnimation(this.lastDirection, true);
|
||||
|
||||
this.setDepth(this.y);
|
||||
|
||||
|
@ -315,6 +322,7 @@ export abstract class Character extends Container {
|
|||
}
|
||||
}
|
||||
this.list.forEach((objectContaining) => objectContaining.destroy());
|
||||
this.outlineColorStoreUnsubscribe();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
|
@ -401,4 +409,12 @@ export abstract class Character extends Container {
|
|||
public get pictureStore(): PictureStore {
|
||||
return this._pictureStore;
|
||||
}
|
||||
|
||||
public setOutlineColor(color: number): void {
|
||||
this.outlineColorStore.setColor(color);
|
||||
}
|
||||
|
||||
public removeOutlineColor(): void {
|
||||
this.outlineColorStore.removeColor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ export const getRessourceDescriptor = (
|
|||
const playerResource = LAYERS[i][textureName];
|
||||
if (playerResource !== undefined) return playerResource;
|
||||
}
|
||||
throw "Could not find a data for texture " + textureName;
|
||||
throw new Error("Could not find a data for texture " + textureName);
|
||||
};
|
||||
|
||||
export const createLoadingPromise = (
|
||||
|
|
|
@ -44,6 +44,7 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||
private startFollowTween?: Phaser.Tweens.Tween;
|
||||
|
||||
private playerToFollow?: Player;
|
||||
private cameraLocked: boolean;
|
||||
|
||||
constructor(scene: GameScene, cameraBounds: { x: number; y: number }, waScaleManager: WaScaleManager) {
|
||||
super();
|
||||
|
@ -51,6 +52,7 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||
|
||||
this.camera = scene.cameras.main;
|
||||
this.cameraBounds = cameraBounds;
|
||||
this.cameraLocked = false;
|
||||
|
||||
this.waScaleManager = waScaleManager;
|
||||
|
||||
|
@ -123,6 +125,8 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||
this.waScaleManager.saveZoom();
|
||||
this.waScaleManager.setFocusTarget(focusOn);
|
||||
|
||||
this.cameraLocked = true;
|
||||
this.unlockCameraWithDelay(duration);
|
||||
this.restoreZoomTween?.stop();
|
||||
this.startFollowTween?.stop();
|
||||
const marginMult = 1 + margin;
|
||||
|
@ -143,8 +147,9 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||
);
|
||||
}
|
||||
|
||||
public leaveFocusMode(player: Player, duration: number = 1000): void {
|
||||
public leaveFocusMode(player: Player, duration = 0): void {
|
||||
this.waScaleManager.setFocusTarget();
|
||||
this.unlockCameraWithDelay(duration);
|
||||
this.startFollowPlayer(player, duration);
|
||||
this.restoreZoom(duration);
|
||||
}
|
||||
|
@ -196,8 +201,14 @@ export class CameraManager extends Phaser.Events.EventEmitter {
|
|||
);
|
||||
}
|
||||
|
||||
public isCameraZoomLocked(): boolean {
|
||||
return [CameraMode.Focus, CameraMode.Positioned].includes(this.cameraMode);
|
||||
public isCameraLocked(): boolean {
|
||||
return this.cameraLocked;
|
||||
}
|
||||
|
||||
private unlockCameraWithDelay(delay: number): void {
|
||||
this.scene.time.delayedCall(delay, () => {
|
||||
this.cameraLocked = false;
|
||||
});
|
||||
}
|
||||
|
||||
private setCameraMode(mode: CameraMode): void {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { emoteEventStream } from "../../Connexion/EmoteEventStream";
|
||||
import type { GameScene } from "./GameScene";
|
||||
import type { Subscription } from "rxjs";
|
||||
import type { RoomConnection } from "../../Connexion/RoomConnection";
|
||||
|
||||
export class EmoteManager {
|
||||
private subscription: Subscription;
|
||||
|
||||
constructor(private scene: GameScene) {
|
||||
this.subscription = emoteEventStream.stream.subscribe((event) => {
|
||||
const actor = this.scene.MapPlayersByKey.get(event.userId);
|
||||
constructor(private scene: GameScene, private connection: RoomConnection) {
|
||||
this.subscription = connection.emoteEventMessageStream.subscribe((event) => {
|
||||
const actor = this.scene.MapPlayersByKey.get(event.actorUserId);
|
||||
if (actor) {
|
||||
actor.playEmote(event.emote);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ export class GameManager {
|
|||
|
||||
getCharacterLayers(): string[] {
|
||||
if (!this.characterLayers) {
|
||||
throw "characterLayers are not set";
|
||||
throw new Error("characterLayers are not set");
|
||||
}
|
||||
return this.characterLayers;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ export class GameManager {
|
|||
* This will close the socket connections and stop the gameScene, but won't remove it.
|
||||
*/
|
||||
leaveGame(targetSceneName: string, sceneClass: Phaser.Scene): void {
|
||||
if (this.currentGameSceneName === null) throw "No current scene id set!";
|
||||
if (this.currentGameSceneName === null) throw new Error("No current scene id set!");
|
||||
const gameScene: GameScene = this.scenePlugin.get(this.currentGameSceneName) as GameScene;
|
||||
gameScene.cleanupClosingScene();
|
||||
gameScene.createSuccessorGameScene(false, false);
|
||||
|
@ -143,7 +143,7 @@ export class GameManager {
|
|||
}
|
||||
|
||||
public getCurrentGameScene(): GameScene {
|
||||
if (this.currentGameSceneName === null) throw "No current scene id set!";
|
||||
if (this.currentGameSceneName === null) throw new Error("No current scene id set!");
|
||||
return this.scenePlugin.get(this.currentGameSceneName) as GameScene;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,14 @@ export class GameMap {
|
|||
let depth = -2;
|
||||
for (const layer of this.flatLayers) {
|
||||
if (layer.type === "tilelayer") {
|
||||
this.phaserLayers.push(phaserMap.createLayer(layer.name, terrains, 0, 0).setDepth(depth));
|
||||
this.phaserLayers.push(
|
||||
phaserMap
|
||||
.createLayer(layer.name, terrains, (layer.x || 0) * 32, (layer.y || 0) * 32)
|
||||
.setDepth(depth)
|
||||
.setAlpha(layer.opacity)
|
||||
.setVisible(layer.visible)
|
||||
.setSize(layer.width, layer.height)
|
||||
);
|
||||
}
|
||||
if (layer.type === "objectgroup" && layer.name === "floorLayer") {
|
||||
depth = DEPTH_OVERLAY_INDEX;
|
||||
|
|
|
@ -123,7 +123,7 @@ export class GameMapPropertiesListener {
|
|||
.then((coWebsite) => {
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite);
|
||||
coWebsiteManager.closeCoWebsite(coWebsite).catch((e) => console.error(e));
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
this.coWebsitesActionTriggerByLayer.delete(layer);
|
||||
} else {
|
||||
|
@ -132,7 +132,8 @@ export class GameMapPropertiesListener {
|
|||
state: OpenCoWebsiteState.OPENED,
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
|
||||
layoutManagerActionStore.removeAction(actionUuid);
|
||||
};
|
||||
|
@ -198,7 +199,7 @@ export class GameMapPropertiesListener {
|
|||
}
|
||||
|
||||
if (coWebsiteOpen.coWebsite !== undefined) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite);
|
||||
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite).catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { Subscription } from "rxjs";
|
||||
import AnimatedTiles from "phaser-animated-tiles";
|
||||
import { Queue } from "queue-typescript";
|
||||
import { get } from "svelte/store";
|
||||
import { get, Unsubscriber } from "svelte/store";
|
||||
|
||||
import { userMessageManager } from "../../Administration/UserMessageManager";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
|
@ -12,7 +12,7 @@ import { UserInputManager } from "../UserInput/UserInputManager";
|
|||
import { gameManager } from "./GameManager";
|
||||
import { touchScreenManager } from "../../Touch/TouchScreenManager";
|
||||
import { PinchManager } from "../UserInput/PinchManager";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { waScaleManager, WaScaleManagerEvent } from "../Services/WaScaleManager";
|
||||
import { EmoteManager } from "./EmoteManager";
|
||||
import { soundManager } from "./SoundManager";
|
||||
import { SharedVariablesManager } from "./SharedVariablesManager";
|
||||
|
@ -40,7 +40,6 @@ import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene";
|
|||
import { GameMap } from "./GameMap";
|
||||
import { PlayerMovement } from "./PlayerMovement";
|
||||
import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator";
|
||||
import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream";
|
||||
import { DirtyScene } from "./DirtyScene";
|
||||
import { TextUtils } from "../Components/TextUtils";
|
||||
import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick";
|
||||
|
@ -55,11 +54,11 @@ import type {
|
|||
MessageUserMovedInterface,
|
||||
MessageUserPositionInterface,
|
||||
OnConnectInterface,
|
||||
PlayerDetailsUpdatedMessageInterface,
|
||||
PointInterface,
|
||||
PositionInterface,
|
||||
RoomJoinedMessageInterface,
|
||||
} from "../../Connexion/ConnexionModels";
|
||||
import type { UserMovedMessage } from "../../Messages/generated/messages_pb";
|
||||
import type { RoomConnection } from "../../Connexion/RoomConnection";
|
||||
import type { ActionableItem } from "../Items/ActionableItem";
|
||||
import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface";
|
||||
|
@ -87,9 +86,13 @@ import GameObject = Phaser.GameObjects.GameObject;
|
|||
import DOMElement = Phaser.GameObjects.DOMElement;
|
||||
import Tileset = Phaser.Tilemaps.Tileset;
|
||||
import SpriteSheetFile = Phaser.Loader.FileTypes.SpriteSheetFile;
|
||||
import Camera = Phaser.Cameras.Scene2D.Camera;
|
||||
import { deepCopy } from "deep-copy-ts";
|
||||
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||
import { MapStore } from "../../Stores/Utils/MapStore";
|
||||
import { followUsersColorStore, followUsersStore } from "../../Stores/FollowStore";
|
||||
import { getColorRgbFromHue } from "../../WebRtc/ColorGenerator";
|
||||
import Camera = Phaser.Cameras.Scene2D.Camera;
|
||||
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
reconnecting: boolean;
|
||||
|
@ -125,6 +128,11 @@ interface DeleteGroupEventInterface {
|
|||
groupId: number;
|
||||
}
|
||||
|
||||
interface PlayerDetailsUpdatedInterface {
|
||||
type: "PlayerDetailsUpdated";
|
||||
details: PlayerDetailsUpdatedMessageInterface;
|
||||
}
|
||||
|
||||
export class GameScene extends DirtyScene {
|
||||
Terrains: Array<Phaser.Tilemaps.Tileset>;
|
||||
CurrentPlayer!: Player;
|
||||
|
@ -137,20 +145,14 @@ export class GameScene extends DirtyScene {
|
|||
groups: Map<number, Sprite>;
|
||||
circleTexture!: CanvasTexture;
|
||||
circleRedTexture!: CanvasTexture;
|
||||
pendingEvents: Queue<
|
||||
| InitUserPositionEventInterface
|
||||
| AddPlayerEventInterface
|
||||
| RemovePlayerEventInterface
|
||||
| UserMovedEventInterface
|
||||
| GroupCreatedUpdatedEventInterface
|
||||
| DeleteGroupEventInterface
|
||||
> = new Queue<
|
||||
pendingEvents = new Queue<
|
||||
| InitUserPositionEventInterface
|
||||
| AddPlayerEventInterface
|
||||
| RemovePlayerEventInterface
|
||||
| UserMovedEventInterface
|
||||
| GroupCreatedUpdatedEventInterface
|
||||
| DeleteGroupEventInterface
|
||||
| PlayerDetailsUpdatedInterface
|
||||
>();
|
||||
private initPosition: PositionInterface | null = null;
|
||||
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
||||
|
@ -164,9 +166,11 @@ export class GameScene extends DirtyScene {
|
|||
private createPromise: Promise<void>;
|
||||
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
||||
private iframeSubscriptionList!: Array<Subscription>;
|
||||
private peerStoreUnsubscribe!: () => void;
|
||||
private emoteUnsubscribe!: () => void;
|
||||
private emoteMenuUnsubscribe!: () => void;
|
||||
private peerStoreUnsubscribe!: Unsubscriber;
|
||||
private emoteUnsubscribe!: Unsubscriber;
|
||||
private emoteMenuUnsubscribe!: Unsubscriber;
|
||||
private followUsersColorStoreUnsubscribe!: Unsubscriber;
|
||||
|
||||
private biggestAvailableAreaStoreUnsubscribe!: () => void;
|
||||
MapUrlFile: string;
|
||||
roomUrl: string;
|
||||
|
@ -237,7 +241,7 @@ export class GameScene extends DirtyScene {
|
|||
const textures = localUser?.textures;
|
||||
if (textures) {
|
||||
for (const texture of textures) {
|
||||
loadCustomTexture(this.load, texture);
|
||||
loadCustomTexture(this.load, texture).catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,7 +268,7 @@ export class GameScene extends DirtyScene {
|
|||
this.load.on(
|
||||
"filecomplete-tilemapJSON-" + this.MapUrlFile,
|
||||
(key: string, type: string, data: unknown) => {
|
||||
this.onMapLoad(data);
|
||||
this.onMapLoad(data).catch((e) => console.error(e));
|
||||
}
|
||||
);
|
||||
return;
|
||||
|
@ -288,14 +292,14 @@ export class GameScene extends DirtyScene {
|
|||
this.load.on(
|
||||
"filecomplete-tilemapJSON-" + this.MapUrlFile,
|
||||
(key: string, type: string, data: unknown) => {
|
||||
this.onMapLoad(data);
|
||||
this.onMapLoad(data).catch((e) => console.error(e));
|
||||
}
|
||||
);
|
||||
// If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered.
|
||||
// In this case, we check in the cache to see if the map is here and trigger the event manually.
|
||||
if (this.cache.tilemap.exists(this.MapUrlFile)) {
|
||||
const data = this.cache.tilemap.get(this.MapUrlFile);
|
||||
this.onMapLoad(data);
|
||||
this.onMapLoad(data).catch((e) => console.error(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -316,7 +320,7 @@ export class GameScene extends DirtyScene {
|
|||
});
|
||||
this.load.scenePlugin("AnimatedTiles", AnimatedTiles, "animatedTiles", "animatedTiles");
|
||||
this.load.on("filecomplete-tilemapJSON-" + this.MapUrlFile, (key: string, type: string, data: unknown) => {
|
||||
this.onMapLoad(data);
|
||||
this.onMapLoad(data).catch((e) => console.error(e));
|
||||
});
|
||||
//TODO strategy to add access token
|
||||
this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile);
|
||||
|
@ -324,7 +328,7 @@ export class GameScene extends DirtyScene {
|
|||
// In this case, we check in the cache to see if the map is here and trigger the event manually.
|
||||
if (this.cache.tilemap.exists(this.MapUrlFile)) {
|
||||
const data = this.cache.tilemap.get(this.MapUrlFile);
|
||||
this.onMapLoad(data);
|
||||
this.onMapLoad(data).catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
@ -345,7 +349,10 @@ export class GameScene extends DirtyScene {
|
|||
private async onMapLoad(data: any): Promise<void> {
|
||||
// Triggered when the map is loaded
|
||||
// Load tiles attached to the map recursively
|
||||
this.mapFile = data.data;
|
||||
|
||||
// The map file can be modified by the scripting API and we don't want to tamper the Phaser cache (in case we come back on the map after visiting other maps)
|
||||
// So we are doing a deep copy
|
||||
this.mapFile = deepCopy(data.data);
|
||||
const url = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf("/"));
|
||||
this.mapFile.tilesets.forEach((tileset) => {
|
||||
if (typeof tileset.name === "undefined" || typeof tileset.image === "undefined") {
|
||||
|
@ -399,21 +406,23 @@ export class GameScene extends DirtyScene {
|
|||
this.load.on("complete", () => {
|
||||
// FIXME: the factory might fail because the resources might not be loaded yet...
|
||||
// We would need to add a loader ended event in addition to the createPromise
|
||||
this.createPromise.then(async () => {
|
||||
itemFactory.create(this);
|
||||
this.createPromise
|
||||
.then(async () => {
|
||||
itemFactory.create(this);
|
||||
|
||||
const roomJoinedAnswer = await this.connectionAnswerPromise;
|
||||
const roomJoinedAnswer = await this.connectionAnswerPromise;
|
||||
|
||||
for (const object of objectsOfType) {
|
||||
// TODO: we should pass here a factory to create sprites (maybe?)
|
||||
for (const object of objectsOfType) {
|
||||
// TODO: we should pass here a factory to create sprites (maybe?)
|
||||
|
||||
// Do we have a state for this object?
|
||||
const state = roomJoinedAnswer.items[object.id];
|
||||
// Do we have a state for this object?
|
||||
const state = roomJoinedAnswer.items[object.id];
|
||||
|
||||
const actionableItem = itemFactory.factory(this, object, state);
|
||||
this.actionableItems.set(actionableItem.getId(), actionableItem);
|
||||
}
|
||||
});
|
||||
const actionableItem = itemFactory.factory(this, object, state);
|
||||
this.actionableItems.set(actionableItem.getId(), actionableItem);
|
||||
}
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -442,13 +451,9 @@ export class GameScene extends DirtyScene {
|
|||
this.pinchManager = new PinchManager(this);
|
||||
}
|
||||
|
||||
this.messageSubscription = worldFullMessageStream.stream.subscribe((message) =>
|
||||
this.showWorldFullError(message)
|
||||
);
|
||||
|
||||
const playerName = gameManager.getPlayerName();
|
||||
if (!playerName) {
|
||||
throw "playerName is not set";
|
||||
throw new Error("playerName is not set");
|
||||
}
|
||||
this.playerName = playerName;
|
||||
this.characterLayers = gameManager.getCharacterLayers();
|
||||
|
@ -483,11 +488,11 @@ export class GameScene extends DirtyScene {
|
|||
if (exitSceneUrl !== undefined) {
|
||||
this.loadNextGame(
|
||||
Room.getRoomPathFromExitSceneUrl(exitSceneUrl, window.location.toString(), this.MapUrlFile)
|
||||
);
|
||||
).catch((e) => console.error(e));
|
||||
}
|
||||
const exitUrl = this.getExitUrl(layer);
|
||||
if (exitUrl !== undefined) {
|
||||
this.loadNextGameFromExitUrl(exitUrl);
|
||||
this.loadNextGameFromExitUrl(exitUrl).catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
if (layer.type === "objectgroup") {
|
||||
|
@ -527,7 +532,7 @@ export class GameScene extends DirtyScene {
|
|||
}
|
||||
|
||||
this.gameMap.exitUrls.forEach((exitUrl) => {
|
||||
this.loadNextGameFromExitUrl(exitUrl);
|
||||
this.loadNextGameFromExitUrl(exitUrl).catch((e) => console.error(e));
|
||||
});
|
||||
|
||||
this.startPositionCalculator = new StartPositionCalculator(
|
||||
|
@ -548,7 +553,10 @@ export class GameScene extends DirtyScene {
|
|||
mediaManager.setUserInputManager(this.userInputManager);
|
||||
|
||||
if (localUserStore.getFullscreen()) {
|
||||
document.querySelector("body")?.requestFullscreen();
|
||||
document
|
||||
.querySelector("body")
|
||||
?.requestFullscreen()
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
//notify game manager can to create currentUser in map
|
||||
|
@ -613,8 +621,6 @@ export class GameScene extends DirtyScene {
|
|||
this.connect();
|
||||
}
|
||||
|
||||
this.emoteManager = new EmoteManager(this);
|
||||
|
||||
let oldPeerNumber = 0;
|
||||
this.peerStoreUnsubscribe = peerStore.subscribe((peers) => {
|
||||
const newPeerNumber = peers.size;
|
||||
|
@ -646,9 +652,26 @@ export class GameScene extends DirtyScene {
|
|||
}
|
||||
});
|
||||
|
||||
Promise.all([this.connectionAnswerPromise as Promise<unknown>, ...scriptPromises]).then(() => {
|
||||
this.scene.wake();
|
||||
this.followUsersColorStoreUnsubscribe = followUsersColorStore.subscribe((color) => {
|
||||
if (color !== undefined) {
|
||||
this.CurrentPlayer.setOutlineColor(color);
|
||||
this.connection?.emitPlayerOutlineColor(color);
|
||||
} else {
|
||||
this.CurrentPlayer.removeOutlineColor();
|
||||
this.connection?.emitPlayerOutlineColor(null);
|
||||
}
|
||||
});
|
||||
|
||||
Promise.all([this.connectionAnswerPromise as Promise<unknown>, ...scriptPromises])
|
||||
.then(() => {
|
||||
this.scene.wake();
|
||||
})
|
||||
.catch((e) =>
|
||||
console.error(
|
||||
"Some scripts failed to load ot the connection failed to establish to WorkAdventure server",
|
||||
e
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -679,7 +702,7 @@ export class GameScene extends DirtyScene {
|
|||
playersStore.connectToRoomConnection(this.connection);
|
||||
userIsAdminStore.set(this.connection.hasTag("admin"));
|
||||
|
||||
this.connection.onUserJoins((message: MessageUserJoined) => {
|
||||
this.connection.userJoinedMessageStream.subscribe((message) => {
|
||||
const userMessage: AddPlayerInterface = {
|
||||
userId: message.userId,
|
||||
characterLayers: message.characterLayers,
|
||||
|
@ -688,35 +711,38 @@ export class GameScene extends DirtyScene {
|
|||
visitCardUrl: message.visitCardUrl,
|
||||
companion: message.companion,
|
||||
userUuid: message.userUuid,
|
||||
outlineColor: message.outlineColor,
|
||||
};
|
||||
this.addPlayer(userMessage);
|
||||
});
|
||||
|
||||
this.connection.onUserMoved((message: UserMovedMessage) => {
|
||||
const position = message.getPosition();
|
||||
this.connection.userMovedMessageStream.subscribe((message) => {
|
||||
const position = message.position;
|
||||
if (position === undefined) {
|
||||
throw new Error("Position missing from UserMovedMessage");
|
||||
}
|
||||
|
||||
const messageUserMoved: MessageUserMovedInterface = {
|
||||
userId: message.getUserid(),
|
||||
userId: message.userId,
|
||||
position: ProtobufClientUtils.toPointInterface(position),
|
||||
};
|
||||
|
||||
this.updatePlayerPosition(messageUserMoved);
|
||||
});
|
||||
|
||||
this.connection.onUserLeft((userId: number) => {
|
||||
this.removePlayer(userId);
|
||||
this.connection.userLeftMessageStream.subscribe((message) => {
|
||||
this.removePlayer(message.userId);
|
||||
});
|
||||
|
||||
this.connection.onGroupUpdatedOrCreated((groupPositionMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||
this.shareGroupPosition(groupPositionMessage);
|
||||
});
|
||||
this.connection.groupUpdateMessageStream.subscribe(
|
||||
(groupPositionMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||
this.shareGroupPosition(groupPositionMessage);
|
||||
}
|
||||
);
|
||||
|
||||
this.connection.onGroupDeleted((groupId: number) => {
|
||||
this.connection.groupDeleteMessageStream.subscribe((message) => {
|
||||
try {
|
||||
this.deleteGroup(groupId);
|
||||
this.deleteGroup(message.groupId);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
@ -728,7 +754,7 @@ export class GameScene extends DirtyScene {
|
|||
this.createSuccessorGameScene(true, true);
|
||||
});
|
||||
|
||||
this.connection.onActionableEvent((message) => {
|
||||
this.connection.itemEventMessageStream.subscribe((message) => {
|
||||
const item = this.actionableItems.get(message.itemId);
|
||||
if (item === undefined) {
|
||||
console.warn(
|
||||
|
@ -741,11 +767,29 @@ export class GameScene extends DirtyScene {
|
|||
item.fire(message.event, message.state, message.parameters);
|
||||
});
|
||||
|
||||
this.connection.playerDetailsUpdatedMessageStream.subscribe((message) => {
|
||||
if (message.details === undefined) {
|
||||
throw new Error("Malformed message. Missing details in PlayerDetailsUpdatedMessage");
|
||||
}
|
||||
this.pendingEvents.enqueue({
|
||||
type: "PlayerDetailsUpdated",
|
||||
details: {
|
||||
userId: message.userId,
|
||||
outlineColor: message.details.outlineColor,
|
||||
removeOutlineColor: message.details.removeOutlineColor,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Triggered when we receive the JWT token to connect to Jitsi
|
||||
*/
|
||||
this.connection.onStartJitsiRoom((jwt, room) => {
|
||||
this.startJitsi(room, jwt);
|
||||
this.connection.sendJitsiJwtMessageStream.subscribe((message) => {
|
||||
this.startJitsi(message.jitsiRoom, message.jwt);
|
||||
});
|
||||
|
||||
this.messageSubscription = this.connection.worldFullMessageStream.subscribe((message) => {
|
||||
this.showWorldFullError(message);
|
||||
});
|
||||
|
||||
// When connection is performed, let's connect SimplePeer
|
||||
|
@ -811,7 +855,7 @@ export class GameScene extends DirtyScene {
|
|||
for (const zone of zones) {
|
||||
const focusable = zone.properties?.find((property) => property.name === "focusable");
|
||||
if (focusable && focusable.value === true) {
|
||||
this.cameraManager.leaveFocusMode(this.CurrentPlayer);
|
||||
this.cameraManager.leaveFocusMode(this.CurrentPlayer, 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -820,12 +864,15 @@ export class GameScene extends DirtyScene {
|
|||
});
|
||||
});
|
||||
|
||||
this.emoteManager = new EmoteManager(this, this.connection);
|
||||
|
||||
// this.gameMap.onLeaveLayer((layers) => {
|
||||
// layers.forEach((layer) => {
|
||||
// iframeListener.sendLeaveLayerEvent(layer.name);
|
||||
// });
|
||||
// });
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
//todo: into dedicated classes
|
||||
|
@ -878,7 +925,7 @@ export class GameScene extends DirtyScene {
|
|||
if (newValue) {
|
||||
this.onMapExit(
|
||||
Room.getRoomPathFromExitSceneUrl(newValue as string, window.location.toString(), this.MapUrlFile)
|
||||
);
|
||||
).catch((e) => console.error(e));
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
layoutManagerActionStore.removeAction("roomAccessDenied");
|
||||
|
@ -887,7 +934,9 @@ export class GameScene extends DirtyScene {
|
|||
});
|
||||
this.gameMap.onPropertyChange(GameMapProperties.EXIT_URL, (newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
this.onMapExit(Room.getRoomPathFromExitUrl(newValue as string, window.location.toString()));
|
||||
this.onMapExit(Room.getRoomPathFromExitUrl(newValue as string, window.location.toString())).catch((e) =>
|
||||
console.error(e)
|
||||
);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
layoutManagerActionStore.removeAction("roomAccessDenied");
|
||||
|
@ -1095,7 +1144,9 @@ ${escapedMessage}
|
|||
this.iframeSubscriptionList.push(
|
||||
iframeListener.playSoundStream.subscribe((playSoundEvent) => {
|
||||
const url = new URL(playSoundEvent.url, this.MapUrlFile);
|
||||
soundManager.playSound(this.load, this.sound, url.toString(), playSoundEvent.config);
|
||||
soundManager
|
||||
.playSound(this.load, this.sound, url.toString(), playSoundEvent.config)
|
||||
.catch((e) => console.error(e));
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -1136,7 +1187,7 @@ ${escapedMessage}
|
|||
this.iframeSubscriptionList.push(
|
||||
iframeListener.loadSoundStream.subscribe((loadSoundEvent) => {
|
||||
const url = new URL(loadSoundEvent.url, this.MapUrlFile);
|
||||
soundManager.loadSound(this.load, this.sound, url.toString());
|
||||
soundManager.loadSound(this.load, this.sound, url.toString()).catch((e) => console.error(e));
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -1147,11 +1198,15 @@ ${escapedMessage}
|
|||
);
|
||||
this.iframeSubscriptionList.push(
|
||||
iframeListener.loadPageStream.subscribe((url: string) => {
|
||||
this.loadNextGameFromExitUrl(url).then(() => {
|
||||
this.events.once(EVENT_TYPE.POST_UPDATE, () => {
|
||||
this.onMapExit(Room.getRoomPathFromExitUrl(url, window.location.toString()));
|
||||
});
|
||||
});
|
||||
this.loadNextGameFromExitUrl(url)
|
||||
.then(() => {
|
||||
this.events.once(EVENT_TYPE.POST_UPDATE, () => {
|
||||
this.onMapExit(Room.getRoomPathFromExitUrl(url, window.location.toString())).catch((e) =>
|
||||
console.error(e)
|
||||
);
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
})
|
||||
);
|
||||
let scriptedBubbleSprite: Sprite;
|
||||
|
@ -1379,6 +1434,21 @@ ${escapedMessage}
|
|||
layoutManagerActionStore.removeAction(message.uuid);
|
||||
});
|
||||
|
||||
iframeListener.registerAnswerer("setPlayerOutline", (message) => {
|
||||
const normalizeColor = (color: number) => Math.min(Math.max(0, Math.round(color)), 255);
|
||||
const red = normalizeColor(message.red);
|
||||
const green = normalizeColor(message.green);
|
||||
const blue = normalizeColor(message.blue);
|
||||
const color = (red << 16) | (green << 8) | blue;
|
||||
this.CurrentPlayer.setOutlineColor(color);
|
||||
this.connection?.emitPlayerOutlineColor(color);
|
||||
});
|
||||
|
||||
iframeListener.registerAnswerer("removePlayerOutline", (message) => {
|
||||
this.CurrentPlayer.removeOutlineColor();
|
||||
this.connection?.emitPlayerOutlineColor(null);
|
||||
});
|
||||
|
||||
iframeListener.registerAnswerer("getPlayerPosition", () => {
|
||||
return {
|
||||
x: this.CurrentPlayer.x,
|
||||
|
@ -1393,7 +1463,7 @@ ${escapedMessage}
|
|||
propertyValue: string | number | boolean | undefined
|
||||
): void {
|
||||
if (propertyName === GameMapProperties.EXIT_URL && typeof propertyValue === "string") {
|
||||
this.loadNextGameFromExitUrl(propertyValue);
|
||||
this.loadNextGameFromExitUrl(propertyValue).catch((e) => console.error(e));
|
||||
}
|
||||
this.gameMap.setLayerProperty(layerName, propertyName, propertyValue);
|
||||
}
|
||||
|
@ -1478,7 +1548,7 @@ ${escapedMessage}
|
|||
|
||||
public cleanupClosingScene(): void {
|
||||
// stop playing audio, close any open website, stop any open Jitsi
|
||||
coWebsiteManager.closeCoWebsites();
|
||||
coWebsiteManager.closeCoWebsites().catch((e) => console.error(e));
|
||||
// Stop the script, if any
|
||||
const scripts = this.getScriptUrls(this.mapFile);
|
||||
for (const script of scripts) {
|
||||
|
@ -1499,6 +1569,7 @@ ${escapedMessage}
|
|||
this.peerStoreUnsubscribe();
|
||||
this.emoteUnsubscribe();
|
||||
this.emoteMenuUnsubscribe();
|
||||
this.followUsersColorStoreUnsubscribe();
|
||||
this.biggestAvailableAreaStoreUnsubscribe();
|
||||
iframeListener.unregisterAnswerer("getState");
|
||||
iframeListener.unregisterAnswerer("loadTileset");
|
||||
|
@ -1507,6 +1578,7 @@ ${escapedMessage}
|
|||
iframeListener.unregisterAnswerer("removeActionMessage");
|
||||
iframeListener.unregisterAnswerer("openCoWebsite");
|
||||
iframeListener.unregisterAnswerer("getCoWebsites");
|
||||
iframeListener.unregisterAnswerer("setPlayerOutline");
|
||||
iframeListener.unregisterAnswerer("setVariable");
|
||||
this.sharedVariablesManager?.close();
|
||||
this.embeddedWebsiteManager?.close();
|
||||
|
@ -1762,6 +1834,12 @@ ${escapedMessage}
|
|||
case "DeleteGroupEvent":
|
||||
this.doDeleteGroup(event.groupId);
|
||||
break;
|
||||
case "PlayerDetailsUpdated":
|
||||
this.doUpdatePlayerDetails(event.details);
|
||||
break;
|
||||
default: {
|
||||
const tmp: never = event;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Let's move all users
|
||||
|
@ -1835,6 +1913,9 @@ ${escapedMessage}
|
|||
addPlayerData.companion,
|
||||
addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined
|
||||
);
|
||||
if (addPlayerData.outlineColor !== undefined) {
|
||||
player.setOutlineColor(addPlayerData.outlineColor);
|
||||
}
|
||||
this.MapPlayers.add(player);
|
||||
this.MapPlayersByKey.set(player.userId, player);
|
||||
player.updatePosition(addPlayerData.position);
|
||||
|
@ -1938,6 +2019,23 @@ ${escapedMessage}
|
|||
this.groups.delete(groupId);
|
||||
}
|
||||
|
||||
doUpdatePlayerDetails(message: PlayerDetailsUpdatedMessageInterface): void {
|
||||
const character = this.MapPlayersByKey.get(message.userId);
|
||||
if (character === undefined) {
|
||||
console.log(
|
||||
"Could not set new details to character with ID ",
|
||||
message.userId,
|
||||
". Did he/she left before te message was received?"
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (message.removeOutlineColor) {
|
||||
character.removeOutlineColor();
|
||||
} else {
|
||||
character.setOutlineColor(message.outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends to the server an event emitted by one of the ActionableItems.
|
||||
*/
|
||||
|
@ -1992,7 +2090,9 @@ ${escapedMessage}
|
|||
const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined;
|
||||
const jitsiWidth = allProps.get(GameMapProperties.JITSI_WIDTH) as number | undefined;
|
||||
|
||||
jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl, jitsiWidth);
|
||||
jitsiFactory
|
||||
.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl, jitsiWidth)
|
||||
.catch((e) => console.error(e));
|
||||
this.connection?.setSilent(true);
|
||||
mediaManager.hideGameOverlay();
|
||||
analyticsClient.enteredJitsi(roomName, this.room.id);
|
||||
|
@ -2047,10 +2147,10 @@ ${escapedMessage}
|
|||
}
|
||||
|
||||
zoomByFactor(zoomFactor: number) {
|
||||
if (this.cameraManager.isCameraZoomLocked()) {
|
||||
if (this.cameraManager.isCameraLocked()) {
|
||||
return;
|
||||
}
|
||||
waScaleManager.zoomModifier *= zoomFactor;
|
||||
waScaleManager.handleZoomByFactor(zoomFactor);
|
||||
biggestAvailableAreaStore.recompute();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,4 +8,5 @@ export interface PlayerInterface {
|
|||
companion: string | null;
|
||||
userUuid: string;
|
||||
color?: string;
|
||||
outlineColor?: number;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ export class PlayerMovement {
|
|||
oldX: this.startPosition.x,
|
||||
oldY: this.startPosition.y,
|
||||
direction: this.endPosition.direction,
|
||||
moving: true,
|
||||
moving: this.endPosition.moving,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export class SharedVariablesManager {
|
|||
this._variables.set(name, value);
|
||||
}
|
||||
|
||||
roomConnection.onSetVariable((name, value) => {
|
||||
roomConnection.variableMessageStream.subscribe(({ name, value }) => {
|
||||
this._variables.set(name, value);
|
||||
|
||||
// On server change, let's notify the iframes
|
||||
|
|
|
@ -40,19 +40,21 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
preload() {
|
||||
this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
if (
|
||||
bodyResourceDescription.level == undefined ||
|
||||
bodyResourceDescription.level < 0 ||
|
||||
bodyResourceDescription.level > 5
|
||||
) {
|
||||
throw "Texture level is null";
|
||||
}
|
||||
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
|
||||
});
|
||||
this.lazyloadingAttempt = true;
|
||||
});
|
||||
this.loadCustomSceneSelectCharacters()
|
||||
.then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
if (
|
||||
bodyResourceDescription.level == undefined ||
|
||||
bodyResourceDescription.level < 0 ||
|
||||
bodyResourceDescription.level > 5
|
||||
) {
|
||||
throw new Error("Texture level is null");
|
||||
}
|
||||
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
|
||||
});
|
||||
this.lazyloadingAttempt = true;
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
|
||||
this.layers = loadAllLayers(this.load);
|
||||
this.lazyloadingAttempt = false;
|
||||
|
|
|
@ -41,12 +41,14 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
|||
}
|
||||
|
||||
preload() {
|
||||
this.loadSelectSceneCharacters().then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
this.playerModels.push(bodyResourceDescription);
|
||||
});
|
||||
this.lazyloadingAttempt = true;
|
||||
});
|
||||
this.loadSelectSceneCharacters()
|
||||
.then((bodyResourceDescriptions) => {
|
||||
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||
this.playerModels.push(bodyResourceDescription);
|
||||
});
|
||||
this.lazyloadingAttempt = true;
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
this.playerModels = loadAllDefaultModels(this.load);
|
||||
this.lazyloadingAttempt = false;
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ export interface ITiledTileSet {
|
|||
|
||||
imageheight: number;
|
||||
imagewidth: number;
|
||||
columns: number;
|
||||
margin: number;
|
||||
name: string;
|
||||
properties?: ITiledMapProperty[];
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import { PlayerAnimationDirections } from "./Animation";
|
||||
import type { GameScene } from "../Game/GameScene";
|
||||
import { UserInputEvent, UserInputManager } from "../UserInput/UserInputManager";
|
||||
import { ActiveEventList, UserInputEvent, UserInputManager } from "../UserInput/UserInputManager";
|
||||
import { Character } from "../Entity/Character";
|
||||
import type { RemotePlayer } from "../Entity/RemotePlayer";
|
||||
|
||||
import { get } from "svelte/store";
|
||||
import { userMovingStore } from "../../Stores/GameStore";
|
||||
import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
|
||||
|
||||
export const hasMovedEventName = "hasMoved";
|
||||
export const requestEmoteEventName = "requestEmote";
|
||||
|
||||
export class Player extends Character {
|
||||
private previousDirection: string = PlayerAnimationDirections.Down;
|
||||
private wasMoving: boolean = false;
|
||||
|
||||
constructor(
|
||||
Scene: GameScene,
|
||||
x: number,
|
||||
|
@ -29,71 +30,105 @@ export class Player extends Character {
|
|||
this.getBody().setImmovable(false);
|
||||
}
|
||||
|
||||
moveUser(delta: number): void {
|
||||
//if user client on shift, camera and player speed
|
||||
let direction = null;
|
||||
let moving = false;
|
||||
|
||||
const activeEvents = this.userInputManager.getEventListForGameTick();
|
||||
const speedMultiplier = activeEvents.get(UserInputEvent.SpeedUp) ? 25 : 9;
|
||||
const moveAmount = speedMultiplier * 20;
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
private inputStep(activeEvents: ActiveEventList, x: number, y: number) {
|
||||
// Process input events
|
||||
if (activeEvents.get(UserInputEvent.MoveUp)) {
|
||||
y = -moveAmount;
|
||||
direction = PlayerAnimationDirections.Up;
|
||||
moving = true;
|
||||
y = y - 1;
|
||||
} else if (activeEvents.get(UserInputEvent.MoveDown)) {
|
||||
y = moveAmount;
|
||||
direction = PlayerAnimationDirections.Down;
|
||||
moving = true;
|
||||
y = y + 1;
|
||||
}
|
||||
|
||||
if (activeEvents.get(UserInputEvent.MoveLeft)) {
|
||||
x = -moveAmount;
|
||||
direction = PlayerAnimationDirections.Left;
|
||||
moving = true;
|
||||
x = x - 1;
|
||||
} else if (activeEvents.get(UserInputEvent.MoveRight)) {
|
||||
x = moveAmount;
|
||||
direction = PlayerAnimationDirections.Right;
|
||||
moving = true;
|
||||
x = x + 1;
|
||||
}
|
||||
moving = moving || activeEvents.get(UserInputEvent.JoystickMove);
|
||||
|
||||
if (x !== 0 || y !== 0) {
|
||||
// Compute movement deltas
|
||||
const followMode = get(followStateStore) !== "off";
|
||||
const speedup = activeEvents.get(UserInputEvent.SpeedUp) && !followMode ? 25 : 9;
|
||||
const moveAmount = speedup * 20;
|
||||
x = x * moveAmount;
|
||||
y = y * moveAmount;
|
||||
|
||||
// Compute moving state
|
||||
const joystickMovement = activeEvents.get(UserInputEvent.JoystickMove);
|
||||
const moving = x !== 0 || y !== 0 || joystickMovement;
|
||||
|
||||
// Compute direction
|
||||
let direction = this.lastDirection;
|
||||
if (moving && !joystickMovement) {
|
||||
if (Math.abs(x) > Math.abs(y)) {
|
||||
direction = x < 0 ? PlayerAnimationDirections.Left : PlayerAnimationDirections.Right;
|
||||
} else {
|
||||
direction = y < 0 ? PlayerAnimationDirections.Up : PlayerAnimationDirections.Down;
|
||||
}
|
||||
}
|
||||
|
||||
// Send movement events
|
||||
const emit = () => this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y });
|
||||
if (moving) {
|
||||
this.move(x, y);
|
||||
this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y, oldX: x, oldY: y });
|
||||
} else if (this.wasMoving && moving) {
|
||||
// slow joystick movement
|
||||
this.move(0, 0);
|
||||
this.emit(hasMovedEventName, {
|
||||
moving,
|
||||
direction: this.previousDirection,
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
oldX: x,
|
||||
oldY: y,
|
||||
});
|
||||
} else if (this.wasMoving && !moving) {
|
||||
emit();
|
||||
} else if (get(userMovingStore)) {
|
||||
this.stop();
|
||||
this.emit(hasMovedEventName, {
|
||||
moving,
|
||||
direction: this.previousDirection,
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
oldX: x,
|
||||
oldY: y,
|
||||
});
|
||||
emit();
|
||||
}
|
||||
|
||||
if (direction !== null) {
|
||||
this.previousDirection = direction;
|
||||
}
|
||||
this.wasMoving = moving;
|
||||
// Update state
|
||||
userMovingStore.set(moving);
|
||||
}
|
||||
|
||||
public isMoving(): boolean {
|
||||
return this.wasMoving;
|
||||
private computeFollowMovement(): number[] {
|
||||
// Find followed WOKA and abort following if we lost it
|
||||
const player = this.scene.MapPlayersByKey.get(get(followUsersStore)[0]);
|
||||
if (!player) {
|
||||
this.scene.connection?.emitFollowAbort();
|
||||
followStateStore.set("off");
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
// Compute movement direction
|
||||
const xDistance = player.x - this.x;
|
||||
const yDistance = player.y - this.y;
|
||||
const distance = Math.pow(xDistance, 2) + Math.pow(yDistance, 2);
|
||||
if (distance < 2000) {
|
||||
return [0, 0];
|
||||
}
|
||||
const xMovement = xDistance / Math.sqrt(distance);
|
||||
const yMovement = yDistance / Math.sqrt(distance);
|
||||
return [xMovement, yMovement];
|
||||
}
|
||||
|
||||
public moveUser(delta: number): void {
|
||||
const activeEvents = this.userInputManager.getEventListForGameTick();
|
||||
const state = get(followStateStore);
|
||||
const role = get(followRoleStore);
|
||||
|
||||
if (activeEvents.get(UserInputEvent.Follow)) {
|
||||
if (state === "off" && this.scene.groups.size > 0) {
|
||||
this.sendFollowRequest();
|
||||
} else if (state === "active") {
|
||||
followStateStore.set("ending");
|
||||
}
|
||||
}
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
if ((state === "active" || state === "ending") && role === "follower") {
|
||||
[x, y] = this.computeFollowMovement();
|
||||
}
|
||||
this.inputStep(activeEvents, x, y);
|
||||
}
|
||||
|
||||
public sendFollowRequest() {
|
||||
this.scene.connection?.emitFollowRequest();
|
||||
followRoleStore.set("leader");
|
||||
followStateStore.set("active");
|
||||
}
|
||||
|
||||
public startFollowing() {
|
||||
followStateStore.set("active");
|
||||
this.scene.connection?.emitFollowConfirmation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,9 @@ export class ErrorScene extends Phaser.Scene {
|
|||
*/
|
||||
public static showError(error: unknown, scene: ScenePlugin): void {
|
||||
console.error(error);
|
||||
if (error instanceof Error) {
|
||||
console.error("Stacktrace: ", error.stack);
|
||||
}
|
||||
console.trace();
|
||||
|
||||
if (typeof error === "string" || error instanceof String) {
|
||||
|
|
|
@ -5,6 +5,10 @@ import type { Game } from "../Game/Game";
|
|||
import { ResizableScene } from "../Login/ResizableScene";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
|
||||
export enum WaScaleManagerEvent {
|
||||
RefreshFocusOnTarget = "wa-scale-manager:refresh-focus-on-target",
|
||||
}
|
||||
|
||||
export class WaScaleManager {
|
||||
private hdpiManager: HdpiManager;
|
||||
private scaleManager!: ScaleManager;
|
||||
|
@ -31,6 +35,10 @@ export class WaScaleManager {
|
|||
height: height * devicePixelRatio,
|
||||
});
|
||||
|
||||
if (gameSize.width == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.actualZoom = realSize.width / gameSize.width / devicePixelRatio;
|
||||
|
||||
this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio);
|
||||
|
@ -65,7 +73,7 @@ export class WaScaleManager {
|
|||
return;
|
||||
}
|
||||
this.zoomModifier = this.getTargetZoomModifierFor(this.focusTarget.width, this.focusTarget.height);
|
||||
this.game.events.emit("wa-scale-manager:refresh-focus-on-target", this.focusTarget);
|
||||
this.game.events.emit(WaScaleManagerEvent.RefreshFocusOnTarget, this.focusTarget);
|
||||
}
|
||||
|
||||
public setFocusTarget(targetDimensions?: { x: number; y: number; width: number; height: number }): void {
|
||||
|
@ -94,6 +102,17 @@ export class WaScaleManager {
|
|||
this.applyNewSize();
|
||||
}
|
||||
|
||||
public handleZoomByFactor(zoomFactor: number): void {
|
||||
this.zoomModifier *= zoomFactor;
|
||||
if (this.focusTarget) {
|
||||
this.game.events.emit(WaScaleManagerEvent.RefreshFocusOnTarget, this.focusTarget);
|
||||
}
|
||||
}
|
||||
|
||||
public getFocusTarget(): { x: number; y: number; width: number; height: number } | undefined {
|
||||
return this.focusTarget;
|
||||
}
|
||||
|
||||
public saveZoom(): void {
|
||||
this._saveZoom = this.hdpiManager.zoomModifier;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import type { Direction } from "../../types";
|
||||
import type { GameScene } from "../Game/GameScene";
|
||||
import { touchScreenManager } from "../../Touch/TouchScreenManager";
|
||||
import { MobileJoystick } from "../Components/MobileJoystick";
|
||||
import { enableUserInputsStore } from "../../Stores/UserInputStore";
|
||||
import type { Direction } from "phaser3-rex-plugins/plugins/virtualjoystick.js";
|
||||
|
||||
interface UserInputManagerDatum {
|
||||
keyInstance: Phaser.Input.Keyboard.Key;
|
||||
|
@ -16,6 +16,7 @@ export enum UserInputEvent {
|
|||
MoveDown,
|
||||
SpeedUp,
|
||||
Interact,
|
||||
Follow,
|
||||
Shout,
|
||||
JoystickMove,
|
||||
}
|
||||
|
@ -147,6 +148,10 @@ export class UserInputManager {
|
|||
event: UserInputEvent.Interact,
|
||||
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE, false),
|
||||
},
|
||||
{
|
||||
event: UserInputEvent.Follow,
|
||||
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F, false),
|
||||
},
|
||||
{
|
||||
event: UserInputEvent.Shout,
|
||||
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F, false),
|
||||
|
|
|
@ -26,7 +26,7 @@ export interface ChatMessage {
|
|||
function getAuthor(authorId: number): PlayerInterface {
|
||||
const author = playersStore.getPlayerById(authorId);
|
||||
if (!author) {
|
||||
throw "Could not find data for author " + authorId;
|
||||
throw new Error("Could not find data for author " + authorId);
|
||||
}
|
||||
return author;
|
||||
}
|
||||
|
|
89
front/src/Stores/FollowStore.ts
Normal file
89
front/src/Stores/FollowStore.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import { derived, writable } from "svelte/store";
|
||||
import { getColorRgbFromHue } from "../WebRtc/ColorGenerator";
|
||||
import { gameManager } from "../Phaser/Game/GameManager";
|
||||
|
||||
type FollowState = "off" | "requesting" | "active" | "ending";
|
||||
type FollowRole = "leader" | "follower";
|
||||
|
||||
export const followStateStore = writable<FollowState>("off");
|
||||
export const followRoleStore = writable<FollowRole>("leader");
|
||||
|
||||
function createFollowUsersStore() {
|
||||
const { subscribe, update, set } = writable<number[]>([]);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
addFollowRequest(leader: number): void {
|
||||
followStateStore.set("requesting");
|
||||
followRoleStore.set("follower");
|
||||
set([leader]);
|
||||
},
|
||||
addFollower(user: number): void {
|
||||
update((followers) => {
|
||||
followers.push(user);
|
||||
return followers;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Removes the follower from the store.
|
||||
* Will update followStateStore and followRoleStore if nobody is following anymore.
|
||||
* @param user
|
||||
*/
|
||||
removeFollower(user: number): void {
|
||||
update((followers) => {
|
||||
const oldFollowerCount = followers.length;
|
||||
followers = followers.filter((id) => id !== user);
|
||||
|
||||
if (followers.length === 0 && oldFollowerCount > 0) {
|
||||
followStateStore.set("off");
|
||||
followRoleStore.set("leader");
|
||||
}
|
||||
|
||||
return followers;
|
||||
});
|
||||
},
|
||||
stopFollowing(): void {
|
||||
set([]);
|
||||
followStateStore.set("off");
|
||||
followRoleStore.set("leader");
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const followUsersStore = createFollowUsersStore();
|
||||
|
||||
/**
|
||||
* This store contains the color of the follow group. It is derived from the ID of the leader.
|
||||
*/
|
||||
export const followUsersColorStore = derived(
|
||||
[followStateStore, followRoleStore, followUsersStore],
|
||||
([$followStateStore, $followRoleStore, $followUsersStore]) => {
|
||||
if ($followStateStore !== "active") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if ($followUsersStore.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let leaderId: number;
|
||||
if ($followRoleStore === "leader") {
|
||||
// Let's get my ID by a quite complicated way....
|
||||
leaderId = gameManager.getCurrentGameScene().connection?.getUserId() ?? 0;
|
||||
} else {
|
||||
leaderId = $followUsersStore[0];
|
||||
}
|
||||
|
||||
// Let's compute a random hue between 0 and 1 that varies enough to be interesting
|
||||
const hue = ((leaderId * 197) % 255) / 255;
|
||||
|
||||
let { r, g, b } = getColorRgbFromHue(hue);
|
||||
if ($followRoleStore === "follower") {
|
||||
// Let's make the followers very slightly darker
|
||||
r *= 0.9;
|
||||
g *= 0.9;
|
||||
b *= 0.9;
|
||||
}
|
||||
return (Math.round(r * 255) << 16) | (Math.round(g * 255) << 8) | Math.round(b * 255);
|
||||
}
|
||||
);
|
|
@ -5,3 +5,5 @@ export const userMovingStore = writable(false);
|
|||
export const requestVisitCardsStore = writable<string | null>(null);
|
||||
|
||||
export const userIsAdminStore = writable(false);
|
||||
|
||||
export const limitMapStore = writable(false);
|
||||
|
|
|
@ -360,39 +360,38 @@ const implementCorrectTrackBehavior = getNavigatorType() === NavigatorType.firef
|
|||
/**
|
||||
* Stops the camera from filming
|
||||
*/
|
||||
function applyCameraConstraints(currentStream: MediaStream | null, constraints: MediaTrackConstraints | boolean): void {
|
||||
async function applyCameraConstraints(
|
||||
currentStream: MediaStream | null,
|
||||
constraints: MediaTrackConstraints | boolean
|
||||
): Promise<void[]> {
|
||||
if (!currentStream) {
|
||||
return;
|
||||
}
|
||||
for (const track of currentStream.getVideoTracks()) {
|
||||
toggleConstraints(track, constraints);
|
||||
return [];
|
||||
}
|
||||
return Promise.all(currentStream.getVideoTracks().map((track) => toggleConstraints(track, constraints)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the microphone from listening
|
||||
*/
|
||||
function applyMicrophoneConstraints(
|
||||
async function applyMicrophoneConstraints(
|
||||
currentStream: MediaStream | null,
|
||||
constraints: MediaTrackConstraints | boolean
|
||||
): void {
|
||||
): Promise<void[]> {
|
||||
if (!currentStream) {
|
||||
return;
|
||||
}
|
||||
for (const track of currentStream.getAudioTracks()) {
|
||||
toggleConstraints(track, constraints);
|
||||
return [];
|
||||
}
|
||||
return Promise.all(currentStream.getAudioTracks().map((track) => toggleConstraints(track, constraints)));
|
||||
}
|
||||
|
||||
function toggleConstraints(track: MediaStreamTrack, constraints: MediaTrackConstraints | boolean): void {
|
||||
async function toggleConstraints(track: MediaStreamTrack, constraints: MediaTrackConstraints | boolean): Promise<void> {
|
||||
if (implementCorrectTrackBehavior) {
|
||||
track.enabled = constraints !== false;
|
||||
} else if (constraints === false) {
|
||||
track.stop();
|
||||
}
|
||||
// @ts-ignore
|
||||
|
||||
if (typeof constraints !== "boolean" && constraints !== true) {
|
||||
track.applyConstraints(constraints);
|
||||
return track.applyConstraints(constraints);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,7 +425,7 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
|||
// TODO: does it make sense to pop this error when retrying?
|
||||
set({
|
||||
type: "error",
|
||||
error: e,
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
// Let's try without video constraints
|
||||
if (constraints.video !== false) {
|
||||
|
@ -444,7 +443,7 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
|||
console.info("Error. Unable to get microphone and/or camera access.", constraints, e);
|
||||
set({
|
||||
type: "error",
|
||||
error: e,
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -473,8 +472,8 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
|||
}
|
||||
}
|
||||
|
||||
applyMicrophoneConstraints(currentStream, constraints.audio || false);
|
||||
applyCameraConstraints(currentStream, constraints.video || false);
|
||||
applyMicrophoneConstraints(currentStream, constraints.audio || false).catch((e) => console.error(e));
|
||||
applyCameraConstraints(currentStream, constraints.video || false).catch((e) => console.error(e));
|
||||
|
||||
if (implementCorrectTrackBehavior) {
|
||||
//on good navigators like firefox, we can instantiate the stream once and simply disable or enable the tracks as needed
|
||||
|
@ -484,7 +483,12 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
|||
type: "success",
|
||||
stream: null,
|
||||
});
|
||||
initStream(constraints);
|
||||
initStream(constraints).catch((e) => {
|
||||
set({
|
||||
type: "error",
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//on bad navigators like chrome, we have to stop the tracks when we mute and reinstantiate the stream when we need to unmute
|
||||
|
@ -496,7 +500,12 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
|||
});
|
||||
} //we reemit the stream if it was muted just to be sure
|
||||
else if (constraints.audio /* && !oldConstraints.audio*/ || (!oldConstraints.video && constraints.video)) {
|
||||
initStream(constraints);
|
||||
initStream(constraints).catch((e) => {
|
||||
set({
|
||||
type: "error",
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
});
|
||||
}
|
||||
oldConstraints = {
|
||||
video: !!constraints.video,
|
||||
|
|
4
front/src/Stores/ModalStore.ts
Normal file
4
front/src/Stores/ModalStore.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
export const showLimitRoomModalStore = writable(false);
|
||||
export const showShareLinkMapModalStore = writable(false);
|
40
front/src/Stores/OutlineColorStore.ts
Normal file
40
front/src/Stores/OutlineColorStore.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
export function createColorStore() {
|
||||
const { subscribe, set } = writable<number | undefined>(undefined);
|
||||
|
||||
let color: number | undefined = undefined;
|
||||
let focused: boolean = false;
|
||||
|
||||
const updateColor = () => {
|
||||
if (focused) {
|
||||
set(0xffff00);
|
||||
} else {
|
||||
set(color);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
pointerOver() {
|
||||
focused = true;
|
||||
updateColor();
|
||||
},
|
||||
|
||||
pointerOut() {
|
||||
focused = false;
|
||||
updateColor();
|
||||
},
|
||||
|
||||
setColor(newColor: number) {
|
||||
color = newColor;
|
||||
updateColor();
|
||||
},
|
||||
|
||||
removeColor() {
|
||||
color = undefined;
|
||||
updateColor();
|
||||
},
|
||||
};
|
||||
}
|
|
@ -3,6 +3,7 @@ import type { PlayerInterface } from "../Phaser/Game/PlayerInterface";
|
|||
import type { RoomConnection } from "../Connexion/RoomConnection";
|
||||
import { getRandomColor } from "../WebRtc/ColorGenerator";
|
||||
import { localUserStore } from "../Connexion/LocalUserStore";
|
||||
import room from "../Api/iframe/room";
|
||||
|
||||
let idCount = 0;
|
||||
|
||||
|
@ -19,7 +20,8 @@ function createPlayersStore() {
|
|||
connectToRoomConnection: (roomConnection: RoomConnection) => {
|
||||
players = new Map<number, PlayerInterface>();
|
||||
set(players);
|
||||
roomConnection.onUserJoins((message) => {
|
||||
// TODO: it would be cool to unsubscribe properly here
|
||||
roomConnection.userJoinedMessageStream.subscribe((message) => {
|
||||
update((users) => {
|
||||
users.set(message.userId, {
|
||||
userId: message.userId,
|
||||
|
@ -33,9 +35,9 @@ function createPlayersStore() {
|
|||
return users;
|
||||
});
|
||||
});
|
||||
roomConnection.onUserLeft((userId) => {
|
||||
roomConnection.userLeftMessageStream.subscribe((message) => {
|
||||
update((users) => {
|
||||
users.delete(userId);
|
||||
users.delete(message.userId);
|
||||
return users;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -153,10 +153,10 @@ export const screenSharingLocalStreamStore = derived<Readable<MediaStreamConstra
|
|||
console.info("Error. Unable to share screen.", e);
|
||||
set({
|
||||
type: "error",
|
||||
error: e,
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
}
|
||||
})();
|
||||
})().catch((e) => console.error(e));
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { writable } from "svelte/store";
|
||||
import { createMessageStore } from "./MessageStore";
|
||||
|
||||
export const banMessageVisibleStore = writable(false);
|
||||
|
||||
export const banMessageContentStore = writable("");
|
||||
export const banMessageStore = createMessageStore();
|
||||
|
|
29
front/src/Stores/TypeMessageStore/MessageStore.ts
Normal file
29
front/src/Stores/TypeMessageStore/MessageStore.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { writable } from "svelte/store";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A store that contains a list of messages to be displayed.
|
||||
*/
|
||||
export function createMessageStore() {
|
||||
const { subscribe, update } = writable<Message[]>([]);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
addMessage: (text: string): void => {
|
||||
update((messages: Message[]) => {
|
||||
return [...messages, { id: uuidv4(), text }];
|
||||
});
|
||||
},
|
||||
clearMessageById: (id: string): void => {
|
||||
update((messages: Message[]) => {
|
||||
messages = messages.filter((message) => message.id !== id);
|
||||
return messages;
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
import { writable } from "svelte/store";
|
||||
import { createMessageStore } from "./MessageStore";
|
||||
|
||||
export const textMessageVisibleStore = writable(false);
|
||||
|
||||
export const textMessageContentStore = writable("");
|
||||
export const textMessageStore = createMessageStore();
|
||||
|
|
|
@ -7,7 +7,7 @@ class TouchScreenManager {
|
|||
|
||||
//found here: https://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript#4819886
|
||||
detectTouchscreen(): boolean {
|
||||
return "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
|
||||
return "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import type { Room } from "../Connexion/Room";
|
|||
import { localUserStore } from "../Connexion/LocalUserStore";
|
||||
|
||||
export enum GameConnexionTypes {
|
||||
anonymous = 1,
|
||||
organization,
|
||||
room = 1,
|
||||
register,
|
||||
empty,
|
||||
unknown,
|
||||
|
@ -19,10 +18,8 @@ class UrlManager {
|
|||
return GameConnexionTypes.login;
|
||||
} else if (url === "/jwt") {
|
||||
return GameConnexionTypes.jwt;
|
||||
} else if (url.includes("_/")) {
|
||||
return GameConnexionTypes.anonymous;
|
||||
} else if (url.includes("@/")) {
|
||||
return GameConnexionTypes.organization;
|
||||
} else if (url.includes("_/") || url.includes("*/") || url.includes("@/")) {
|
||||
return GameConnexionTypes.room;
|
||||
} else if (url.includes("register/")) {
|
||||
return GameConnexionTypes.register;
|
||||
} else if (url === "/") {
|
||||
|
@ -41,7 +38,7 @@ class UrlManager {
|
|||
if (window.location.pathname === room.id) return;
|
||||
//Set last room visited! (connected or nor, must to be saved in localstorage and cache API)
|
||||
//use href to keep # value
|
||||
localUserStore.setLastRoomUrl(room.href);
|
||||
localUserStore.setLastRoomUrl(room.href).catch((e) => console.error(e));
|
||||
const hash = window.location.hash;
|
||||
const search = room.search.toString();
|
||||
history.pushState({}, "WorkAdventure", room.id + (search ? "?" + search : "") + hash);
|
||||
|
|
|
@ -149,7 +149,7 @@ class CoWebsiteManager {
|
|||
}
|
||||
|
||||
buttonCloseCoWebsites.blur();
|
||||
this.closeCoWebsites();
|
||||
this.closeCoWebsites().catch((e) => console.error(e));
|
||||
});
|
||||
|
||||
const buttonFullScreenFrame = HtmlUtils.getElementByIdOrFail(cowebsiteFullScreenButtonId);
|
||||
|
@ -515,70 +515,72 @@ class CoWebsiteManager {
|
|||
throw new Error("Too many we");
|
||||
}
|
||||
|
||||
Promise.resolve(callback(this.cowebsiteBufferDom)).then((iframe) => {
|
||||
iframe?.classList.add("pixel");
|
||||
Promise.resolve(callback(this.cowebsiteBufferDom))
|
||||
.then((iframe) => {
|
||||
iframe?.classList.add("pixel");
|
||||
|
||||
if (!iframe.id) {
|
||||
do {
|
||||
iframe.id = "cowebsite-iframe-" + (Math.random() + 1).toString(36).substring(7);
|
||||
} while (this.getCoWebsiteById(iframe.id));
|
||||
}
|
||||
|
||||
const onloadPromise = new Promise<void>((resolve) => {
|
||||
iframe.onload = () => resolve();
|
||||
});
|
||||
|
||||
const icon = this.generateCoWebsiteIcon(iframe);
|
||||
|
||||
const coWebsite = {
|
||||
iframe,
|
||||
icon,
|
||||
position: position ?? this.coWebsites.length,
|
||||
};
|
||||
|
||||
// Iframe management on mobile
|
||||
icon.addEventListener("click", () => {
|
||||
if (this.isSmallScreen()) {
|
||||
this.moveRightPreviousCoWebsite(coWebsite, 0);
|
||||
if (!iframe.id) {
|
||||
do {
|
||||
iframe.id = "cowebsite-iframe-" + (Math.random() + 1).toString(36).substring(7);
|
||||
} while (this.getCoWebsiteById(iframe.id));
|
||||
}
|
||||
});
|
||||
|
||||
this.coWebsites.push(coWebsite);
|
||||
this.cowebsiteSubIconsDom.appendChild(icon);
|
||||
const onloadPromise = new Promise<void>((resolve) => {
|
||||
iframe.onload = () => resolve();
|
||||
});
|
||||
|
||||
const onTimeoutPromise = new Promise<void>((resolve) => {
|
||||
setTimeout(() => resolve(), 2000);
|
||||
});
|
||||
const icon = this.generateCoWebsiteIcon(iframe);
|
||||
|
||||
this.currentOperationPromise = this.currentOperationPromise
|
||||
.then(() => Promise.race([onloadPromise, onTimeoutPromise]))
|
||||
.then(() => {
|
||||
if (coWebsite.position === 0) {
|
||||
this.openMain();
|
||||
if (widthPercent) {
|
||||
this.widthPercent = widthPercent;
|
||||
}
|
||||
const coWebsite = {
|
||||
iframe,
|
||||
icon,
|
||||
position: position ?? this.coWebsites.length,
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
this.fire();
|
||||
// Iframe management on mobile
|
||||
icon.addEventListener("click", () => {
|
||||
if (this.isSmallScreen()) {
|
||||
this.moveRightPreviousCoWebsite(coWebsite, 0);
|
||||
}
|
||||
});
|
||||
|
||||
this.coWebsites.push(coWebsite);
|
||||
this.cowebsiteSubIconsDom.appendChild(icon);
|
||||
|
||||
const onTimeoutPromise = new Promise<void>((resolve) => {
|
||||
setTimeout(() => resolve(), 2000);
|
||||
});
|
||||
|
||||
this.currentOperationPromise = this.currentOperationPromise
|
||||
.then(() => Promise.race([onloadPromise, onTimeoutPromise]))
|
||||
.then(() => {
|
||||
if (coWebsite.position === 0) {
|
||||
this.openMain();
|
||||
if (widthPercent) {
|
||||
this.widthPercent = widthPercent;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.fire();
|
||||
position !== undefined
|
||||
? this.moveRightPreviousCoWebsite(coWebsite, coWebsite.position)
|
||||
: this.moveCoWebsite(coWebsite, coWebsite.position);
|
||||
}, animationTime);
|
||||
} else {
|
||||
position !== undefined
|
||||
? this.moveRightPreviousCoWebsite(coWebsite, coWebsite.position)
|
||||
: this.moveCoWebsite(coWebsite, coWebsite.position);
|
||||
}, animationTime);
|
||||
} else {
|
||||
position !== undefined
|
||||
? this.moveRightPreviousCoWebsite(coWebsite, coWebsite.position)
|
||||
: this.moveCoWebsite(coWebsite, coWebsite.position);
|
||||
}
|
||||
}
|
||||
|
||||
return resolve(coWebsite);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error loadCoWebsite => ", err);
|
||||
this.removeCoWebsiteFromStack(coWebsite);
|
||||
return reject();
|
||||
});
|
||||
});
|
||||
return resolve(coWebsite);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Error loadCoWebsite => ", err);
|
||||
this.removeCoWebsiteFromStack(coWebsite);
|
||||
return reject();
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error("Error loadCoWebsite >=> ", e));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -603,20 +605,23 @@ class CoWebsiteManager {
|
|||
return this.currentOperationPromise;
|
||||
}
|
||||
|
||||
public closeJitsi() {
|
||||
public async closeJitsi() {
|
||||
const jitsi = this.searchJitsi();
|
||||
if (jitsi) {
|
||||
this.closeCoWebsite(jitsi);
|
||||
return this.closeCoWebsite(jitsi);
|
||||
}
|
||||
}
|
||||
|
||||
public closeCoWebsites(): Promise<void> {
|
||||
this.currentOperationPromise = this.currentOperationPromise.then(() => {
|
||||
this.coWebsites.forEach((coWebsite: CoWebsite) => {
|
||||
this.closeCoWebsite(coWebsite);
|
||||
});
|
||||
public async closeCoWebsites(): Promise<void> {
|
||||
await this.currentOperationPromise;
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
this.coWebsites.forEach((coWebsite: CoWebsite) => {
|
||||
promises.push(this.closeCoWebsite(coWebsite));
|
||||
});
|
||||
return this.currentOperationPromise;
|
||||
await Promise.all(promises);
|
||||
// TODO: this.currentOperationPromise does not point any more on the last promise
|
||||
return;
|
||||
}
|
||||
|
||||
public getGameSize(): { width: number; height: number } {
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
export function getRandomColor(): string {
|
||||
const { r, g, b } = getColorRgbFromHue(Math.random());
|
||||
return toHexa(r, g, b);
|
||||
}
|
||||
|
||||
function toHexa(r: number, g: number, b: number): string {
|
||||
return "#" + Math.floor(r * 256).toString(16) + Math.floor(g * 256).toString(16) + Math.floor(b * 256).toString(16);
|
||||
}
|
||||
|
||||
export function getColorRgbFromHue(hue: number): { r: number; g: number; b: number } {
|
||||
const golden_ratio_conjugate = 0.618033988749895;
|
||||
let hue = Math.random();
|
||||
hue += golden_ratio_conjugate;
|
||||
hue %= 1;
|
||||
return hsv_to_rgb(hue, 0.5, 0.95);
|
||||
}
|
||||
|
||||
function stringToDouble(string: string): number {
|
||||
let num = 1;
|
||||
for (const char of string.split("")) {
|
||||
num *= char.charCodeAt(0);
|
||||
}
|
||||
return (num % 255) / 255;
|
||||
}
|
||||
|
||||
//todo: test this.
|
||||
function hsv_to_rgb(hue: number, saturation: number, brightness: number): string {
|
||||
function hsv_to_rgb(hue: number, saturation: number, brightness: number): { r: number; g: number; b: number } {
|
||||
const h_i = Math.floor(hue * 6);
|
||||
const f = hue * 6 - h_i;
|
||||
const p = brightness * (1 - saturation);
|
||||
|
@ -46,7 +62,11 @@ function hsv_to_rgb(hue: number, saturation: number, brightness: number): string
|
|||
b = q;
|
||||
break;
|
||||
default:
|
||||
throw "h_i cannot be " + h_i;
|
||||
throw new Error("h_i cannot be " + h_i);
|
||||
}
|
||||
return "#" + Math.floor(r * 256).toString(16) + Math.floor(g * 256).toString(16) + Math.floor(b * 256).toString(16);
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ export function getNavigatorType(): NavigatorType {
|
|||
} else if (window.navigator.userAgent.includes("Safari")) {
|
||||
return NavigatorType.safari;
|
||||
}
|
||||
throw "Couldn't detect navigator type";
|
||||
throw new Error("Couldn't detect navigator type");
|
||||
}
|
||||
export function isAndroid(): boolean {
|
||||
return window.navigator.userAgent.includes("Android");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { JITSI_URL } from "../Enum/EnvironmentVariable";
|
||||
import { coWebsiteManager } from "./CoWebsiteManager";
|
||||
import { CoWebsite, coWebsiteManager } from "./CoWebsiteManager";
|
||||
import { requestedCameraState, requestedMicrophoneState } from "../Stores/MediaStore";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
|
@ -140,8 +140,8 @@ class JitsiFactory {
|
|||
interfaceConfig?: object,
|
||||
jitsiUrl?: string,
|
||||
jitsiWidth?: number
|
||||
): void {
|
||||
coWebsiteManager.addCoWebsite(
|
||||
): Promise<CoWebsite> {
|
||||
return coWebsiteManager.addCoWebsite(
|
||||
async (cowebsiteDiv) => {
|
||||
// Jitsi meet external API maintains some data in local storage
|
||||
// which is sent via the appData URL parameter when joining a
|
||||
|
@ -200,7 +200,7 @@ class JitsiFactory {
|
|||
const jitsiCoWebsite = coWebsiteManager.searchJitsi();
|
||||
|
||||
if (jitsiCoWebsite) {
|
||||
coWebsiteManager.closeJitsi();
|
||||
coWebsiteManager.closeJitsi().catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
this.jitsiApi.removeListener("audioMuteStatusChanged", this.audioCallback);
|
||||
|
|
|
@ -75,30 +75,32 @@ export class SimplePeer {
|
|||
*/
|
||||
private initialise() {
|
||||
//receive signal by gemer
|
||||
this.Connection.receiveWebrtcSignal((message: WebRtcSignalReceivedMessageInterface) => {
|
||||
this.Connection.webRtcSignalToClientMessageStream.subscribe((message: WebRtcSignalReceivedMessageInterface) => {
|
||||
this.receiveWebrtcSignal(message);
|
||||
});
|
||||
|
||||
//receive signal by gemer
|
||||
this.Connection.receiveWebrtcScreenSharingSignal((message: WebRtcSignalReceivedMessageInterface) => {
|
||||
this.receiveWebrtcScreenSharingSignal(message);
|
||||
});
|
||||
this.Connection.webRtcScreenSharingSignalToClientMessageStream.subscribe(
|
||||
(message: WebRtcSignalReceivedMessageInterface) => {
|
||||
this.receiveWebrtcScreenSharingSignal(message);
|
||||
}
|
||||
);
|
||||
|
||||
mediaManager.showGameOverlay();
|
||||
|
||||
//receive message start
|
||||
this.Connection.receiveWebrtcStart((message: UserSimplePeerInterface) => {
|
||||
this.Connection.webRtcStartMessageStream.subscribe((message: UserSimplePeerInterface) => {
|
||||
this.receiveWebrtcStart(message);
|
||||
});
|
||||
|
||||
this.Connection.disconnectMessage((data: WebRtcDisconnectMessageInterface): void => {
|
||||
this.Connection.webRtcDisconnectMessageStream.subscribe((data: WebRtcDisconnectMessageInterface): void => {
|
||||
this.closeConnection(data.userId);
|
||||
});
|
||||
}
|
||||
|
||||
private receiveWebrtcStart(user: UserSimplePeerInterface): void {
|
||||
this.Users.push(user);
|
||||
// Note: the clients array contain the list of all clients (even the ones we are already connected to in case a user joints a group)
|
||||
// Note: the clients array contain the list of all clients (even the ones we are already connected to in case a user joins a group)
|
||||
// So we can receive a request we already had before. (which will abort at the first line of createPeerConnection)
|
||||
// This would be symmetrical to the way we handle disconnection.
|
||||
|
||||
|
@ -121,7 +123,7 @@ export class SimplePeer {
|
|||
peerConnection.destroy();
|
||||
const peerConnexionDeleted = this.PeerConnectionArray.delete(user.userId);
|
||||
if (!peerConnexionDeleted) {
|
||||
throw "Error to delete peer connection";
|
||||
throw new Error("Error to delete peer connection");
|
||||
}
|
||||
//return this.createPeerConnection(user, localStream);
|
||||
} else {
|
||||
|
@ -175,7 +177,7 @@ export class SimplePeer {
|
|||
peerConnection.destroy();
|
||||
const peerConnexionDeleted = this.PeerScreenSharingConnectionArray.delete(user.userId);
|
||||
if (!peerConnexionDeleted) {
|
||||
throw "Error to delete peer connection";
|
||||
throw new Error("Error to delete peer connection");
|
||||
}
|
||||
this.createPeerConnection(user);
|
||||
} else {
|
||||
|
@ -227,7 +229,7 @@ export class SimplePeer {
|
|||
|
||||
const userIndex = this.Users.findIndex((user) => user.userId === userId);
|
||||
if (userIndex < 0) {
|
||||
throw "Couldn't delete user";
|
||||
throw new Error("Couldn't delete user");
|
||||
} else {
|
||||
this.Users.splice(userIndex, 1);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from "./Api/Events/IframeEvent";
|
||||
import chat from "./Api/iframe/chat";
|
||||
import type { IframeCallback } from "./Api/iframe/IframeApiContribution";
|
||||
import nav from "./Api/iframe/nav";
|
||||
import nav, { CoWebsite } from "./Api/iframe/nav";
|
||||
import controls from "./Api/iframe/controls";
|
||||
import ui from "./Api/iframe/ui";
|
||||
import sound from "./Api/iframe/sound";
|
||||
|
@ -136,17 +136,17 @@ const wa = {
|
|||
/**
|
||||
* @deprecated Use WA.nav.openCoWebSite instead
|
||||
*/
|
||||
openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = ""): void {
|
||||
openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = ""): Promise<CoWebsite> {
|
||||
console.warn("Method WA.openCoWebSite is deprecated. Please use WA.nav.openCoWebSite instead");
|
||||
nav.openCoWebSite(url, allowApi, allowPolicy);
|
||||
return nav.openCoWebSite(url, allowApi, allowPolicy);
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated Use WA.nav.closeCoWebSite instead
|
||||
*/
|
||||
closeCoWebSite(): void {
|
||||
closeCoWebSite(): Promise<void> {
|
||||
console.warn("Method WA.closeCoWebSite is deprecated. Please use WA.nav.closeCoWebSite instead");
|
||||
nav.closeCoWebSite();
|
||||
return nav.closeCoWebSite();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
37
front/src/rex-plugins.d.ts
vendored
37
front/src/rex-plugins.d.ts
vendored
|
@ -1,6 +1,39 @@
|
|||
//import Phaser from "phaser";
|
||||
|
||||
declare module "phaser3-rex-plugins/plugins/virtualjoystick.js" {
|
||||
const content: any; // eslint-disable-line
|
||||
export default content;
|
||||
/*const content: any; // eslint-disable-line
|
||||
export default content;*/
|
||||
import GameObject = Phaser.GameObjects.GameObject;
|
||||
import { Scene } from "phaser";
|
||||
|
||||
type CursorKey = {
|
||||
isDown: boolean;
|
||||
};
|
||||
|
||||
export type Direction = "left" | "right" | "up" | "down";
|
||||
|
||||
interface CursorKeys extends Record<Direction, CursorKey> {
|
||||
left: CursorKey;
|
||||
right: CursorKey;
|
||||
up: CursorKey;
|
||||
down: CursorKey;
|
||||
}
|
||||
|
||||
class VirtualJoystick extends GameObject {
|
||||
constructor(scene: Scene, config: unknown);
|
||||
enable: boolean;
|
||||
base: GameObjects.Image;
|
||||
thumb: GameObjects.Image;
|
||||
setRadius: (radius: number) => void;
|
||||
y: number;
|
||||
x: number;
|
||||
forceX: number;
|
||||
forceY: number;
|
||||
visible: boolean;
|
||||
createCursorKeys: () => CursorKeys;
|
||||
}
|
||||
|
||||
export default VirtualJoystick;
|
||||
}
|
||||
declare module "phaser3-rex-plugins/plugins/gestures-plugin.js" {
|
||||
const content: any; // eslint-disable-line
|
||||
|
|
|
@ -1,27 +1,3 @@
|
|||
import type Phaser from "phaser";
|
||||
|
||||
export type CursorKey = {
|
||||
isDown: boolean;
|
||||
};
|
||||
|
||||
export type Direction = "left" | "right" | "up" | "down";
|
||||
|
||||
export interface CursorKeys extends Record<Direction, CursorKey> {
|
||||
left: CursorKey;
|
||||
right: CursorKey;
|
||||
up: CursorKey;
|
||||
down: CursorKey;
|
||||
}
|
||||
|
||||
export interface IVirtualJoystick extends Phaser.GameObjects.GameObject {
|
||||
y: number;
|
||||
x: number;
|
||||
forceX: number;
|
||||
forceY: number;
|
||||
visible: boolean;
|
||||
createCursorKeys: () => CursorKeys;
|
||||
}
|
||||
|
||||
export enum Easing {
|
||||
Linear = "Linear",
|
||||
QuadEaseIn = "Quad.easeIn",
|
||||
|
|
|
@ -1066,6 +1066,7 @@ div.action.danger p.action-body{
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
|
||||
& > div {
|
||||
position: relative;
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
import "jasmine";
|
||||
import {PlayerMovement} from "../../../src/Phaser/Game/PlayerMovement";
|
||||
import { PlayerMovement } from "../../../src/Phaser/Game/PlayerMovement";
|
||||
|
||||
describe("Interpolation / Extrapolation", () => {
|
||||
it("should interpolate", () => {
|
||||
const playerMovement = new PlayerMovement({
|
||||
x: 100, y: 200
|
||||
}, 42000,
|
||||
const playerMovement = new PlayerMovement(
|
||||
{
|
||||
x: 100,
|
||||
y: 200,
|
||||
},
|
||||
42000,
|
||||
{
|
||||
x: 200,
|
||||
y: 100,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
moving: true,
|
||||
direction: "up"
|
||||
direction: "up",
|
||||
},
|
||||
42200
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
expect(playerMovement.isOutdated(42100)).toBe(false);
|
||||
expect(playerMovement.isOutdated(43000)).toBe(true);
|
||||
|
@ -26,8 +28,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||
y: 150,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
direction: 'up',
|
||||
moving: true
|
||||
direction: "up",
|
||||
moving: true,
|
||||
});
|
||||
|
||||
expect(playerMovement.getPosition(42200)).toEqual({
|
||||
|
@ -35,8 +37,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||
y: 100,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
direction: 'up',
|
||||
moving: true
|
||||
direction: "up",
|
||||
moving: true,
|
||||
});
|
||||
|
||||
expect(playerMovement.getPosition(42300)).toEqual({
|
||||
|
@ -44,22 +46,25 @@ describe("Interpolation / Extrapolation", () => {
|
|||
y: 50,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
direction: 'up',
|
||||
moving: true
|
||||
direction: "up",
|
||||
moving: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("should not extrapolate if we stop", () => {
|
||||
const playerMovement = new PlayerMovement({
|
||||
x: 100, y: 200
|
||||
}, 42000,
|
||||
const playerMovement = new PlayerMovement(
|
||||
{
|
||||
x: 100,
|
||||
y: 200,
|
||||
},
|
||||
42000,
|
||||
{
|
||||
x: 200,
|
||||
y: 100,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
moving: false,
|
||||
direction: "up"
|
||||
direction: "up",
|
||||
},
|
||||
42200
|
||||
);
|
||||
|
@ -69,22 +74,25 @@ describe("Interpolation / Extrapolation", () => {
|
|||
y: 100,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
direction: 'up',
|
||||
moving: false
|
||||
direction: "up",
|
||||
moving: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("should should keep moving until it stops", () => {
|
||||
const playerMovement = new PlayerMovement({
|
||||
x: 100, y: 200
|
||||
}, 42000,
|
||||
it("should keep moving until it stops", () => {
|
||||
const playerMovement = new PlayerMovement(
|
||||
{
|
||||
x: 100,
|
||||
y: 200,
|
||||
},
|
||||
42000,
|
||||
{
|
||||
x: 200,
|
||||
y: 100,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
moving: false,
|
||||
direction: "up"
|
||||
direction: "up",
|
||||
},
|
||||
42200
|
||||
);
|
||||
|
@ -94,8 +102,8 @@ describe("Interpolation / Extrapolation", () => {
|
|||
y: 150,
|
||||
oldX: 100,
|
||||
oldY: 200,
|
||||
direction: 'up',
|
||||
moving: true
|
||||
direction: "up",
|
||||
moving: false,
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
|
630
front/yarn.lock
630
front/yarn.lock
|
@ -2,13 +2,6 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@7.12.11":
|
||||
version "7.12.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
|
||||
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
|
||||
|
@ -21,7 +14,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
|
||||
integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==
|
||||
|
||||
"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13":
|
||||
"@babel/highlight@^7.12.13":
|
||||
version "7.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf"
|
||||
integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==
|
||||
|
@ -37,23 +30,35 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@cspotcode/source-map-consumer@0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
|
||||
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
|
||||
|
||||
"@cspotcode/source-map-support@0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
|
||||
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-consumer" "0.8.0"
|
||||
|
||||
"@discoveryjs/json-ext@^0.5.0":
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d"
|
||||
integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==
|
||||
|
||||
"@eslint/eslintrc@^0.4.1":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14"
|
||||
integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==
|
||||
"@eslint/eslintrc@^1.0.5":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318"
|
||||
integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.1.1"
|
||||
espree "^7.3.0"
|
||||
globals "^12.1.0"
|
||||
debug "^4.3.2"
|
||||
espree "^9.2.0"
|
||||
globals "^13.9.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.2.1"
|
||||
js-yaml "^3.13.1"
|
||||
js-yaml "^4.1.0"
|
||||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
|
@ -88,6 +93,20 @@
|
|||
dependencies:
|
||||
"@fortawesome/fontawesome-common-types" "^0.2.35"
|
||||
|
||||
"@humanwhocodes/config-array@^0.9.2":
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914"
|
||||
integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==
|
||||
dependencies:
|
||||
"@humanwhocodes/object-schema" "^1.2.1"
|
||||
debug "^4.1.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@humanwhocodes/object-schema@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@joeattardi/emoji-button@^4.6.2":
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@joeattardi/emoji-button/-/emoji-button-4.6.2.tgz#75baf4ce27324e4d6fb90292f8b248235f638ad0"
|
||||
|
@ -131,11 +150,84 @@
|
|||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
|
||||
integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==
|
||||
|
||||
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
|
||||
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
|
||||
|
||||
"@protobufjs/base64@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
|
||||
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
|
||||
|
||||
"@protobufjs/codegen@^2.0.4":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
|
||||
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
|
||||
|
||||
"@protobufjs/eventemitter@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
|
||||
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
|
||||
|
||||
"@protobufjs/fetch@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
|
||||
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
|
||||
dependencies:
|
||||
"@protobufjs/aspromise" "^1.1.1"
|
||||
"@protobufjs/inquire" "^1.1.0"
|
||||
|
||||
"@protobufjs/float@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
|
||||
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
|
||||
|
||||
"@protobufjs/inquire@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
|
||||
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
|
||||
|
||||
"@protobufjs/path@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
|
||||
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
|
||||
|
||||
"@protobufjs/pool@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
|
||||
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
|
||||
|
||||
"@protobufjs/utf8@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
||||
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
|
||||
|
||||
"@sentry/types@^6.11.0":
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.12.0.tgz#b7395688a79403c6df8d8bb8d81deb8222519853"
|
||||
integrity sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA==
|
||||
|
||||
"@tsconfig/node10@^1.0.7":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
|
||||
integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
|
||||
|
||||
"@tsconfig/node12@^1.0.7":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
|
||||
integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
|
||||
|
||||
"@tsconfig/node14@^1.0.0":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
|
||||
integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
|
||||
|
||||
"@tsconfig/node16@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
||||
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
||||
|
||||
"@tsconfig/svelte@^1.0.10":
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-1.0.10.tgz#30ec7feeee0bdf38b12a50f0686f8a2e7b6b9dc0"
|
||||
|
@ -239,16 +331,26 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.7.4.tgz#99a49aa9a5f8dc86fc249ed13ed59552c6ce862d"
|
||||
integrity sha512-L3FKeEwMm8e8hqGvt7cSesVmGtavpRyHV1FNDq+Pm5pS4x5eFmE70ZERXCSBWAiLQqXBcZRUrwV59FZLQl/GxQ==
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
|
||||
version "7.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
|
||||
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
|
||||
|
||||
"@types/json-schema@^7.0.9":
|
||||
version "7.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
|
||||
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||
|
||||
"@types/long@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
|
||||
|
||||
"@types/mime@^1":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
|
||||
|
@ -273,11 +375,26 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.0.tgz#d6fed7d6bc6854306da3dea1af9f874b00783e26"
|
||||
integrity sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==
|
||||
|
||||
"@types/node@>=13.7.0":
|
||||
version "17.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.5.tgz#57ca67ec4e57ad9e4ef5a6bab48a15387a1c83e0"
|
||||
integrity sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==
|
||||
|
||||
"@types/object-hash@^1.3.0":
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.3.4.tgz#079ba142be65833293673254831b5e3e847fe58b"
|
||||
integrity sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==
|
||||
|
||||
"@types/parse-json@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||
|
||||
"@types/prettier@^1.19.0":
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f"
|
||||
integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==
|
||||
|
||||
"@types/pug@^2.0.4":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.4.tgz#8772fcd0418e3cd2cc171555d73007415051f4b2"
|
||||
|
@ -393,75 +510,75 @@
|
|||
"@types/webpack-sources" "*"
|
||||
source-map "^0.6.0"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.23.0.tgz#29d3c9c81f6200b1fd6d8454cfb007ba176cde80"
|
||||
integrity sha512-tGK1y3KIvdsQEEgq6xNn1DjiFJtl+wn8JJQiETtCbdQxw1vzjXyAaIkEmO2l6Nq24iy3uZBMFQjZ6ECf1QdgGw==
|
||||
"@typescript-eslint/eslint-plugin@^5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz#efd8668b3d6627c46ce722c2afe813928fe120a0"
|
||||
integrity sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.23.0"
|
||||
"@typescript-eslint/scope-manager" "4.23.0"
|
||||
debug "^4.1.1"
|
||||
"@typescript-eslint/experimental-utils" "5.6.0"
|
||||
"@typescript-eslint/scope-manager" "5.6.0"
|
||||
debug "^4.3.2"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
lodash "^4.17.15"
|
||||
regexpp "^3.0.0"
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
ignore "^5.1.8"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.23.0.tgz#f2059434cd6e5672bfeab2fb03b7c0a20622266f"
|
||||
integrity sha512-WAFNiTDnQfrF3Z2fQ05nmCgPsO5o790vOhmWKXbbYQTO9erE1/YsFot5/LnOUizLzU2eeuz6+U/81KV5/hFTGA==
|
||||
"@typescript-eslint/experimental-utils@5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz#f3a5960f2004abdcac7bb81412bafc1560841c23"
|
||||
integrity sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/scope-manager" "4.23.0"
|
||||
"@typescript-eslint/types" "4.23.0"
|
||||
"@typescript-eslint/typescript-estree" "4.23.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.6.0"
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
"@typescript-eslint/typescript-estree" "5.6.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.23.0.tgz#239315d38e42e852bef43a4b0b01bef78f78911c"
|
||||
integrity sha512-wsvjksHBMOqySy/Pi2Q6UuIuHYbgAMwLczRl4YanEPKW5KVxI9ZzDYh3B5DtcZPQTGRWFJrfcbJ6L01Leybwug==
|
||||
"@typescript-eslint/parser@^5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.6.0.tgz#11677324659641400d653253c03dcfbed468d199"
|
||||
integrity sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.23.0"
|
||||
"@typescript-eslint/types" "4.23.0"
|
||||
"@typescript-eslint/typescript-estree" "4.23.0"
|
||||
debug "^4.1.1"
|
||||
"@typescript-eslint/scope-manager" "5.6.0"
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
"@typescript-eslint/typescript-estree" "5.6.0"
|
||||
debug "^4.3.2"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz#8792ef7eacac122e2ec8fa2d30a59b8d9a1f1ce4"
|
||||
integrity sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w==
|
||||
"@typescript-eslint/scope-manager@5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz#9dd7f007dc8f3a34cdff6f79f5eaab27ae05157e"
|
||||
integrity sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.23.0"
|
||||
"@typescript-eslint/visitor-keys" "4.23.0"
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
"@typescript-eslint/visitor-keys" "5.6.0"
|
||||
|
||||
"@typescript-eslint/types@4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.23.0.tgz#da1654c8a5332f4d1645b2d9a1c64193cae3aa3b"
|
||||
integrity sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw==
|
||||
"@typescript-eslint/types@5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.6.0.tgz#745cb1b59daadcc1f32f7be95f0f68accf38afdd"
|
||||
integrity sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz#0753b292097523852428a6f5a1aa8ccc1aae6cd9"
|
||||
integrity sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw==
|
||||
"@typescript-eslint/typescript-estree@5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz#dfbb19c9307fdd81bd9c650c67e8397821d7faf0"
|
||||
integrity sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.23.0"
|
||||
"@typescript-eslint/visitor-keys" "4.23.0"
|
||||
debug "^4.1.1"
|
||||
globby "^11.0.1"
|
||||
is-glob "^4.0.1"
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
"@typescript-eslint/visitor-keys" "5.6.0"
|
||||
debug "^4.3.2"
|
||||
globby "^11.0.4"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.23.0":
|
||||
version "4.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz#7215cc977bd3b4ef22467b9023594e32f9e4e455"
|
||||
integrity sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg==
|
||||
"@typescript-eslint/visitor-keys@5.6.0":
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz#3e36509e103fe9713d8f035ac977235fd63cb6e6"
|
||||
integrity sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.23.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@webassemblyjs/ast@1.11.0":
|
||||
version "1.11.0"
|
||||
|
@ -624,16 +741,21 @@ acorn-jsx@^5.3.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
|
||||
integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
|
||||
|
||||
acorn@^7.4.0:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
acorn-walk@^8.1.1:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||
|
||||
acorn@^8.2.1:
|
||||
version "8.2.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0"
|
||||
integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==
|
||||
|
||||
acorn@^8.4.1, acorn@^8.6.0:
|
||||
version "8.6.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
|
||||
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
|
||||
|
||||
after@0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
||||
|
@ -667,16 +789,6 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
|
|||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^8.0.1:
|
||||
version "8.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.4.0.tgz#48984fdb2ce225cab15795f0772a8d85669075e4"
|
||||
integrity sha512-7QD2l6+KBSLwf+7MuYocbWvRPdOu63/trReTLu2KFwkgctnub1auoF+Y1WYcm09CTM7quuscrzqmASaLHC/K4Q==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-colors@^3.0.0:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
|
||||
|
@ -714,6 +826,11 @@ ansi-regex@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
|
@ -749,12 +866,10 @@ arg@^4.1.0:
|
|||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
arr-diff@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
@ -1614,6 +1729,11 @@ cssesc@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||
|
||||
dataloader@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8"
|
||||
integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
|
@ -1628,13 +1748,20 @@ debug@^3.1.1, debug@^3.2.6:
|
|||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^4.3.2:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@~3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
|
@ -1657,6 +1784,11 @@ dedent@^0.7.0:
|
|||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
||||
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
||||
|
||||
deep-copy-ts@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-copy-ts/-/deep-copy-ts-0.5.0.tgz#b9493d8e2bae85ef7d659c16eb707c13efb84499"
|
||||
integrity sha512-/3cgBcMkznRf5BM8wu6YWz3SQUkHzgh/v1TZFjevztLj9sMjFvNFBtpN4uUtPzw/rA/TldyD6c6LRL1zno4+YA==
|
||||
|
||||
deep-equal@^1.0.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
||||
|
@ -2041,12 +2173,17 @@ escape-string-regexp@^1.0.5:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-plugin-svelte3@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-3.2.1.tgz#f0f24150ecea3061c38c69e282bea26dc3e660c6"
|
||||
integrity sha512-YoBR9mLoKCjGghJ/gvpnFZKaMEu/VRcuxpSRS8KuozuEo7CdBH7bmBHa6FmMm0i4kJnOyx+PVsaptz96K6H/4Q==
|
||||
|
||||
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
||||
eslint-scope@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
||||
|
@ -2054,79 +2191,83 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
|||
esrecurse "^4.3.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^2.0.0, eslint-utils@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
|
||||
integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
|
||||
eslint-scope@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153"
|
||||
integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
|
||||
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
|
||||
eslint-utils@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
|
||||
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
eslint-visitor-keys@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||
|
||||
eslint@^7.26.0:
|
||||
version "7.26.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.26.0.tgz#d416fdcdcb3236cd8f282065312813f8c13982f6"
|
||||
integrity sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg==
|
||||
eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2"
|
||||
integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==
|
||||
|
||||
eslint@^8.4.1:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.4.1.tgz#d6531bbf3e598dffd7c0c7d35ec52a0b30fdfa2d"
|
||||
integrity sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "7.12.11"
|
||||
"@eslint/eslintrc" "^0.4.1"
|
||||
"@eslint/eslintrc" "^1.0.5"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
debug "^4.0.1"
|
||||
debug "^4.3.2"
|
||||
doctrine "^3.0.0"
|
||||
enquirer "^2.3.5"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^2.1.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
espree "^7.3.1"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^7.1.0"
|
||||
eslint-utils "^3.0.0"
|
||||
eslint-visitor-keys "^3.1.0"
|
||||
espree "^9.2.0"
|
||||
esquery "^1.4.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^6.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^5.0.0"
|
||||
glob-parent "^6.0.1"
|
||||
globals "^13.6.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^3.13.1"
|
||||
js-yaml "^4.1.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
lodash "^4.17.21"
|
||||
lodash.merge "^4.6.2"
|
||||
minimatch "^3.0.4"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.1"
|
||||
progress "^2.0.0"
|
||||
regexpp "^3.1.0"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.2.1"
|
||||
strip-ansi "^6.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
strip-json-comments "^3.1.0"
|
||||
table "^6.0.4"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^7.3.0, espree@^7.3.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
|
||||
integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
|
||||
espree@^9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.2.0.tgz#c50814e01611c2d0f8bd4daa83c369eabba80dbc"
|
||||
integrity sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==
|
||||
dependencies:
|
||||
acorn "^7.4.0"
|
||||
acorn "^8.6.0"
|
||||
acorn-jsx "^5.3.1"
|
||||
eslint-visitor-keys "^1.3.0"
|
||||
|
||||
esprima@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
eslint-visitor-keys "^3.1.0"
|
||||
|
||||
esquery@^1.4.0:
|
||||
version "1.4.0"
|
||||
|
@ -2308,7 +2449,7 @@ extglob@^2.0.4:
|
|||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
@ -2462,10 +2603,10 @@ foreach@^2.0.5:
|
|||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=
|
||||
|
||||
fork-ts-checker-webpack-plugin@^6.2.9:
|
||||
version "6.2.9"
|
||||
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.2.9.tgz#08f51b685a48b09ab3ec079a8501762422443120"
|
||||
integrity sha512-D/KSb/2VeiOy3odDerrC16WiZ1t5TLwiFfZmuDeTXcf3Km79M+f8nTCIdKkokxybybrgMcStbx0QpGaseePxnA==
|
||||
fork-ts-checker-webpack-plugin@^6.5.0:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz#0282b335fa495a97e167f69018f566ea7d2a2b5e"
|
||||
integrity sha512-cS178Y+xxtIjEUorcHddKS7yCMlrDPV31mt47blKKRfMd70Kxu5xruAFE2o9sDY6wVC5deuob/u/alD04YYHnw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@types/json-schema" "^7.0.5"
|
||||
|
@ -2609,13 +2750,20 @@ glob-parent@^3.1.0:
|
|||
is-glob "^3.1.0"
|
||||
path-dirname "^1.0.0"
|
||||
|
||||
glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0, glob-parent@~5.1.2:
|
||||
glob-parent@^5.1.0, glob-parent@~5.1.0, glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-parent@^6.0.1:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||
dependencies:
|
||||
is-glob "^4.0.3"
|
||||
|
||||
glob-to-regexp@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
|
||||
|
@ -2633,13 +2781,6 @@ glob@^7.0.3, glob@^7.1.3, glob@^7.1.6:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^12.1.0:
|
||||
version "12.4.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8"
|
||||
integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==
|
||||
dependencies:
|
||||
type-fest "^0.8.1"
|
||||
|
||||
globals@^13.6.0:
|
||||
version "13.8.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.8.0.tgz#3e20f504810ce87a8d72e55aecf8435b50f4c1b3"
|
||||
|
@ -2647,10 +2788,17 @@ globals@^13.6.0:
|
|||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globby@^11.0.1:
|
||||
version "11.0.3"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
|
||||
integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
|
||||
globals@^13.9.0:
|
||||
version "13.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e"
|
||||
integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globby@^11.0.4:
|
||||
version "11.0.4"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
|
||||
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
|
||||
dependencies:
|
||||
array-union "^2.1.0"
|
||||
dir-glob "^3.0.1"
|
||||
|
@ -2951,6 +3099,11 @@ ignore@^5.1.4:
|
|||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
|
||||
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
|
||||
|
||||
ignore@^5.1.8:
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb"
|
||||
integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==
|
||||
|
||||
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -3193,6 +3346,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
|
|||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-glob@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-nan@^1.2.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
|
||||
|
@ -3374,13 +3534,12 @@ js-tokens@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
|
||||
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
|
||||
version "1.0.2"
|
||||
|
@ -3397,11 +3556,6 @@ json-schema-traverse@^0.4.1:
|
|||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema-traverse@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
|
@ -3576,22 +3730,17 @@ locate-path@^5.0.0:
|
|||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.truncate@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
||||
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21:
|
||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
@ -3624,6 +3773,11 @@ lokijs@^1.5.12:
|
|||
resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.5.12.tgz#cb55b37009bdf09ee7952a6adddd555b893653a0"
|
||||
integrity sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==
|
||||
|
||||
long@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
|
||||
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
|
||||
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||
|
@ -4027,6 +4181,11 @@ object-copy@^0.1.0:
|
|||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-hash@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
|
||||
integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
|
||||
|
||||
object-inspect@^1.9.0:
|
||||
version "1.10.3"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
|
||||
|
@ -4519,6 +4678,11 @@ prettier-plugin-svelte@^2.5.0:
|
|||
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.5.0.tgz#7922534729f7febe59b4c56c3f5360539f0d8ab1"
|
||||
integrity sha512-+iHY2uGChOngrgKielJUnqo74gIL/EO5oeWm8MftFWjEi213lq9QYTOwm1pv4lI1nA61tdgf80CF2i5zMcu1kw==
|
||||
|
||||
prettier@^2.0.2:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||
|
||||
prettier@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
|
||||
|
@ -4547,6 +4711,25 @@ progress@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
protobufjs@^6.8.8:
|
||||
version "6.11.2"
|
||||
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b"
|
||||
integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==
|
||||
dependencies:
|
||||
"@protobufjs/aspromise" "^1.1.2"
|
||||
"@protobufjs/base64" "^1.1.2"
|
||||
"@protobufjs/codegen" "^2.0.4"
|
||||
"@protobufjs/eventemitter" "^1.1.0"
|
||||
"@protobufjs/fetch" "^1.1.0"
|
||||
"@protobufjs/float" "^1.0.2"
|
||||
"@protobufjs/inquire" "^1.1.0"
|
||||
"@protobufjs/path" "^1.1.2"
|
||||
"@protobufjs/pool" "^1.1.0"
|
||||
"@protobufjs/utf8" "^1.1.0"
|
||||
"@types/long" "^4.0.1"
|
||||
"@types/node" ">=13.7.0"
|
||||
long "^4.0.0"
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
|
||||
|
@ -4762,10 +4945,10 @@ regexp.prototype.flags@^1.2.0:
|
|||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
regexpp@^3.0.0, regexpp@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
|
||||
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
|
||||
regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
|
||||
relateurl@^0.2.7:
|
||||
version "0.2.7"
|
||||
|
@ -4803,11 +4986,6 @@ require-directory@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
require-main-filename@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
|
@ -5291,7 +5469,7 @@ source-map-resolve@^0.5.0:
|
|||
source-map-url "^0.4.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
source-map-support@^0.5.17, source-map-support@~0.5.12, source-map-support@~0.5.19:
|
||||
source-map-support@~0.5.12, source-map-support@~0.5.19:
|
||||
version "0.5.19"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||
|
@ -5375,11 +5553,6 @@ split-string@^3.0.1, split-string@^3.0.2:
|
|||
dependencies:
|
||||
extend-shallow "^3.0.0"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||
|
||||
standardized-audio-context@^25.2.4:
|
||||
version "25.2.4"
|
||||
resolved "https://registry.yarnpkg.com/standardized-audio-context/-/standardized-audio-context-25.2.4.tgz#d64dbdd70615171ec90d1b7151a0d945af94cf3d"
|
||||
|
@ -5512,6 +5685,13 @@ strip-ansi@^6.0.0:
|
|||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
|
@ -5614,18 +5794,6 @@ tabbable@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261"
|
||||
integrity sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==
|
||||
|
||||
table@^6.0.4:
|
||||
version "6.7.1"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
|
||||
integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
|
||||
dependencies:
|
||||
ajv "^8.0.1"
|
||||
lodash.clonedeep "^4.5.0"
|
||||
lodash.truncate "^4.4.2"
|
||||
slice-ansi "^4.0.0"
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
tapable@^1.0.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||
|
@ -5735,28 +5903,63 @@ toidentifier@1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
ts-loader@^9.1.2:
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.1.2.tgz#ba9b9abb05a514e8ff825791a3f6fcf793272728"
|
||||
integrity sha512-ryMgATvLLl+z8zQvdlm6Pep0slmwxFWIEnq/5VdiLVjqQXnFJgO+qNLGIIP+d2N2jsFZ9MibZCVDb2bSp7OmEA==
|
||||
ts-loader@^9.2.6:
|
||||
version "9.2.6"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
|
||||
integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
enhanced-resolve "^5.0.0"
|
||||
micromatch "^4.0.0"
|
||||
semver "^7.3.4"
|
||||
|
||||
ts-node@^9.1.1:
|
||||
version "9.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d"
|
||||
integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==
|
||||
ts-node@^10.4.0:
|
||||
version "10.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
||||
integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-support" "0.7.0"
|
||||
"@tsconfig/node10" "^1.0.7"
|
||||
"@tsconfig/node12" "^1.0.7"
|
||||
"@tsconfig/node14" "^1.0.0"
|
||||
"@tsconfig/node16" "^1.0.2"
|
||||
acorn "^8.4.1"
|
||||
acorn-walk "^8.1.1"
|
||||
arg "^4.1.0"
|
||||
create-require "^1.1.0"
|
||||
diff "^4.0.1"
|
||||
make-error "^1.1.1"
|
||||
source-map-support "^0.5.17"
|
||||
yn "3.1.1"
|
||||
|
||||
ts-poet@^4.5.0:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-poet/-/ts-poet-4.6.1.tgz#015dc823d726655af9f095c900f84ed7c60e2dd3"
|
||||
integrity sha512-DXJ+mBJIDp+jiaUgB4N5I/sczHHDU2FWacdbDNVAVS4Mh4hb7ckpvUWVW7m7/nAOcjR0r4Wt+7AoO7FeJKExfA==
|
||||
dependencies:
|
||||
"@types/prettier" "^1.19.0"
|
||||
lodash "^4.17.15"
|
||||
prettier "^2.0.2"
|
||||
|
||||
ts-proto-descriptors@^1.2.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-proto-descriptors/-/ts-proto-descriptors-1.3.1.tgz#760ebaaa19475b03662f7b358ffea45b9c5348f5"
|
||||
integrity sha512-Cybb3fqceMwA6JzHdC32dIo8eVGVmXrM6TWhdk1XQVVHT/6OQqk0ioyX1dIdu3rCIBhRmWUhUE4HsyK+olmgMw==
|
||||
dependencies:
|
||||
long "^4.0.0"
|
||||
protobufjs "^6.8.8"
|
||||
|
||||
ts-proto@^1.96.0:
|
||||
version "1.96.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-proto/-/ts-proto-1.96.0.tgz#63768d7da533b337aee84db065dd66773bd4cac9"
|
||||
integrity sha512-fKwaGzi8EOCU9xwmcXK917jj1WhFdLbFkPRawQ+5CAZM9eSXr/mpkz/yEctXCiuei364z6jAB2Odb64KCDFTPQ==
|
||||
dependencies:
|
||||
"@types/object-hash" "^1.3.0"
|
||||
dataloader "^1.4.0"
|
||||
object-hash "^1.3.1"
|
||||
protobufjs "^6.8.8"
|
||||
ts-poet "^4.5.0"
|
||||
ts-proto-descriptors "^1.2.1"
|
||||
|
||||
tsconfig-paths@^3.9.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
|
||||
|
@ -5777,7 +5980,7 @@ tslib@^2.0.0, tslib@^2.0.3, tslib@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
tsutils@^3.21.0:
|
||||
version "3.21.0"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
|
||||
|
@ -5821,11 +6024,6 @@ type-fest@^0.21.3:
|
|||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
type-fest@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
type-is@~1.6.17, type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
|
@ -5839,10 +6037,10 @@ typescript@*:
|
|||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
|
||||
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
|
||||
|
||||
typescript@^4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
|
||||
integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==
|
||||
typescript@^4.5.3:
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
|
||||
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
|
||||
|
||||
unbox-primitive@^1.0.0:
|
||||
version "1.0.1"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue