From d6b38ed79ebc25c352591e5a3757fedd48e6cdfe Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sat, 9 Oct 2021 14:57:44 +0100 Subject: [PATCH] [feature] Live cursors MVP (#137) * Adds very basic live cursors * Adds ability to hide pages / menu --- .../core/src/components/canvas/canvas.tsx | 8 +- .../core/src/components/renderer/renderer.tsx | 27 ++- packages/core/src/components/user/index.ts | 1 + packages/core/src/components/user/user.tsx | 21 +++ packages/core/src/components/users/index.ts | 1 + packages/core/src/components/users/users.tsx | 20 +++ packages/core/src/hooks/useStyle.tsx | 9 + packages/core/src/types.ts | 8 + packages/dev/.env.local | 1 + packages/dev/esbuild.config.mjs | 1 + packages/dev/src/app.tsx | 10 +- packages/dev/src/liveblocks.tsx | 84 --------- packages/dev/src/multiplayer/cursors.tsx | 3 + packages/dev/src/multiplayer/index.ts | 1 + packages/dev/src/multiplayer/multiplayer.tsx | 164 ++++++++++++++++++ .../tldraw/src/components/tldraw/tldraw.tsx | 34 +++- packages/tldraw/src/state/tlstate.ts | 90 +++++++--- packages/tldraw/src/types.ts | 20 ++- .../www/components/multiplayer-editor.tsx | 102 ++++++++--- packages/www/public/sw.js | 2 +- packages/www/public/sw.js.map | 2 +- ...GQ4.js => worker-j4SQSxW4Y5BQ1MYBuhDPd.js} | 0 22 files changed, 455 insertions(+), 154 deletions(-) create mode 100644 packages/core/src/components/user/index.ts create mode 100644 packages/core/src/components/user/user.tsx create mode 100644 packages/core/src/components/users/index.ts create mode 100644 packages/core/src/components/users/users.tsx create mode 100644 packages/dev/.env.local delete mode 100644 packages/dev/src/liveblocks.tsx create mode 100644 packages/dev/src/multiplayer/cursors.tsx create mode 100644 packages/dev/src/multiplayer/index.ts create mode 100644 packages/dev/src/multiplayer/multiplayer.tsx rename packages/www/public/{worker-NIc7Y9Sxqfi5NjIQO6GQ4.js => worker-j4SQSxW4Y5BQ1MYBuhDPd.js} (100%) diff --git a/packages/core/src/components/canvas/canvas.tsx b/packages/core/src/components/canvas/canvas.tsx index 423fd2ed6..e15fd5427 100644 --- a/packages/core/src/components/canvas/canvas.tsx +++ b/packages/core/src/components/canvas/canvas.tsx @@ -8,11 +8,12 @@ import { useCameraCss, useKeyEvents, } from '+hooks' -import type { TLBinding, TLPage, TLPageState, TLShape } from '+types' +import type { TLBinding, TLPage, TLPageState, TLShape, TLUser, TLUsers } from '+types' import { ErrorFallback } from '+components/error-fallback' import { ErrorBoundary } from '+components/error-boundary' import { Brush } from '+components/brush' import { Page } from '+components/page' +import { Users } from '+components/users' import { useResizeObserver } from '+hooks/useResizeObserver' import { inputs } from '+inputs' @@ -23,6 +24,8 @@ function resetError() { interface CanvasProps> { page: TLPage pageState: TLPageState + users?: TLUsers + userId?: string hideBounds?: boolean hideHandles?: boolean hideIndicators?: boolean @@ -34,6 +37,8 @@ export function Canvas>({ id, page, pageState, + users, + userId, meta, hideHandles = false, hideBounds = false, @@ -83,6 +88,7 @@ export function Canvas>({ meta={meta} /> {pageState.brush && } + {users && } diff --git a/packages/core/src/components/renderer/renderer.tsx b/packages/core/src/components/renderer/renderer.tsx index 2cd669db0..60ea8183c 100644 --- a/packages/core/src/components/renderer/renderer.tsx +++ b/packages/core/src/components/renderer/renderer.tsx @@ -12,7 +12,7 @@ import type { import { Canvas } from '../canvas' import { Inputs } from '../../inputs' import { useTLTheme, TLContext, TLContextType } from '../../hooks' -import type { TLShapeUtil } from '+index' +import type { TLShapeUtil, TLUser, TLUsers } from '+index' export interface RendererProps extends Partial> { @@ -23,7 +23,6 @@ export interface RendererProps> /** * The current page, containing shapes and bindings. @@ -34,29 +33,37 @@ export interface RendererProps /** - * When true, the renderer will not show the bounds for selected objects. + * (optional) When true, the renderer will not show the bounds for selected objects. */ hideBounds?: boolean /** - * When true, the renderer will not show the handles of shapes with handles. + * (optional) When true, the renderer will not show the handles of shapes with handles. */ hideHandles?: boolean /** - * When true, the renderer will not show indicators for selected or + * (optional) When true, the renderer will not show indicators for selected or * hovered objects, */ hideIndicators?: boolean /** - * When true, the renderer will ignore all inputs that were not made + * (optional) hen true, the renderer will ignore all inputs that were not made * by a stylus or pen-type device. */ isPenMode?: boolean /** - * An object of custom options that should be passed to rendered shapes. + * (optional) An object of custom options that should be passed to rendered shapes. */ meta?: M /** @@ -82,6 +89,8 @@ export function Renderer(null) + + return ( +
+ ) +} diff --git a/packages/core/src/components/users/index.ts b/packages/core/src/components/users/index.ts new file mode 100644 index 000000000..2b9fc3e87 --- /dev/null +++ b/packages/core/src/components/users/index.ts @@ -0,0 +1 @@ +export * from './users' diff --git a/packages/core/src/components/users/users.tsx b/packages/core/src/components/users/users.tsx new file mode 100644 index 000000000..ef31554f6 --- /dev/null +++ b/packages/core/src/components/users/users.tsx @@ -0,0 +1,20 @@ +import * as React from 'react' +import { User } from '+components/user/user' +import type { TLUsers } from '+types' + +export interface UserProps { + userId?: string + users: TLUsers +} + +export function Users({ userId, users }: UserProps) { + return ( + <> + {Object.values(users) + .filter((user) => user.id !== userId) + .map((user) => ( + + ))} + + ) +} diff --git a/packages/core/src/hooks/useStyle.tsx b/packages/core/src/hooks/useStyle.tsx index 0bea1498f..e2d21fd01 100644 --- a/packages/core/src/hooks/useStyle.tsx +++ b/packages/core/src/hooks/useStyle.tsx @@ -233,6 +233,15 @@ const tlcss = css` pointer-events: none; } + .tl-user { + left: -4px; + top: -4px; + height: 8px; + width: 8px; + border-radius: 100%; + pointer-events: none; + } + .tl-selected { fill: transparent; stroke: var(--tl-selectStroke); diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 25074c3ad..c60bbd24b 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -16,6 +16,8 @@ export interface TLPage { bindings: Record } +export type TLUsers = Record + export interface TLPageState { id: string selectedIds: string[] @@ -32,6 +34,12 @@ export interface TLPageState { currentParentId?: string | null } +export interface TLUser { + id: string + color: string + point: number[] +} + export interface TLHandle { id: string index: number diff --git a/packages/dev/.env.local b/packages/dev/.env.local new file mode 100644 index 000000000..cd40368bd --- /dev/null +++ b/packages/dev/.env.local @@ -0,0 +1 @@ +LIVEBLOCKS_PUBLIC_API_KEY=pk_live_1LJGGaqBSNLjLT-4Jalkl-U9 \ No newline at end of file diff --git a/packages/dev/esbuild.config.mjs b/packages/dev/esbuild.config.mjs index cea1cc480..398a8f1ae 100644 --- a/packages/dev/esbuild.config.mjs +++ b/packages/dev/esbuild.config.mjs @@ -23,6 +23,7 @@ esbuild incremental: isDevServer, target: ['chrome58', 'firefox57', 'safari11', 'edge18'], define: { + 'process.env.LIVEBLOCKS_PUBLIC_API_KEY': process.env.LIVEBLOCKS_PUBLIC_API_KEY, 'process.env.NODE_ENV': isDevServer ? '"development"' : '"production"', }, watch: isDevServer && { diff --git a/packages/dev/src/app.tsx b/packages/dev/src/app.tsx index 2a4615ddf..7d320b902 100644 --- a/packages/dev/src/app.tsx +++ b/packages/dev/src/app.tsx @@ -4,8 +4,8 @@ import Basic from './basic' import Controlled from './controlled' import Imperative from './imperative' import Embedded from './embedded' -import NoSizeEmbedded from '+no-size-embedded' -import LiveBlocks from './liveblocks' +import NoSizeEmbedded from './no-size-embedded' +import { Multiplayer } from './multiplayer' import ChangingId from './changing-id' import Core from './core' import './styles.css' @@ -35,8 +35,8 @@ export default function App(): JSX.Element { - - + +
    @@ -62,7 +62,7 @@ export default function App(): JSX.Element { embedded (no size)
  • - liveblocks + multiplayer
diff --git a/packages/dev/src/liveblocks.tsx b/packages/dev/src/liveblocks.tsx deleted file mode 100644 index b3b4813d7..000000000 --- a/packages/dev/src/liveblocks.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import * as React from 'react' -import { - TLDraw, - ColorStyle, - DashStyle, - TLDrawState, - SizeStyle, - TLDrawDocument, - TLDrawShapeType, -} from '@tldraw/tldraw' -import { createClient } from '@liveblocks/client' -import { LiveblocksProvider, RoomProvider, useObject } from '@liveblocks/react' - -const publicAPIKey = process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY as string - -const client = createClient({ - publicApiKey: publicAPIKey, -}) - -export default function LiveBlocks() { - return ( - - - - - - ) -} - -function TLDrawWrapper() { - const doc = useObject('doc', { - id: 'doc', - pages: { - page1: { - id: 'page1', - shapes: { - rect1: { - id: 'rect1', - type: TLDrawShapeType.Rectangle, - parentId: 'page1', - name: 'Rectangle', - childIndex: 1, - point: [100, 100], - size: [100, 100], - style: { - dash: DashStyle.Draw, - size: SizeStyle.Medium, - color: ColorStyle.Blue, - }, - }, - }, - bindings: {}, - }, - }, - pageStates: { - page1: { - id: 'page1', - selectedIds: ['rect1'], - camera: { - point: [0, 0], - zoom: 1, - }, - }, - }, - }) - - const handleChange = React.useCallback( - (state: TLDrawState, patch, reason) => { - if (!doc) return - if (reason.startsWith('command')) { - doc.update(patch.document) - } - }, - [doc] - ) - - if (doc === null) return
loading...
- - return ( -
- -
- ) -} diff --git a/packages/dev/src/multiplayer/cursors.tsx b/packages/dev/src/multiplayer/cursors.tsx new file mode 100644 index 000000000..4d50834fc --- /dev/null +++ b/packages/dev/src/multiplayer/cursors.tsx @@ -0,0 +1,3 @@ +export function Cursors() { + return
hi
+} diff --git a/packages/dev/src/multiplayer/index.ts b/packages/dev/src/multiplayer/index.ts new file mode 100644 index 000000000..44e9f8535 --- /dev/null +++ b/packages/dev/src/multiplayer/index.ts @@ -0,0 +1 @@ +export * from './multiplayer' diff --git a/packages/dev/src/multiplayer/multiplayer.tsx b/packages/dev/src/multiplayer/multiplayer.tsx new file mode 100644 index 000000000..7fb5868fd --- /dev/null +++ b/packages/dev/src/multiplayer/multiplayer.tsx @@ -0,0 +1,164 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import * as React from 'react' +import { TLDraw, TLDrawState, TLDrawDocument, TLDrawUser, Data } from '@tldraw/tldraw' +import { createClient, Presence } from '@liveblocks/client' +import { + LiveblocksProvider, + RoomProvider, + useErrorListener, + useObject, + useSelf, + useOthers, + useMyPresence, +} from '@liveblocks/react' +import { Utils } from '@tldraw/core' + +interface TLDrawUserPresence extends Presence { + user: TLDrawUser +} + +const publicAPIKey = 'pk_live_1LJGGaqBSNLjLT-4Jalkl-U9' + +const client = createClient({ + publicApiKey: publicAPIKey, +}) + +const ROOM_ID = 'mp-test-1' + +export function Multiplayer() { + return ( + + + + + + ) +} + +function TLDrawWrapper() { + const [docId] = React.useState(() => Utils.uniqueId()) + + const [error, setError] = React.useState() + + const [tlstate, setTlstate] = React.useState() + + useErrorListener((err) => setError(err)) + + const doc = useObject<{ uuid: string; document: TLDrawDocument }>('doc', { + uuid: docId, + document: { + id: 'test-room', + pages: { + page: { + id: 'page', + shapes: {}, + bindings: {}, + }, + }, + pageStates: { + page: { + id: 'page', + selectedIds: [], + camera: { + point: [0, 0], + zoom: 1, + }, + }, + }, + }, + }) + + // Put the tlstate into the window, for debugging. + const handleMount = React.useCallback((tlstate: TLDrawState) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + window.tlstate = tlstate + setTlstate(tlstate) + }, []) + + const handleChange = React.useCallback( + (_tlstate: TLDrawState, state: Data, reason: string) => { + // If the client updates its document, update the room's document + if (reason.startsWith('command')) { + doc?.update({ uuid: docId, document: state.document }) + } + + // When the client updates its presence, update the room + if (reason === 'patch:room:self:update' && state.room) { + const room = client.getRoom(ROOM_ID) + if (!room) return + const { userId, users } = state.room + room.updatePresence({ id: userId, user: users[userId] }) + } + }, + [docId, doc] + ) + + React.useEffect(() => { + const room = client.getRoom(ROOM_ID) + + if (!room) return + if (!doc) return + if (!tlstate) return + + // Update the user's presence with the user from state + const { users, userId } = tlstate.state.room + room.updatePresence({ id: userId, user: users[userId] }) + + // Subscribe to presence changes; when others change, update the state + room.subscribe('others', (others) => { + tlstate.updateUsers( + others + .toArray() + .filter((other) => other.presence) + .map((other) => other.presence!.user) + .filter(Boolean) + ) + }) + + room.subscribe('event', (event) => { + if (event.event?.name === 'exit') { + tlstate.removeUser(event.event.userId) + } + }) + + function handleDocumentUpdates() { + if (!doc) return + if (!tlstate) return + + const docObject = doc.toObject() + + // Only merge the change if it caused by someone else + if (docObject.uuid !== docId) { + tlstate.mergeDocument(docObject.document) + } + } + + function handleExit() { + room?.broadcastEvent({ name: 'exit', userId: tlstate?.state.room.userId }) + } + + window.addEventListener('beforeunload', handleExit) + + // When the shared document changes, update the state + doc.subscribe(handleDocumentUpdates) + + // Load the shared document + tlstate.loadDocument(doc.toObject().document) + + return () => { + window.removeEventListener('beforeunload', handleExit) + doc.unsubscribe(handleDocumentUpdates) + } + }, [doc, docId, tlstate]) + + if (error) return
Error: {error.message}
+ + if (doc === null) return
Loading...
+ + return ( +
+ +
+ ) +} diff --git a/packages/tldraw/src/components/tldraw/tldraw.tsx b/packages/tldraw/src/components/tldraw/tldraw.tsx index 24402bf9a..758485214 100644 --- a/packages/tldraw/src/components/tldraw/tldraw.tsx +++ b/packages/tldraw/src/components/tldraw/tldraw.tsx @@ -31,6 +31,8 @@ const isSelectedShapeWithHandlesSelector = (s: Data) => { const pageSelector = (s: Data) => s.document.pages[s.appState.currentPageId] +const usersSelector = (s: Data) => s.room?.users + const pageStateSelector = (s: Data) => s.document.pageStates[s.appState.currentPageId] const isDarkModeSelector = (s: Data) => s.settings.isDarkMode @@ -42,10 +44,12 @@ export interface TLDrawProps { * (optional) If provided, the component will load / persist state under this key. */ id?: string + /** * (optional) The document to load or update from. */ document?: TLDrawDocument + /** * (optional) The current page id. */ @@ -55,10 +59,22 @@ export interface TLDrawProps { * (optional) Whether the editor should immediately receive focus. Defaults to true. */ autofocus?: boolean + + /** + * (optional) Whether to show the menu UI. + */ + showMenu?: boolean + + /** + * (optional) Whether to show the pages UI. + */ + showPages?: boolean + /** * (optional) A callback to run when the component mounts. */ onMount?: (state: TLDrawState) => void + /** * (optional) A callback to run when the component's state changes. */ @@ -70,6 +86,8 @@ export function TLDraw({ document, currentPageId, autofocus = true, + showMenu = true, + showPages = true, onMount, onChange, }: TLDrawProps) { @@ -98,6 +116,8 @@ export function TLDraw({ currentPageId={currentPageId} document={document} autofocus={autofocus} + showPages={showPages} + showMenu={showMenu} /> @@ -108,11 +128,15 @@ function InnerTldraw({ id, currentPageId, autofocus, + showPages, + showMenu, document, }: { id?: string currentPageId?: string - autofocus?: boolean + autofocus: boolean + showPages: boolean + showMenu: boolean document?: TLDrawDocument }) { const { tlstate, useSelector } = useTLDrawContext() @@ -125,6 +149,8 @@ function InnerTldraw({ const pageState = useSelector(pageStateSelector) + const users = useSelector(usersSelector) + const isDarkMode = useSelector(isDarkModeSelector) const isFocusMode = useSelector(isFocusModeSelector) @@ -188,6 +214,8 @@ function InnerTldraw({ id={id} page={page} pageState={pageState} + users={users} + userId={tlstate.state.room.userId} shapeUtils={tldrawShapeUtils} theme={theme} meta={meta} @@ -253,8 +281,8 @@ function InnerTldraw({ ) : ( <>
- - + {showMenu && } + {showPages && }
diff --git a/packages/tldraw/src/state/tlstate.ts b/packages/tldraw/src/state/tlstate.ts index 33fc444ec..840704935 100644 --- a/packages/tldraw/src/state/tlstate.ts +++ b/packages/tldraw/src/state/tlstate.ts @@ -37,6 +37,7 @@ import { TLDrawBinding, GroupShape, TLDrawCommand, + TLDrawUser, } from '~types' import { TLDR } from './tldr' import { defaultStyle } from '~shape' @@ -66,6 +67,8 @@ const defaultDocument: TLDrawDocument = { }, } +const uuid = Utils.uniqueId() + const defaultState: Data = { settings: { isPenMode: false, @@ -94,6 +97,17 @@ const defaultState: Data = { }, }, document: defaultDocument, + room: { + id: 'local', + userId: uuid, + users: { + [uuid]: { + id: uuid, + color: 'dodgerBlue', + point: [100, 100], + }, + }, + }, } export class TLDrawState extends StateManager { @@ -144,15 +158,10 @@ export class TLDrawState extends StateManager { onChange?: (tlstate: TLDrawState, data: Data, reason: string) => void, onMount?: (tlstate: TLDrawState) => void ) { - super(defaultState, id, 2, (prev, next, prevVersion) => { - const state = { ...prev } - if (prevVersion === 1) - state.settings = { - ...state.settings, - isZoomSnap: next.settings.isZoomSnap, - } - return state - }) + super(defaultState, id, 2.3, (prev, next) => ({ + ...next, + ...prev, + })) this._onChange = onChange this._onMount = onMount @@ -327,6 +336,15 @@ export class TLDrawState extends StateManager { }) } + // Remove any exited users + if (data.room !== prev.room) { + Object.values(prev.room.users).forEach((user) => { + if (data.room.users[user.id] === undefined) { + delete data.room.users[user.id] + } + }) + } + const currentPageId = data.appState.currentPageId // Apply selected style change, if any @@ -340,12 +358,6 @@ export class TLDrawState extends StateManager { } } - // Check that the correct page id is active (delete me?) - - if (data.document.pageStates[currentPageId].id !== currentPageId) { - throw Error('Current page id is not the current page state!') - } - return data } @@ -543,6 +555,31 @@ export class TLDrawState extends StateManager { return this } + /** + * + * @param document + */ + updateUsers = (users: TLDrawUser[], isOwnUpdate = false) => { + this.patchState( + { + room: { + users: Object.fromEntries(users.map((user) => [user.id, user])), + }, + }, + isOwnUpdate ? 'room:self:update' : 'room:user:update' + ) + } + + removeUser = (userId: string) => { + this.patchState({ + room: { + users: { + [userId]: undefined, + }, + }, + }) + } + /** * Merge a new document patch into the current document. * @param document @@ -619,15 +656,6 @@ export class TLDrawState extends StateManager { currentPageStates[this.currentPageId].selectedIds = [editingId] } - console.log('next state', { - ...this.state, - appState: nextAppState, - document: { - ...document, - pageStates: currentPageStates, - }, - }) - return this.replaceState( { ...this.state, @@ -2567,6 +2595,20 @@ export class TLDrawState extends StateManager { /* ----------------- Pointer Events ----------------- */ onPointerMove: TLPointerEventHandler = (info) => { + if (this.state.room) { + const { users, userId } = this.state.room + + this.updateUsers( + [ + { + ...users[userId], + point: this.getPagePoint(info.point), + }, + ], + true + ) + } + // Several events (e.g. pan) can trigger the same "pointer move" behavior this.updateOnPointerMove(info) } diff --git a/packages/tldraw/src/types.ts b/packages/tldraw/src/types.ts index ccdc89d12..c47d73f5d 100644 --- a/packages/tldraw/src/types.ts +++ b/packages/tldraw/src/types.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/ban-types */ import type { TLBinding, TLShapeProps } from '@tldraw/core' import type { TLShape, TLShapeUtil, TLHandle } from '@tldraw/core' -import type { TLPage, TLPageState } from '@tldraw/core' +import type { TLPage, TLUser, TLPageState } from '@tldraw/core' import type { StoreApi } from 'zustand' import type { Command, Patch } from 'rko' @@ -29,10 +29,21 @@ export interface TLDrawSettings { isFocusMode: boolean } +export enum TLUserStatus { + Idle = 'idle', + Connecting = 'connecting', + Connected = 'connected', + Disconnected = 'disconnected', +} + export interface TLDrawMeta { isDarkMode: boolean } +export interface TLDrawUser extends TLUser { + id: string +} + export type TLDrawShapeProps = TLShapeProps< T, E, @@ -40,7 +51,6 @@ export type TLDrawShapeProps = TLShape > export interface Data { - document: TLDrawDocument settings: TLDrawSettings appState: { selectedStyle: ShapeStyles @@ -55,6 +65,12 @@ export interface Data { isEmptyCanvas: boolean status: { current: TLDrawStatus; previous: TLDrawStatus } } + document: TLDrawDocument + room: { + id: string + userId: string + users: Record + } } export type TLDrawPatch = Patch diff --git a/packages/www/components/multiplayer-editor.tsx b/packages/www/components/multiplayer-editor.tsx index 8b6c92026..461db131c 100644 --- a/packages/www/components/multiplayer-editor.tsx +++ b/packages/www/components/multiplayer-editor.tsx @@ -1,12 +1,16 @@ -import { TLDraw, TLDrawState, Data, TLDrawDocument } from '@tldraw/tldraw' +import { TLDraw, TLDrawState, Data, TLDrawDocument, TLDrawUser } from '@tldraw/tldraw' import * as gtag from '-utils/gtag' import * as React from 'react' -import { createClient } from '@liveblocks/client' +import { createClient, Presence } from '@liveblocks/client' import { LiveblocksProvider, RoomProvider, useObject, useErrorListener } from '@liveblocks/react' import { Utils } from '@tldraw/core' +interface TLDrawPresence extends Presence { + user: TLDrawUser +} + const client = createClient({ - publicApiKey: 'pk_live_1LJGGaqBSNLjLT-4Jalkl-U9', + publicApiKey: process.env.NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY, }) export default function MultiplayerEditor({ id }: { id: string }) { @@ -20,19 +24,18 @@ export default function MultiplayerEditor({ id }: { id: string }) { } function Editor({ id }: { id: string }) { - const [uuid] = React.useState(() => Utils.uniqueId()) - const [error, setError] = React.useState(null) + const [docId] = React.useState(() => Utils.uniqueId()) + + const [error, setError] = React.useState() + const [tlstate, setTlstate] = React.useState() - useErrorListener((err) => { - console.log(err) - setError(err) - }) + useErrorListener((err) => setError(err)) const doc = useObject<{ uuid: string; document: TLDrawDocument }>('doc', { - uuid, + uuid: docId, document: { - id, + id: 'test-room', pages: { page: { id: 'page', @@ -61,9 +64,9 @@ function Editor({ id }: { id: string }) { setTlstate(tlstate) }, []) - // Send events to gtag as actions. const handleChange = React.useCallback( (_tlstate: TLDrawState, state: Data, reason: string) => { + // If the client updates its document, update the room's document / gtag if (reason.startsWith('command')) { gtag.event({ action: reason, @@ -72,37 +75,86 @@ function Editor({ id }: { id: string }) { value: 0, }) - if (doc) { - doc.update({ uuid, document: state.document }) - } + doc?.update({ uuid: docId, document: state.document }) + } + + // When the client updates its presence, update the room + if (reason === 'patch:room:self:update' && state.room) { + const room = client.getRoom(id) + if (!room) return + const { userId, users } = state.room + room.updatePresence({ id: userId, user: users[userId] }) } }, - [uuid, doc] + [docId, doc, id] ) React.useEffect(() => { + const room = client.getRoom(id) + + if (!room) return if (!doc) return if (!tlstate) return - function updateState() { + // Update the user's presence with the user from state + const { users, userId } = tlstate.state.room + room.updatePresence({ id: userId, user: users[userId] }) + + // Subscribe to presence changes; when others change, update the state + room.subscribe('others', (others) => { + tlstate.updateUsers( + others + .toArray() + .filter((other) => other.presence) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + .map((other) => other.presence!.user) + .filter(Boolean) + ) + }) + + room.subscribe('event', (event) => { + if (event.event?.name === 'exit') { + tlstate.removeUser(event.event.userId) + } + }) + + function handleDocumentUpdates() { + if (!doc) return + if (!tlstate) return + const docObject = doc.toObject() - if (docObject.uuid === uuid) return - tlstate.mergeDocument(docObject.document) + + // Only merge the change if it caused by someone else + if (docObject.uuid !== docId) { + tlstate.mergeDocument(docObject.document) + } } - updateState() - doc.subscribe(updateState) + function handleExit() { + room?.broadcastEvent({ name: 'exit', userId: tlstate?.state.room.userId }) + } - return () => doc.unsubscribe(updateState) - }, [doc, uuid, tlstate]) + window.addEventListener('beforeunload', handleExit) + + // When the shared document changes, update the state + doc.subscribe(handleDocumentUpdates) + + // Load the shared document + tlstate.loadDocument(doc.toObject().document) + + return () => { + window.removeEventListener('beforeunload', handleExit) + doc.unsubscribe(handleDocumentUpdates) + } + }, [doc, docId, tlstate, id]) if (error) return
Error: {error.message}
- if (doc === null) return
loading...
+ if (doc === null) return
Loading...
return (
- +
) } diff --git a/packages/www/public/sw.js b/packages/www/public/sw.js index 7f5f26436..56017d2b7 100644 --- a/packages/www/public/sw.js +++ b/packages/www/public/sw.js @@ -1,2 +1,2 @@ -if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let s=Promise.resolve();return i[e]||(s=new Promise((async s=>{if("document"in self){const i=document.createElement("script");i.src=e,document.head.appendChild(i),i.onload=s}else importScripts(e),s()}))),s.then((()=>{if(!i[e])throw new Error(`Module ${e} didn’t register its module`);return i[e]}))},s=(s,i)=>{Promise.all(s.map(e)).then((e=>i(1===e.length?e[0]:e)))},i={require:Promise.resolve(s)};self.define=(s,c,n)=>{i[s]||(i[s]=Promise.resolve().then((()=>{let i={};const a={uri:location.origin+s.slice(1)};return Promise.all(c.map((s=>{switch(s){case"exports":return i;case"module":return a;default:return e(s)}}))).then((e=>{const s=n(...e);return i.default||(i.default=s),i}))})))}}define("./sw.js",["./workbox-7288c796"],(function(e){"use strict";importScripts("worker-NIc7Y9Sxqfi5NjIQO6GQ4.js"),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/NIc7Y9Sxqfi5NjIQO6GQ4/_buildManifest.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/NIc7Y9Sxqfi5NjIQO6GQ4/_ssgManifest.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/254.10c67190b7df2eb48f07.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/254.10c67190b7df2eb48f07.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/351.ef5501c80d8efe478fd4.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/351.ef5501c80d8efe478fd4.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/735.0b03369e8efcfb4266ba.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/735.0b03369e8efcfb4266ba.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/877-0b732eab4d2ed323649e.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/877-0b732eab4d2ed323649e.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/933.7eff08edcaba8f928024.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/933.7eff08edcaba8f928024.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/main-1622cb38e93933783343.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/main-1622cb38e93933783343.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/_app-6ae16e08a077d60c5eef.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/_app-6ae16e08a077d60c5eef.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/polyfills-a40ef1678bae11e696dba45124eadd70.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/webpack-30e5d82df786e710bf85.js",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/chunks/webpack-30e5d82df786e710bf85.js.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/css/188c96206215c999865a.css",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/_next/static/css/188c96206215c999865a.css.map",revision:"NIc7Y9Sxqfi5NjIQO6GQ4"},{url:"/android-chrome-192x192.png",revision:"57c9c4cd91d24d48b7ffdda0768fd225"},{url:"/android-chrome-512x512.png",revision:"8d2454e6cf551f8ca1e1d5670b13a8d1"},{url:"/android-chrome-maskable-192x192.png",revision:"71c93ce0b34d2fbb4c6654a9131a3d9d"},{url:"/android-chrome-maskable-512x512.png",revision:"4265b8c09997b16ac1493500b43f3755"},{url:"/android-chrome-maskable-beta-512x512.png",revision:"145800cf2381faf1c0f4a61c29a88448"},{url:"/apple-touch-icon.png",revision:"8081d08be3673ec33dbeecab06706b2b"},{url:"/favicon-16x16.png",revision:"ac17d75b1ee007781212853a57b88285"},{url:"/favicon-32x32.png",revision:"360bc7cd4706c0657917f3b78fed6b71"},{url:"/favicon.ico",revision:"b2bf6bb7b4d0234f3e6df44fd7d5707e"},{url:"/flat.png",revision:"e0460141713b5c94104ce19b36c4b462"},{url:"/icons/Redo.svg",revision:"6196f61a2053ff606d5746eb3ab380e3"},{url:"/icons/Trash.svg",revision:"5f2c42a17b7d8459f2e556b6209a61c6"},{url:"/icons/Undo.svg",revision:"24de701870630f51132f9bed3f18ee8f"},{url:"/icons/grab.svg",revision:"a1ca9e5c31d1edd2558ab075f72fde4e"},{url:"/icons/pointer.svg",revision:"dff260f896fe23adb83341639fdf93be"},{url:"/icons/resize.svg",revision:"0a3cb701d15731e25919783801d18f95"},{url:"/images/hello.mp4",revision:"b716f249cc6c781c91b0ac9dc23423b3"},{url:"/manifest.json",revision:"3e4cd02739cceee25488c97ca2ed59da"},{url:"/vercel.svg",revision:"4b4f1876502eb6721764637fe5c41702"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:i,state:c})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")}),new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")}),new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>!(self.origin===e.origin)),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")})); +if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let s=Promise.resolve();return n[e]||(s=new Promise((async s=>{if("document"in self){const n=document.createElement("script");n.src=e,document.head.appendChild(n),n.onload=s}else importScripts(e),s()}))),s.then((()=>{if(!n[e])throw new Error(`Module ${e} didn’t register its module`);return n[e]}))},s=(s,n)=>{Promise.all(s.map(e)).then((e=>n(1===e.length?e[0]:e)))},n={require:Promise.resolve(s)};self.define=(s,i,a)=>{n[s]||(n[s]=Promise.resolve().then((()=>{let n={};const c={uri:location.origin+s.slice(1)};return Promise.all(i.map((s=>{switch(s){case"exports":return n;case"module":return c;default:return e(s)}}))).then((e=>{const s=a(...e);return n.default||(n.default=s),n}))})))}}define("./sw.js",["./workbox-7288c796"],(function(e){"use strict";importScripts("worker-j4SQSxW4Y5BQ1MYBuhDPd.js"),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/chunks/254.f6cd96a81f27f9412bc6.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/254.f6cd96a81f27f9412bc6.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/351.5b8ef6201bbe533c7336.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/351.5b8ef6201bbe533c7336.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/735.0b03369e8efcfb4266ba.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/735.0b03369e8efcfb4266ba.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/877-0b732eab4d2ed323649e.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/877-0b732eab4d2ed323649e.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/933.7eff08edcaba8f928024.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/933.7eff08edcaba8f928024.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/main-1622cb38e93933783343.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/main-1622cb38e93933783343.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/_app-f969d07b144252b4e453.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/_app-f969d07b144252b4e453.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/polyfills-a40ef1678bae11e696dba45124eadd70.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/webpack-aeb8ef0e7d4985984bae.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/chunks/webpack-aeb8ef0e7d4985984bae.js.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/css/188c96206215c999865a.css",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/css/188c96206215c999865a.css.map",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/j4SQSxW4Y5BQ1MYBuhDPd/_buildManifest.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/_next/static/j4SQSxW4Y5BQ1MYBuhDPd/_ssgManifest.js",revision:"j4SQSxW4Y5BQ1MYBuhDPd"},{url:"/android-chrome-192x192.png",revision:"57c9c4cd91d24d48b7ffdda0768fd225"},{url:"/android-chrome-512x512.png",revision:"8d2454e6cf551f8ca1e1d5670b13a8d1"},{url:"/android-chrome-maskable-192x192.png",revision:"71c93ce0b34d2fbb4c6654a9131a3d9d"},{url:"/android-chrome-maskable-512x512.png",revision:"4265b8c09997b16ac1493500b43f3755"},{url:"/android-chrome-maskable-beta-512x512.png",revision:"145800cf2381faf1c0f4a61c29a88448"},{url:"/apple-touch-icon.png",revision:"8081d08be3673ec33dbeecab06706b2b"},{url:"/favicon-16x16.png",revision:"ac17d75b1ee007781212853a57b88285"},{url:"/favicon-32x32.png",revision:"360bc7cd4706c0657917f3b78fed6b71"},{url:"/favicon.ico",revision:"b2bf6bb7b4d0234f3e6df44fd7d5707e"},{url:"/flat.png",revision:"e0460141713b5c94104ce19b36c4b462"},{url:"/icons/Redo.svg",revision:"6196f61a2053ff606d5746eb3ab380e3"},{url:"/icons/Trash.svg",revision:"5f2c42a17b7d8459f2e556b6209a61c6"},{url:"/icons/Undo.svg",revision:"24de701870630f51132f9bed3f18ee8f"},{url:"/icons/grab.svg",revision:"a1ca9e5c31d1edd2558ab075f72fde4e"},{url:"/icons/pointer.svg",revision:"dff260f896fe23adb83341639fdf93be"},{url:"/icons/resize.svg",revision:"0a3cb701d15731e25919783801d18f95"},{url:"/images/hello.mp4",revision:"b716f249cc6c781c91b0ac9dc23423b3"},{url:"/manifest.json",revision:"3e4cd02739cceee25488c97ca2ed59da"},{url:"/vercel.svg",revision:"4b4f1876502eb6721764637fe5c41702"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:s,event:n,state:i})=>s&&"opaqueredirect"===s.type?new Response(s.body,{status:200,statusText:"OK",headers:s.headers}):s}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;const s=e.pathname;return!s.startsWith("/api/auth/")&&!!s.startsWith("/api/")}),new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")}),new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>!(self.origin===e.origin)),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")})); //# sourceMappingURL=sw.js.map diff --git a/packages/www/public/sw.js.map b/packages/www/public/sw.js.map index 9ea5851ba..b040a6e35 100644 --- a/packages/www/public/sw.js.map +++ b/packages/www/public/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../../../../../private/var/folders/g7/7xq6v0ls5lq_ks1yh3lbgrr00000gn/T/692208afc4415b2b068ba91563647c21/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {ExpirationPlugin as workbox_expiration_ExpirationPlugin} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-expiration/ExpirationPlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {StaleWhileRevalidate as workbox_strategies_StaleWhileRevalidate} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/StaleWhileRevalidate.mjs';\nimport {RangeRequestsPlugin as workbox_range_requests_RangeRequestsPlugin} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-range-requests/RangeRequestsPlugin.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \"worker-NIc7Y9Sxqfi5NjIQO6GQ4.js\"\n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"/_next/static/NIc7Y9Sxqfi5NjIQO6GQ4/_buildManifest.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/NIc7Y9Sxqfi5NjIQO6GQ4/_ssgManifest.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/254.10c67190b7df2eb48f07.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/254.10c67190b7df2eb48f07.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/351.ef5501c80d8efe478fd4.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/351.ef5501c80d8efe478fd4.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/735.0b03369e8efcfb4266ba.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/735.0b03369e8efcfb4266ba.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/877-0b732eab4d2ed323649e.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/877-0b732eab4d2ed323649e.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/933.7eff08edcaba8f928024.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/933.7eff08edcaba8f928024.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/main-1622cb38e93933783343.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/main-1622cb38e93933783343.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_app-6ae16e08a077d60c5eef.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_app-6ae16e08a077d60c5eef.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/polyfills-a40ef1678bae11e696dba45124eadd70.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/webpack-30e5d82df786e710bf85.js\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/chunks/webpack-30e5d82df786e710bf85.js.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/css/188c96206215c999865a.css\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/_next/static/css/188c96206215c999865a.css.map\",\n \"revision\": \"NIc7Y9Sxqfi5NjIQO6GQ4\"\n },\n {\n \"url\": \"/android-chrome-192x192.png\",\n \"revision\": \"57c9c4cd91d24d48b7ffdda0768fd225\"\n },\n {\n \"url\": \"/android-chrome-512x512.png\",\n \"revision\": \"8d2454e6cf551f8ca1e1d5670b13a8d1\"\n },\n {\n \"url\": \"/android-chrome-maskable-192x192.png\",\n \"revision\": \"71c93ce0b34d2fbb4c6654a9131a3d9d\"\n },\n {\n \"url\": \"/android-chrome-maskable-512x512.png\",\n \"revision\": \"4265b8c09997b16ac1493500b43f3755\"\n },\n {\n \"url\": \"/android-chrome-maskable-beta-512x512.png\",\n \"revision\": \"145800cf2381faf1c0f4a61c29a88448\"\n },\n {\n \"url\": \"/apple-touch-icon.png\",\n \"revision\": \"8081d08be3673ec33dbeecab06706b2b\"\n },\n {\n \"url\": \"/favicon-16x16.png\",\n \"revision\": \"ac17d75b1ee007781212853a57b88285\"\n },\n {\n \"url\": \"/favicon-32x32.png\",\n \"revision\": \"360bc7cd4706c0657917f3b78fed6b71\"\n },\n {\n \"url\": \"/favicon.ico\",\n \"revision\": \"b2bf6bb7b4d0234f3e6df44fd7d5707e\"\n },\n {\n \"url\": \"/flat.png\",\n \"revision\": \"e0460141713b5c94104ce19b36c4b462\"\n },\n {\n \"url\": \"/icons/Redo.svg\",\n \"revision\": \"6196f61a2053ff606d5746eb3ab380e3\"\n },\n {\n \"url\": \"/icons/Trash.svg\",\n \"revision\": \"5f2c42a17b7d8459f2e556b6209a61c6\"\n },\n {\n \"url\": \"/icons/Undo.svg\",\n \"revision\": \"24de701870630f51132f9bed3f18ee8f\"\n },\n {\n \"url\": \"/icons/grab.svg\",\n \"revision\": \"a1ca9e5c31d1edd2558ab075f72fde4e\"\n },\n {\n \"url\": \"/icons/pointer.svg\",\n \"revision\": \"dff260f896fe23adb83341639fdf93be\"\n },\n {\n \"url\": \"/icons/resize.svg\",\n \"revision\": \"0a3cb701d15731e25919783801d18f95\"\n },\n {\n \"url\": \"/images/hello.mp4\",\n \"revision\": \"b716f249cc6c781c91b0ac9dc23423b3\"\n },\n {\n \"url\": \"/manifest.json\",\n \"revision\": \"3e4cd02739cceee25488c97ca2ed59da\"\n },\n {\n \"url\": \"/vercel.svg\",\n \"revision\": \"4b4f1876502eb6721764637fe5c41702\"\n }\n], {\n \"ignoreURLParametersMatching\": []\n});\nworkbox_precaching_cleanupOutdatedCaches();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({request, response, event, state}) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, {status: 200, statusText: 'OK', headers: response.headers}); } return response; } }] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.(?:gstatic)\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"google-fonts-webfonts\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 31536000 })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.(?:googleapis)\\.com\\/.*/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"google-fonts-stylesheets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 604800 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-font-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 604800 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-image-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 64, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\/_next\\/image\\?url=.+$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"next-image\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 64, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:mp3|wav|ogg)$/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"static-audio-assets\", plugins: [new workbox_range_requests_RangeRequestsPlugin(), new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:mp4)$/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"static-video-assets\", plugins: [new workbox_range_requests_RangeRequestsPlugin(), new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:js)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-js-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:css|less)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-style-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\/_next\\/data\\/.+\\/.+\\.json$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"next-data\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:json|xml|csv)$/i, new workbox_strategies_NetworkFirst({ \"cacheName\":\"static-data-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n if (!isSameOrigin) return false\n const pathname = url.pathname\n // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without impact other environment\n // Above route is default for next-auth, you may need to change it if your OAuth workflow has a different callback route\n // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809\n if (pathname.startsWith('/api/auth/')) return false\n if (pathname.startsWith('/api/')) return true\n return false\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"apis\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 16, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n if (!isSameOrigin) return false\n const pathname = url.pathname\n if (pathname.startsWith('/api/')) return false\n return true\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"others\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n return !isSameOrigin\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"cross-origin\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 3600 })] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","async","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_CacheFirst","workbox_expiration_ExpirationPlugin","maxEntries","maxAgeSeconds","workbox_strategies_StaleWhileRevalidate","workbox_range_requests_RangeRequestsPlugin","url","origin","pathname","startsWith"],"mappings":"0yBAqBAA,cACE,mCASFC,KAAKC,kDAU+B,CAClC,KACS,iEACK,yBAEd,KACS,+DACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,kEACK,yBAEd,KACS,sEACK,yBAEd,KACS,6DACK,yBAEd,KACS,iEACK,yBAEd,KACS,mEACK,yBAEd,KACS,uEACK,yBAEd,KACS,qEACK,yBAEd,KACS,yEACK,yBAEd,KACS,oEACK,yBAEd,KACS,wEACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,mEACK,yBAEd,KACS,uEACK,yBAEd,KACS,qEACK,yBAEd,KACS,yEACK,yBAEd,KACS,sEACK,yBAEd,KACS,0EACK,yBAEd,KACS,0EACK,yBAEd,KACS,8EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,8EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,sDACK,yBAEd,KACS,0DACK,yBAEd,KACS,uCACK,oCAEd,KACS,uCACK,oCAEd,KACS,gDACK,oCAEd,KACS,gDACK,oCAEd,KACS,qDACK,oCAEd,KACS,iCACK,oCAEd,KACS,8BACK,oCAEd,KACS,8BACK,oCAEd,KACS,wBACK,oCAEd,KACS,qBACK,oCAEd,KACS,2BACK,oCAEd,KACS,4BACK,oCAEd,KACS,2BACK,oCAEd,KACS,2BACK,oCAEd,KACS,8BACK,oCAEd,KACS,6BACK,oCAEd,KACS,6BACK,oCAEd,KACS,0BACK,oCAEd,KACS,uBACK,qCAEb,6BAC8B,+CAMH,IAAK,IAAIC,eAAgC,WAAc,YAAaC,QAAS,CAAC,CAAEC,gBAAiBC,OAAQC,QAAAA,EAASC,SAAAA,EAAUC,MAAAA,EAAOC,MAAAA,KAAiBF,GAA8B,mBAAlBA,EAASG,KAAoC,IAAIC,SAASJ,EAASK,KAAM,CAACC,OAAQ,IAAKC,WAAY,KAAMC,QAASR,EAASQ,UAAoBR,MAAmB,uBAClU,0CAA2C,IAAIS,aAA8B,WAAc,wBAAyBb,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,aAAiB,uBACvN,6CAA8C,IAAIC,uBAAwC,WAAc,2BAA4BjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,YAAe,uBACrO,8CAA+C,IAAIC,uBAAwC,WAAc,qBAAsBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,YAAe,uBAChO,wCAAyC,IAAIC,uBAAwC,WAAc,sBAAuBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBAC3N,2BAA4B,IAAIC,uBAAwC,WAAc,aAAcjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACrM,sBAAuB,IAAIH,aAA8B,WAAc,sBAAuBb,QAAS,CAAC,IAAIkB,sBAA8C,IAAIJ,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACjP,cAAe,IAAIH,aAA8B,WAAc,sBAAuBb,QAAS,CAAC,IAAIkB,sBAA8C,IAAIJ,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACzO,aAAc,IAAIC,uBAAwC,WAAc,mBAAoBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBAC7L,mBAAoB,IAAIC,uBAAwC,WAAc,sBAAuBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACtM,gCAAiC,IAAIC,uBAAwC,WAAc,YAAajB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACzM,uBAAwB,IAAIjB,eAAgC,WAAc,qBAAsBC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBACjM,EAAEG,IAAAA,WACLtB,KAAKuB,SAAWD,EAAIC,QACtB,OAAO,QACpBC,EAAWF,EAAIE,gBAIjBA,EAASC,WAAW,iBACpBD,EAASC,WAAW,WAEvB,IAAIvB,eAAgC,WAAc,6BAA+B,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBAC/J,EAAEG,IAAAA,WACLtB,KAAKuB,SAAWD,EAAIC,QACtB,OAAO,SACTD,EAAIE,SACRC,WAAW,WAEvB,IAAIvB,eAAgC,WAAc,+BAAiC,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBACjK,EAAEG,IAAAA,OACLtB,KAAKuB,SAAWD,EAAIC,SAExC,IAAIrB,eAAgC,WAAc,qCAAuC,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,UAAa"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../../../../../private/var/folders/g7/7xq6v0ls5lq_ks1yh3lbgrr00000gn/T/fa5ae3888d4aada597f35a7dd8081aab/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {ExpirationPlugin as workbox_expiration_ExpirationPlugin} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-expiration/ExpirationPlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {StaleWhileRevalidate as workbox_strategies_StaleWhileRevalidate} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-strategies/StaleWhileRevalidate.mjs';\nimport {RangeRequestsPlugin as workbox_range_requests_RangeRequestsPlugin} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-range-requests/RangeRequestsPlugin.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/steve/Developer/Github/tldraw/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \"worker-j4SQSxW4Y5BQ1MYBuhDPd.js\"\n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"/_next/static/chunks/254.f6cd96a81f27f9412bc6.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/254.f6cd96a81f27f9412bc6.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/351.5b8ef6201bbe533c7336.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/351.5b8ef6201bbe533c7336.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/735.0b03369e8efcfb4266ba.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/735.0b03369e8efcfb4266ba.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/877-0b732eab4d2ed323649e.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/877-0b732eab4d2ed323649e.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/933.7eff08edcaba8f928024.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/933.7eff08edcaba8f928024.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/framework-6904c37ecf5b200e4e2e.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/main-1622cb38e93933783343.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/main-1622cb38e93933783343.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_app-f969d07b144252b4e453.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_app-f969d07b144252b4e453.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/_error-1cd1e11cd5e9c8211770.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/index-8e8448b898c0d9f22e4d.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k-53de1c8919efff3ddeba.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/k/%5Bid%5D-8cd85905a07a5dddf65d.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r-5cd32ab311ef7c240ff8.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/r/%5Bid%5D-3fa909f484a15cfc154e.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhh-3c469f1a3ffc0b8dd10c.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/shhhmp-118dc6c36903f542a0c3.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/signout-a8947582f064b3d8c5e6.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/sponsorware-e687fb2bd1ed8729e0f3.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u-4e2e7f6288f3059347cb.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/pages/u/%5Bid%5D-22351fd7f99494553332.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/polyfills-a40ef1678bae11e696dba45124eadd70.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/webpack-aeb8ef0e7d4985984bae.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/chunks/webpack-aeb8ef0e7d4985984bae.js.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/css/188c96206215c999865a.css\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/css/188c96206215c999865a.css.map\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/j4SQSxW4Y5BQ1MYBuhDPd/_buildManifest.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/_next/static/j4SQSxW4Y5BQ1MYBuhDPd/_ssgManifest.js\",\n \"revision\": \"j4SQSxW4Y5BQ1MYBuhDPd\"\n },\n {\n \"url\": \"/android-chrome-192x192.png\",\n \"revision\": \"57c9c4cd91d24d48b7ffdda0768fd225\"\n },\n {\n \"url\": \"/android-chrome-512x512.png\",\n \"revision\": \"8d2454e6cf551f8ca1e1d5670b13a8d1\"\n },\n {\n \"url\": \"/android-chrome-maskable-192x192.png\",\n \"revision\": \"71c93ce0b34d2fbb4c6654a9131a3d9d\"\n },\n {\n \"url\": \"/android-chrome-maskable-512x512.png\",\n \"revision\": \"4265b8c09997b16ac1493500b43f3755\"\n },\n {\n \"url\": \"/android-chrome-maskable-beta-512x512.png\",\n \"revision\": \"145800cf2381faf1c0f4a61c29a88448\"\n },\n {\n \"url\": \"/apple-touch-icon.png\",\n \"revision\": \"8081d08be3673ec33dbeecab06706b2b\"\n },\n {\n \"url\": \"/favicon-16x16.png\",\n \"revision\": \"ac17d75b1ee007781212853a57b88285\"\n },\n {\n \"url\": \"/favicon-32x32.png\",\n \"revision\": \"360bc7cd4706c0657917f3b78fed6b71\"\n },\n {\n \"url\": \"/favicon.ico\",\n \"revision\": \"b2bf6bb7b4d0234f3e6df44fd7d5707e\"\n },\n {\n \"url\": \"/flat.png\",\n \"revision\": \"e0460141713b5c94104ce19b36c4b462\"\n },\n {\n \"url\": \"/icons/Redo.svg\",\n \"revision\": \"6196f61a2053ff606d5746eb3ab380e3\"\n },\n {\n \"url\": \"/icons/Trash.svg\",\n \"revision\": \"5f2c42a17b7d8459f2e556b6209a61c6\"\n },\n {\n \"url\": \"/icons/Undo.svg\",\n \"revision\": \"24de701870630f51132f9bed3f18ee8f\"\n },\n {\n \"url\": \"/icons/grab.svg\",\n \"revision\": \"a1ca9e5c31d1edd2558ab075f72fde4e\"\n },\n {\n \"url\": \"/icons/pointer.svg\",\n \"revision\": \"dff260f896fe23adb83341639fdf93be\"\n },\n {\n \"url\": \"/icons/resize.svg\",\n \"revision\": \"0a3cb701d15731e25919783801d18f95\"\n },\n {\n \"url\": \"/images/hello.mp4\",\n \"revision\": \"b716f249cc6c781c91b0ac9dc23423b3\"\n },\n {\n \"url\": \"/manifest.json\",\n \"revision\": \"3e4cd02739cceee25488c97ca2ed59da\"\n },\n {\n \"url\": \"/vercel.svg\",\n \"revision\": \"4b4f1876502eb6721764637fe5c41702\"\n }\n], {\n \"ignoreURLParametersMatching\": []\n});\nworkbox_precaching_cleanupOutdatedCaches();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({request, response, event, state}) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, {status: 200, statusText: 'OK', headers: response.headers}); } return response; } }] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.(?:gstatic)\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"google-fonts-webfonts\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 31536000 })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.(?:googleapis)\\.com\\/.*/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"google-fonts-stylesheets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 604800 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-font-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 4, maxAgeSeconds: 604800 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-image-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 64, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\/_next\\/image\\?url=.+$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"next-image\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 64, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:mp3|wav|ogg)$/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"static-audio-assets\", plugins: [new workbox_range_requests_RangeRequestsPlugin(), new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:mp4)$/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"static-video-assets\", plugins: [new workbox_range_requests_RangeRequestsPlugin(), new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:js)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-js-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:css|less)$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"static-style-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\/_next\\/data\\/.+\\/.+\\.json$/i, new workbox_strategies_StaleWhileRevalidate({ \"cacheName\":\"next-data\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(/\\.(?:json|xml|csv)$/i, new workbox_strategies_NetworkFirst({ \"cacheName\":\"static-data-assets\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n if (!isSameOrigin) return false\n const pathname = url.pathname\n // Exclude /api/auth/callback/* to fix OAuth workflow in Safari without impact other environment\n // Above route is default for next-auth, you may need to change it if your OAuth workflow has a different callback route\n // Issue: https://github.com/shadowwalker/next-pwa/issues/131#issuecomment-821894809\n if (pathname.startsWith('/api/auth/')) return false\n if (pathname.startsWith('/api/')) return true\n return false\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"apis\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 16, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n if (!isSameOrigin) return false\n const pathname = url.pathname\n if (pathname.startsWith('/api/')) return false\n return true\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"others\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 86400 })] }), 'GET');\nworkbox_routing_registerRoute(({url}) => {\n const isSameOrigin = self.origin === url.origin\n return !isSameOrigin\n }, new workbox_strategies_NetworkFirst({ \"cacheName\":\"cross-origin\",\"networkTimeoutSeconds\":10, plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 32, maxAgeSeconds: 3600 })] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","async","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_CacheFirst","workbox_expiration_ExpirationPlugin","maxEntries","maxAgeSeconds","workbox_strategies_StaleWhileRevalidate","workbox_range_requests_RangeRequestsPlugin","url","origin","pathname","startsWith"],"mappings":"0yBAqBAA,cACE,mCASFC,KAAKC,kDAU+B,CAClC,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,4DACK,yBAEd,KACS,gEACK,yBAEd,KACS,kEACK,yBAEd,KACS,sEACK,yBAEd,KACS,6DACK,yBAEd,KACS,iEACK,yBAEd,KACS,mEACK,yBAEd,KACS,uEACK,yBAEd,KACS,qEACK,yBAEd,KACS,yEACK,yBAEd,KACS,oEACK,yBAEd,KACS,wEACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,mEACK,yBAEd,KACS,uEACK,yBAEd,KACS,qEACK,yBAEd,KACS,yEACK,yBAEd,KACS,sEACK,yBAEd,KACS,0EACK,yBAEd,KACS,0EACK,yBAEd,KACS,8EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,yEACK,yBAEd,KACS,6EACK,yBAEd,KACS,8EACK,yBAEd,KACS,gEACK,yBAEd,KACS,oEACK,yBAEd,KACS,sDACK,yBAEd,KACS,0DACK,yBAEd,KACS,iEACK,yBAEd,KACS,+DACK,yBAEd,KACS,uCACK,oCAEd,KACS,uCACK,oCAEd,KACS,gDACK,oCAEd,KACS,gDACK,oCAEd,KACS,qDACK,oCAEd,KACS,iCACK,oCAEd,KACS,8BACK,oCAEd,KACS,8BACK,oCAEd,KACS,wBACK,oCAEd,KACS,qBACK,oCAEd,KACS,2BACK,oCAEd,KACS,4BACK,oCAEd,KACS,2BACK,oCAEd,KACS,2BACK,oCAEd,KACS,8BACK,oCAEd,KACS,6BACK,oCAEd,KACS,6BACK,oCAEd,KACS,0BACK,oCAEd,KACS,uBACK,qCAEb,6BAC8B,+CAMH,IAAK,IAAIC,eAAgC,WAAc,YAAaC,QAAS,CAAC,CAAEC,gBAAiBC,OAAQC,QAAAA,EAASC,SAAAA,EAAUC,MAAAA,EAAOC,MAAAA,KAAiBF,GAA8B,mBAAlBA,EAASG,KAAoC,IAAIC,SAASJ,EAASK,KAAM,CAACC,OAAQ,IAAKC,WAAY,KAAMC,QAASR,EAASQ,UAAoBR,MAAmB,uBAClU,0CAA2C,IAAIS,aAA8B,WAAc,wBAAyBb,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,aAAiB,uBACvN,6CAA8C,IAAIC,uBAAwC,WAAc,2BAA4BjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,YAAe,uBACrO,8CAA+C,IAAIC,uBAAwC,WAAc,qBAAsBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,EAAGC,cAAe,YAAe,uBAChO,wCAAyC,IAAIC,uBAAwC,WAAc,sBAAuBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBAC3N,2BAA4B,IAAIC,uBAAwC,WAAc,aAAcjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACrM,sBAAuB,IAAIH,aAA8B,WAAc,sBAAuBb,QAAS,CAAC,IAAIkB,sBAA8C,IAAIJ,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACjP,cAAe,IAAIH,aAA8B,WAAc,sBAAuBb,QAAS,CAAC,IAAIkB,sBAA8C,IAAIJ,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACzO,aAAc,IAAIC,uBAAwC,WAAc,mBAAoBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBAC7L,mBAAoB,IAAIC,uBAAwC,WAAc,sBAAuBjB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACtM,gCAAiC,IAAIC,uBAAwC,WAAc,YAAajB,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,uBACzM,uBAAwB,IAAIjB,eAAgC,WAAc,qBAAsBC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBACjM,EAAEG,IAAAA,WACLtB,KAAKuB,SAAWD,EAAIC,QACtB,OAAO,QACpBC,EAAWF,EAAIE,gBAIjBA,EAASC,WAAW,iBACpBD,EAASC,WAAW,WAEvB,IAAIvB,eAAgC,WAAc,6BAA+B,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBAC/J,EAAEG,IAAAA,WACLtB,KAAKuB,SAAWD,EAAIC,QACtB,OAAO,SACTD,EAAIE,SACRC,WAAW,WAEvB,IAAIvB,eAAgC,WAAc,+BAAiC,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,WAAc,wBACjK,EAAEG,IAAAA,OACLtB,KAAKuB,SAAWD,EAAIC,SAExC,IAAIrB,eAAgC,WAAc,qCAAuC,GAAIC,QAAS,CAAC,IAAIc,mBAAoC,CAAEC,WAAY,GAAIC,cAAe,UAAa"} \ No newline at end of file diff --git a/packages/www/public/worker-NIc7Y9Sxqfi5NjIQO6GQ4.js b/packages/www/public/worker-j4SQSxW4Y5BQ1MYBuhDPd.js similarity index 100% rename from packages/www/public/worker-NIc7Y9Sxqfi5NjIQO6GQ4.js rename to packages/www/public/worker-j4SQSxW4Y5BQ1MYBuhDPd.js