Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
sam2_pytorch
Commits
3af09475
Commit
3af09475
authored
Dec 05, 2025
by
luopl
Browse files
"Initial commit"
parents
Pipeline
#3140
canceled with stages
Changes
585
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1469 additions
and
0 deletions
+1469
-0
demo/frontend/src/main.tsx
demo/frontend/src/main.tsx
+24
-0
demo/frontend/src/routes/DemoPage.tsx
demo/frontend/src/routes/DemoPage.tsx
+65
-0
demo/frontend/src/routes/DemoPageWrapper.tsx
demo/frontend/src/routes/DemoPageWrapper.tsx
+87
-0
demo/frontend/src/routes/PageNotFoundPage.tsx
demo/frontend/src/routes/PageNotFoundPage.tsx
+29
-0
demo/frontend/src/routes/__generated__/DemoPageQuery.graphql.ts
...rontend/src/routes/__generated__/DemoPageQuery.graphql.ts
+114
-0
demo/frontend/src/settings/ApprovableInput.tsx
demo/frontend/src/settings/ApprovableInput.tsx
+119
-0
demo/frontend/src/settings/SAM2Settings.tsx
demo/frontend/src/settings/SAM2Settings.tsx
+39
-0
demo/frontend/src/settings/SettingsContextProvider.tsx
demo/frontend/src/settings/SettingsContextProvider.tsx
+97
-0
demo/frontend/src/settings/SettingsModal.tsx
demo/frontend/src/settings/SettingsModal.tsx
+95
-0
demo/frontend/src/settings/SettingsReducer.ts
demo/frontend/src/settings/SettingsReducer.ts
+70
-0
demo/frontend/src/settings/useSettingsContext.tsx
demo/frontend/src/settings/useSettingsContext.tsx
+21
-0
demo/frontend/src/theme/colors.ts
demo/frontend/src/theme/colors.ts
+26
-0
demo/frontend/src/theme/gradientStyle.ts
demo/frontend/src/theme/gradientStyle.ts
+18
-0
demo/frontend/src/theme/tokens.stylex.ts
demo/frontend/src/theme/tokens.stylex.ts
+116
-0
demo/frontend/src/types/mp4box/index.d.ts
demo/frontend/src/types/mp4box/index.d.ts
+283
-0
demo/frontend/src/vite-env.d.ts
demo/frontend/src/vite-env.d.ts
+16
-0
demo/frontend/tailwind.config.js
demo/frontend/tailwind.config.js
+132
-0
demo/frontend/tsconfig.json
demo/frontend/tsconfig.json
+47
-0
demo/frontend/tsconfig.node.json
demo/frontend/tsconfig.node.json
+27
-0
demo/frontend/vite.config.ts
demo/frontend/vite.config.ts
+44
-0
No files found.
demo/frontend/src/main.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
App
from
'
@/App.tsx
'
;
import
*
as
React
from
'
react
'
;
import
*
as
ReactDOM
from
'
react-dom/client
'
;
ReactDOM
.
createRoot
(
document
.
getElementById
(
'
root
'
)
!
).
render
(
<
React
.
StrictMode
>
<
App
/>
</
React
.
StrictMode
>,
);
demo/frontend/src/routes/DemoPage.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
Toolbar
from
'
@/common/components/toolbar/Toolbar
'
;
import
DemoVideoEditor
from
'
@/common/components/video/editor/DemoVideoEditor
'
;
import
useInputVideo
from
'
@/common/components/video/useInputVideo
'
;
import
StatsView
from
'
@/debug/stats/StatsView
'
;
import
{
VideoData
}
from
'
@/demo/atoms
'
;
import
DemoPageLayout
from
'
@/layouts/DemoPageLayout
'
;
import
{
DemoPageQuery
}
from
'
@/routes/__generated__/DemoPageQuery.graphql
'
;
import
{
useEffect
,
useMemo
}
from
'
react
'
;
import
{
graphql
,
useLazyLoadQuery
}
from
'
react-relay
'
;
import
{
Location
,
useLocation
}
from
'
react-router-dom
'
;
type
LocationState
=
{
video
?:
VideoData
;
};
export
default
function
DemoPage
()
{
const
{
state
}
=
useLocation
()
as
Location
<
LocationState
>
;
const
data
=
useLazyLoadQuery
<
DemoPageQuery
>
(
graphql
`
query DemoPageQuery {
defaultVideo {
path
posterPath
url
posterUrl
height
width
}
}
`
,
{},
);
const
{
setInputVideo
}
=
useInputVideo
();
const
video
=
useMemo
(()
=>
{
return
state
?.
video
??
data
.
defaultVideo
;
},
[
state
,
data
]);
useEffect
(()
=>
{
setInputVideo
(
video
);
},
[
video
,
setInputVideo
]);
return
(
<
DemoPageLayout
>
<
StatsView
/>
<
Toolbar
/>
<
DemoVideoEditor
video
=
{
video
}
/>
</
DemoPageLayout
>
);
}
demo/frontend/src/routes/DemoPageWrapper.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
LoadingStateScreen
from
'
@/common/loading/LoadingStateScreen
'
;
import
DemoPage
from
'
@/routes/DemoPage
'
;
import
stylex
from
'
@stylexjs/stylex
'
;
import
{
isFirefox
}
from
'
react-device-detect
'
;
const
styles
=
stylex
.
create
({
link
:
{
textDecorationLine
:
'
underline
'
,
color
:
'
#A7B3BF
'
,
},
});
const
REQUIRED_WINDOW_APIS
=
[
'
VideoEncoder
'
,
'
VideoDecoder
'
,
'
VideoFrame
'
];
function
isBrowserSupported
()
{
for
(
const
api
of
REQUIRED_WINDOW_APIS
)
{
if
(
!
(
api
in
window
))
{
return
false
;
}
}
// Test if transferControlToOffscreen is supported. For example, this will
// fail on iOS version < 16.4
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/transferControlToOffscreen
const
canvas
=
document
.
createElement
(
'
canvas
'
);
if
(
typeof
canvas
.
transferControlToOffscreen
!==
'
function
'
)
{
return
false
;
}
return
true
;
}
export
default
function
DemoPageWrapper
()
{
const
isBrowserUnsupported
=
!
isBrowserSupported
();
if
(
isBrowserUnsupported
&&
isFirefox
)
{
const
nightlyUrl
=
'
https://wiki.mozilla.org/Nightly
'
;
return
(
<
LoadingStateScreen
title
=
"Sorry Firefox!"
description
=
{
<
div
>
This version of Firefox doesn’t support the video features we’ll
need to run this demo. You can either update Firefox to the latest
nightly build
{
'
'
}
<
a
{
...
stylex
.
props
(
styles
.
link
)
}
href
=
{
nightlyUrl
}
target
=
"_blank"
rel
=
"noreferrer"
>
here
</
a
>
, or try again using Chrome or Safari.
</
div
>
}
linkProps
=
{
{
to
:
'
..
'
,
label
:
'
Back to homepage
'
}
}
/>
);
}
if
(
isBrowserUnsupported
)
{
return
(
<
LoadingStateScreen
title
=
"Uh oh, this browser isn’t supported."
description
=
"This browser doesn’t support the video features we’ll need to run this demo. Try again using Chrome, Safari, or Firefox Nightly."
linkProps
=
{
{
to
:
'
..
'
,
label
:
'
Back to homepage
'
}
}
/>
);
}
return
<
DemoPage
/>;
}
demo/frontend/src/routes/PageNotFoundPage.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
LoadingStateScreen
from
'
@/common/loading/LoadingStateScreen
'
;
export
default
function
PageNotFoundPage
()
{
return
(
<
LoadingStateScreen
title
=
"Page not found"
description
=
"It looks like you might be in the wrong place."
linkProps
=
{
{
to
:
'
..
'
,
label
:
'
Click here to access the SAM 2 Demo
'
,
}
}
/>
);
}
demo/frontend/src/routes/__generated__/DemoPageQuery.graphql.ts
0 → 100644
View file @
3af09475
/**
* @generated SignedSource<<f457eacd20a61cba601921caee2a18f5>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import
{
ConcreteRequest
,
Query
}
from
'
relay-runtime
'
;
export
type
DemoPageQuery$variables
=
Record
<
PropertyKey
,
never
>
;
export
type
DemoPageQuery$data
=
{
readonly
defaultVideo
:
{
readonly
height
:
number
;
readonly
path
:
string
;
readonly
posterPath
:
string
|
null
|
undefined
;
readonly
posterUrl
:
string
;
readonly
url
:
string
;
readonly
width
:
number
;
};
};
export
type
DemoPageQuery
=
{
response
:
DemoPageQuery$data
;
variables
:
DemoPageQuery$variables
;
};
const
node
:
ConcreteRequest
=
(
function
(){
var
v0
=
[
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
concreteType
"
:
"
Video
"
,
"
kind
"
:
"
LinkedField
"
,
"
name
"
:
"
defaultVideo
"
,
"
plural
"
:
false
,
"
selections
"
:
[
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
path
"
,
"
storageKey
"
:
null
},
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
posterPath
"
,
"
storageKey
"
:
null
},
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
url
"
,
"
storageKey
"
:
null
},
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
posterUrl
"
,
"
storageKey
"
:
null
},
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
height
"
,
"
storageKey
"
:
null
},
{
"
alias
"
:
null
,
"
args
"
:
null
,
"
kind
"
:
"
ScalarField
"
,
"
name
"
:
"
width
"
,
"
storageKey
"
:
null
}
],
"
storageKey
"
:
null
}
];
return
{
"
fragment
"
:
{
"
argumentDefinitions
"
:
[],
"
kind
"
:
"
Fragment
"
,
"
metadata
"
:
null
,
"
name
"
:
"
DemoPageQuery
"
,
"
selections
"
:
(
v0
/*: any*/
),
"
type
"
:
"
Query
"
,
"
abstractKey
"
:
null
},
"
kind
"
:
"
Request
"
,
"
operation
"
:
{
"
argumentDefinitions
"
:
[],
"
kind
"
:
"
Operation
"
,
"
name
"
:
"
DemoPageQuery
"
,
"
selections
"
:
(
v0
/*: any*/
)
},
"
params
"
:
{
"
cacheID
"
:
"
71cbafce4d2d047acdc54d86504f2d2e
"
,
"
id
"
:
null
,
"
metadata
"
:
{},
"
name
"
:
"
DemoPageQuery
"
,
"
operationKind
"
:
"
query
"
,
"
text
"
:
"
query DemoPageQuery {
\n
defaultVideo {
\n
path
\n
posterPath
\n
url
\n
posterUrl
\n
height
\n
width
\n
}
\n
}
\n
"
}
};
})();
(
node
as
any
).
hash
=
"
63c9465d78b30d42d6fc11e50a9af142
"
;
export
default
node
;
demo/frontend/src/settings/ApprovableInput.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
Tooltip
from
'
@/common/components/Tooltip
'
;
import
{
ArrowPathIcon
,
CheckIcon
,
XMarkIcon
}
from
'
@heroicons/react/24/solid
'
;
import
{
ChangeEvent
,
KeyboardEvent
,
useEffect
,
useMemo
,
useState
}
from
'
react
'
;
import
{
Button
,
Form
,
Input
,
Join
}
from
'
react-daisyui
'
;
type
Props
<
T
extends
string
|
number
>
=
Omit
<
React
.
InputHTMLAttributes
<
HTMLInputElement
>
,
'
size
'
|
'
color
'
|
'
onChange
'
>
&
{
label
:
string
;
defaultValue
:
T
;
initialValue
:
T
;
onChange
:
(
value
:
string
)
=>
void
;
};
function
getStep
(
value
:
number
)
{
const
stringValue
=
String
(
value
);
const
decimals
=
stringValue
.
split
(
'
.
'
)[
1
];
if
(
decimals
!=
null
)
{
// Not using 0.1 ** decimals.length because this will result in rounding
// errors, e.g., 0.1 ** 2 => 0.010000000000000002.
return
1
/
10
**
decimals
.
length
;
}
return
1
;
}
export
default
function
ApprovableInput
<
T
extends
string
|
number
>
({
label
,
defaultValue
,
initialValue
,
onChange
,
...
otherProps
}:
Props
<
T
>
)
{
const
[
value
,
setValue
]
=
useState
<
string
>
(
`
${
initialValue
}
`
);
useEffect
(()
=>
{
setValue
(
`
${
initialValue
}
`
);
},
[
initialValue
]);
const
step
=
useMemo
(()
=>
{
return
typeof
defaultValue
===
'
number
'
&&
isFinite
(
defaultValue
)
?
getStep
(
defaultValue
)
:
undefined
;
},
[
defaultValue
]);
return
(
<
div
>
<
Form
.
Label
className
=
"flex-col items-start gap-2"
title
=
{
label
}
>
<
Join
className
=
"w-full"
>
<
Input
{
...
otherProps
}
className
=
"w-full join-item"
value
=
{
value
}
step
=
{
step
}
placeholder
=
{
`
${
defaultValue
}
`
}
onChange
=
{
(
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
setValue
(
event
.
target
.
value
);
}
}
onKeyDown
=
{
(
event
:
KeyboardEvent
<
HTMLInputElement
>
)
=>
{
if
(
event
.
key
===
'
Enter
'
)
{
event
.
preventDefault
();
onChange
(
value
);
}
}
}
/>
<
Tooltip
message
=
"Reset to default"
>
<
Button
className
=
"join-item"
onClick
=
{
event
=>
{
event
.
preventDefault
();
setValue
(
`
${
defaultValue
}
`
);
}
}
>
<
ArrowPathIcon
className
=
"h-4 w-4"
/>
</
Button
>
</
Tooltip
>
<
Tooltip
message
=
"Revert change"
>
<
Button
className
=
"join-item"
color
=
"neutral"
disabled
=
{
initialValue
==
value
}
onClick
=
{
event
=>
{
event
.
preventDefault
();
setValue
(
`
${
initialValue
}
`
);
}
}
>
<
XMarkIcon
className
=
"h-4 w-4"
/>
</
Button
>
</
Tooltip
>
<
Tooltip
message
=
"Apply change"
>
<
Button
className
=
"join-item"
color
=
"primary"
disabled
=
{
initialValue
==
value
}
onClick
=
{
event
=>
{
event
.
preventDefault
();
onChange
(
value
);
}
}
>
<
CheckIcon
className
=
"h-4 w-4"
/>
</
Button
>
</
Tooltip
>
</
Join
>
</
Form
.
Label
>
</
div
>
);
}
demo/frontend/src/settings/SAM2Settings.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
{
INFERENCE_API_ENDPOINT
,
VIDEO_API_ENDPOINT
}
from
'
@/demo/DemoConfig
'
;
import
ApprovableInput
from
'
@/settings/ApprovableInput
'
;
import
useSettingsContext
from
'
@/settings/useSettingsContext
'
;
export
default
function
SAMVSettings
()
{
const
{
settings
,
dispatch
}
=
useSettingsContext
();
return
(
<
div
>
<
ApprovableInput
label
=
"Video API Endpoint"
defaultValue
=
{
VIDEO_API_ENDPOINT
}
initialValue
=
{
settings
.
videoAPIEndpoint
}
onChange
=
{
url
=>
dispatch
({
type
:
'
change-video-api-endpoint
'
,
url
})
}
/>
<
ApprovableInput
label
=
"Inference API Endpoint"
defaultValue
=
{
INFERENCE_API_ENDPOINT
}
initialValue
=
{
settings
.
inferenceAPIEndpoint
}
onChange
=
{
url
=>
dispatch
({
type
:
'
change-inference-api-endpoint
'
,
url
})
}
/>
</
div
>
);
}
demo/frontend/src/settings/SettingsContextProvider.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
emptyFunction
from
'
@/common/utils/emptyFunction
'
;
import
{
INFERENCE_API_ENDPOINT
,
VIDEO_API_ENDPOINT
}
from
'
@/demo/DemoConfig
'
;
import
SettingsModal
from
'
@/settings/SettingsModal
'
;
import
{
Action
,
DEFAULT_SETTINGS
,
Settings
,
settingsReducer
,
}
from
'
@/settings/SettingsReducer
'
;
import
{
PropsWithChildren
,
createContext
,
useCallback
,
useMemo
,
useRef
,
}
from
'
react
'
;
import
{
useImmerReducer
}
from
'
use-immer
'
;
type
ContextProps
=
{
settings
:
Settings
;
dispatch
:
React
.
Dispatch
<
Action
>
;
openModal
:
()
=>
void
;
closeModal
:
()
=>
void
;
hasChanged
:
boolean
;
};
export
const
SettingsContext
=
createContext
<
ContextProps
>
({
settings
:
DEFAULT_SETTINGS
,
dispatch
:
emptyFunction
,
openModal
:
emptyFunction
,
closeModal
:
emptyFunction
,
hasChanged
:
false
,
});
type
Props
=
PropsWithChildren
;
export
default
function
SettingsContextProvider
({
children
}:
Props
)
{
const
[
state
,
dispatch
]
=
useImmerReducer
(
settingsReducer
,
DEFAULT_SETTINGS
,
settings
=>
{
// Load the settings from local storage. Eventually use the reducer init
// to handle initial loading.
return
settingsReducer
(
settings
,
{
type
:
'
load-state
'
});
},
);
const
modalRef
=
useRef
<
HTMLDialogElement
>
(
null
);
const
openModal
=
useCallback
(()
=>
{
modalRef
.
current
?.
showModal
();
},
[
modalRef
]);
const
handleCloseModal
=
useCallback
(()
=>
{
modalRef
.
current
?.
close
();
},
[
modalRef
]);
const
hasChanged
=
useMemo
(()
=>
{
return
(
VIDEO_API_ENDPOINT
!==
state
.
videoAPIEndpoint
||
INFERENCE_API_ENDPOINT
!==
state
.
inferenceAPIEndpoint
);
},
[
state
.
videoAPIEndpoint
,
state
.
inferenceAPIEndpoint
]);
const
value
=
useMemo
(
()
=>
({
settings
:
state
,
dispatch
,
openModal
,
closeModal
:
handleCloseModal
,
hasChanged
,
}),
[
state
,
dispatch
,
openModal
,
handleCloseModal
,
hasChanged
],
);
return
(
<
SettingsContext
.
Provider
value
=
{
value
}
>
{
children
}
<
SettingsModal
ref
=
{
modalRef
}
/>
</
SettingsContext
.
Provider
>
);
}
demo/frontend/src/settings/SettingsModal.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
{
DEMO_FRIENDLY_NAME
}
from
'
@/demo/DemoConfig
'
;
import
SAM2Settings
from
'
@/settings/SAM2Settings
'
;
import
{
XMarkIcon
}
from
'
@heroicons/react/24/solid
'
;
import
{
forwardRef
,
useState
}
from
'
react
'
;
import
{
Button
,
Modal
}
from
'
react-daisyui
'
;
import
useSettingsContext
from
'
./useSettingsContext
'
;
type
Props
=
unknown
;
type
Config
=
{
key
:
'
sam2
'
;
title
:
string
;
component
:
React
.
ElementType
;
};
const
SettingsConfig
:
Config
[]
=
[
{
key
:
'
sam2
'
,
title
:
DEMO_FRIENDLY_NAME
,
component
:
SAM2Settings
,
},
];
export
default
forwardRef
<
HTMLDialogElement
,
Props
>
(
function
SettingsModal
(
_props
,
ref
)
{
const
{
closeModal
}
=
useSettingsContext
();
const
[
activeConfig
,
setActiveConfig
]
=
useState
<
Config
>
(
SettingsConfig
[
0
]);
const
SettingsComponent
=
activeConfig
.
component
;
return
(
<
Modal
data
-
testid
=
"settings-modal"
ref
=
{
ref
}
className
=
"lg:absolute lg:top-10 lg:w-11/12 lg:max-w-4xl flex flex-col"
responsive
=
{
true
}
>
<
Button
size
=
"sm"
color
=
"ghost"
shape
=
"circle"
className
=
"absolute right-2 top-2"
startIcon
=
{
<
XMarkIcon
className
=
"w-6 h-6"
/>
}
onClick
=
{
closeModal
}
/>
<
Modal
.
Header
className
=
"font-bold"
>
Settings
</
Modal
.
Header
>
<
Modal
.
Body
className
=
"flex flex-col grow overflow-hidden"
>
<
div
className
=
"flex flex-col md:lg:flex-row gap-4 md:lg:gap-12 overflow-hidden"
>
<
div
className
=
"flex flex-row shrink-0 md:lg:flex-col gap-4 md:lg:py-2 overflow-x-auto"
>
{
SettingsConfig
.
map
(
config
=>
(
<
div
key
=
{
config
.
key
}
data
-
testid
=
{
`show-settings-
${
config
.
key
}
`
}
className
=
{
`cursor-pointer whitespace-nowrap
${
activeConfig
.
key
===
config
.
key
&&
'
text-primary
'
}
${
activeConfig
.
key
===
config
.
key
&&
'
sm:underline md:lg:no-underline sm:underline-offset-4
'
}
`
}
onClick
=
{
()
=>
setActiveConfig
(
config
)
}
>
{
config
.
title
}
</
div
>
))
}
</
div
>
<
div
data
-
testid
=
{
`settings-
${
activeConfig
.
key
}
`
}
className
=
"overflow-hidden overflow-y-auto grow md:lg:pt-2"
>
<
div
className
=
"flex flex-col grow-0 flex-1"
>
<
h1
className
=
"hidden md:lg:block"
>
{
activeConfig
.
title
}
</
h1
>
<
SettingsComponent
/>
</
div
>
</
div
>
</
div
>
</
Modal
.
Body
>
<
Modal
.
Actions
className
=
"shrink-0"
>
<
Button
onClick
=
{
closeModal
}
>
Close
</
Button
>
</
Modal
.
Actions
>
</
Modal
>
);
},
);
demo/frontend/src/settings/SettingsReducer.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
{
INFERENCE_API_ENDPOINT
,
VIDEO_API_ENDPOINT
}
from
'
@/demo/DemoConfig
'
;
export
type
Settings
=
{
videoAPIEndpoint
:
string
;
inferenceAPIEndpoint
:
string
;
};
// Key used to store the settings in the browser's local storage.
export
const
SAM2_SETTINGS_KEY
=
'
SAM2_SETTINGS_KEY
'
;
export
type
Action
=
|
{
type
:
'
load-state
'
}
|
{
type
:
'
change-video-api-endpoint
'
;
url
:
string
}
|
{
type
:
'
change-inference-api-endpoint
'
;
url
:
string
};
export
const
DEFAULT_SETTINGS
:
Settings
=
{
videoAPIEndpoint
:
VIDEO_API_ENDPOINT
,
inferenceAPIEndpoint
:
INFERENCE_API_ENDPOINT
,
};
export
function
settingsReducer
(
state
:
Settings
,
action
:
Action
):
Settings
{
function
storeSettings
(
newState
:
Settings
):
void
{
localStorage
.
setItem
(
SAM2_SETTINGS_KEY
,
JSON
.
stringify
(
newState
));
}
switch
(
action
.
type
)
{
case
'
load-state
'
:
{
try
{
const
serializedSettings
=
localStorage
.
getItem
(
SAM2_SETTINGS_KEY
);
if
(
serializedSettings
!=
null
)
{
return
JSON
.
parse
(
serializedSettings
)
as
Settings
;
}
else
{
// Store default settings in local storage. This will populate the
// settings in the local storage on first app load or when user
// cleared the browser cache.
storeSettings
(
state
);
}
}
catch
{
// Could not parse settings. Using default settings instead.
}
return
state
;
}
case
'
change-video-api-endpoint
'
:
state
.
videoAPIEndpoint
=
action
.
url
;
break
;
case
'
change-inference-api-endpoint
'
:
state
.
inferenceAPIEndpoint
=
action
.
url
;
break
;
}
// Store the settings state on every change
storeSettings
(
state
);
return
state
;
}
demo/frontend/src/settings/useSettingsContext.tsx
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
{
useContext
}
from
'
react
'
;
import
{
SettingsContext
}
from
'
@/settings/SettingsContextProvider
'
;
export
default
function
useSettingsContext
()
{
return
useContext
(
SettingsContext
);
}
demo/frontend/src/theme/colors.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export
const
THEME_COLORS
=
[
'
#3880F3
'
,
'
#F0AA19
'
,
'
#00D2BE
'
,
'
#28D232
'
,
'
#8773FF
'
,
'
#00C8F0
'
,
'
#FA8719
'
,
'
#E6193B
'
,
'
#FA7DC8
'
,
];
demo/frontend/src/theme/gradientStyle.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export
const
BLUE_PINK_FILL
=
'
from-[#595FEF] from-40% to-[#FB73A5]
'
;
export
const
BLUE_PINK_FILL_BR
=
'
bg-gradient-to-br from-[#595FEF] from-30% to-[#FB73A5]
'
;
demo/frontend/src/theme/tokens.stylex.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
*
as
stylex
from
'
@stylexjs/stylex
'
;
export
const
spacing
=
stylex
.
defineVars
({
'
0
'
:
'
0rem
'
,
'
0.5
'
:
'
0.125rem
'
,
'
1
'
:
'
0.25rem
'
,
'
1.5
'
:
'
0.375rem
'
,
'
2
'
:
'
0.5rem
'
,
'
2.5
'
:
'
0.625rem
'
,
'
3
'
:
'
0.75rem
'
,
'
3.5
'
:
'
0.875rem
'
,
'
4
'
:
'
1rem
'
,
'
5
'
:
'
1.25rem
'
,
'
6
'
:
'
1.5rem
'
,
'
7
'
:
'
1.75rem
'
,
'
8
'
:
'
2rem
'
,
'
9
'
:
'
2.25rem
'
,
'
10
'
:
'
2.5rem
'
,
'
11
'
:
'
2.75rem
'
,
'
12
'
:
'
3rem
'
,
});
export
const
gap
=
stylex
.
defineVars
({
4
:
'
1rem
'
/* 16px */
,
});
export
const
w
=
stylex
.
defineVars
({
full
:
'
100%
'
,
12
:
'
3rem
'
/* 48px */
,
96
:
'
24rem
'
/* 384px */
,
});
export
const
m
=
stylex
.
defineVars
({
3
:
'
0.75rem
'
/* 12px */
,
});
export
const
fontSize
=
stylex
.
defineVars
({
xs
:
'
0.75rem
'
,
sm
:
'
0.875rem
'
,
base
:
'
1rem
'
,
lg
:
'
1.125rem
'
,
xl
:
'
1.25rem
'
,
'
2xl
'
:
'
1.5rem
'
,
});
export
const
fontWeight
=
stylex
.
defineVars
({
thin
:
100
,
extralight
:
200
,
light
:
300
,
normal
:
400
,
medium
:
500
,
semibold
:
600
,
bold
:
700
,
extrabold
:
800
,
});
export
const
color
=
stylex
.
defineVars
({
subtitle
:
'
rgb(107 114 128)
'
,
'
gray-900
'
:
'
rgb(17 24 39)
'
,
'
gray-800
'
:
'
rgb(26 28 31)
'
,
'
gray-700
'
:
'
rgb(55 62 65)
'
,
'
blue-600
'
:
'
rgb(37 99 235)
'
,
});
export
const
screenSizes
=
{
sm
:
640
,
md
:
768
,
lg
:
1024
,
xl
:
1280
,
'
2xl
'
:
1536
,
};
export
const
borderRadius
=
stylex
.
defineVars
({
sm
:
'
0.125rem
'
,
md
:
'
0.375rem
'
,
lg
:
'
0.5rem
'
,
xl
:
'
0.75rem
'
,
});
export
const
top
=
stylex
.
defineVars
({
0
:
0
,
1
:
'
0.25rem
'
/* 4px */
,
2
:
'
0.5rem
'
/* 8px */
,
});
export
const
right
=
stylex
.
defineVars
({
0
:
0
,
1
:
'
0.25rem
'
/* 4px */
,
2
:
'
0.5rem
'
/* 8px */
,
});
export
const
gradients
=
stylex
.
defineVars
({
rainbow
:
'
linear-gradient(#000, #000) padding-box, linear-gradient(to right bottom, #FB73A5,#595FEF,#94EAE2,#FCCB6B) border-box
'
,
rainbowReverse
:
'
linear-gradient(#000, #000) padding-box, linear-gradient(to left top, #FB73A5,#595FEF,#94EAE2,#FCCB6B) border-box
'
,
yellowTeal
:
'
linear-gradient(#000, #000) padding-box, linear-gradient(to right bottom, #94EAE2,#FCCB6B) border-box
'
,
});
demo/frontend/src/types/mp4box/index.d.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare
module
'
mp4box
'
{
export
interface
MP4MediaTrackEdit
{
media_rate_fraction
:
number
;
media_rate_integer
:
number
;
media_time
:
number
;
segment_duration
:
number
;
}
export
interface
MP4MediaTrack
{
id
:
number
;
created
:
Date
;
modified
:
Date
;
movie_duration
:
number
;
movie_timescale
:
number
;
layer
:
number
;
alternate_group
:
number
;
volume
:
number
;
track_width
:
number
;
track_height
:
number
;
timescale
:
number
;
duration
:
number
;
bitrate
:
number
;
codec
:
string
;
language
:
string
;
nb_samples
:
number
;
samples_duration
:
number
;
edits
:
MP4MediaTrackEdit
[];
}
export
interface
MP4VideoData
{
width
:
number
;
height
:
number
;
}
export
interface
MP4VideoTrack
extends
MP4MediaTrack
{
video
:
MP4VideoData
;
}
export
interface
MP4AudioData
{
sample_rate
:
number
;
channel_count
:
number
;
sample_size
:
number
;
}
export
interface
MP4AudioTrack
extends
MP4MediaTrack
{
audio
:
MP4AudioData
;
}
export
type
MP4Track
=
MP4VideoTrack
|
MP4AudioTrack
;
export
interface
MP4Info
{
duration
:
number
;
timescale
:
number
;
fragment_duration
:
number
;
isFragmented
:
boolean
;
isProgressive
:
boolean
;
hasIOD
:
boolean
;
brands
:
string
[];
created
:
Date
;
modified
:
Date
;
tracks
:
MP4Track
[];
audioTracks
:
MP4AudioTrack
[];
videoTracks
:
MP4VideoTrack
[];
otherTracks
:
MP4VideoTrack
[];
}
export
interface
MP4Sample
{
alreadyRead
:
number
;
chunk_index
:
number
;
chunk_run_index
:
number
;
cts
:
number
;
data
:
Uint8Array
;
degradation_priority
:
number
;
depends_on
:
number
;
description
:
unknown
;
description_index
:
number
;
dts
:
number
;
duration
:
number
;
has_redundancy
:
number
;
is_depended_on
:
number
;
is_leading
:
number
;
is_sync
:
boolean
;
number
:
number
;
offset
:
number
;
size
:
number
;
timescale
:
number
;
track_id
:
number
;
}
export
type
MP4ArrayBuffer
=
ArrayBuffer
&
{
fileStart
:
number
};
export
class
DataStream
{
static
BIG_ENDIAN
:
boolean
;
static
LITTLE_ENDIAN
:
boolean
;
buffer
:
ArrayBuffer
;
constructor
(
arrayBuffer
?:
ArrayBuffer
,
byteOffset
:
number
,
endianness
:
boolean
,
):
void
;
}
export
interface
Trak
{
mdia
?:
{
minf
?:
{
stbl
?:
{
stsd
?:
{
entries
:
{
avcC
?:
{
write
:
(
stream
:
DataStream
)
=>
void
;
};
hvcC
?:
{
write
:
(
stream
:
DataStream
)
=>
void
;
};
}[];
};
};
};
};
}
export
namespace
BoxParser
{
export
class
Box
{
size
?:
number
;
data
?:
Uint8Array
;
constructor
(
type
?:
string
,
size
?:
number
);
add
(
name
:
string
):
Box
;
addBox
(
box
:
Box
):
Box
;
addEntry
(
value
:
string
,
prop
?:
string
):
void
;
write
(
stream
:
DataStream
):
void
;
writeHeader
(
stream
:
DataStream
,
msg
?:
string
):
void
;
computeSize
():
void
;
}
export
class
ContainerBox
extends
Box
{}
export
class
avcCBox
extends
ContainerBox
{}
export
class
hvcCBox
extends
ContainerBox
{}
export
class
vpcCBox
extends
ContainerBox
{}
export
class
av1CBox
extends
ContainerBox
{}
}
export
interface
TrackOptions
{
id
?:
number
;
type
?:
string
;
width
?:
number
;
height
?:
number
;
duration
?:
number
;
layer
?:
number
;
timescale
?:
number
;
media_duration
?:
number
;
language
?:
string
;
hdlr
?:
string
;
// video
avcDecoderConfigRecord
?:
BufferSource
;
// audio
balance
?:
number
;
channel_count
?:
number
;
samplesize
?:
number
;
samplerate
?:
number
;
//captions
namespace
?:
string
;
schema_location
?:
string
;
auxiliary_mime_types
?:
string
;
description
?:
BoxParser
.
Box
;
description_boxes
?:
BoxParser
.
Box
[];
default_sample_description_index_id
?:
number
;
default_sample_duration
?:
number
;
default_sample_size
?:
number
;
default_sample_flags
?:
number
;
}
export
interface
SampleOptions
{
sample_description_index
?:
number
;
duration
?:
number
;
cts
?:
number
;
dts
?:
number
;
is_sync
?:
boolean
;
is_leading
?:
number
;
depends_on
?:
number
;
is_depended_on
?:
number
;
has_redundancy
?:
number
;
degradation_priority
?:
number
;
}
export
interface
Sample
{
number
:
number
;
track_id
:
number
;
timescale
:
number
;
description_index
:
number
;
description
:
{
avcC
?:
BoxParser
.
avcCBox
;
// h.264
hvcC
?:
BoxParser
.
hvcCBox
;
// hevc
vpcC
?:
BoxParser
.
vpcCBox
;
// vp9
av1C
?:
BoxParser
.
av1CBox
;
// av1
};
data
:
ArrayBuffer
;
size
:
number
;
alreadyRead
?:
number
;
duration
:
number
;
cts
:
number
;
dts
:
number
;
is_sync
:
boolean
;
is_leading
?:
number
;
depends_on
?:
number
;
is_depended_on
?:
number
;
has_redundancy
?:
number
;
degradation_priority
?:
number
;
offset
?:
number
;
}
export
interface
MP4File
{
getBuffer
():
MP4ArrayBuffer
;
addTrack
(
options
?:
TrackOptions
):
number
;
addSample
(
track
:
number
,
data
:
ArrayBuffer
,
options
?:
SampleOptions
,
):
Sample
;
addSample
(
trackID
:
number
,
uint8
:
Uint8Array
,
arg2
:
{
duration
:
number
;
is_sync
:
boolean
},
):
void
;
onMoovStart
?:
()
=>
void
;
onReady
?:
(
info
:
MP4Info
)
=>
void
;
onError
?:
(
e
:
string
)
=>
void
;
onSamples
?:
(
id
:
number
,
user
:
unknown
,
samples
:
MP4Sample
[])
=>
unknown
;
appendBuffer
(
data
:
MP4ArrayBuffer
):
number
;
save
(
fileName
:
string
):
void
;
start
():
void
;
stop
():
void
;
/**
* Indicates that the next samples to process (for extraction or
* segmentation) start at the given time (Number, in seconds) or at the
* time of the previous Random Access Point (if useRap is true, default
* is false). Returns the offset in the file of the next bytes to be
* provided via appendBuffer.
*
* @param time - Start at the given time (Number, in seconds)
* @param useRap - Random Access Point (if useRap is true, default is false)
* @returns Returns the offset in the file of the next bytes to be provided via appendBuffer.
*/
seek
:
(
time
:
number
,
useRap
:
boolean
)
=>
number
;
flush
():
void
;
releaseUsedSamples
(
trackId
:
number
,
sampleNumber
:
number
):
void
;
setExtractionOptions
(
trackId
:
number
,
user
?:
unknown
,
options
?:
{
nbSamples
?:
number
;
rapAlignment
?:
number
},
):
void
;
getTrackById
(
trackId
:
number
):
Trak
;
}
export
function
createFile
():
MP4File
;
export
{};
}
demo/frontend/src/vite-env.d.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <reference types="vite/client" />
demo/frontend/tailwind.config.js
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
tailwindCSSTypography
from
'
@tailwindcss/typography
'
;
import
daisyui
from
'
daisyui
'
;
import
*
as
daisyColorThemes
from
'
daisyui/src/theming/themes
'
;
/** @type {import('tailwindcss').Config} */
export
default
{
content
:
[
'
./index.html
'
,
'
./src/**/*.{js,ts,jsx,tsx}
'
,
'
node_modules/daisyui/dist/**/*.js
'
,
'
node_modules/react-daisyui/dist/**/*.js
'
,
],
daisyui
:
{
styled
:
true
,
themes
:
[
{
light
:
{
...
daisyColorThemes
[
'
[data-theme=light]
'
],
'
base-100
'
:
'
#FFFFFF
'
,
'
base-200
'
:
'
#F1F4F7
'
,
'
base-300
'
:
'
#DEE3E9
'
,
primary
:
'
#0064E0
'
,
'
primary-content
'
:
'
#FFFFFF
'
,
secondary
:
'
#0F191E
'
,
'
secondary-content
'
:
'
#FFFFFF
'
,
accent
:
'
#6441D2
'
,
'
accent-content
'
:
'
#FFFFFF
'
,
info
:
'
#009B9B
'
,
'
info-content
'
:
'
#FFFFFF
'
,
success
:
'
#0F9B14
'
,
'
success-content
'
:
'
#FFFFFF
'
,
warning
:
'
#FA8719
'
,
'
warning-content
'
:
'
#FFFFFF
'
,
error
:
'
#C80A28
'
,
'
error-content
'
:
'
#FFFFFF
'
,
'
--rounded-box
'
:
'
0.35rem
'
,
// border radius rounded-box utility class, used in card and other large boxes
'
--rounded-btn
'
:
'
0.35rem
'
,
// border radius rounded-btn utility class, used in buttons and similar element
'
--rounded-badge
'
:
'
1rem
'
,
// border radius rounded-badge utility class, used in badges and similar
},
},
'
dark
'
,
],
},
theme
:
{
fontSize
:
{
xs
:
[
'
0.75rem
'
,
{
lineHeight
:
'
1.5
'
}],
sm
:
[
'
0.875rem
'
,
{
lineHeight
:
'
1.5
'
}],
base
:
[
'
1rem
'
,
{
lineHeight
:
'
1.5
'
}],
lg
:
[
'
1.125rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
500
}],
xl
:
[
'
1.25rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
500
}],
'
2xl
'
:
[
'
1.5rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
500
,
letterSpacing
:
'
0.005rem
'
},
],
'
3xl
'
:
[
'
2.25rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
500
,
letterSpacing
:
'
0.01rem
'
},
],
'
4xl
'
:
[
'
3rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
500
,
letterSpacing
:
'
0.016rem
'
},
],
'
5xl
'
:
[
'
4rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
400
,
letterSpacing
:
'
0.016rem
'
},
],
'
6xl
'
:
[
'
5rem
'
,
{
lineHeight
:
'
1.2
'
,
fontWeight
:
400
,
letterSpacing
:
'
0.016rem
'
},
],
},
extend
:
{
colors
:
{
graydark
:
{
50
:
'
#f1f4f7
'
,
100
:
'
#DEE3E9
'
,
200
:
'
#CBD2D9
'
,
300
:
'
#A7B3BF
'
,
400
:
'
#8595A4
'
,
500
:
'
#667788
'
,
600
:
'
#465A69
'
,
700
:
'
#343845
'
,
800
:
'
#1A1C1F
'
,
900
:
'
#0F191E
'
,
},
},
lineHeight
:
{
tight
:
1.2
,
},
backgroundImage
:
{
dot
:
'
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAABdJREFUGBljYGBg+A/FQAoTMGEKDUcRAATwAgFGIXEOAAAAAElFTkSuQmCC)
'
,
},
keyframes
:
{
wiggle
:
{
'
0%, 100%
'
:
{
transform
:
'
rotate(-3deg)
'
},
'
50%
'
:
{
transform
:
'
rotate(3deg)
'
},
},
},
animation
:
{
wiggle
:
'
wiggle .25s ease-in-out
'
,
},
typography
:
{
DEFAULT
:
{
css
:
{
maxWidth
:
'
100%
'
,
// add required value here
a
:
{
textDecoration
:
'
none
'
,
},
},
},
},
},
},
plugins
:
[
tailwindCSSTypography
,
daisyui
],
};
demo/frontend/tsconfig.json
0 → 100644
View file @
3af09475
/**
*
Copyright
(c)
Meta
Platforms,
Inc.
and
affiliates.
*
*
Licensed
under
the
Apache
License,
Version
2.0
(the
"License"
);
*
you
may
not
use
this
file
except
in
compliance
with
the
License.
*
You
may
obtain
a
copy
of
the
License
at
*
*
http://www.apache.org/licenses/LICENSE
-2.0
*
*
Unless
required
by
applicable
law
or
agreed
to
in
writing,
software
*
distributed
under
the
License
is
distributed
on
an
"AS IS"
BASIS,
*
WITHOUT
WARRANTIES
OR
CONDITIONS
OF
ANY
KIND,
either
express
or
implied.
*
See
the
License
for
the
specific
language
governing
permissions
and
*
limitations
under
the
License.
*/
{
"compilerOptions"
:
{
"target"
:
"ES2020"
,
"useDefineForClassFields"
:
true
,
"lib"
:
[
"ES2020"
,
"DOM"
,
"DOM.Iterable"
,
"webworker"
],
"module"
:
"ESNext"
,
"skipLibCheck"
:
true
,
/*
Bundler
mode
*/
"moduleResolution"
:
"bundler"
,
"allowImportingTsExtensions"
:
true
,
"resolveJsonModule"
:
true
,
"isolatedModules"
:
true
,
"esModuleInterop"
:
true
,
//
esModuleInterop
true
required
for
Jest
"noEmit"
:
true
,
"jsx"
:
"react-jsx"
,
/*
Linting
*/
"strict"
:
true
,
"noUnusedLocals"
:
true
,
"noUnusedParameters"
:
true
,
"noFallthroughCasesInSwitch"
:
true
,
"baseUrl"
:
"./src"
,
"paths"
:
{
"mp4box"
:
[
"types/mp4box"
],
"@/*"
:
[
"*"
]
}
},
"include"
:
[
"src"
],
"references"
:
[{
"path"
:
"./tsconfig.node.json"
}]
}
demo/frontend/tsconfig.node.json
0 → 100644
View file @
3af09475
/**
*
Copyright
(c)
Meta
Platforms,
Inc.
and
affiliates.
*
*
Licensed
under
the
Apache
License,
Version
2.0
(the
"License"
);
*
you
may
not
use
this
file
except
in
compliance
with
the
License.
*
You
may
obtain
a
copy
of
the
License
at
*
*
http://www.apache.org/licenses/LICENSE
-2.0
*
*
Unless
required
by
applicable
law
or
agreed
to
in
writing,
software
*
distributed
under
the
License
is
distributed
on
an
"AS IS"
BASIS,
*
WITHOUT
WARRANTIES
OR
CONDITIONS
OF
ANY
KIND,
either
express
or
implied.
*
See
the
License
for
the
specific
language
governing
permissions
and
*
limitations
under
the
License.
*/
{
"compilerOptions"
:
{
"composite"
:
true
,
"skipLibCheck"
:
true
,
"module"
:
"ESNext"
,
"target"
:
"ES2017"
,
"moduleResolution"
:
"bundler"
,
"allowSyntheticDefaultImports"
:
true
,
"strictNullChecks"
:
true
},
"include"
:
[
"vite.config.ts"
,
"schemas"
]
}
demo/frontend/vite.config.ts
0 → 100644
View file @
3af09475
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
react
from
'
@vitejs/plugin-react
'
;
import
jotaiDebugLabel
from
'
jotai/babel/plugin-debug-label
'
;
import
jotaiReactRefresh
from
'
jotai/babel/plugin-react-refresh
'
;
import
path
from
'
path
'
;
import
{
defineConfig
}
from
'
vite
'
;
import
babel
from
'
vite-plugin-babel
'
;
import
relay
from
'
vite-plugin-relay
'
;
import
{
stylexPlugin
}
from
'
vite-plugin-stylex-dev
'
;
export
default
defineConfig
({
resolve
:
{
alias
:
{
'
@
'
:
path
.
resolve
(
__dirname
,
'
./src
'
),
},
},
plugins
:
[
react
({
babel
:
{
plugins
:
[
jotaiDebugLabel
,
jotaiReactRefresh
],
},
}),
stylexPlugin
(),
relay
,
babel
(),
],
worker
:
{
plugins
:
()
=>
[
relay
],
},
});
Prev
1
…
10
11
12
13
14
15
16
17
18
…
30
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment