* feat: support batch video upscaling with folder upload and directory save
- Add multi-file selection and entire folder upload (webkitdirectory)
- Support drag & drop of both files and folders via FileSystemEntry API
- Add save directory picker using File System Access API (showDirectoryPicker)
- Process videos sequentially with per-file progress and status tracking
- Add right-side result list with click-to-compare functionality
- Add per-video duration and total batch duration display
- Add retry button for failed items with error detail display
- Remove auto-play on comparison viewer load
- Fix worker error handling: handle "error" command to reject stale promises
- Fix event listener accumulation in video comparison (AbortController)
- Fix XSS risk by escaping HTML in all innerHTML injections
- Fix URL revocation timing in download to prevent large file truncation
- Extract writeToSaveDirectory and truncateName helpers to reduce duplication
- Add Usage Guide panel explaining single/multiple/folder upload options
Files changed:
docs/upscaler/index.html (+1110/-181)
docs/upscaler/upscaler.js (+110)
* fix: prevent auto-play and resource consumption during upscaling
- Set preload="metadata" on preview and comparison video elements
- Explicitly pause preview video after setting src in showVideoPreview
- Remove preview video seek sync from batch processing progress callbacks
(was causing continuous decode during upscaling, wasting GPU resources)
- Remove preview video seek sync from retry progress callback
- All videos now require manual play; no background resource usage
* fix: improve upscaled video quality with higher bitrate and codec support
- Raise base bitrate from 2.5 Mbps (25e5) to 8 Mbps (8e6) for standard and
firefox processors, preventing quality loss when source videos have high
bitrates (e.g. 720p @ 16.7 Mbps was producing 1440p @ 10 Mbps, smaller
than the original file)
- Double the bitrate for mediabunny processor (X.n1 * 2) to account for the
4x pixel increase from 2x upscaling
- Add H.264 Level 5.1 (avc1.640033) and Level 5.2 (avc1.640034) codecs to
the fallback lists, since Level 4.0 (avc1.640028, ~24.6 Mbps) cannot
support the higher bitrates for 1440p+ outputs
- Add latencyMode: "quality" to VideoEncoder configs for both standard and
firefox processors, prioritizing encoding quality over latency (suitable
for offline processing)
* feat: add video data comparison panel for original vs upscaled metrics
- Add a comparison data table below the file info bar showing 6 metrics:
Resolution, File Size, Duration, Est. Bitrate, Pixels, Process Time
- Display per-metric change percentage with color-coded indicators:
green (↑) for improvements, red (↓) for regressions, gray for neutral
- Estimated bitrate calculated from file size × 8 / video duration
- Table renders after both original and upscaled video metadata loads
- Auto-hide panel on reset
* fix: make video data comparison panel full-width and responsive
- Move comparison data table from inside the left column to the full-width
area below the left/right layout, so it is no longer constrained by the
comparison viewer column width
- Remove table-fixed colgroup and overflow-x-auto that caused horizontal
scrolling on smaller screens
- Table now uses w-full auto-layout, displaying all 4 columns (Metric,
Original, Upscaled, Change) without requiring horizontal scrolling
---------
Co-authored-by: rionzhao <rionzhao@tencent.com>
`art.play()` is an async wrapper around the native `video.play()` promise, which
rejects when a pending play request is interrupted (`pause()`, `load()`, a new
`src`, or the element being removed) and when autoplay is blocked.
Every internal caller fires it from an event handler and cannot await it, so the
rejection escapes as a global `unhandledrejection`. Error trackers report it as
an uncaught crash even though the player recovers on its own — for example
destroying the player right after mount, which is routine when the video sits in
a modal the user can close quickly.
Add a `silencePromise` util (the same approach video.js uses) and apply it to the
non-awaited internal call sites: mask, play control, mini player, loop restart,
autoPlayback jump, hotkey and click toggles.
`switchMix` is fixed too, for a second symptom: `await art.play()` inside the
async `video:canplay` handler both leaked the rejection and left the `switchUrl`
promise pending forever, since the throw never reached the enclosing executor's
`reject`. It now settles.
The public API is unchanged: `art.play()` and `art.toggle()` still return the
original promise, so applications that call them keep their own rejection to
handle. Only the internal, non-awaited copy is silenced.
The notice.show getter was declared as boolean while the setter accepts string, Error or false. TypeScript uses the getter return type when checking property assignment, causing TS2322 when assigning a string to notice.show.
Root causes fixed:
1. Remove starvation check that suspends AudioContext — it freezes the
video clock and causes playback to stall permanently
2. Add backpressure (1s BUFFER_AHEAD) to prevent audio pump from decoding
unbounded buffers, starving the video decoder
3. Add setTimeout(0) yield between batches so video rAF callbacks can run
4. Batch audio buffer reads (16 per iteration) to reduce IPC overhead
5. Fix latestScheduledEndTime time-domain: use media-time (same domain as
currentTime) instead of AudioContext-time, so backpressure check works
correctly after seeking
Without these fixes, playing a large file (9+ GB) with audio causes:
- Audio pump decodes hundreds of buffers in 1 second (195s of audio decoded
in 1s wall clock)
- Main thread blocked by 177 IPC calls/sec from audio iterator
- Video frames never render (rAF starved)
- After seek: backpressure never triggers due to time-domain mismatch,
causing persistent stutter and eventual silence
feat: add danmuku plugin and i18n setup documentation
- Introduced a new danmuku plugin with multiple run code options in the documentation.
- Added language settings documentation for i18n, including default languages, import instructions, and examples for adding and modifying languages.
- Implemented input handling for media sources in the artplayer-proxy-mediabunny package, supporting various formats including HLS.
- Created m3u8 control functionalities for managing audio and video quality settings in the player.
Update mediabunny.js
- Introduced a new danmuku plugin with multiple run code options in the documentation.
- Added language settings documentation for i18n, including default languages, import instructions, and examples for adding and modifying languages.
- Implemented input handling for media sources in the artplayer-proxy-mediabunny package, supporting various formats including HLS.
- Created m3u8 control functionalities for managing audio and video quality settings in the player.
- Created a new documentation file for the danmuku plugin with code examples.
- Added a comprehensive guide for language settings (i18n) including default languages, importing languages, adding new languages, and modifying existing languages.
- Included code snippets for initializing the Artplayer with different language settings.
feat: implement safe area insets for improved video rotation handling
feat: add console log for safe area insets in autoOrientation plugin
feat: enhance mobile meta tags for better web app support
- Created a new documentation file for the danmuku plugin with code examples.
- Added a new documentation file for language settings (i18n) with detailed instructions on language imports, default languages, and how to add or modify languages.
- Included code snippets for initializing the Artplayer with different language settings.
- Consolidated loading styles in loading.less for better structure.
- Updated mask styles in mask.less to enhance clarity.
- Refined mini popup styles in mini.less, adding transition effects.
- Improved mixins in mixins.less for consistent styling across components.
- Adjusted mobile styles in mobile.less for better responsiveness.
- Enhanced notice styles in notice.less for improved visibility.
- Streamlined plugin styles in plugins.less for better organization.
- Simplified poster styles in poster.less for clarity.
- Refined progress styles in progress.less, enhancing hover effects.
- Updated selector styles in selector.less for better interaction.
- Improved settings styles in setting.less for better usability.
- Enhanced subtitle styles in subtitle.less for better visibility.
- Updated variable definitions in variables.less for consistency.
- Refined video styles in video.less for improved layout.
- Enhanced volume control styles in volume.less for better user experience.
- Optimized rate limiting logic in build-llm.js and trans-docs.js for better performance.
- Removed cursor pointer from .art-mask-show in mask.less for better UX.
- Added cursor pointer to .art-progress in progress.less to indicate interactivity.
- Adjusted hover effect for .art-control-progress-inner in progress.less to enhance visual feedback.
- Increased --art-progress-top-gap variable from 8px to 10px in variables.less for improved layout.
- Removed cursor pointer from .art-video in video.less to streamline styling.
- Updated descriptions and terminology across various component documentation files for improved clarity.
- Changed headings and section titles for better readability and consistency.
- Enhanced the language and structure of the documentation to provide clearer guidance on usage and configuration.
- Removed the `fix-docs.js` script as its functionality has been integrated into the translation process.
- Improved the translation script to handle Markdown code block issues and added retry logic for API calls.
- Updated API key environment variable from DEEPL_API_KEY to DEEPSEEK_API_KEY
- Increased maximum text chunk length from 5000 to 8000 characters
- Implemented request timeout and retry logic for API calls
- Added handling for rate limiting responses (HTTP 429)
- Improved error handling for API responses
- Created a new documentation file for the danmuku plugin, including code snippets for usage.
- Added a new i18n setup guide, detailing language settings, default languages, language imports, and how to add or modify languages.
- Included example code for initializing the Artplayer with different languages and importing language files.
- Created a new documentation file for the danmuku plugin with code examples for usage.
- Added a new i18n setup guide, detailing language settings, default languages, and how to import and modify languages.
- Included code snippets for initializing the Artplayer with different languages and examples for adding new languages.
- Removed the old ArtplayerPluginIframe implementation.
- Added ArtplayerToolIframe class with methods for iframe communication.
- Implemented postMessage and onMessage methods for message handling.
- Created a new TypeScript definition file for ArtplayerToolIframe.
- Updated documentation links to point to the new iframe tool.
- Added npm ignore file and README for the new package.
- Included compiled and uncompiled versions of the new iframe tool.
- Updated package.json with relevant metadata and exports.
- Replaced `toPascalCase` with `getGlobalName` in build and dev scripts to standardize global variable naming for packages.
- Added `toCamelCase` and `getGlobalName` utility functions in `utils.js` to handle naming conventions based on package type.
- Removed the assignment of Artplayer to the global window object in index.js of the artplayer package.
- Eliminated the window export for the template plugin in index.js, streamlining the code and reducing global scope pollution.
- Added a new script `build:test` to generate test cases from documentation code examples.
- Enhanced documentation files by ensuring proper code block formatting and adding missing closing backticks.
- Updated various markdown files to include new code blocks and fixed formatting issues.
feat: add danmuku plugin documentation and i18n setup guide
- Created a new documentation file for the danmuku plugin with code examples.
- Added a comprehensive guide for language settings (i18n) including default languages, importing languages, adding new languages, and modifying existing languages.
- Included code snippets for initializing the Artplayer with different language settings.
Add internationalization support for multiple languages in Artplayer
- Introduced Arabic (ar), Czech (cs), Spanish (es), Persian (fa), French (fr), Indonesian (id), Polish (pl), Russian (ru), Turkish (tr), Vietnamese (vi), and Traditional Chinese (zh-tw) translations.
- Created corresponding JavaScript and ES module files for each language containing translated strings for player controls and settings.
- Added a new documentation file for language settings in the project.
feat: add initial implementation of start option page with interactive code execution buttons
feat: add danmuku plugin documentation and i18n setup guide
- Created a new documentation file for the danmuku plugin, providing code examples for usage.
- Added a comprehensive guide for language settings, including default languages, importing languages, adding new languages, and modifying existing languages.
- Included code snippets for initializing the Artplayer with different language settings and importing language files.
refactor: update danmuku worker implementation and remove unused i18n files
- Changed the way the Danmuku class creates a Web Worker by using a worker loader instead of creating a blob.
- Removed Arabic, Czech, Spanish, Persian, French, Indonesian, Polish, Russian, Turkish, Vietnamese, and Traditional Chinese i18n files as they are no longer needed.
- Updated the Vite build configuration to disable banners for inline workers and added a plugin to remove worker banners from generated code.
feat: add danmuku plugin and i18n setup documentation
- Created a new documentation file for the danmuku plugin, providing code examples for usage.
- Added a new documentation file for language settings (i18n), detailing how to set default languages, import languages, and add new languages.
- Included code snippets for initializing the Artplayer with different language settings and examples for modifying existing languages.
feat: add danmuku plugin and i18n setup documentation
- Created a new documentation file for the danmuku plugin with code examples.
- Added a new documentation file for language settings (i18n) including import instructions and examples for setting default and custom languages.
- Updated the i18n documentation to include details on adding and modifying languages.
feat: add danmuku plugin and i18n setup documentation
- Created a new JavaScript file for the danmuku plugin documentation with multiple code execution buttons.
- Added a new JavaScript file for i18n (internationalization) setup documentation, including instructions for language settings, importing languages, and modifying language options.
- Included examples for setting default languages and adding new languages in the i18n documentation.
Refactor code structure for improved readability and maintainability
feat: update index.html for improved UI and UX with enhanced metadata and styling
feat: redesign index.html for enhanced UI and UX with improved layout and styling
feat: update index.html for improved UI with clearer messaging and streamlined layout
Update index.html
feat: enhance index.html with improved UI components, styling, and drag-and-drop support for video uploads
feat: update index.html for enhanced UI and improved video upload experience with preview functionality
- Implemented a new HTML interface for image and video upscaling with WebGPU and WebGL support.
- Created the Upscaler class to handle image and video processing, including loading weights, managing workers, and handling real-time upscaling.
- Added support for selecting processing modes (small, medium, large) and handling file uploads.
- Integrated progress tracking and result display for processed images and videos.
- Implemented functionality for downloading processed results and real-time video processing from a URL.
- Implemented a callback pool in the Web Worker to handle concurrent requests without overwriting onmessage.
- Modified postMessage to generate unique IDs for messages and store corresponding callbacks.
- Improved state management by using in-place deletion for removing danmu from state pools.
- Optimized the rendering loop to batch calculate the top positions of danmu elements, reducing DOM reads and improving performance.
- Added a new function getDanmuTopBatch in the worker to handle batch requests for top calculations.
- Created a new documentation file for the danmuku plugin with code examples.
- Added a comprehensive guide for language settings (i18n) including default languages, importing languages, adding new languages, and modifying existing languages.
- Included code snippets for initializing the Artplayer with different language configurations.
- Moved the canvas size calculation logic into a dedicated function `calcCanvasSize`.
- Called `calcCanvasSize` to set the initial width and height of the canvas.
- Removed duplicate `calcCanvasSize` function definition from the code.
- Changed the return function to be async for handling asynchronous operations.
- Updated the call to startRealtimeUpscale to await its completion, allowing for proper handling of the upscale process with the specified network size option.
- Implemented methods for initializing the upscaling process, loading weights, and processing images and videos.
- Added support for real-time video upscaling using OffscreenCanvas and Web Workers.
- Included utility functions for loading image and video metadata, handling blob responses, and managing network configurations.
- Introduced methods for downloading upscaled content and managing GPU capabilities.
- Added error handling and progress tracking for the upscaling process.
- Created a new documentation file for the danmuku plugin with code examples.
- Added a new documentation file for language settings (i18n) with detailed instructions on language imports, default languages, and how to add or modify languages.
Remove debugging border from the websr plugin's styling
Enhance canvas sizing logic in artplayer-plugin-websr
- Updated canvas positioning to center it within the player.
- Introduced a new function to calculate canvas size based on the video aspect ratio.
- Adjusted canvas dimensions during initialization and on resize events to maintain aspect ratio.
- Ensured canvas styles are updated to reflect the calculated dimensions.
feat: add comparison mode to artplayer-plugin-websr
- Updated README.md to reflect new comparison feature and simplified content.
- Modified package.json to remove unnecessary keywords.
- Enhanced index.js to implement comparison functionality, allowing users to compare original and upscaled video.
- Added new methods for enabling, disabling, and toggling comparison mode, as well as setting and getting the comparison position.
- Updated TypeScript definitions to include new comparison options and methods.
- Organized the control layout by grouping related styles together.
- Enhanced the alignment and spacing properties for better consistency.
- Maintained existing functionality while improving code clarity.
- Merged tooltip styling sections into a cohesive structure.
- Added comments for clarity on tooltip components and their functionalities.
- Ensured consistent formatting and indentation throughout the file.
- Preserved original functionality while enhancing readability and maintainability.
- Deleted the plugin files including JavaScript, CSS, README, and type definitions.
- Removed references to the plugin from the documentation.
- Cleaned up the package structure by removing the .npmignore and package.json files related to the plugin.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, import instructions, and examples for adding and modifying languages.
- Updated the i18n documentation to reflect changes in language handling and provide clear examples for users.
feat: add JASSUB type definitions and update common.js references
feat: add JASSUB plugin for advanced subtitle rendering in HTML5 video
- Implemented a new JASSUB class for handling subtitle rendering with options for video and canvas targets.
- Added support for both synchronous and asynchronous rendering modes.
- Integrated Web Worker for offloading rendering tasks, improving performance.
- Included methods for managing subtitle tracks, styles, and events.
- Added color space verification and handling to ensure accurate subtitle display.
- Implemented local font access for enhanced typography options in subtitles.
- Introduced a benchmarking feature to assess rendering performance.
refactor: update README and type definitions for artplayer-plugin-jassub
- Removed installation and usage instructions from README.md for clarity.
- Updated index.js to remove direct assignment of jassub instance to art.
- Enhanced type definitions in artplayer-plugin-jassub.d.ts to include detailed JassubOption and JassubInstance interfaces.
- Implemented a React template with Vite, including ESLint configuration and necessary dependencies.
- Created a Vue template with Vite, including setup for Artplayer and plugins.
- Added internationalization support in both React and Vue examples.
- Included sample video and Danmuku plugin integration in both frameworks.
- Established project structure with appropriate configuration files and README documentation.
- Implemented the audio track plugin for ArtPlayer, allowing audio to be synchronized with video playback.
- Added main functionality in `src/index.js` to handle audio playback, synchronization, and event listeners for play, pause, seek, and volume changes.
- Created TypeScript definitions for the plugin in `types/artplayer-plugin-audio-track.d.ts`.
- Included necessary build files in `dist/` for various module formats (CommonJS, ES Module, and legacy).
- Updated package metadata in `package.json` and added a README for documentation.
- Added `.npmignore` to exclude unnecessary files from the package.
Added a flag to manage the fetching state of video frames in the VideoEngine class. This change ensures that the updateNextFrame method does not attempt to fetch new frames while a previous fetch is still in progress, preventing potential race conditions and improving stability during playback.
- Deleted ARCHITECTURE.md file to streamline project documentation.
- Refactored AudioEngine, EventTarget, MediaBunnyEngine, VideoEngine, VideoShim, and index.js for improved readability by adding consistent line breaks and spacing.
- Enhanced code structure by ensuring single-responsibility principles and clearer flow in methods.
- Updated TypeScript definitions for better clarity on options available in the artplayer-proxy-mediabunny package.
- Updated the way properties from the shim instance and its prototype are retrieved.
- Replaced the for-in loop with a Set to ensure all properties, including inherited ones, are considered.
- Excluded the 'constructor' property from being added to the canvas.
refactor: remove unused utility functions and streamline event handling
- Deleted `videoEvents.js`, `clamp.js`, and `sleep.js` as they were not utilized.
- Introduced a new `EventTarget` class to manage event listeners more efficiently.
- Enhanced `MediaBunnyEngine`, `AudioEngine`, `VideoEngine`, and `VideoShim` to utilize the new event system.
- Updated type definitions in `artplayer-proxy-mediabunny.d.ts` to include new configuration options.
- Added comprehensive architecture documentation to clarify the structure and flow of the MediaBunny engine.
- Refactored the codebase for improved readability and maintainability, including better naming conventions and JSDoc comments.
Refactor styles for consistency and improved theming
- Updated context menu styles to use new spacing and surface mixins.
- Adjusted control styles to utilize touch hit size for better accessibility.
- Refined info panel padding and applied panel surface mixin for uniformity.
- Standardized mini player transitions and background colors.
- Introduced new mixins for panel surfaces and flyout animations.
- Enhanced notice padding and applied consistent spacing variables.
- Updated plugin styles to use new icon sizes and panel surface mixin.
- Improved progress bar styles with consistent surface and shadow properties.
- Refactored selector styles to utilize new surface mixin and flyout animations.
- Streamlined setting panel styles with consistent spacing and hover effects.
- Added new variables for spacing, surface colors, and icon sizes.
- Updated volume panel styles to use new spacing and flyout animations.
feat(cssVar): add new CSS variables for enhanced theming and layout
Refactor styles in ArtPlayer
- Updated transition properties across various LESS files to use the new `--art-ease-standard` variable for consistency.
- Added new CSS variables for mobile padding and border radius.
- Introduced shadow variables for different elevation levels.
- Minor adjustments to ensure proper formatting and consistency in LESS files, including adding missing newlines at the end of files.
refactor: replace art-text-muted mixin with direct font-size in setting.less
Refactor styles for context menu, info panel, and settings
- Updated font sizes to use the new variable `--art-font-size-sm` for consistency across context menus, info panels, and settings.
- Introduced a new mixin `.art-menu-item-base` to standardize menu item styles, including padding and hover effects.
- Adjusted padding and positioning for tooltip elements in the progress bar.
- Added new CSS variables for tip padding and offset to enhance maintainability and readability of styles.
- Bump version from 1.0.1 to 1.0.2 in package.json.
- Refactor index.js to remove unused variables and simplify event handling.
- Enhance title display logic in the chapter plugin for better user experience.
- Update styles in style.less for smoother transitions and improved visibility of chapter titles.
- Removed unnecessary hover event handling for thumbnails.
- Updated thumbnail visibility logic to always show when loading.
- Enhanced CSS for progress tip and thumbnails with scaling and opacity transitions.
- Added hover class to manage thumbnail visibility on progress hover.
- Updated the progress tooltip to display the current time or '00:00' when no time is available.
- Improved hover functionality by adding/removing a class on the player element based on the hover state.
- Refactored mousemove event handling to streamline tooltip visibility and highlight display logic.
- Removed unnecessary display property manipulation for the tooltip in CSS.
- Created a new documentation file for language settings in i18n.
- Added examples for setting default languages and importing additional languages.
- Included instructions for adding and modifying languages in the ArtPlayer plugin.
- Introduced a new plugin: artplayer-plugin-liquid-glass with various build formats (legacy, mjs, etc.).
Remove options section from README for clarity
Add 'waiting' event emission during seeking in mediabunnyEngine
This change emits a 'waiting' event when the seeking process begins,
improving the event handling and allowing for better synchronization
during media playback.
fix(audioEngine): adjust audio context suspension timing for improved playback responsiveness
refactor(mediabunnyVideoShim): remove redundant width and height getters; enhance poster setter and add setAttribute method
feat: initialize artplayer-proxy-mediabunny with essential files and structure
feat: implement audio and video engines for mediabunny integration
- Added audioEngine.js to handle audio playback using MediaBunny.
- Created mediabunnyEngine.js to manage both audio and video playback.
- Implemented videoEngine.js for rendering video on a canvas.
- Introduced canvasProxy.js to create a canvas element and manage its methods.
- Developed mediabunnyVideoShim.js to bridge ArtPlayer and MediaBunny functionalities.
- Added videoEvents.js for custom event handling related to video playback.
- Included a utility function clamp.js for value clamping.
feat: add playback rate control to audio and video engines
- Introduced playback rate management in the audio engine, allowing dynamic adjustment of playback speed.
- Updated the mediabunny engine to expose the new setPlaybackRate method.
- Enhanced the mediabunny video shim to support playback rate adjustments, including getter and setter for playbackRate.
- Added event emission for rate changes to ensure proper handling in the application.
Enhance audio engine and video shim functionality
- Added a check to ensure the audio context is initialized before playing audio in the audio engine.
- Introduced a new 'playing' getter in the video shim to accurately reflect the playback state, indicating when the video is neither paused nor ended.
Refactor audio context initialization to handle errors and remove async/await
- Changed `ensureAudioContext` from async to synchronous to simplify error handling.
- Added a try-catch block to handle potential errors when creating the AudioContext with a specified sample rate.
- Updated calls to `ensureAudioContext` to remove unnecessary await statements.
Enhance Mediabunny Engine and Video Shim with State Management and Error Handling
- Added readyState, networkState, and error properties to the Mediabunny Engine for better state management.
- Implemented error handling during media loading, emitting appropriate events on error.
- Updated the Video Engine to emit a 'timeupdate' event for better synchronization.
- Extended the Mediabunny Video Shim to expose new properties (readyState, networkState, error) and methods for improved functionality.
- Added seekable property to the Video Shim to provide seekable range based on media duration.
- Implemented additional properties and methods in the Video Shim for autoplay, loop, controls, currentSrc, poster, preload, defaultMuted, and defaultPlaybackRate.
- Enhanced requestVideoFrameCallback and cancelVideoFrameCallback methods for better frame handling.
refactor: streamline audio and video engine implementations
- Updated audioEngine.js to improve readability and maintainability by using consistent formatting and simplifying function structures.
- Refactored mediabunnyEngine.js to enhance clarity and ensure consistent coding style.
- Enhanced videoEngine.js with improved async handling and clearer function definitions.
- Modified canvasProxy.js to maintain consistent formatting and improve readability.
- Updated mediabunnyVideoShim.js to streamline event handling and improve clarity.
- Refactored videoEvents.js for better readability and consistency in event listener management.
- Simplified clamp.js for improved readability.
feat: enhance audio and video loading with metadata callbacks
- Updated audioEngine to accept an optional onMetadata callback in the load function, which is triggered upon loading completion.
- Modified mediabunnyEngine to handle video and audio loading concurrently, emitting loadedmetadata and durationchange events only when both are ready.
- Enhanced videoEngine to include an onMetadata callback in the load function, ensuring metadata events are emitted appropriately.
- Implemented a throttling mechanism for the timeupdate event in videoEngine to reduce event emissions and improve performance.
feat: add seeking state and played property to mediabunny engine and video shim
- Introduced a `_seeking` state in the mediabunny engine to track seek operations.
- Emitted 'seeking' and 'seeked' events during seek operations.
- Added a `seeking` getter to expose the seeking state.
- Implemented a `played` property in the video shim to provide playback range information.
- Added `width` and `height` getters to the video shim for better video dimension access.
- Enhanced cross-origin handling in the video shim.
feat(audioEngine): enhance audio playback management with starvation detection
- Added an event emitter to notify when the audio context is waiting.
- Implemented a starvation check that suspends the audio context if playback is delayed.
- Introduced a mechanism to track the latest scheduled end time of audio buffers.
- Updated the handling of audio buffer playback to ensure proper state transitions.
refactor: remove unnecessary comments and streamline code in audio, video, and mediabunny engines
feat: add resize functionality to canvas proxy and update type definitions
- Implemented a resize function in canvasProxy.js to adjust canvas size based on player dimensions and video metadata.
- Updated TypeScript definitions for artplayer-proxy-mediabunny to include option and result types.
- Modified build-ts script to include all plugin type definitions.
- Added TypeScript definitions for artplayer-proxy-canvas and artplayer-proxy-mediabunny.
refactor: remove unused properties from Artplayer instance and make option parameter optional in artplayerProxyCanvas type definition
Enhance Mediabunny and Video Engine functionality
- Added event listener for 'ended' event in mediabunnyEngine to handle playback state.
- Modified seek function to check if playback should resume after seeking.
- Reset canvas dimensions to zero in videoEngine when video track is not available or cannot be decoded.
- Ensured canvas is cleared when video track is invalid to prevent rendering issues.
Emit 'waiting' event during loadstart in mediabunnyEngine
Refactor event emission in mediabunnyEngine and add sleep utility function
- Changed the event emission for 'loadstart' to be asynchronous using setTimeout.
- Introduced a new utility function 'sleep' to facilitate delayed execution in promises.
feat: enhance mediabunny proxy with new options and source handling
- Added options for event delay, load timeout, timeupdate interval, AV sync tolerance, poster, and source in README.
- Implemented source normalization in audio and video engines to support URL, Blob, and ReadableStream.
- Updated mediabunny engine to handle new options and improve load handling with timeout and error management.
- Enhanced video engine to draw a poster when no video source is available and manage playback rate.
- Modified shim to accept source option and integrate with the new engine options.
- Updated TypeScript definitions to reflect new options and source types.
feat: add dropLateFrames option to video and mediabunny engines
- Introduced dropLateFrames option in mediabunnyEngine and videoEngine to control frame dropping behavior.
- Updated videoEngine logic to handle frame rendering based on the dropLateFrames setting.
- Added type definition for dropLateFrames in TypeScript declaration file.
fix: delay loadstart event emission to ensure proper event handling
The 'loadstart' event emission is now wrapped in a setTimeout to ensure it is triggered after the current call stack is cleared. This change aims to improve the timing of event emissions and prevent potential issues with event handling in the mediabunny engine.
feat: add preflight range check and drop late frames option
- Updated README.md to include new options: dropLateFrames and preflightRange.
- Enhanced mediabunnyEngine to support new options with default values.
- Implemented preflight function in videoEngine to check server support for Range requests.
- Adjusted videoEngine to utilize preflight check before loading media.
- Updated TypeScript definitions to include preflightRange option.
Remove aspectRatio option from Artplayer configuration
Update README and mediabunny example URL for consistency
Refactor code structure for improved readability and maintainability
Update dependencies and fix play/seek state management in mediabunnyEngine
Refactor code structure for improved readability and maintainability
fix(types): update export syntax and formatting in TypeScript declaration files
Remove options section from README for clarity
Add 'waiting' event emission during seeking in mediabunnyEngine
This change emits a 'waiting' event when the seeking process begins,
improving the event handling and allowing for better synchronization
during media playback.
fix(audioEngine): adjust audio context suspension timing for improved playback responsiveness
refactor(mediabunnyVideoShim): remove redundant width and height getters; enhance poster setter and add setAttribute method
feat: initialize artplayer-proxy-mediabunny with essential files and structure
feat: implement audio and video engines for mediabunny integration
- Added audioEngine.js to handle audio playback using MediaBunny.
- Created mediabunnyEngine.js to manage both audio and video playback.
- Implemented videoEngine.js for rendering video on a canvas.
- Introduced canvasProxy.js to create a canvas element and manage its methods.
- Developed mediabunnyVideoShim.js to bridge ArtPlayer and MediaBunny functionalities.
- Added videoEvents.js for custom event handling related to video playback.
- Included a utility function clamp.js for value clamping.
feat: add playback rate control to audio and video engines
- Introduced playback rate management in the audio engine, allowing dynamic adjustment of playback speed.
- Updated the mediabunny engine to expose the new setPlaybackRate method.
- Enhanced the mediabunny video shim to support playback rate adjustments, including getter and setter for playbackRate.
- Added event emission for rate changes to ensure proper handling in the application.
Enhance audio engine and video shim functionality
- Added a check to ensure the audio context is initialized before playing audio in the audio engine.
- Introduced a new 'playing' getter in the video shim to accurately reflect the playback state, indicating when the video is neither paused nor ended.
Refactor audio context initialization to handle errors and remove async/await
- Changed `ensureAudioContext` from async to synchronous to simplify error handling.
- Added a try-catch block to handle potential errors when creating the AudioContext with a specified sample rate.
- Updated calls to `ensureAudioContext` to remove unnecessary await statements.
Enhance Mediabunny Engine and Video Shim with State Management and Error Handling
- Added readyState, networkState, and error properties to the Mediabunny Engine for better state management.
- Implemented error handling during media loading, emitting appropriate events on error.
- Updated the Video Engine to emit a 'timeupdate' event for better synchronization.
- Extended the Mediabunny Video Shim to expose new properties (readyState, networkState, error) and methods for improved functionality.
- Added seekable property to the Video Shim to provide seekable range based on media duration.
- Implemented additional properties and methods in the Video Shim for autoplay, loop, controls, currentSrc, poster, preload, defaultMuted, and defaultPlaybackRate.
- Enhanced requestVideoFrameCallback and cancelVideoFrameCallback methods for better frame handling.
refactor: streamline audio and video engine implementations
- Updated audioEngine.js to improve readability and maintainability by using consistent formatting and simplifying function structures.
- Refactored mediabunnyEngine.js to enhance clarity and ensure consistent coding style.
- Enhanced videoEngine.js with improved async handling and clearer function definitions.
- Modified canvasProxy.js to maintain consistent formatting and improve readability.
- Updated mediabunnyVideoShim.js to streamline event handling and improve clarity.
- Refactored videoEvents.js for better readability and consistency in event listener management.
- Simplified clamp.js for improved readability.
feat: enhance audio and video loading with metadata callbacks
- Updated audioEngine to accept an optional onMetadata callback in the load function, which is triggered upon loading completion.
- Modified mediabunnyEngine to handle video and audio loading concurrently, emitting loadedmetadata and durationchange events only when both are ready.
- Enhanced videoEngine to include an onMetadata callback in the load function, ensuring metadata events are emitted appropriately.
- Implemented a throttling mechanism for the timeupdate event in videoEngine to reduce event emissions and improve performance.
feat: add seeking state and played property to mediabunny engine and video shim
- Introduced a `_seeking` state in the mediabunny engine to track seek operations.
- Emitted 'seeking' and 'seeked' events during seek operations.
- Added a `seeking` getter to expose the seeking state.
- Implemented a `played` property in the video shim to provide playback range information.
- Added `width` and `height` getters to the video shim for better video dimension access.
- Enhanced cross-origin handling in the video shim.
feat(audioEngine): enhance audio playback management with starvation detection
- Added an event emitter to notify when the audio context is waiting.
- Implemented a starvation check that suspends the audio context if playback is delayed.
- Introduced a mechanism to track the latest scheduled end time of audio buffers.
- Updated the handling of audio buffer playback to ensure proper state transitions.
refactor: remove unnecessary comments and streamline code in audio, video, and mediabunny engines
feat: add resize functionality to canvas proxy and update type definitions
- Implemented a resize function in canvasProxy.js to adjust canvas size based on player dimensions and video metadata.
- Updated TypeScript definitions for artplayer-proxy-mediabunny to include option and result types.
- Modified build-ts script to include all plugin type definitions.
- Added TypeScript definitions for artplayer-proxy-canvas and artplayer-proxy-mediabunny.
refactor: remove unused properties from Artplayer instance and make option parameter optional in artplayerProxyCanvas type definition
Enhance Mediabunny and Video Engine functionality
- Added event listener for 'ended' event in mediabunnyEngine to handle playback state.
- Modified seek function to check if playback should resume after seeking.
- Reset canvas dimensions to zero in videoEngine when video track is not available or cannot be decoded.
- Ensured canvas is cleared when video track is invalid to prevent rendering issues.
Emit 'waiting' event during loadstart in mediabunnyEngine
Refactor event emission in mediabunnyEngine and add sleep utility function
- Changed the event emission for 'loadstart' to be asynchronous using setTimeout.
- Introduced a new utility function 'sleep' to facilitate delayed execution in promises.
feat: enhance mediabunny proxy with new options and source handling
- Added options for event delay, load timeout, timeupdate interval, AV sync tolerance, poster, and source in README.
- Implemented source normalization in audio and video engines to support URL, Blob, and ReadableStream.
- Updated mediabunny engine to handle new options and improve load handling with timeout and error management.
- Enhanced video engine to draw a poster when no video source is available and manage playback rate.
- Modified shim to accept source option and integrate with the new engine options.
- Updated TypeScript definitions to reflect new options and source types.
feat: add dropLateFrames option to video and mediabunny engines
- Introduced dropLateFrames option in mediabunnyEngine and videoEngine to control frame dropping behavior.
- Updated videoEngine logic to handle frame rendering based on the dropLateFrames setting.
- Added type definition for dropLateFrames in TypeScript declaration file.
fix: delay loadstart event emission to ensure proper event handling
The 'loadstart' event emission is now wrapped in a setTimeout to ensure it is triggered after the current call stack is cleared. This change aims to improve the timing of event emissions and prevent potential issues with event handling in the mediabunny engine.
feat: add preflight range check and drop late frames option
- Updated README.md to include new options: dropLateFrames and preflightRange.
- Enhanced mediabunnyEngine to support new options with default values.
- Implemented preflight function in videoEngine to check server support for Range requests.
- Adjusted videoEngine to utilize preflight check before loading media.
- Updated TypeScript definitions to include preflightRange option.
Remove aspectRatio option from Artplayer configuration
Update README and mediabunny example URL for consistency
Refactor code structure for improved readability and maintainability
Update dependencies and fix play/seek state management in mediabunnyEngine
- Removed !important from background-image in the art-bottom class.
- Increased blur effect to 12px for the art-liquid-glass class.
- Changed background color to a darker rgba value for better visibility.
- Updated Artplayer class to specify environment as 'development' | 'production'.
- Refined template query method to return specific element types.
- Improved event proxy method to handle multiple event names.
- Enhanced storage get method to support both key retrieval and full record retrieval.
- Modified i18n interface to include language initialization and partial language records.
- Adjusted notice interface to provide a getter for show state and a setter for messages.
- Updated layers, controls, and contextmenu to allow undefined elements.
- Enhanced subtitle interface with initialization method.
- Refined hotkey methods to use KeyboardEvent instead of Event.
- Updated setting methods to return updated settings instead of arrays.
- Improved plugin method to return a promise.
- Added new events for video handling and refined existing event parameters.
- Enhanced option interface for proxy and plugins to support promises.
- Updated player interface to include reset method.
- Refined setting props to allow optional values.
- Enhanced template interface with additional control elements.
- Improved utils methods for querying and manipulating DOM elements.
fix: update type definitions for notice and subtitle properties, and refine event types
fix: remove unnecessary console warnings in event listener error handling
fix: refactor event listener management to use Set for better performance and error handling
Implement code changes to enhance functionality and improve performance
chore: add initial empty files for artplayer.d.ts, llm.txt, and build-llm.js
Refactor Artplayer examples for improved readability and consistency
- Updated mobile.js to enhance code formatting and structure.
- Refined mpegts.js for better readability and consistency in function usage.
- Improved multiple.subtitles.js with clearer structure and modern syntax.
- Enhanced setting.test.js for better organization and clarity in settings management.
- Streamlined thumbnail.js for consistent formatting.
- Updated vast.js for improved readability and consistency in plugin usage.
- Refined vtt.thumbnail.js for better code organization.
- Enhanced webtorrent.js for improved readability and consistency in async handling.
- Updated TypeScript definitions for various plugins to maintain consistency in export statements.
- Adjusted package.json linting script to include TypeScript files in the docs/assets/ts directory.
- Removed outdated types.test.js file to clean up the test suite.
refactor: remove outdated documentation files and update translation script
- Deleted i18n.md and option.md documentation files as they are no longer needed.
- Updated trans-docs.js to streamline the translation process and improve error handling.
- Adjusted plugin template package.json for consistency.
- Changed console.log to console.warn in various test files for better logging practices.
feat: add danmaku plugin documentation and i18n support
- Introduced comprehensive documentation for the Danmaku library, including installation, usage examples, and configuration options.
- Added language settings documentation, highlighting the need for manual language imports starting from version 5.1.0.
- Updated basic options documentation with detailed descriptions and examples for player configuration options.
Refactor documentation for clarity and consistency; update translation script to handle large Markdown chunks
refactor: improve documentation clarity and consistency across various components
- Updated property descriptions in layers.md and setting.md for better readability.
- Enhanced language and structure in index.md, danmuku.md, i18n.md, and option.md to ensure uniformity.
- Corrected minor grammatical errors and improved phrasing throughout the documentation.
- Ensured consistent formatting in tables and code snippets for better user experience.
feat: add build script for generating llm.txt and update translation source directories
Refactor build-llm.js to improve concurrency and enhance prompt clarity
- Introduced a MAX_CONCURRENT_REQUESTS constant to manage concurrent API requests.
- Added a runConcurrent function to handle task execution with a limit on concurrent requests.
- Updated the askDeepSeek function to include more informative logging.
- Enhanced prompts for summarizing documentation, TypeScript definitions, and JavaScript examples to improve clarity and maintain formatting.
- Modified the main function to fetch files concurrently and streamline the summarization process.
Increase text chunk size from 5000 to 8000 in summarizeSection function for improved processing of larger files.
fix: update lint script to include .js files in the scripts directory
- Added a null check for the target parameter in the check method of the Control class to prevent potential errors when target is undefined.
- Implemented a similar null check in the check method of the Setting class for consistency and error handling.
- Updated FULLSCREEN_WEB_IN_BODY property in Artplayer to true for enabling fullscreen mode in web environments.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the i18n setup guide with code snippets for better clarity and usability.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive i18n setup instructions, including default language settings, language imports, and examples for adding and modifying languages.
- Updated the structure and content of the i18n documentation to enhance clarity and usability.
- Implemented a new danmuku plugin in the React template for displaying bullet comments.
- Added internationalization (i18n) support with French and Indonesian languages.
- Updated the App component to include the new Player component with options for video playback.
- Enhanced the Player component to initialize Artplayer with plugins and language settings.
- Created separate files for App and Player components to improve code organization.
- Added example usage of language settings and plugins in the Player component.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive i18n (internationalization) setup instructions, including default language settings, language imports, and examples for adding and modifying languages.
- Updated the structure of the i18n documentation for better clarity and usability.
- Deleted Indonesian (id.mjs), Polish (pl.js, pl.mjs), Russian (ru.js, ru.mjs), Turkish (tr.js, tr.mjs), Vietnamese (vi.js, vi.mjs), and Traditional Chinese (zh-tw.js, zh-tw.mjs) language files from the i18n directory.
- Updated package version in package.json from 5.3.0-beta.0 to 5.3.0-beta.1.
- Cleaned up screenfull.js by removing unnecessary code related to native API checks.
- Introduced a new static property REMOVE_SRC_WHEN_DESTROY in Artplayer to control whether the video source should be removed when the player is destroyed.
- Updated the destroy method in Artplayer to conditionally remove the video source based on the new property.
- Removed the line that sets the video source to an empty string in the Template class's destroy method, as this is now handled in Artplayer.
- Updated TypeScript definitions to include the new REMOVE_SRC_WHEN_DESTROY property.
- Created a new documentation file for the danmuku plugin with code examples.
- Added a comprehensive guide for language settings, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the i18n documentation to reflect changes in language handling and provide code snippets for implementation.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive i18n setup instructions, including default language settings, language imports, and examples for adding and modifying languages.
- Updated the structure of the i18n documentation for clarity and usability.
- Added sleep utility to introduce a delay before emitting resize events after opening and closing the document Picture-in-Picture.
- Updated the close function to be asynchronous for better handling of the sleep delay.
- Emit 'resize' event after adding the document Picture-in-Picture class to the player.
- Emit 'resize' event after removing the document Picture-in-Picture class from the player.
- Created a new documentation file for the danmuku plugin with interactive code examples.
- Added comprehensive language settings documentation, including default languages, import instructions, and examples for adding and modifying languages.
- Updated the i18n documentation to reflect changes in language handling and provide clearer examples for users.
- React: Removed unnecessary dependencies from useEffect in Artplayer component.
- Vue: Simplified instance emission in Artplayer component by removing nextTick.
- Build script: Added cpy to copy built i18n files to a new directory and set context to browser for Parcel.
- Implemented a build script to compile i18n files and copy them to the docs directory.
- Added compiled i18n files for Arabic, Czech, Spanish, Persian, French, Indonesian, Polish, Russian, Turkish, Vietnamese, and Traditional Chinese.
- Created an HTML file to demonstrate the usage of Artplayer with i18n support, including language options and a sample video.
- Created a new documentation file for the danmuku plugin with code examples for usage.
- Added comprehensive language settings documentation, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the i18n setup guide to reflect changes in language handling and provide code snippets for implementation.
- Created a new documentation file for the danmuku plugin with interactive code execution.
- Added comprehensive i18n setup instructions, including default language settings, language imports, and examples for adding and modifying languages.
- Introduced a test file to verify the integration of the danmuku plugin.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the i18n setup guide to reflect changes in language handling and provide code snippets for implementation.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, import methods, and how to add or modify languages.
- Updated the i18n setup guide to reflect changes in language handling and provide code snippets for implementation.
- Changed event handling from `art.proxy` to `art.on` for visibility change and pointer events in the ads and danmuku plugins to improve consistency and maintainability.
- Bumped version of the danmuku plugin from 5.1.8 to 5.1.9.
- Added pointer events to the global event initialization in the core to ensure proper event handling across the application.
- Added a check in the Artplayer constructor to throw an error if instantiated outside a browser environment.
- Updated the isBrowser utility to ensure both window and document are defined.
- Removed unused user agent checks for WeChat, IE, and Android from compatibility utilities.
- Updated TypeScript definitions to reflect the removal of unused properties.
- Added a basic test case for Artplayer initialization in SSR context.
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the structure of the i18n documentation to improve clarity and usability.
- Introduced a new globalInit function to manage document and window events.
- Replaced direct event proxies with a unified bindGlobalEvents method.
- Updated event handling in various modules to utilize the new global event system.
- Removed the deprecated documentInit module.
- Bumped version to 5.2.6 in package.json.
- Renamed variable `dpipOK` to `isSupported` for clarity in checking Document Picture-in-Picture support.
- Updated the `open` function to use the new `isSupported` variable.
- Removed redundant checks in the `close` function related to Document Picture-in-Picture support.
- Added `isSupported` and `isActive` properties to the plugin's result interface in TypeScript definitions.
- Cleaned up the code for better readability and maintainability.
- Implemented the core functionality of the Document Picture-in-Picture plugin.
- Created main plugin file `artplayer-plugin-document-pip.js` with support for opening and closing the PIP window.
- Added legacy support in `artplayer-plugin-document-pip.legacy.js`.
- Defined plugin options in `package.json` and included necessary metadata.
- Developed the main logic in `src/index.js`, including style copying and event handling.
- Created TypeScript definitions in `types/artplayer-plugin-document-pip.d.ts` for better type safety.
- Introduced `artplayer-plugin-pip` to enable Picture-in-Picture functionality.
- Updated `artplayer.d.ts` to export new types related to the plugin.
- Added example usage of the plugin in `pip.js`.
- Created TypeScript definitions for the plugin in `artplayer-plugin-pip.d.ts`.
- Implemented the plugin logic in `index.js` with necessary styles and event handling.
- Updated documentation to include the new plugin and its usage.
- Added README and package.json for the new plugin.
- Refactored rotation logic for web fullscreen to use a dedicated function.
- Added checks to prevent race conditions when applying rotation.
- Improved handling of native fullscreen orientation locking.
- Simplified class management for orientation states.
- Updated state retrieval to use constants for class names.
- Updated arrow-left.svg, arrow-right.svg, check.svg, and loading.svg to remove fill attributes from path elements for better flexibility in styling.
- Modified aspect-ratio.svg and config.svg to maintain consistency in SVG structure by removing unnecessary fill attributes.
- Ensured playback-rate.svg retains its structure while removing fill attributes for improved styling options.
chore: update lerna configuration formatting
chore: bump version in package.json to 6.0.0
fix: modify build scripts for improved readability and consistency
feat: enhance translation scripts with better error handling and progress tracking
chore: improve plugin creation script for better user experience
style: format svgo configuration for consistency
- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, importing languages, adding new languages, and modifying existing languages.
- Updated the i18n setup examples to reflect the latest changes in language handling.
- Introduced a new dataset attribute `data-id` to DOM elements for unique identification of danmuku items.
- Updated validation to include an optional `id` field for danmuku objects.
- Changed the property `$id` to `$index` for better clarity on its purpose as an index rather than a unique identifier.
- Ensured the `data-id` attribute is set for visibility control during hover interactions.
Refactor utility functions for improved readability and consistency
- Updated compatibility.js to use consistent line endings and formatting.
- Refactored component.js for better readability and structure, including consistent use of arrow functions and binding.
- Simplified dom.js functions with consistent formatting and improved readability.
- Enhanced emitter.js with consistent formatting and arrow function usage.
- Streamlined error.js for improved readability and consistency.
- Refactored file.js to use consistent formatting and improved readability.
- Improved format.js functions for better readability and consistency.
- Updated index.js to maintain consistent export formatting.
- Refactored property.js for improved readability and consistency.
- Enhanced subtitle.js with consistent formatting and improved readability.
- Refactored time.js for better readability and consistent formatting.
fix: update lint script to target only source files for consistency
Revert "fix: restore export statements for various plugins and update type definitions for better clarity"
This reverts commit b5e969d81ec765cd8a34b06e6ef4f232ef25087f.
fix: restore export statements for various plugins and update type definitions for better clarity
Refactor type definitions to use interfaces instead of type aliases for better extensibility and clarity across i18n, icons, option, player, quality, setting, subtitle, template, and utils modules.
- Replaced direct usage of event.composedPath() with a new utility function getComposedPath in Control component.
- Updated includeFromEvent function to utilize getComposedPath for better compatibility.
- Implemented getComposedPath function to ensure consistent event path retrieval across different browsers.
- Created a new documentation file for the danmuku plugin, detailing its usage and providing code examples.
- Added a comprehensive guide for language settings (i18n), including instructions for importing languages, setting default languages, and modifying language options.
- Included code snippets for initializing the Artplayer with different languages and examples for adding new languages.
- Simplified version display in context menu and template by directly importing version from package.json.
- Removed static version and environment methods from Artplayer class, replacing them with dynamic imports.
- Eliminated placeholder injection logic from build and dev scripts, streamlining the build process.
- Cleaned up build and dev scripts for better readability and maintainability.
- Updated the context menu version function to dynamically append the application version to the link and include a ref parameter in the URL.
- Removed the build version log from the initialization logs in the Artplayer class.
- Cleaned up the version and environment getters to return unquoted strings.
- Modified the config method to accept an initialization flag, allowing for configuration during the initial setup without triggering unnecessary updates.
- Updated the call to config in the constructor to pass the new initialization flag.
- Implemented an event listener for 'video:volumechange' to adjust the gain node's value based on the current volume of the artplayer instance.
- This enhancement ensures that the audio processing reflects the user's volume adjustments in real-time.
- Implemented pcmToWav function to convert PCM audio data to WAV format.
- Updated onAudioChunk callback to receive both PCM and WAV buffers.
- Modified TypeScript definitions to reflect changes in onAudioChunk parameter and append method.
- Renamed `hideTimeout` to `autoHideTimeout` for clarity.
- Updated the default options destructuring for better readability.
- Removed unnecessary comments and cleaned up the audio processing logic.
- Ensured that the audio buffer is processed correctly before sending to the `onAudioChunk` callback.
Refactor artplayerPluginAsr: Enhance audio capture and processing
- Introduced gainNode for audio output management.
- Added mediaStream and mediaStreamSource for fallback audio capture.
- Refactored startCapture and stopCapture functions for better clarity and error handling.
- Improved audio source setup with a dedicated function for capturing audio from video.
- Ensured proper disconnection of audio nodes and cleanup of resources on destroy.
feat: enhance ASR plugin with improved subtitle handling and styling
fix: rename autoClearTimer to hideTimer for consistency in ASR plugin
Update asr.js
feat: refactor ASR plugin to improve audio chunk handling and WebSocket management
Update asr.js
fix: rename autoClearTimeout to cleanupTimeout for consistency
Update asr.js
feat: refactor ASR handling and improve WebSocket management
Update index.js
feat: add append and clear functions to enhance audio chunk handling
Update asr.js
Update asr.js
feat: release version 2.0.0 of artplayer-plugin-asr
- Implemented core functionality for audio recording using AudioWorklet.
- Added support for configurable audio capture interval and sample rate.
- Introduced WAV encoding for recorded audio chunks.
- Created a new plugin structure with proper TypeScript definitions.
- Added legacy support for older environments.
- Updated package.json with necessary metadata and export configurations.
- Included comprehensive inline documentation for better maintainability.
- Moved the 'video:progress' event listener to be consistent with the RAF and timeupdate events.
- Ensured 'setBar' for 'loaded' is emitted during both RAF and video:progress events.
- Cleaned up the structure for better readability and maintainability.
The code changes in this commit update the video element in Artplayer to support custom canvas or video. This enhancement allows for more flexibility in handling video playback and rendering. Additionally, new options such as volume, autoplay, autoSize, screenshot, setting, loop, flip, playbackRate, aspectRatio, fullscreen, fullscreenWeb, miniProgressBar, and autoPlayback are added to provide more control over the video player. These changes improve the functionality and usability of Artplayer.
refactor: Update animation frame handling in artplayer-proxy-webav
The code changes replace the use of `requestAnimationFrame` with `setInterval` in the `start` function of `artplayer-proxy-webav`. This change improves the performance and stability of the animation frame handling, ensuring a smoother playback experience.
The code changes update the loadedTime getter in Artplayer to handle different scenarios. The getter now checks for the presence of the loadedTime property in the video element and returns it if available, otherwise it falls back to the previous logic of retrieving the buffered end time. This update improves the reliability and compatibility of Artplayer's loadedTime functionality.
The code changes update the loadedTime and playing getters in Artplayer to handle different scenarios. The loadedTime getter now checks for the presence of the loadedTime property in the video element and returns it if available, otherwise it falls back to the previous logic of retrieving the buffered end time. Similarly, the playing getter now checks for the presence of the playing property in the video element and returns it if available, otherwise it falls back to the previous logic of determining if the video is playing based on its current time, paused state, ended state, and ready state. These updates improve the reliability and compatibility of Artplayer's loadedTime and playing functionality.
The code changes update the heading for the library section in both the README and docs files. The heading is changed from "Library" to "Libraries" to provide a more accurate description of the content. This refactor improves the clarity and consistency of the documentation.
The code changes introduce new proxy options (`artplayer-proxy-webav` and `artplayer-proxy-libmedia`) in Artplayer, allowing for the use of third-party video and canvas proxies. This enhancement provides more flexibility in handling video playback and rendering, improving the overall performance and compatibility of Artplayer.
This commit updates the `libmedia.js`, `option.d.ts`, `index.js`, `template.js`, and `scheme/index.js` files in the Artplayer repository. The changes introduce a new `video` property in the `Option` type, allowing for the use of a custom video element in Artplayer. The `video` property can be set to `null`, an `HTMLCanvasElement`, or an `HTMLVideoElement`. This enhancement provides flexibility in rendering video content and improves compatibility with different platforms and use cases.
The build timestamp in Artplayer has been updated to "2024-08-15 23:17:21". This commit ensures that the build timestamp accurately reflects the latest changes made to the codebase.
This commit refactors the `thumbnails` implementation in Artplayer to improve code readability and maintainability. The code changes remove unnecessary variables and simplify the logic for displaying thumbnails. This refactor enhances the overall performance and user experience of the Artplayer plugin.
The code changes introduce a new `art.thumbnails` property that allows for dynamic setting of thumbnails in Artplayer. This feature enhances the user experience by providing a visual preview of the video content.
* chore: Bump artplayer-plugin-danmuku version to 5.1.0
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Refactor getDanmuTop function to handle additional cases
* chore: Refactor getDanmuTop function to handle additional cases
* chore: Update danmuku plugin with new mount option
* chore: Update danmuku plugin with new mount option
* chore: Refactor danmuku plugin to always create a new Setting instance
* Refactor danmuku plugin to always create a new Setting instance
* Refactor danmuku plugin to always create a new Setting instance
* Update danmuku.js
* Update danmuku.js
* Refactor danmuku plugin to include a new Setting instance
* Refactor danmuku plugin to include a new Setting instance
* Refactor danmuku plugin styles for better alignment and spacing
* Refactor danmuku plugin styles for better alignment and spacing
* Refactor danmuku plugin styles for better alignment and spacing
* Refactor danmuku plugin styles for better alignment and spacing
* Refactor danmuku plugin styles for better alignment and spacing
* chore: Update package.json files
* Refactor danmuku plugin to remove unnecessary whitespace in the setting template
* chore: Remove ESLint configuration files and update npm dependencies
* chore: Update ESLint configuration to disable console warnings and fix unused variable warnings
* chore: Update ESLint configuration to fix quotes rule
* Update package.json
* Update package.json
* Update setting.js
* chore: Compress CSS code in build script
* chore: Update build script to compress JavaScript code
* chore: Update build script to compress JavaScript code
* chore: Refactor setting.js to improve code organization and remove unused variables
* chore: Add isHover flag to Control component for better control hiding behavior
* chore: Update Control component to use $bottom instead of $controls for better control hiding behavior
* Update package.json
* Update package.json
* Update package.json
* chore: Update lerna.json to use independent versioning and yarn as npm client
* refactor: Update Danmuku class to support configurable modes and visibility
* refactor: Update Danmuku styles for better visibility and configurability
* feat: Update font weight in Danmuku styles for better readability
* refactor: Update Danmuku class to support configurable modes and visibility
* refactor: Add opacity, area, font, and speed sliders to Danmuku settings
* refactor: Initialize sliders for opacity, area, font, and speed in Danmuku settings
* feat: Add slider UI for opacity, area, and speed in Danmuku settings
* feat: Update slider styles in Danmuku settings for better visibility and configurability
* refactor: Improve Danmuku settings UI for better visibility and configurability
* refactor: Improve Danmuku settings UI for better visibility and configurability
* refactor: Update slider styles in Danmuku settings for better visibility and configurability
* refactor: Update margin slider initialization in Danmuku settings
* refactor: Update slider styles and initialization in Danmuku settings
* refactor: Update Danmuku class to support configurable visibility
* refactor: Update Danmuku class to support configurable visibility
* refactor: Update Danmuku class to support configurable visibility
* refactor: Update Danmuku class to support configurable visibility
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Improve Danmuku settings UI for better visibility and configurability
* add lock
* refactor: Add lock and unlock methods to Danmuku settings
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* Update artplayer-plugin-danmuku.d.ts
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings event listeners
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
* refactor: Update Danmuku settings UI for better visibility and configurability
Update progress bar height in Artplayer
Add dynamic layer, controller, menu, and setting item management
Update Changelog_CN
Update utils.js
Update package.json
Update built-in management in Artplayer
Update i18n documentation
Add support for new languages
Update language import and modification
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
- Fix safe area issue when enter web fullscreen [#1033](https://github.com/zhw2590582/ArtPlayer/issues/1033)
## [5.4.0] - 2026-03-12
- Refactor `Parcel` to `Vite`
- Change `Artplayer.FULLSCREEN_WEB_IN_BODY` defaults to `true`
- The `reset` method is used to reset video request
[ArtPlayer.js](https://artplayer.org) is an easy-to-use and feature-rich HTML5 video player, and most of the player's functional controls support customization, which makes it easy to connect with your business logic. In addition, it directly supports `.vtt`, `.ass` and `.srt` subtitle formats. Integration with other dependencies such as `flv.js`, `hls.js`, `dash.js`, etc. is also very simple. The code is highly decoupled, the structure and logic are clear, and it is easy to track errors and add new features.
[ArtPlayer.js](https://artplayer.org) is an easy-to-use and feature-rich HTML5 video player, and most of the player's functional controls support customization, which makes it easy to connect with your business logic. In addition, it directly supports `.vtt`, `.ass` and `.srt` subtitle formats. Integration with other dependencies such as `flv.js`, `hls.js`, `dash.js`, etc. is also very simple. The code is highly decoupled, the structure and logic are clear, and it is easy to track errors and add new features.
!function(t,e){"object"==typeofexports&&"undefined"!=typeofmodule?module.exports=e():"function"==typeofdefine&&define.amd?define(e):(t="undefined"!=typeofglobalThis?globalThis:t||self).artplayerPluginDanmuku=e()}(this,(function(){"use strict";functiont(t,e,n){returneint?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}functione(t,e){for(varn=0;n<e.length;n++){vari=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"ini&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}varn={"zh-cn":{"Danmu opacity":"弹幕透明度","Danmu speed":"弹幕速度","Danmu size":"弹幕大小","Danmu text cannot be empty":"弹幕文本不能为空","The length of the danmu does not exceed":"弹幕文本字数不能超过","Danmu speed synchronous playback multiple":"弹幕速度同步播放倍数"},"zh-tw":{"Danmu opacity":"彈幕透明度","Danmu speed":"彈幕速度","Danmu size":"弹幕大小","Danmu text cannot be empty":"彈幕文本不能為空","The length of the danmu does not exceed":"彈幕文本字數不能超過","Danmu speed synchronous playback multiple":"彈幕速度同步播放倍數"}};functioni(t){vare=t.i18n,n=t.events.proxy;return{name:"danmuku-opacity",index:10,html:'<div class="art-setting-header">'.concat(e.get("Danmu opacity"),': <span class="art-value">100</span>%</div><div class="art-setting-range"><input type="range" value="1" min="0.1" max="1" step="0.1"></div>'),mounted:function(e){vari=e.querySelector("input[type=range]"),r=e.querySelector(".art-value");n(i,"change",(function(){vare=i.value;r.innerText=100*Number(e),t.plugins.artplayerPluginDanmuku.config({opacity:Number(e)})})),t.on("artplayerPluginDanmuku:config",(function(t){i.value!==t.opacity&&(i.value=t.opacity,r.innerText=100*t.opacity)}))}}}functionr(t){vare=t.i18n,n=t.events.proxy;return{name:"danmuku-size",index:11,html:'<div class="art-setting-header">'.concat(e.get("Danmu size"),': <span class="art-value">25</span>px</div><div class="art-setting-range"><input type="range" value="25" min="14" max="30" step="1"></div>'),mounted:function(e){vari=e.querySelector("input[type=range]"),r=e.querySelector(".art-value");n(i,"change",(function(){vare=i.value;r.innerText=e,t.plugins.artplayerPluginDanmuku.config({fontSize:Number(e)})})),t.on("artplayerPluginDanmuku:config",(function(t){i.value!==t.fontSize&&(i.value=t.fontSize,r.innerText=t.fontSize)}))}}}functiona(t){vare=t.i18n,n=t.events.proxy;return{name:"danmuku-speed",index:12,html:'<div class="art-setting-header">'.concat(e.get("Danmu speed"),': <span class="art-value">5</span>s</div><div class="art-setting-range"><input type="range" value="5" min="1" max="10" step="1"></div>'),mounted:function(e){vari=e.querySelector("input[type=range]"),r=e.querySelector(".art-value");n(i,"change",(function(){vare=i.value;r.innerText=e,t.plugins.artplayerPluginDanmuku.config({speed:Number(e)})})),t.on("artplayerPluginDanmuku:config",(function(t){i.value!==t.speed&&(i.value=t.speed,r.innerText=t.speed)}))}}}functiono(t){vare=t.i18n,n=t.events.proxy;return{name:"danmuku-synchronousPlayback",index:13,html:'<label class="art-setting-checkbox"><input type="checkbox"/>'.concat(e.get("Danmu speed synchronous playback multiple"),"</label>"),mounted:function(e){vari=e.querySelector("input[type=checkbox]");n(i,"change",(function(){t.plugins.artplayerPluginDanmuku.config({synchronousPlayback:i.checked})})),t.on("artplayerPluginDanmuku:config",(function(t){i.checked!==t.synchronousPlayback&&(i.checked=t.synchronousPlayback)}))}}}functionu(t,e,n){returnt.filter((function(t){returnt.$state===e})).map(n)}functions(t,e){varn=t.getBoundingClientRect();returne?n[e]:n}functionl(t,e){(null==e||e>t.length)&&(e=t.length);for(varn=0,i=newArray(e);n<e;n++)i[n]=t[n];returni}functionc(t,e){returnfunction(t){if(Array.isArray(t))returnt}(t)||function(t,e){varn=null==t?null:"undefined"!=typeofSymbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){vari,r,a=[],o=!0,u=!1;try{for(n=n.call(t);!(o=(i=n.next()).done)&&(a.push(i.value),!e||a.length!==e);o=!0);}catch(t){u=!0,r=t}finally{try{o||null==n.return||n.return()}finally{if(u)throwr}}returna}}(t,e)||function(t,e){if(t){if("string"==typeoft)returnl(t,e);varn=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void0}}(t,e)||function(){thrownewTypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}functionp(t){switch(t){case1:case2:case3:default:return0;case4:case5:return1}}functionf(t){returnfetch(t).then((function(t){returnt.text()})).then((function(t){returnfunction(t){if("string"!=typeoft)return[];vare=t.match(/<d([\S ]*?>[\S ]*?)<\/d>/gi);returne&&e.length?e.map((function(t){vare=c(t.match(/<d p="(.+)">(.+)<\/d>/)Line truncated
!function(t,e){"object"==typeofexports&&"undefined"!=typeofmodule?module.exports=e():"function"==typeofdefine&&define.amd?define(e):(t="undefined"!=typeofglobalThis?globalThis:t||self).ArtplayerToolGithub=e()}(this,(function(){"use strict";"undefined"!=typeofglobalThis?globalThis:"undefined"!=typeofwindow?window:"undefined"!=typeofglobal?global:"undefined"!=typeofself&&self;vart={exports:{}};returnfunction(t,e){t.exports=function(){vart,e=function(t,e,r){returneint?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t},r=function(t){for(varr=1;r<arguments.length;r++){varn=null!=arguments[r]?arguments[r]:{},o=Object.keys(n);"function"==typeofObject.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter((function(t){returnObject.getOwnPropertyDescriptor(n,t).enumerable})))),o.forEach((function(r){e(t,r,n[r])}))}returnt},n=(function(t){vare=function(t){vare,r=Object.prototype,n=r.hasOwnProperty,o="function"==typeofSymbol?Symbol:{},i=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";functionu(t,e,r,n){varo=e&&e.prototypeinstanceofd?e:d,i=Object.create(o.prototype),a=newj(n||[]);returni._invoke=function(t,e,r){varn=f;returnfunction(o,i){if(n===l)thrownewError("Generator is already running");if(n===p){if("throw"===o)throwi;returnS()}for(r.method=o,r.arg=i;;){vara=r.delegate;if(a){varc=O(a,r);if(c){if(c===y)continue;returnc}}if("next"===r.method)r.sent=r._sent=r.arg;elseif("throw"===r.method){if(n===f)thrown=p,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n=l;varu=s(t,e,r);if("normal"===u.type){if(n=r.done?p:h,u.arg===y)continue;return{value:u.arg,done:r.done}}"throw"===u.type&&(n=p,r.method="throw",r.arg=u.arg)}}}(t,r,a),i}functions(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}t.wrap=u;varf="suspendedStart",h="suspendedYield",l="executing",p="completed",y={};functiond(){}functiong(){}functionv(){}varm={};m[i]=function(){returnthis};varw=Object.getPrototypeOf,b=w&&w(w(P([])));b&&b!==r&&n.call(b,i)&&(m=b);varx=v.prototype=d.prototype=Object.create(m);functionk(t){["next","throw","return"].forEach((function(e){t[e]=function(t){returnthis._invoke(e,t)}}))}functionL(t){vare;this._invoke=function(r,o){functioni(){returnnewPromise((function(e,i){!functione(r,o,i,a){varc=s(t[r],t,o);if("throw"!==c.type){varu=c.arg,f=u.value;returnf&&"object"==typeoff&&n.call(f,"__await")?Promise.resolve(f.__await).then((function(t){e("next",t,i,a)}),(function(t){e("throw",t,i,a)})):Promise.resolve(f).then((function(t){u.value=t,i(u)}),(function(t){returne("throw",t,i,a)}))}a(c.arg)}(r,o,e,i)}))}returne=e?e.then(i,i):i()}}functionO(t,r){varn=t.iterator[r.method];if(n===e){if(r.delegate=null,"throw"===r.method){if(t.iterator.return&&(r.method="return",r.arg=e,O(t,r),"throw"===r.method))returny;r.method="throw",r.arg=newTypeError("The iterator does not provide a 'throw' method")}returny}varo=s(n,t.iterator,r.arg);if("throw"===o.type)returnr.method="throw",r.arg=o.arg,r.delegate=null,y;vari=o.arg;returni?i.done?(r[t.resultName]=i.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=e),r.delegate=null,y):i:(r.method="throw",r.arg=newTypeError("iterator result is not an object"),r.delegate=null,y)}function_(t){vare={tryLoc:t[0]};1int&&(e.catchLoc=t[1]),2int&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}functionE(t){vare=t.completion||{};e.type="normal",deletee.arg,t.completion=e}functionj(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(_,this),this.reset(!0)}functionP(t){if(t){varr=t[i];if(r)returnr.call(t);if("function"==typeoft.next)returnt;if(!isNaN(t.length)){varo=-1,a=functionr(){for(;++o<t.length;)if(n.call(t,o))returnr.value=t[o],r.done=!1,r;returnr.value=e,r.done=!0,r};returna.next=a}}return{next:S}}functionS(){return{value:e,done:!0}}returng.prototype=x.constructor=v,v.constructor=g,v[c]=g.displayName="GeneratorFunction",t.isGeneratorFunction=function(t){vare="function"==typeoft&&t.constructor;return!!e&&(e===g||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){returnObject.setPrototypeOf?Object.setPrototypeOf(t,v):(t.__proto__=v,cint||(t[c]="GeneratorFunction")),t.prototype=Object.create(x),t},t.awrap=function(t){return{__await:t}},k(L.prototype),L.prototype[a]=function(){returnthis},t.AsyncIterator=L,t.async=function(e,r,n,o){vari=newL(u(e,r,n,o));returnt.isGeneratorFunction(r)?i:i.next().then((function(t){returnt.done?t.value:i.next()}))},k(x),x[c]="Generator",x[i]=function(){returnthis},x.toString=function(){return"[object Generator]"},t.keys=function(t){vare=[];for(varrint)e.push(r);returne.reverse(),functionr(){for(;e.length;){varn=e.pop();if(nint)returnr.value=n,r.done=!1,r}returnr.done=!0,r}},t.values=P,j.prototype={constructor:j,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sentLine truncated
!function(t,e){"object"==typeofexports&&"undefined"!=typeofmodule?module.exports=e():"function"==typeofdefine&&define.amd?define(e):(t="undefined"!=typeofglobalThis?globalThis:t||self).ArtplayerToolThumbnail=e()}(this,(function(){"use strict";functiont(t,e){if(!(tinstanceofe))thrownewTypeError("Cannot call a class as a function")}functione(t,e){for(varn=0;n<e.length;n++){vari=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"ini&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}functionn(t){if(void0===t)thrownewReferenceError("this hasn't been initialised - super() hasn't been called");returnt}functioni(t,e){returni=Object.setPrototypeOf||function(t,e){returnt.__proto__=e,t},i(t,e)}functiono(t){returno="function"==typeofSymbol&&"symbol"==typeofSymbol.iterator?function(t){returntypeoft}:function(t){returnt&&"function"==typeofSymbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeoft},o(t)}functionr(t,e){if(e&&("object"===o(e)||"function"==typeofe))returne;if(void0!==e)thrownewTypeError("Derived constructors may only return object or undefined");returnn(t)}functiona(t){returna=Object.setPrototypeOf?Object.getPrototypeOf:function(t){returnt.__proto__||Object.getPrototypeOf(t)},a(t)}vars={exports:{}};functionu(){}functionh(t){returnnewPromise((function(e){returnsetTimeout(e,t)}))}functionl(t,e,n){returnMath.max(Math.min(t,Math.max(e,n)),Math.min(e,n))}functionc(t){vare=function(){if("undefined"==typeofReflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeofProxy)return!0;try{returnBoolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();returnfunction(){varn,i=a(t);if(e){varo=a(this).constructor;n=Reflect.construct(i,arguments,o)}elsen=i.apply(this,arguments);returnr(this,n)}}u.prototype={on:function(t,e,n){vari=this.e||(this.e={});return(i[t]||(i[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){vari=this;functiono(){i.off(t,o),e.apply(n,arguments)}returno._=e,this.on(t,o,n)},emit:function(t){for(vare=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),i=0,o=n.length;i<o;i++)n[i].fn.apply(n[i].ctx,e);returnthis},off:function(t,e){varn=this.e||(this.e={}),i=n[t],o=[];if(i&&e)for(varr=0,a=i.length;r<a;r++)i[r].fn!==e&&i[r].fn._!==e&&o.push(i[r]);returno.length?n[t]=o:deleten[t],this}},s.exports=u,s.exports.TinyEmitter=u;varf=function(o){!function(t,e){if("function"!=typeofe&&null!==e)thrownewTypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&i(t,e)}(f,o);varr,a,s,u=c(f);functionf(){vare,i=arguments.length>0&&void0!==arguments[0]?arguments[0]:{};returnt(this,f),(e=u.call(this)).processing=!1,e.option={},e.setup(Object.assign({},f.DEFAULTS,i)),e.video=f.creatVideo(),e.duration=0,e.inputChange=e.inputChange.bind(n(e)),e.ondrop=e.ondrop.bind(n(e)),e.option.fileInput.addEventListener("change",e.inputChange),e.option.fileInput.addEventListener("dragover",f.ondragover),e.option.fileInput.addEventListener("drop",f.ondrop),e}returnr=f,a=[{key:"ondrop",value:function(t){t.preventDefault();vare=t.dataTransfer.files[0];this.loadVideo(e)}},{key:"setup",value:function(){vart=this,e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{};this.option=Object.assign({},this.option,e);varn=this.option,i=n.fileInput,o=n.delay,r=n.number,a=n.width,s=n.height,u=n.column;if(this.errorHandle(iinstanceofElement,"The 'fileInput' is not a Element"),"INPUT"!==i.tagName||"file"!==i.type){i.style.position="relative";varh=document.createElement("input");h.type="file",h.style.position="absolute",h.style.width="100%",h.style.height="100%",h.style.left="0",h.style.top="0",h.style.right="0",h.style.bottom="0",h.style.opacity="0",i.appendChild(h),this.option.fileInput=h}return["delay","number","width","height","column","begin","end"].forEach((function(e){t.errorHandle("number"==typeoft.option[e],"The '".concat(e,"' is not a number"))})),this.option.delay=l(o,10,1e3),this.option.number=l(r,10,1e3),this.option.width=l(a,10,1e3),this.option.height=l(s,10,1e3),this.option.column=l(u,1,1e3),this}},{key:"inputChange",value:function(){vart=this.option.fileInput.files[0];this.loadVideo(t)}},{key:"loadVideo",value:function(t){vare=this,n=this.option.delay;if(t){vari=this.video.canPlayType(t.type);this.errorHandle("maybe"===i||"probably"===i,"Playback of this file format is not supported: ".concat(t.type));varo=URL.createObjectURL(t);this.videoUrl=o,this.file=t,this.emit("file",this.file),this.video.src=o,h(n).then((function(){e.emit("video",e.video)})).catch((function(t){throwe.emit("error",t.message),t}))}}},{key:"start",value:function(){vart=this;if(!this.video.duration)returnh(1e3).then(this.start);vare=this.option,n=e.width,i=e.height,o=e.number,r=e.delay,a=e.begin,s=e.end;this.option.begin=l(a,0,this.video.duration),this.optionLine truncated
!function(t,e){"object"==typeofexports&&"undefined"!=typeofmodule?module.exports=e():"function"==typeofdefine&&define.amd?define(e):(t="undefined"!=typeofglobalThis?globalThis:t||self).Artplayer=e()}(this,(function(){"use strict";functiont(t,e){if(!(tinstanceofe))thrownewTypeError("Cannot call a class as a function")}functione(t,e){for(varr=0;r<e.length;r++){varn=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"inn&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}functionr(t,r,n){returnr&&e(t.prototype,r),n&&e(t,n),t}functionn(t){if(void0===t)thrownewReferenceError("this hasn't been initialised - super() hasn't been called");returnt}functiono(t,e){returno=Object.setPrototypeOf||function(t,e){returnt.__proto__=e,t},o(t,e)}functioni(t,e){if("function"!=typeofe&&null!==e)thrownewTypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&o(t,e)}functiona(t){returna="function"==typeofSymbol&&"symbol"==typeofSymbol.iterator?function(t){returntypeoft}:function(t){returnt&&"function"==typeofSymbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeoft},a(t)}functionc(t,e){if(e&&("object"===a(e)||"function"==typeofe))returne;if(void0!==e)thrownewTypeError("Derived constructors may only return object or undefined");returnn(t)}functionl(t){returnl=Object.setPrototypeOf?Object.getPrototypeOf:function(t){returnt.__proto__||Object.getPrototypeOf(t)},l(t)}!function(t,e){void0===e&&(e={});varr=e.insertAt;if(t&&"undefined"!=typeofdocument){varn=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===r&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=t:o.appendChild(document.createTextNode(t))}}('.art-video-player{zoom:1;-webkit-tap-highlight-color:rgba(0,0,0,0);-ms-high-contrast-adjust:none;background-color:#000;color:#eee;direction:ltr;display:flex;font-family:Roboto,Arial,Helvetica,sans-serif;font-size:14px;height:100%;line-height:1.3;margin:0auto;outline:0;position:relative;text-align:left;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%;z-index:20}.art-video-player*{box-sizing:border-box;margin:0;padding:0}.art-video-player::-webkit-scrollbar{width:5px}.art-video-player::-webkit-scrollbar-thumb{background-color:#666}.art-video-player::-webkit-scrollbar-thumb:hover{background-color:#ccc}.art-video-player.art-icon{align-items:center;display:inline-flex;justify-content:center;line-height:1.5}.art-video-player.art-iconsvg{fill:#fff}.art-video-playerimg{max-width:100%;vertical-align:top}@supports((-webkit-backdrop-filter:initial)or(backdrop-filter:initial)){.art-video-player.art-backdrop-filter{-webkit-backdrop-filter:saturate(180%)blur(20px);backdrop-filter:saturate(180%)blur(20px);background-color:rgba(0,0,0,.7)!important}}.art-video-player.art-video{background-color:#000;cursor:pointer;z-index:10}.art-video-player.art-poster,.art-video-player.art-video{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.art-video-player.art-poster{background-position:50%;background-repeat:no-repeat;background-size:cover;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:11}.art-video-player.art-subtitle{bottom:10px;color:#fff;display:none;font-size:20px;padding:020px;pointer-events:none;position:absolute;text-align:center;text-shadow:.5px.5px.5pxrgba(0,0,0,.5);width:100%;z-index:20}.art-video-player.art-subtitlep{height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;line-height:1.2;margin:5px00;word-break:break-all}.art-video-player.art-bilingualp:nth-child(n+2){transform:scale(.6);transform-origin:centertop}.art-video-player.art-subtitle-show.art-subtitle{display:block}.art-video-player.art-control-show.art-subtitle{bottom:50px}.art-video-player.art-danmuku{z-index:30}.art-video-player.art-danmuku,.art-video-player.art-layers{bottom:0;height:100%;left:0;overflow:hidden;pointer-events:none;position:absolute;right:0;top:0;width:100%}.art-video-player.art-layers{display:none;z-index:40}.art-video-player.art-layers.art-layer{pointer-events:auto}.art-video-player.art-layer-show.art-layers{display:block}.art-video-player.art-mask{align-items:center;bottom:0;display:none;height:100%;justify-content:center;left:0;overflow:hidden;pointer-events:none;position:absolute;right:0;top:0;width:100%;z-index:50}.art-video-player.art-mask.art-state{align-items:center;bottom:55px;display:flex;height:60px;justify-content:center;opacity:.6;position:absolute;right:30px;width:60px}.art-video-player.art-mask-show.art-mask{display:flex}.art-video-player.art-loading{align-items:center;bottom:0;display:none;height:100%;justify-content:center;left:0;pointer-events:none;position:Line truncated
Frozen source identities and complete upstream notice texts for selected site components and font references. Unresolved font/media and embedded provenance gates remain open; this inventory is not publication clearance.
Generated by yarn build:site-notices. Runtime asset URLs are retained; reviewed local patches are identified below.
The original 3.15.0 LICENSE is preserved unchanged; its missing MIT body is supplemented separately using the MIT text explicitly referenced by upstream. Exact reconstruction from the pinned source and lockfile establishes eight bundled package dependencies and webpack bootstrap; their complete notices and attribution are distributed below. ArtPlayer retains its reproducible lifecycle patch and the original script URL/UMD/CSS contracts.
The complete upstream Monaco LICENSE/ThirdPartyNotices are retained. The unmodified bundled Codicons font exactly matches @vscode/codicons 0.0.26; its historical README, CC BY 4.0 content license, MIT code license and added attribution are distributed below. Other site assets remain subject to their separate provenance reviews.
The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. The identified embedded-source and attribution review is complete for this frozen vendor boundary. Source records bind each component to its original notices; this inventory is not publication clearance. The original full lockfile and historical online Closure service are not recovered. Modified replicator and Emotion/Stylis copies retain upstream author licenses; the original Emotion online Closure stage is not claimed to be reproducible. MurmurHash credits include Gary Court and Austin Appleby. The customStringify snippet matches Stack Overflow answer revision 5 under CC BY-SA 4.0; its separate attribution, source and full license are supplied. This is a mixed-license bundle, not MIT-only.
Four selected font families only. CHAWP matches author bytes; other full notice references have explicit font-table differences. Other fonts and complete redistribution provenance remain open under SITE-07/VENDOR-05.
Included component: Liberation Sans 2.00.5 reference
functionca(a){a=["object"==typeofglobalThis&&globalThis,a,"object"==typeofwindow&&window,"object"==typeofself&&self,"object"==typeofglobal&&global];for(varb=0;b<a.length;++b){varc=a[b];if(c&&c.Math==Math)returnc}throwError("Cannot find global object");}vary=ca(this);functionz(a,b){if(b)a:{varc=y;a=a.split(".");for(vard=0;d<a.length-1;d++){vare=a[d];if(!(einc))breaka;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}}
z("Symbol",function(a){functionb(g){if(thisinstanceofb)thrownewTypeError("Symbol is not a constructor");returnnewc(d+(g||"")+"_"+e++,g)}functionc(g,f){this.h=g;ba(this,"description",{configurable:!0,writable:!0,value:f})}if(a)returna;c.prototype.toString=function(){returnthis.h};vard="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",e=0;returnb});
varha="function"==typeofObject.create?Object.create:function(a){functionb(){}b.prototype=a;returnnewb},ia;if("function"==typeofObject.setPrototypeOf)ia=Object.setPrototypeOf;else{varja;a:{varka={a:!0},la={};try{la.__proto__=ka;ja=la.a;breaka}catch(a){}ja=!1}ia=ja?function(a,b){a.__proto__=b;if(a.__proto__!==b)thrownewTypeError(a+" is not extensible");returna}:null}varma=ia;
functionna(a,b){a.prototype=ha(b.prototype);a.prototype.constructor=a;if(ma)ma(a,b);elsefor(varcinb)if("prototype"!=c)if(Object.defineProperties){vard=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}elsea[c]=b[c];a.za=b.prototype}functionoa(){this.m=!1;this.j=null;this.i=void0;this.h=1;this.v=this.s=0;this.l=null}functionpa(a){if(a.m)thrownewTypeError("Generator is already running");a.m=!0}oa.prototype.u=function(a){this.i=a};
functionta(a,b,c,d){try{vare=b.call(a.h.j,c);if(!(einstanceofObject))thrownewTypeError("Iterator result "+e+" is not an object");if(!e.done)returna.h.m=!1,e;varg=e.value}catch(f){returna.h.j=null,qa(a.h,f),ua(a)}a.h.j=null;d.call(a.h,g);returnua(a)}functionua(a){for(;a.h.h;)try{varb=a.i(a.h);if(b)returna.h.m=!1,{value:b.value,done:!1}}catch(c){a.h.i=void0,qa(a.h,c)}a.h.m=!1;if(a.h.l){b=a.h.l;a.h.l=null;if(b.na)throwb.ma;return{value:b.return,done:!0}}return{value:void0,done:!0}}
z("String.prototype.includes",function(a){returna?a:function(b,c){if(null==this)thrownewTypeError("The 'this' value for String.prototype.includes must not be null or undefined");if(binstanceofRegExp)thrownewTypeError("First argument to String.prototype.includes must not be a regular expression");return-1!==this.indexOf(b,c||0)}});varya=this||self;
functionWa(a){if(!a)returnXa||(Xa=newVa(0,0));if(!/^-?\d+$/.test(a))returnnull;if(16>a.length)Sa(Number(a));elseif(Ua)a=BigInt(a),G=Number(a&BigInt(4294967295))>>>0,H=Number(a>>BigInt(32)&BigInt(4294967295));else{varb=+("-"===a[0]);H=G=0;for(varc=a.length,d=b,e=(c-b)%6+b;e<=c;d=e,e+=6)d=Number(a.slice(d,e)),H*=1E6,G=1E6*G+d,4294967296<=G&&(H+=G/4294967296|0,G%=4294967296);b&&(b=A(Ta(G,H)),a=b.next().value,b=b.next().value,G=a,H=b)}returnnewVa(G,H)}varXa;functionYa(a,b){returnError("Invalid wire type: "+a+" (at position "+b+")")}functionZa(){returnError("Failed to read varint, encoding is invalid.")}function$a(a,b){returnError("Tried to read past the end of the data "+b+" > "+a)};functionK(){throwError("Invalid UTF8");}functionab(a,b){b=String.fromCharCode.apply(null,b);returnnull==a?b:a+b}varbb=void0,cb,db="undefined"!==typeofTextDecoder,eb,fb="undefined"!==typeofTextEncoder;vargb;functionhb(a){if(a!==Qa)throwError("illegal external caller");}functionib(a,b){hb(b);this.V=a;if(null!=a&&0===a.length)throwError("ByteString should be constructed with non-empty values");}functionjb(){returngb||(gb=newib(null,Qa))}functionkb(a){hb(Qa);varb=a.V;b=null==b||Ia&&null!=b&&binstanceofUint8Array?b:"string"===typeofb?Na(b):null;returnnull==b?b:a.V=b};functionlb(a){if("string"===typeofa)return{buffer:Na(a),C:!1};if(Array.isArray(a))return{buffer:newUint8Array(a),C:!1};if(a.constructor===Uint8Array)return{buffer:a,C:!1};if(a.constructor===ArrayBuffer)return{buffer:newUint8Array(a),C:!1};if(a.constructor===ib)return{buffer:kb(a)||Pa(),C:!0};if(ainstanceofUint8Array)return{buffer:newUint8Array(a.buffer,a.byteOffset,a.byteLength),C:!1};throwError("Type not convertible to a Uint8Array, expected a Uint8Array, an ArrayBuffer, a base64 encoded string, a ByteString or an Array of numbers");
functionob(a){varb=a.i,c=a.h,d=b[c++],e=d&127;if(d&128&&(d=b[c++],e|=(d&127)<<7,d&128&&(d=b[c++],e|=(d&127)<<14,d&128&&(d=b[c++],e|=(d&127)<<21,d&128&&(d=b[c++],e|=d<<28,d&128&&b[c++]&128&&b[c++]&128&&b[c++]&128&&b[c++]&128&&b[c++]&128)))))throwZa();L(a,c);returne}functionpb(a,b){if(0>b)throwError("Tried to read a negative byte length: "+b);varc=a.h,d=c+b;if(d>a.j)throw$a(b,a.j-c);a.h=d;returnc}varqb=[];functionrb(){this.h=[]}rb.prototype.length=function(){returnthis.h.length};rb.prototype.end=function(){vara=this.h;this.h=[];returna};functionsb(a,b,c){for(;0<c||127<b;)a.h.push(b&127|128),b=(b>>>7|c<<25)>>>0,c>>>=7;a.h.push(b)}functionM(a,b){for(;127<b;)a.h.push(b&127|128),b>>>=7;a.h.push(b)};functiontb(a,b){if(qb.length){varc=qb.pop();nb(c,a,b);a=c}elsea=newmb(a,b);this.h=a;this.j=this.h.h;this.i=this.l=-1;this.setOptions(b)}tb.prototype.setOptions=function(a){a=void0===a?{}:a;this.ca=void0===a.ca?!1:a.ca};tb.prototype.reset=function(){this.h.reset();this.j=this.h.h;this.i=this.l=-1};
functionub(a){varb=a.h;if(b.h==b.j)return!1;a.j=a.h.h;varc=ob(a.h)>>>0;b=c>>>3;c&=7;if(!(0<=c&&5>=c))throwYa(c,a.j);if(1>b)throwError("Invalid field number: "+b+" (at position "+a.j+")");a.l=b;a.i=c;return!0}
functionAb(a){P(a,1);returna}functionBb(a,b){R(b,(a|0)&-51)}functionCb(a,b){R(b,(a|18)&-41)};varDb={};functionEb(a){returnnull!==a&&"object"===typeofa&&!Array.isArray(a)&&a.constructor===Object}varFb,Gb=[];R(Gb,23);Fb=Object.freeze(Gb);functionHb(a){if(Q(a.o)&2)throwError("Cannot mutate an immutable Message");}functionIb(a){varb=a.length;(b=b?a[b-1]:void0)&&Eb(b)?b.g=1:(b={},a.push((b.g=1,b)))};functionJb(a){varb=a.i+a.G;returna.B||(a.B=a.o[b]={})}functionS(a,b){return-1===b?null:b>=a.i?a.B?a.B[b]:void0:a.o[b+a.G]}functionU(a,b,c,d){Hb(a);Kb(a,b,c,d)}functionKb(a,b,c,d){a.j&&(a.j=void0);b>=a.i||d?Jb(a)[b]=c:(a.o[b+a.G]=c,(a=a.B)&&bina&&deletea[b])}functionLb(a,b,c,d){vare=S(a,b);Array.isArray(e)||(e=Fb);varg=Q(e);g&1||Ab(e);if(d)g&2||P(e,2),c&1||Object.freeze(e);else{d=!(c&2);varf=g&2;c&1||!f?d&&g&16&&!f&&zb(e,16):(e=Ab(Array.prototype.slice.call(e)),Kb(a,b,e))}returne}
functionV(a,b,c){if(null!=c&&"number"!==typeofc)throwError("Value of float/double field must be a number|null|undefined, found "+typeofc+": "+c);U(a,b,c)}functionQb(a,b,c,d,e){Hb(a);varg=Nb(a,c,b,!1,!1);c=null!=d?d:newc;a=Lb(a,b,2,!1);void0!=e?(g.splice(e,0,c),a.splice(e,0,c.o)):(g.push(c),a.push(c.o));c.C()&&zb(a,8);returnc}functionRb(a,b){returnnull==a?b:a}functionW(a,b,c){c=void0===c?0:c;returnRb(Mb(a,b),c)};varSb;functionTb(a){switch(typeofa){case"number":returnisFinite(a)?a:String(a);case"object":if(a)if(Array.isArray(a)){if(0!==(Q(a)&128))returna=Array.prototype.slice.call(a),Ib(a),a}else{if(Ia&&null!=a&&ainstanceofUint8Array)returnKa(a);if(ainstanceofib){varb=a.V;returnnull==b?"":"string"===typeofb?b:a.V=Ka(b)}}}returna};functionUb(a,b,c,d){if(null!=a){if(Array.isArray(a))a=Vb(a,b,c,void0!==d);elseif(Eb(a)){vare={},g;for(gina)e[g]=Ub(a[g],b,c,d);a=e}elsea=b(a,d);returna}}functionVb(a,b,c,d){vare=Q(a);d=d?!!(e&16):void0;a=Array.prototype.slice.call(a);for(varg=0;g<a.length;g++)a[g]=Ub(a[g],b,c,d);c(e,a);returna}functionWb(a){returna.ja===Db?a.toJSON():Tb(a)}functionXb(a,b){a&128&&Ib(b)};functionYb(a,b,c){c=void0===c?Cb:c;if(null!=a){if(Ia&&ainstanceofUint8Array)returna.length?newib(newUint8Array(a),Qa):jb();if(Array.isArray(a)){vard=Q(a);if(d&2)returna;if(b&&!(d&32)&&(d&16||0===d))returnR(a,d|2),a;a=Vb(a,Yb,d&4?Cb:c,!0);b=Q(a);b&4&&b&2&&Object.freeze(a);returna}returna.ja===Db?Zb(a):a}}
void0;this.o=a;a:{g=this.o.length;d=g-1;if(g&&(g=this.o[d],Eb(g))){this.B=g;this.i=d-this.G;breaka}void0!==b&&-1<b?(this.i=Math.max(b,d+1-this.G),this.B=void0):this.i=Number.MAX_VALUE}if(!e&&this.B&&"g"inthis.B)throwError('Unexpected "g" flag in sparse object of message that is not a group type.');if(c){b=k&&!f&&!0;e=this.i;varn;for(k=0;k<c.length;k++)f=c[k],f<e?(f+=this.G,(d=a[f])?ac(d,b):a[f]=Fb):(n||(n=Jb(this)),(d=n[f])?ac(d,b):n[f]=Fb)}}
functionoc(a,b,c,d,e,g){b.P=a[0];varf=1;if(a.length>f&&"number"!==typeofa[f]){varh=a[f++];c(b,h)}for(;f<a.length;){c=a[f++];for(vark=f+1;k<a.length&&"number"!==typeofa[k];)k++;h=a[f++];k-=f;switch(k){case0:d(b,c,h);break;case1:(k=lc(a,f))?(f++,e(b,c,h,k)):d(b,c,h,a[f++]);break;case2:k=f++;k=lc(a,k);e(b,c,h,k,a[f++]);break;case3:g(b,c,h,a[f++],a[f++],a[f++]);break;case4:g(b,c,h,a[f++],a[f++],a[f++],a[f++]);break;default:throwError("unexpected number of binary field arguments: "+k);}}returnb}
d=void0===d?!1:d;if(fb){if(d&&/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/.test(b))throwError("Found an unpaired surrogate");b=(eb||(eb=newTextEncoder)).encode(b)}else{for(vare=0,g=newUint8Array(3*b.length),f=0;f<b.length;f++){varh=b.charCodeAt(f);if(128>h)g[e++]=h;else{if(2048>h)g[e++]=h>>6|192;else{if(55296<=h&&57343>=h){if(56319>=h&&f<b.length){vark=b.charCodeAt(++f);if(56320<=k&&57343>=k){h=1024*(h-55296)+k-56320+65536;g[e++]=h>>18|240;g[e++]=h>>12&63|128;
g[e++]=h>>6&63|128;g[e++]=h&63|128;continue}elsef--}if(d)throwError("Found an unpaired surrogate");h=65533}g[e++]=h>>12|224;g[e++]=h>>6&63|128}g[e++]=h&63|128}}b=e===g.length?g:g.subarray(0,e)}M(a.h,8*c+2);M(a.h,b.length);N(a,a.h.end());N(a,b)}}),Ec=Ac(function(a,b,c,d,e){if(2!==a.i)return!1;b=Qb(b,c,d);c=a.h.j;d=ob(a.h)>>>0;varg=a.h.h+d,f=g-c;0>=f&&(a.h.j=g,e(b,a,void0,void0,void0),f=g-a.h.h);if(f)throwError("Message parsing ended unexpectedly. Expected to read "+(d+" bytes, instead read "+
(d-f)+" bytes, either the data ended unexpectedly or the message misreported its own length"));a.h.h=g;a.h.j=c;return!0},function(a,b,c,d,e){b=Ob(b,d,c);if(null!=b)for(d=0;d<b.length;d++){varg=a;M(g.h,8*c+2);varf=g.h.end();N(g,f);f.push(g.i);g=f;e(b[d],a);f=a;varh=g.pop();for(h=f.i+f.h.length()-h;127<h;)g.push(h&127|128),h>>>=7,f.i++;g.push(h);f.i++}});functionFc(a){returnfunction(b,c){a:{if(wb.length){vard=wb.pop();d.setOptions(c);nb(d.h,b,c);b=d}elseb=newtb(b,c);try{vare=hc(a);varg=ic(newe.P,b,e);breaka}finally{e=b.h,e.i=null,e.m=!1,e.l=0,e.j=0,e.h=0,e.S=!1,b.l=-1,b.i=-1,100>wb.length&&wb.push(b)}g=void0}returng}}functionGc(a){returnfunction(){varb=newxb;rc(this,b,qc(a));N(b,b.h.end());for(varc=newUint8Array(b.i),d=b.j,e=d.length,g=0,f=0;f<e;f++){varh=d[f];c.set(h,g);g+=h.length}b.j=[c];returnc}};functionZ(a){X.call(this,a)}na(Z,X);varHc=[Z,1,Cc,2,Y,3,Dc,4,Dc];Z.prototype.l=Gc(Hc);functionIc(a){X.call(this,a,-1,Jc)}na(Ic,X);Ic.prototype.addClassification=function(a,b){Qb(this,1,Z,a,b);returnthis};varJc=[1],Kc=Fc([Ic,1,Ec,Hc]);functionLc(a){X.call(this,a)}na(Lc,X);varMc=[Lc,1,Y,2,Y,3,Y,4,Y,5,Y];Lc.prototype.l=Gc(Mc);functionNc(a){X.call(this,a,-1,Oc)}na(Nc,X);varOc=[1],Pc=Fc([Nc,1,Ec,Mc]);functionQc(a){X.call(this,a)}na(Qc,X);varRc=[Qc,1,Y,2,Y,3,Y,4,Y,5,Y,6,Bc],Sc=Fc(Rc);Qc.prototype.l=Gc(Rc);functionTc(a,b,c){c=a.createShader(0===c?a.VERTEX_SHADER:a.FRAGMENT_SHADER);a.shaderSource(c,b);a.compileShader(c);if(!a.getShaderParameter(c,a.COMPILE_STATUS))throwError("Could not compile WebGL shader.\n\n"+a.getShaderInfoLog(c));returnc};functionUc(a){returnOb(a,Z,1).map(function(b){varc=S(b,1);return{index:null==c?0:c,qa:W(b,2),label:null!=S(b,3)?Rb(S(b,3),""):void0,displayName:null!=S(b,4)?Rb(S(b,4),""):void0}})};functionVc(a){return{x:W(a,1),y:W(a,2),z:W(a,3),visibility:null!=Mb(a,4)?W(a,4):void0}};functionWc(a,b){this.i=a;this.h=b;this.m=0}
functioned(a){this.h=a;this.listeners={};this.l={};this.L={};this.s={};this.v={};this.M=this.u=this.ga=!0;this.I=Promise.resolve();this.fa="";this.D={};this.locateFile=a&&a.locateFile||ad;if("object"===typeofwindow)varb=window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/";elseif("undefined"!==typeoflocation)b=location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/";elsethrowError("solutions can only be loaded on a web page or in a web worker");
gd(a,a.h.graph.url),0):(n.h=0,n=void0);returnn})}(),D(p,Promise.all([l,k,m]),7);if("function"!==typeofimportScripts)throwError("solutions can only be loaded on a web page or in a web worker");d=b.filter(function(n){returnvoid0===n.simd||n.simd&&c||!n.simd&&!c}).map(function(n){returna.locateFile(n.url,a.ha)});importScripts.apply(null,ea(d));e=a;returnD(p,createMediapipeSolutionsWasm(Module),6);case6:e.i=p.i;a.m=newOffscreenCanvas(1,1);a.i.canvas=a.m;g=a.i.GL.createContext(a.m,{antialias:!1,
alpha:!1,va:"undefined"!==typeofWebGL2RenderingContext?2:1});a.i.GL.makeContextCurrent(g);p.h=4;break;case7:a.m=document.createElement("canvas");r=a.m.getContext("webgl2",{});if(!r&&(r=a.m.getContext("webgl",{}),!r))returnalert("Failed to create WebGL canvas context when passing video frame."),p.return();a.K=r;a.i.canvas=a.m;a.i.createContext(a.m,!0,!0,{});case4:a.j=newa.i.SolutionWasm,a.ga=!1,p.h=0}})}
varModule=typeofcreateMediapipeSolutionsWasm!="undefined"?createMediapipeSolutionsWasm:{};varreadyPromiseResolve,readyPromiseReject;Module["ready"]=newPromise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});["_main","_fflush","___getTypeName","__embind_initialize_bindings","onRuntimeInitialized"].forEach(prop=>{if(!Object.getOwnPropertyDescriptor(Module["ready"],prop)){Object.defineProperty(Module["ready"],prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}});varmoduleOverrides=Object.assign({},Module);vararguments_=[];varthisProgram="./this.program";varquit_=(status,toThrow)=>{throwtoThrow};varENVIRONMENT_IS_WEB=typeofwindow=="object";varENVIRONMENT_IS_WORKER=typeofimportScripts=="function";varENVIRONMENT_IS_NODE=typeofprocess=="object"&&typeofprocess.versions=="object"&&typeofprocess.versions.node=="string";varENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){thrownewError("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}varscriptDirectory="";functionlocateFile(path){if(Module["locateFile"]){returnModule["locateFile"](path,scriptDirectory)}returnscriptDirectory+path}varread_,readAsync,readBinary,setWindowTitle;functionlogExceptionOnExit(e){if(einstanceofExitStatus)return;lettoLog=e;if(e&&typeofe=="object"&&e.stack){toLog=[e,e.stack]}err("exiting due to exception: "+toLog)}if(ENVIRONMENT_IS_NODE){if(typeofprocess=="undefined"||!process.release||process.release.name!=="node")thrownewError("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");varfs=require("fs");varnodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?newURL(filename):nodePath.normalize(filename);returnfs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{varret=read_(filename,true);if(!ret.buffer){ret=newUint8Array(ret)}assert(ret.buffer);returnret};readAsync=(filename,onload,onerror)=>{filename=isFileURI(filename)?newURL(filename):nodePath.normalize(filename);fs.readFile(filename,function(err,data){if(err)onerror(err);elseonload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(exinstanceofExitStatus)){throwex}});process["on"]("unhandledRejection",function(reason){throwreason});quit_=(status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throwtoThrow}logExceptionOnExit(toThrow);process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}elseif(ENVIRONMENT_IS_SHELL){if(typeofprocess=="object"&&typeofrequire==="function"||typeofwindow=="object"||typeofimportScripts=="function")thrownewError("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeofread!="undefined"){read_=functionshell_read(f){returnread(f)}}readBinary=functionreadBinary(f){letdata;if(typeofreadbuffer=="function"){returnnewUint8Array(readbuffer(f))}data=read(f,"binary");assert(typeofdata=="object");returndata};readAsync=functionreadAsync(f,onload,onerror){setTimeout(()=>onload(readBinary(f)),0)};if(typeofscriptArgs!="undefined"){arguments_=scriptArgs}elseif(typeofarguments!="undefined"){arguments_=arguments}if(typeofquit=="function"){quit_=(status,toThrow)=>{logExceptionOnExit(toThrow);quit(status)}}if(typeofprint!="undefined"){if(typeofconsole=="undefined")console={};console.log=print;console.warn=console.error=typeofprintErr!="undefined"?printErr:print}}elseif(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}elseif(typeofdocument!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeofwindow=="object"||typeofimportScripts=="function"))thrownewError("notcompiledforthisenvironment(didyoubuildtoHTMLandtrytorunitnotontheweb,orsetENVIRONMENTtosomething-likenode-anLine truncated
varModule=typeofcreateMediapipeSolutionsWasm!="undefined"?createMediapipeSolutionsWasm:{};varreadyPromiseResolve,readyPromiseReject;Module["ready"]=newPromise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});["_main","_fflush","___getTypeName","__embind_initialize_bindings","onRuntimeInitialized"].forEach(prop=>{if(!Object.getOwnPropertyDescriptor(Module["ready"],prop)){Object.defineProperty(Module["ready"],prop,{get:()=>abort("You are getting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"),set:()=>abort("You are setting "+prop+" on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")})}});varmoduleOverrides=Object.assign({},Module);vararguments_=[];varthisProgram="./this.program";varquit_=(status,toThrow)=>{throwtoThrow};varENVIRONMENT_IS_WEB=typeofwindow=="object";varENVIRONMENT_IS_WORKER=typeofimportScripts=="function";varENVIRONMENT_IS_NODE=typeofprocess=="object"&&typeofprocess.versions=="object"&&typeofprocess.versions.node=="string";varENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){thrownewError("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)")}varscriptDirectory="";functionlocateFile(path){if(Module["locateFile"]){returnModule["locateFile"](path,scriptDirectory)}returnscriptDirectory+path}varread_,readAsync,readBinary,setWindowTitle;functionlogExceptionOnExit(e){if(einstanceofExitStatus)return;lettoLog=e;if(e&&typeofe=="object"&&e.stack){toLog=[e,e.stack]}err("exiting due to exception: "+toLog)}if(ENVIRONMENT_IS_NODE){if(typeofprocess=="undefined"||!process.release||process.release.name!=="node")thrownewError("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");varfs=require("fs");varnodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?newURL(filename):nodePath.normalize(filename);returnfs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{varret=read_(filename,true);if(!ret.buffer){ret=newUint8Array(ret)}assert(ret.buffer);returnret};readAsync=(filename,onload,onerror)=>{filename=isFileURI(filename)?newURL(filename):nodePath.normalize(filename);fs.readFile(filename,function(err,data){if(err)onerror(err);elseonload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(exinstanceofExitStatus)){throwex}});process["on"]("unhandledRejection",function(reason){throwreason});quit_=(status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throwtoThrow}logExceptionOnExit(toThrow);process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}elseif(ENVIRONMENT_IS_SHELL){if(typeofprocess=="object"&&typeofrequire==="function"||typeofwindow=="object"||typeofimportScripts=="function")thrownewError("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeofread!="undefined"){read_=functionshell_read(f){returnread(f)}}readBinary=functionreadBinary(f){letdata;if(typeofreadbuffer=="function"){returnnewUint8Array(readbuffer(f))}data=read(f,"binary");assert(typeofdata=="object");returndata};readAsync=functionreadAsync(f,onload,onerror){setTimeout(()=>onload(readBinary(f)),0)};if(typeofscriptArgs!="undefined"){arguments_=scriptArgs}elseif(typeofarguments!="undefined"){arguments_=arguments}if(typeofquit=="function"){quit_=(status,toThrow)=>{logExceptionOnExit(toThrow);quit(status)}}if(typeofprint!="undefined"){if(typeofconsole=="undefined")console={};console.log=print;console.warn=console.error=typeofprintErr!="undefined"?printErr:print}}elseif(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}elseif(typeofdocument!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeofwindow=="object"||typeofimportScripts=="function"))thrownewError("notcompiledforthisenvironment(didyoubuildtoHTMLandtrytorunitnotontheweb,orsetENVIRONMENTtosomething-likenode-anLine truncated
"use strict";asyncfunctionModule(i={}){varg,v=i,y=(...t)=>console.log(...t),h=(...t)=>console.error(...t);functionT(){j?.(v)}G=(t=>()=>{t(),self.wasmMemory=B,self.HEAPU8C=newUint8ClampedArray(B.buffer),self.HEAPU8=newUint8Array(B.buffer)})(G);functionP(t){throwt}varj,w,C,A,M,E,O,ie,oe,le=!1;functionG(){vart=B.buffer;w=newInt8Array(t),A=newInt16Array(t),C=newUint8Array(t),M=newUint16Array(t),E=newInt32Array(t),O=newUint32Array(t),ie=newFloat32Array(t),oe=newFloat64Array(t)}function$e(){{vart=62914560;B=newWebAssembly.Memory({initial:t/65536,maximum:32768})}G()}$e();varX=t=>Xe(t),Q=()=>Qe(),B,fe=newTextDecoder,Z=(t,r,n,s)=>{varo=r+n;if(s)returno;for(;t[r]&&!(r>=o);)++r;returnr},q=(t,r,n)=>{if(!t)return"";vars=Z(C,t,r,n);returnfe.decode(C.subarray(t,s))},Ce=(t,r,n,s)=>P(`Assertion failed: ${q(t)}, at: `+[r?q(r):"unknown filename",n,s?q(s):"unknown function"]);function_e(t,r,n){return0}varwe=(t,r,n)=>{};functiontr(t,r,n){return0}functionnr(t,r,n,s){}varar=()=>P(""),sr=(t,r,n,s,o)=>{},U=t=>{for(varr="";;){varn=C[t++];if(!n)returnr;r+=String.fromCharCode(n)}},J={},K={},ue={},N=classextendsError{constructor(r){super(r),this.name="BindingError"}},$=t=>{thrownewN(t)};functionir(t,r,n={}){vars=r.name;if(t||$(`type "${s}" must have a positive integer typeid pointer`),K.hasOwnProperty(t)){if(n.ignoreDuplicateRegistrations)return;$(`Cannot register type '${s}' twice`)}if(K[t]=r,deleteue[t],J.hasOwnProperty(t)){varo=J[t];deleteJ[t],o.forEach(l=>l())}}functionL(t,r,n={}){returnir(t,r,n)}varor=(t,r,n,s)=>{r=U(r),L(t,{name:r,fromWireType:function(o){return!!o},toWireType:function(o,l){returnl?n:s},readValueFromPointer:function(o){returnthis.fromWireType(C[o])},destructorFunction:null})},lr=t=>({count:t.count,deleteScheduled:t.deleteScheduled,preservePointerOnDelete:t.preservePointerOnDelete,ptr:t.ptr,ptrType:t.ptrType,smartPtr:t.smartPtr,smartPtrType:t.smartPtrType}),Te=t=>{functionr(n){returnn.$$.ptrType.registeredClass.name}$(r(t)+" instance already deleted")},Pe=!1,Me=t=>{},fr=t=>{t.smartPtr?t.smartPtrType.rawDestructor(t.smartPtr):t.ptrType.registeredClass.rawDestructor(t.ptr)},Re=t=>{t.count.value-=1;varr=t.count.value===0;r&&fr(t)},ee=t=>globalThis.FinalizationRegistry?(Pe=newFinalizationRegistry(r=>{Re(r.$$)}),ee=r=>{varn=r.$$,s=!!n.smartPtr;if(s){varo={$$:n};Pe.register(r,o,r)}returnr},Me=r=>Pe.unregister(r),ee(t)):(ee=r=>r,t),ce=[],ur=()=>{for(;ce.length;){vart=ce.pop();t.$$.deleteScheduled=!1,t.delete()}},Ee,cr=()=>{lett=de.prototype;Object.assign(t,{isAliasOf(n){if(!(thisinstanceofde)||!(ninstanceofde))return!1;vars=this.$$.ptrType.registeredClass,o=this.$$.ptr;n.$$=n.$$;for(varl=n.$$.ptrType.registeredClass,u=n.$$.ptr;s.baseClass;)o=s.upcast(o),s=s.baseClass;for(;l.baseClass;)u=l.upcast(u),l=l.baseClass;returns===l&&o===u},clone(){if(this.$$.ptr||Te(this),this.$$.preservePointerOnDelete)returnthis.$$.count.value+=1,this;varn=ee(Object.create(Object.getPrototypeOf(this),{$$:{value:lr(this.$$)}}));returnn.$$.count.value+=1,n.$$.deleteScheduled=!1,n},delete(){this.$$.ptr||Te(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&$("Object already scheduled for deletion"),Me(this),Re(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void0,this.$$.ptr=void0)},isDeleted(){return!this.$$.ptr},deleteLater(){returnthis.$$.ptr||Te(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&$("Object already scheduled for deletion"),ce.push(this),ce.length===1&&Ee&&Ee(ur),this.$$.deleteScheduled=!0,this}});constr=Symbol.dispose;r&&(t[r]=t.delete)};functionde(){}varke=(t,r)=>Object.defineProperty(r,"name",{value:t}),We={},Ue=(t,r,n)=>{if(t[r].overloadTable===void0){vars=t[r];t[r]=function(...o){returnt[r].overloadTable.hasOwnProperty(o.length)||$(`Function '${n}' called with an invalid number of arguments (${o.length}) - expects one of (${t[r].overloadTable})!`),t[r].overloadTable[o.length].apply(this,o)},t[r].overloadTable=[],t[r].overloadTable[s.argCount]=s}},dr=(t,r,n)=>{v.hasOwnProperty(t)?((n===void0||v[t].overloadTable!==void0&&v[t].overloadTable[n]!==void0)&&$(`Cannot register public name '${t}' twice`),Ue(v,t,t),v[t].overloadTable.hasOwnProperty(n)&&$(`Cannot register multiple overloads of a function with the same number of arguments (${n})!`),v[t].overloadTable[n]=r):(v[t]=r,v[t].argCount=n)},vr=48,pr=57,gr=t=>{t=t.replace(/[^a-zA-Z0-9_]/g,"$");varr=t.charCodeAt(0);returnr>=vr&&r<=pr?`_${t}`:t};functionbr(t,r,n,s,o,l,u,f){this.name=t,this.constructor=r,this.instancePrototype=n,this.rawDestructor=s,this.baseClass=o,this.getActualType=l,this.upcast=u,this.downcast=f,this.pureVirtualFunctions=[]}varve=(t,r,n)=>{for(;r!==n;)r.upcast||$(`Expected null or instance of ${n.name}, got an instance of ${r.name}`),t=r.upcast(t),r=r.baseClass;returnt},je=t=>{if(t===null)return"null";varr=typeoft;returnr==="object"||r==="array"||r==="function"?t.toString():""+t};functionhr(t,r){if(r===null)returnthis.isReferencLine truncated
Loaded 100 of 4308 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.