Spaces:
Sleeping
Sleeping
Jon Taylor
commited on
Commit
·
b3de037
1
Parent(s):
71f583a
deps
Browse files- Dockerfile +2 -2
- app/bot.py +16 -11
- frontend/app/components/Call.js +41 -11
- frontend/app/components/CreateRoom.js +42 -1
- frontend/package.json +2 -0
- frontend/tailwind.config.js +1 -1
- frontend/yarn.lock +17 -0
Dockerfile
CHANGED
|
@@ -51,11 +51,11 @@ RUN cd frontend && npm install
|
|
| 51 |
|
| 52 |
# Copy frontend app and build
|
| 53 |
COPY --chown=user frontend/ frontend/
|
| 54 |
-
|
| 55 |
|
| 56 |
# Copy everything else
|
| 57 |
COPY --chown=user app/ app/
|
| 58 |
COPY --chown=user server.py server.py
|
| 59 |
|
| 60 |
-
|
| 61 |
CMD ["python3", "server.py"]
|
|
|
|
| 51 |
|
| 52 |
# Copy frontend app and build
|
| 53 |
COPY --chown=user frontend/ frontend/
|
| 54 |
+
RUN cd frontend && npm run build
|
| 55 |
|
| 56 |
# Copy everything else
|
| 57 |
COPY --chown=user app/ app/
|
| 58 |
COPY --chown=user server.py server.py
|
| 59 |
|
| 60 |
+
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
|
| 61 |
CMD ["python3", "server.py"]
|
app/bot.py
CHANGED
|
@@ -30,13 +30,14 @@ class DailyVision(EventHandler):
|
|
| 30 |
self.__pipeline = Pipeline
|
| 31 |
self.__camera = None
|
| 32 |
self.__time = time.time()
|
| 33 |
-
self.__queue = queue.Queue()
|
| 34 |
self.__app_quit = False
|
| 35 |
self.__image_buffer = None
|
| 36 |
self.__bot_name = bot_name
|
| 37 |
self.__room_url = room_url
|
| 38 |
self.__room_name = room_name
|
| 39 |
self.__expiration = expiration
|
|
|
|
| 40 |
self.__idle = idle
|
| 41 |
|
| 42 |
# Create the pipeline (this might take a moment)
|
|
@@ -101,7 +102,7 @@ class DailyVision(EventHandler):
|
|
| 101 |
})
|
| 102 |
|
| 103 |
def process_frames(self):
|
| 104 |
-
params =
|
| 105 |
|
| 106 |
while not self.__app_quit:
|
| 107 |
# Is anyone watching?
|
|
@@ -114,6 +115,7 @@ class DailyVision(EventHandler):
|
|
| 114 |
self.logger.info(f"Expiration timer exceeded. Exiting...")
|
| 115 |
self.__app_quit = True
|
| 116 |
break
|
|
|
|
| 117 |
try:
|
| 118 |
#video_frame = self.__queue.get(timeout=5)
|
| 119 |
video_frame = self.__image_buffer
|
|
@@ -124,7 +126,8 @@ class DailyVision(EventHandler):
|
|
| 124 |
self.__camera.write_frame(result_image.tobytes())
|
| 125 |
except queue.Empty:
|
| 126 |
pass
|
| 127 |
-
|
|
|
|
| 128 |
def on_video_frame(self, participant_id, video_frame):
|
| 129 |
# Process ~15 frames per second (considering incoming frames at 30fps).
|
| 130 |
if time.time() - self.__time > float(os.getenv("FPS_CAP", 0.0333)):
|
|
@@ -132,16 +135,18 @@ class DailyVision(EventHandler):
|
|
| 132 |
self.__image_buffer = video_frame
|
| 133 |
#self.__queue.put(video_frame)
|
| 134 |
|
| 135 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
self.__client.send_app_message(
|
| 137 |
{
|
| 138 |
-
"
|
| 139 |
-
"reaction": {
|
| 140 |
-
"emoji": emoji,
|
| 141 |
-
"room": "main-room",
|
| 142 |
-
"sessionId": "bot",
|
| 143 |
-
"id": time.time(),
|
| 144 |
-
},
|
| 145 |
}
|
| 146 |
)
|
| 147 |
|
|
|
|
| 30 |
self.__pipeline = Pipeline
|
| 31 |
self.__camera = None
|
| 32 |
self.__time = time.time()
|
| 33 |
+
#self.__queue = queue.Queue()
|
| 34 |
self.__app_quit = False
|
| 35 |
self.__image_buffer = None
|
| 36 |
self.__bot_name = bot_name
|
| 37 |
self.__room_url = room_url
|
| 38 |
self.__room_name = room_name
|
| 39 |
self.__expiration = expiration
|
| 40 |
+
self.__params = Pipeline.InputParams()
|
| 41 |
self.__idle = idle
|
| 42 |
|
| 43 |
# Create the pipeline (this might take a moment)
|
|
|
|
| 102 |
})
|
| 103 |
|
| 104 |
def process_frames(self):
|
| 105 |
+
params = self.__params
|
| 106 |
|
| 107 |
while not self.__app_quit:
|
| 108 |
# Is anyone watching?
|
|
|
|
| 115 |
self.logger.info(f"Expiration timer exceeded. Exiting...")
|
| 116 |
self.__app_quit = True
|
| 117 |
break
|
| 118 |
+
"""
|
| 119 |
try:
|
| 120 |
#video_frame = self.__queue.get(timeout=5)
|
| 121 |
video_frame = self.__image_buffer
|
|
|
|
| 126 |
self.__camera.write_frame(result_image.tobytes())
|
| 127 |
except queue.Empty:
|
| 128 |
pass
|
| 129 |
+
"""
|
| 130 |
+
|
| 131 |
def on_video_frame(self, participant_id, video_frame):
|
| 132 |
# Process ~15 frames per second (considering incoming frames at 30fps).
|
| 133 |
if time.time() - self.__time > float(os.getenv("FPS_CAP", 0.0333)):
|
|
|
|
| 135 |
self.__image_buffer = video_frame
|
| 136 |
#self.__queue.put(video_frame)
|
| 137 |
|
| 138 |
+
def on_app_message(self, message, sender):
|
| 139 |
+
# Update pipeline settings based on message data
|
| 140 |
+
print(message)
|
| 141 |
+
self.__params = self.__pipeline.InputParams(**message)
|
| 142 |
+
print(self.__params)
|
| 143 |
+
#print(self.__pipeline.Info())
|
| 144 |
+
return
|
| 145 |
+
|
| 146 |
+
def wave(self):
|
| 147 |
self.__client.send_app_message(
|
| 148 |
{
|
| 149 |
+
"prompt": self.__params.prompt,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
}
|
| 151 |
)
|
| 152 |
|
frontend/app/components/Call.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
| 1 |
"use client";
|
| 2 |
|
| 3 |
-
import { useCallback, useEffect, useState } from "react";
|
| 4 |
-
import Card from "../components/Card";
|
| 5 |
-
import { VideoCameraIcon, PaintBrushIcon } from "@heroicons/react/24/outline";
|
| 6 |
-
import Avatar from "../components/Avatar";
|
| 7 |
-
import CreateRoom from "../components/CreateRoom";
|
| 8 |
-
import { apiUrl } from "../utils";
|
| 9 |
-
import Join from "../components/Joining";
|
| 10 |
import {
|
| 11 |
DailyVideo,
|
|
|
|
| 12 |
useLocalSessionId,
|
| 13 |
useParticipantIds,
|
| 14 |
} from "@daily-co/daily-react";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
const STATE_IDLE = "idle";
|
| 17 |
const STATE_JOINING = "joining";
|
|
@@ -24,8 +25,13 @@ export default function Call() {
|
|
| 24 |
const [callState, setCallState] = useState(STATE_IDLE);
|
| 25 |
const [roomUrl, setRoomUrl] = useState();
|
| 26 |
const [botState, setBotState] = useState(BOT_STATE_STARTING);
|
|
|
|
|
|
|
| 27 |
const localSessionId = useLocalSessionId();
|
| 28 |
const participantIds = useParticipantIds({ filter: "remote" });
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
const start = useCallback(async () => {
|
| 31 |
const resp = await fetch(`${apiUrl}/start`, {
|
|
@@ -62,11 +68,11 @@ export default function Call() {
|
|
| 62 |
return <Join roomUrl={roomUrl} onJoin={() => setCallState(STATE_JOINED)} />;
|
| 63 |
}
|
| 64 |
|
|
|
|
| 65 |
// Main call loop
|
| 66 |
return (
|
| 67 |
-
<main className="container py-
|
| 68 |
-
|
| 69 |
-
<div className="grid grid-cols-2 grid-flow-col gap-4">
|
| 70 |
<div>
|
| 71 |
<Card headerText="Local Webcam" HeaderIcon={VideoCameraIcon}>
|
| 72 |
<div className="overflow-hidden bg-gray-50 sm:rounded-lg">
|
|
@@ -75,7 +81,31 @@ export default function Call() {
|
|
| 75 |
</div>
|
| 76 |
</div>
|
| 77 |
</Card>
|
| 78 |
-
<div className="relative">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
</div>
|
| 80 |
<div>
|
| 81 |
<Card headerText="Inference" HeaderIcon={PaintBrushIcon}>
|
|
|
|
| 1 |
"use client";
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
import {
|
| 4 |
DailyVideo,
|
| 5 |
+
useAppMessage,
|
| 6 |
useLocalSessionId,
|
| 7 |
useParticipantIds,
|
| 8 |
} from "@daily-co/daily-react";
|
| 9 |
+
import { PaintBrushIcon, VideoCameraIcon } from "@heroicons/react/24/outline";
|
| 10 |
+
import { useCallback, useEffect, useState } from "react";
|
| 11 |
+
import Avatar from "../components/Avatar";
|
| 12 |
+
import Card from "../components/Card";
|
| 13 |
+
import CreateRoom from "../components/CreateRoom";
|
| 14 |
+
import Join from "../components/Joining";
|
| 15 |
+
import { apiUrl } from "../utils";
|
| 16 |
|
| 17 |
const STATE_IDLE = "idle";
|
| 18 |
const STATE_JOINING = "joining";
|
|
|
|
| 25 |
const [callState, setCallState] = useState(STATE_IDLE);
|
| 26 |
const [roomUrl, setRoomUrl] = useState();
|
| 27 |
const [botState, setBotState] = useState(BOT_STATE_STARTING);
|
| 28 |
+
const [params, setParams] = useState({});
|
| 29 |
+
|
| 30 |
const localSessionId = useLocalSessionId();
|
| 31 |
const participantIds = useParticipantIds({ filter: "remote" });
|
| 32 |
+
const sendAppMessage = useAppMessage({
|
| 33 |
+
onAppMessage: useCallback((ev) => setParams(ev.data), []),
|
| 34 |
+
});
|
| 35 |
|
| 36 |
const start = useCallback(async () => {
|
| 37 |
const resp = await fetch(`${apiUrl}/start`, {
|
|
|
|
| 68 |
return <Join roomUrl={roomUrl} onJoin={() => setCallState(STATE_JOINED)} />;
|
| 69 |
}
|
| 70 |
|
| 71 |
+
console.log(params);
|
| 72 |
// Main call loop
|
| 73 |
return (
|
| 74 |
+
<main className="container py-12">
|
| 75 |
+
<div className="grid grid-cols-2 grid-flow-col gap-12">
|
|
|
|
| 76 |
<div>
|
| 77 |
<Card headerText="Local Webcam" HeaderIcon={VideoCameraIcon}>
|
| 78 |
<div className="overflow-hidden bg-gray-50 sm:rounded-lg">
|
|
|
|
| 81 |
</div>
|
| 82 |
</div>
|
| 83 |
</Card>
|
| 84 |
+
<div className="relative">
|
| 85 |
+
<div>
|
| 86 |
+
<label
|
| 87 |
+
htmlFor="comment"
|
| 88 |
+
className="block text-sm font-medium leading-6 text-gray-900"
|
| 89 |
+
>
|
| 90 |
+
Add your comment
|
| 91 |
+
</label>
|
| 92 |
+
<div className="mt-2">
|
| 93 |
+
<textarea
|
| 94 |
+
rows={4}
|
| 95 |
+
name="comment"
|
| 96 |
+
id="comment"
|
| 97 |
+
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
| 98 |
+
defaultValue={params.prompt || ""}
|
| 99 |
+
/>
|
| 100 |
+
</div>
|
| 101 |
+
</div>
|
| 102 |
+
Config - Resolution, Mbps, FPS
|
| 103 |
+
<button
|
| 104 |
+
onClick={() => sendAppMessage({ prompt: "Big ol' car" }, "*")}
|
| 105 |
+
>
|
| 106 |
+
Send test app message
|
| 107 |
+
</button>
|
| 108 |
+
</div>
|
| 109 |
</div>
|
| 110 |
<div>
|
| 111 |
<Card headerText="Inference" HeaderIcon={PaintBrushIcon}>
|
frontend/app/components/CreateRoom.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
| 1 |
-
import { ArrowRightIcon } from "@heroicons/react/20/solid";
|
| 2 |
import { useState } from "react";
|
| 3 |
import { apiUrl } from "../utils";
|
| 4 |
|
| 5 |
export default function CreateRoom({ onCreateRoom }) {
|
| 6 |
const [fetching, setFetching] = useState(false);
|
|
|
|
|
|
|
| 7 |
|
| 8 |
async function create() {
|
| 9 |
setFetching(true);
|
|
@@ -48,6 +50,45 @@ export default function CreateRoom({ onCreateRoom }) {
|
|
| 48 |
<ArrowRightIcon className="-h-5 w-5" aria-hidden="true" />
|
| 49 |
</button>
|
| 50 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
</div>
|
| 52 |
</div>
|
| 53 |
);
|
|
|
|
| 1 |
+
import { ArrowRightIcon, ChevronRightIcon } from "@heroicons/react/20/solid";
|
| 2 |
import { useState } from "react";
|
| 3 |
import { apiUrl } from "../utils";
|
| 4 |
|
| 5 |
export default function CreateRoom({ onCreateRoom }) {
|
| 6 |
const [fetching, setFetching] = useState(false);
|
| 7 |
+
const [roomUrl, setRoomUrl] = useState();
|
| 8 |
+
const [showManual, setShowManual] = useState(false);
|
| 9 |
|
| 10 |
async function create() {
|
| 11 |
setFetching(true);
|
|
|
|
| 50 |
<ArrowRightIcon className="-h-5 w-5" aria-hidden="true" />
|
| 51 |
</button>
|
| 52 |
</div>
|
| 53 |
+
|
| 54 |
+
<hr className="my-6" />
|
| 55 |
+
|
| 56 |
+
<div
|
| 57 |
+
className="inline-flex text-sm text-gray-500 cursor-pointer"
|
| 58 |
+
onClick={() => setShowManual(!showManual)}
|
| 59 |
+
>
|
| 60 |
+
Join an existing room
|
| 61 |
+
<ChevronRightIcon
|
| 62 |
+
className={`w-5 h-5 text-gray-300 transition-transform ${
|
| 63 |
+
showManual && "rotate-90"
|
| 64 |
+
}`}
|
| 65 |
+
/>
|
| 66 |
+
</div>
|
| 67 |
+
|
| 68 |
+
{showManual && (
|
| 69 |
+
<div className="mt-5 sm:flex sm:items-center">
|
| 70 |
+
<div className="w-full">
|
| 71 |
+
<label htmlFor="room" className="sr-only">
|
| 72 |
+
Daily Room URL
|
| 73 |
+
</label>
|
| 74 |
+
<input
|
| 75 |
+
type="text"
|
| 76 |
+
name="room"
|
| 77 |
+
id="room"
|
| 78 |
+
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
| 79 |
+
placeholder="https://..."
|
| 80 |
+
onChange={(e) => setRoomUrl(e.target.value)}
|
| 81 |
+
/>
|
| 82 |
+
</div>
|
| 83 |
+
<button
|
| 84 |
+
type="submit"
|
| 85 |
+
onClick={() => onCreateRoom(roomUrl)}
|
| 86 |
+
className="mt-3 inline-flex w-full items-center justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 sm:ml-3 sm:mt-0 sm:w-auto"
|
| 87 |
+
>
|
| 88 |
+
Join
|
| 89 |
+
</button>
|
| 90 |
+
</div>
|
| 91 |
+
)}
|
| 92 |
</div>
|
| 93 |
</div>
|
| 94 |
);
|
frontend/package.json
CHANGED
|
@@ -14,11 +14,13 @@
|
|
| 14 |
"@headlessui/react": "^1.7.17",
|
| 15 |
"@heroicons/react": "^2.0.18",
|
| 16 |
"next": "14.0.3",
|
|
|
|
| 17 |
"react": "^18",
|
| 18 |
"react-dom": "^18",
|
| 19 |
"recoil": "^0.7.7"
|
| 20 |
},
|
| 21 |
"devDependencies": {
|
|
|
|
| 22 |
"autoprefixer": "^10.0.1",
|
| 23 |
"eslint": "^8",
|
| 24 |
"eslint-config-next": "14.0.3",
|
|
|
|
| 14 |
"@headlessui/react": "^1.7.17",
|
| 15 |
"@heroicons/react": "^2.0.18",
|
| 16 |
"next": "14.0.3",
|
| 17 |
+
"nextjs": "^0.0.3",
|
| 18 |
"react": "^18",
|
| 19 |
"react-dom": "^18",
|
| 20 |
"recoil": "^0.7.7"
|
| 21 |
},
|
| 22 |
"devDependencies": {
|
| 23 |
+
"@tailwindcss/forms": "^0.5.7",
|
| 24 |
"autoprefixer": "^10.0.1",
|
| 25 |
"eslint": "^8",
|
| 26 |
"eslint-config-next": "14.0.3",
|
frontend/tailwind.config.js
CHANGED
|
@@ -24,5 +24,5 @@ module.exports = {
|
|
| 24 |
},
|
| 25 |
},
|
| 26 |
},
|
| 27 |
-
plugins: [],
|
| 28 |
};
|
|
|
|
| 24 |
},
|
| 25 |
},
|
| 26 |
},
|
| 27 |
+
plugins: [require("@tailwindcss/forms")],
|
| 28 |
};
|
frontend/yarn.lock
CHANGED
|
@@ -285,6 +285,13 @@
|
|
| 285 |
dependencies:
|
| 286 |
tslib "^2.4.0"
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
"@types/json5@^0.0.29":
|
| 289 |
version "0.0.29"
|
| 290 |
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
|
@@ -1721,6 +1728,11 @@ micromatch@^4.0.4, micromatch@^4.0.5:
|
|
| 1721 |
braces "^3.0.2"
|
| 1722 |
picomatch "^2.3.1"
|
| 1723 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1724 |
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
| 1725 |
version "3.1.2"
|
| 1726 |
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
|
@@ -1785,6 +1797,11 @@ next@14.0.3:
|
|
| 1785 |
"@next/swc-win32-ia32-msvc" "14.0.3"
|
| 1786 |
"@next/swc-win32-x64-msvc" "14.0.3"
|
| 1787 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1788 |
node-releases@^2.0.14:
|
| 1789 |
version "2.0.14"
|
| 1790 |
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
|
|
|
|
| 285 |
dependencies:
|
| 286 |
tslib "^2.4.0"
|
| 287 |
|
| 288 |
+
"@tailwindcss/forms@^0.5.7":
|
| 289 |
+
version "0.5.7"
|
| 290 |
+
resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.7.tgz#db5421f062a757b5f828bc9286ba626c6685e821"
|
| 291 |
+
integrity sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==
|
| 292 |
+
dependencies:
|
| 293 |
+
mini-svg-data-uri "^1.2.3"
|
| 294 |
+
|
| 295 |
"@types/json5@^0.0.29":
|
| 296 |
version "0.0.29"
|
| 297 |
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
|
|
|
| 1728 |
braces "^3.0.2"
|
| 1729 |
picomatch "^2.3.1"
|
| 1730 |
|
| 1731 |
+
mini-svg-data-uri@^1.2.3:
|
| 1732 |
+
version "1.4.4"
|
| 1733 |
+
resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
|
| 1734 |
+
integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
|
| 1735 |
+
|
| 1736 |
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
| 1737 |
version "3.1.2"
|
| 1738 |
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
|
|
|
| 1797 |
"@next/swc-win32-ia32-msvc" "14.0.3"
|
| 1798 |
"@next/swc-win32-x64-msvc" "14.0.3"
|
| 1799 |
|
| 1800 |
+
nextjs@^0.0.3:
|
| 1801 |
+
version "0.0.3"
|
| 1802 |
+
resolved "https://registry.yarnpkg.com/nextjs/-/nextjs-0.0.3.tgz#4f4d1d6a257be920d9b9649d4d9522c724a4e543"
|
| 1803 |
+
integrity sha512-mYbDUo4/sRAZ8TqK63PCpYnFiLg7BICG/ot9+guOrUKd4/Fo71ZmEQ41IZbH6nqbQvG7SXTBuofJXAIWfNho0w==
|
| 1804 |
+
|
| 1805 |
node-releases@^2.0.14:
|
| 1806 |
version "2.0.14"
|
| 1807 |
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
|