Commit Graph

70247 Commits

Author SHA1 Message Date
Engiber Lozada
01b300336b Property Editors: Added form control and mandatory support to editors in picker group(Color, Content, Date, Document, Eye dropper, Multi URL). (#20684)
* Added form control support to color picker.

* Avoid submit when readonly is true.

* Added mandatory support.

* Added form control support to date picker.

* Removed an unused import.

* Added form control and mandatory support to document picker.

* Added form control support to Eye dropper.

* Added. mandatory support for multi url picker also bind inner input in the eye dropper.

* Removed unused import.

* fix update of value

* fixing not needed override of get and set methods

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
2025-11-14 14:04:20 +00:00
Eric
6b4503cc7b Content Sorting: increase modal size (#20835)
Modal size increase for sorting content
2025-11-14 14:42:30 +01:00
Andy Butland
a4438e5b21 Decimal property editor: Flexibly parse decimal value with different separators (closes #20823) (#20828)
* Flexibly parse decimal value with different separators.

* Applied suggestions from code review.
2025-11-14 10:20:12 +09:00
Engiber Lozada
73847d1eff Property Editors: Added form control and mandatory support to editors in rich content group(Code editor, Markdown, Block grid) (#20693)
* Added mandatory support for block grid property editor.

* Added form control and mandatory support to code editor.

* Added form control and mandatory support to markdown editor.

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
2025-11-13 20:57:27 +00:00
Engiber Lozada
e549217e66 Content Type Designer: Use input-with-alias and implement regex validation for Alias. (#20755)
* Implemented input-with-alias in the content-type-design-editor.

* Added auto-generate-alias property to the input and revert deletion of checkAliasAutoGenerate method.

* Added form-validation-message.

* Added validation to the input-with-alias element to avoid special characters.
2025-11-13 20:42:48 +00:00
Engiber Lozada
8b076597b3 Entity Sign: Improve Firefox visibility and add focus support. (#20733)
* Chenged right and left position of the infobox.

* Added focus support to open the modal.

* Moved tabindex out the constructor and added support for enter and space keys.
2025-11-13 20:37:54 +00:00
Engiber Lozada
bbd30363a2 Media Picker: Remove duplicate loaders in media cards. (#20793)
* Removed isLoding condition from the rich media input and let the thumbnail handle the loader.

* Removed unused import.

* change loader and adjust lit property configuration

* update reflect configuration

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
2025-11-13 20:38:32 +01:00
Andreas Zerbst
617d301479 Hides the content files that come from the Microsoft.CodeAnalysis.Workspaces.Common package in the web.ui project in 17 (#20825)
* Hide content files

* Update src/Umbraco.Web.UI/Umbraco.Web.UI.csproj

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 14:39:51 +00:00
Jacob Overgaard
931041c635 Merge remote-tracking branch 'origin/v16/dev' 2025-11-13 14:19:10 +01:00
Jacob Overgaard
15c6ca7628 Merge remote-tracking branch 'origin/release/16.4' into v16/dev 2025-11-13 14:15:24 +01:00
Mathias Helsengren
714fbf3119 Keyboard navigation: Return to opening element after modal close (#20782)
Removed the detroy from the modelContext.
It being destroyed prevented the uui-button getting into focus again after closing the modal.
2025-11-13 12:55:45 +01:00
Jacob Overgaard
eeda55c06f Preview: Add validation support to Save and Preview button (closes #20616) (#20805)
* chore(mock): adds missing try/catch around document lookup

* fix: lets the 'save and preview' button extend the 'save' button to follow the same logic in terms of when it enables/disabled - it did not have much logic before

* fix: runs validation from the server when save and previewing to ensure the UI shows what is missing
2025-11-13 11:25:17 +00:00
Andy Butland
597eb58063 Merge branch 'release/17.0'
# Conflicts:
#	src/Umbraco.Web.UI.Client/package.json
#	version.json
2025-11-13 10:48:51 +01:00
NguyenThuyLan
b65d2b0ec7 Collection view test: update changes for v17 (#20812)
update extension for collection view test

Co-authored-by: Lan Nguyen Thuy <lnt@umbraco.dk>
2025-11-13 16:00:21 +07:00
Kenn Jacobsen
640f9f2615 Use HTTPS by default (#20813) 2025-11-13 09:47:08 +01:00
Andy Butland
f075223412 Relations: Exclude the relate parent on delete relation type from checks for related documents and media on delete, when disable delete with references is enabled (closes #20803) (#20811)
* Exclude the relate parent on delete relation type from checks for related documents and media on delete, when disable delete with references is enabled.

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Applied suggestions from code review.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 09:32:18 +01:00
Engiber Lozada
d4d4b8a50a Content Type Designer: Always register root route to support drag-and-drop into empty Generic tab. (#20809)
Always register root route to enable drag-drop on empty Generic tab.
2025-11-13 09:19:33 +01:00
Kenn Jacobsen
49ba89c22a Move access/refresh tokens to secure cookies (#20779)
* feat: adds the `credentials: include` header to all manual requests

* feat: adds `credentials: include` as a configurable option to xhr requests (and sets it by default to true)

* feat: configures the auto-generated fetch client from hey-api to include credentials by default

* Add OpenIddict handler to hide tokens from the back-office client

* Make back-office token redaction optional (default false)

* Clear back-office token cookies on logout

* Add configuration for backoffice cookie settings

* Make cookies forcefully secure + move cookie handler enabling to the BackOfficeTokenCookieSettings

* Use the "__Host-" prefix for cookie names

* docs: adds documentation on cookie settings

* build: sets up launch profile for vscode with new cookie recommended settings

* docs: adds extra note around SameSite settings

* docs: adds extra note around SameSite settings

* Respect sites that do not use HTTPS

* Explicitly invalidate potentially valid, old refresh tokens that should no longer be used

* Removed obsolete const

---------

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
2025-11-13 08:19:42 +01:00
Andy Butland
14f4c54312 Bumped version to 17.0.0-rc3. 2025-11-13 07:11:35 +01:00
Andy Butland
c295271757 Bumped version to 16.4.0-rc2. 2025-11-13 06:39:10 +01:00
NguyenThuyLan
139b528bda Database migrations: Support DateOnly and TimeOnly in syntax providers (#20784)
* sql column type map include dateonly and timeonly

* Split Mapper and add check null value

* Minor code tidy resolving a few warnings.

* add spaces

* clean code

---------

Co-authored-by: Lan Nguyen Thuy <lnt@umbraco.dk>
Co-authored-by: Andy Butland <abutland73@gmail.com>
2025-11-13 11:10:51 +07:00
Justin Neville
ca15aadf0e Fix for partial view caches not being cleared when content is publish… (#20794)
* Fix for partial view caches not being cleared when content is published/unpublished

* Update src/Umbraco.Core/Cache/Refreshers/Implement/ContentCacheRefresher.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Change logic for clearing partial view cache

* Changed logic to only clear partial cache when content is published/unpublished or trashed

---------

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2025-11-13 09:21:26 +09:00
Andreas Zerbst
c60cf90ffe E2E: QA added entity picker acceptance tests (#20776)
* Added entity picker settings

* Updated tests

* Updated nightly pipeline

* Updated tests

* Bumped versions

* Fixed indentation

* Added comments

* Cleaned up

* Removed duplicate

* Bumped version

* Updated naming
2025-11-12 10:18:53 +01:00
dependabot[bot]
c9fc2f2a19 Bump playwright and @playwright/test in /tests/Umbraco.Tests.AcceptanceTest (#20579)
* Bump playwright and @playwright/test

Bumps [playwright](https://github.com/microsoft/playwright) to 1.56.1 and updates ancestor dependency [@playwright/test](https://github.com/microsoft/playwright). These dependencies need to be updated together.


Updates `playwright` from 1.50.0 to 1.56.1
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.50.0...v1.56.1)

Updates `@playwright/test` from 1.50.0 to 1.56.1
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.50.0...v1.56.1)

---
updated-dependencies:
- dependency-name: playwright
  dependency-version: 1.56.1
  dependency-type: indirect
- dependency-name: "@playwright/test"
  dependency-version: 1.56.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bumped version of test helper

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nhu Dinh <hnd@umbraco.dk>
2025-11-12 13:33:21 +07:00
Andy Butland
cbdb1d567f Dependencies: Update to .NET 10 (#20796)
Update to .NET 10.
2025-11-11 19:18:17 +00:00
Niels Lyngsø
31072bab51 Stop using promise.reject to avoid the promise to resolve. (#20790) 2025-11-11 13:43:28 +00:00
Warren Buckley
9ad4a7eeba Adds Clear Clipboard button & logic (#20757)
* Adds new dictionary/localization item for the clipboard dialog clear all prompt

* Removes the wrapping uui-box and moved inside the component itself

* Adds Clear Clipboard button and logic

* Adds uui-box from outer components consuimg this into this component
* Adds a header to uui-box
* Adds a conditional uui-button when we have items in clipboard
* Adds confirm dialog/prompt to ask if user wants to clear all items

* Adds in general_clipboard item to use in the UUI-box header

* Removes extra space & moves the requestItems outside the for loop

* Be a better citizen

Make sure the promise for the modal is caught and we return out early if user explictiy cancels modal or presses ESC

* Cleanup my noisy comments for a re-review

---------

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
2025-11-11 11:50:23 +00:00
Sven Geusens
0858d02172 Single block migration (#20663)
* WiP blocklist migration

* Mostly working migration

* [WIP] deconstructed the migration to prefetch and process all data that requires the old definitions

* Working singleblock migration

* Abstracted some logic and applied it to settings elements too.

* Align class and file name.

* Minor code warning resolution.

* More and better comments + made classes internal where it made sense

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
2025-11-11 11:43:03 +00:00
Andy Butland
524912a893 Fix accidental update to global.json. 2025-11-11 11:37:00 +01:00
Andy Butland
d687c4365a Member types: Prepare container support (#20715)
* Add MemberType/MemberTypeContainer to supported EntityContainer object types

* Implement MemberTypeContainerRepository

* Prepare base controller for MemberTypeTreeControllerBase.

* Revert "Prepare base controller for MemberTypeTreeControllerBase."

This reverts commit ad213a23add5e511b1fba6580ca563156cd9c043.

* Added foldersOnly flag in readiness for support in 17.1.

* Added foldersOnly flag in readiness for support in 17.1 (2).

---------

Co-authored-by: Ronald Barendse <ronald@barend.se>
2025-11-11 19:18:52 +09:00
Jacob Overgaard
55769b1747 Merge remote-tracking branch 'origin/release/17.0' 2025-11-11 09:51:49 +01:00
Jacob Overgaard
0797a3fa59 Merge remote-tracking branch 'origin/release/16.4' 2025-11-11 09:51:13 +01:00
NguyenThuyLan
41582de9d1 Collection view: add tests for create and using collection view (#20667)
* write test for custom collection view test

* add clean

* Update tests/Umbraco.Tests.AcceptanceTest/tests/ExtensionRegistry/CollectionView.spec.ts

Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>

---------

Co-authored-by: Lan Nguyen Thuy <lnt@umbraco.dk>
Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>
2025-11-11 14:46:54 +07:00
Andy Butland
cfa32b265a Integration Tests: Avoid asserting on errors for permission tests (#20643)
* Added integration tests for PropertyTypeUsageService and adjusted assert in management API permissions test.

* Commented or fixed management API integration tests verifying permissions where we were asserting on an error response.
2025-11-11 05:59:25 +00:00
Mathias Helsengren
d8198d2f5c Accessibility: Adding a label attribute for <uui-button> in news dashboard (#20780)
Added 'label attribute to the uui-button in the umb-news.card.element + Removing the redundant text for uui-button since label attribute is now present
2025-11-11 06:33:31 +01:00
Niels Lyngsø
12b483ff05 Fix block list inline mode (#20745)
* Fix block list inline mode

https://github.com/umbraco/Umbraco-CMS/issues/20618

* Fixed potential runtime errors

* Code cleanup

* Fixed Code Health Review

* Revert some changes

Commented out unused state properties and related code.

* Remove commented-out state property in block workspace view

* fix localization

* no need for question mark after ids, they should be presented as required

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
Co-authored-by: Niels Lyngsø <nsl@umbraco.dk>
2025-11-10 17:42:16 +01:00
Niels Lyngsø
43688148ae Cherry pick #20745 2025-11-10 17:40:58 +01:00
Andrej Davidovic
9fa382e84d Fix block list inline mode (#20745)
* Fix block list inline mode

https://github.com/umbraco/Umbraco-CMS/issues/20618

* Fixed potential runtime errors

* Code cleanup

* Fixed Code Health Review

* Revert some changes

Commented out unused state properties and related code.

* Remove commented-out state property in block workspace view

* fix localization

* no need for question mark after ids, they should be presented as required

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
Co-authored-by: Niels Lyngsø <nsl@umbraco.dk>
2025-11-10 16:17:30 +00:00
Jacob Overgaard
ab51aac5c6 Backoffice Item Pickers: Show error for missing items in 10 picker types (closes #19329, #20270, #20367) (#20762)
* Add errorDetail property to umb-entity-item-ref

Add optional errorDetail property to display additional context
(such as file paths or IDs) in error states. This enhances the
error display to show both the error message and relevant details.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Make _removeItem protected in UmbPickerInputContext

Change #removeItem from private to protected to allow subclasses
to reuse the removal logic while customizing the confirmation dialog.
This enables better extensibility for specialized picker contexts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix static file picker to show error state for missing files

Update umb-input-static-file to observe statuses and render based
on item state (loading, error, success). When a static file is
missing (API returns empty array), displays error state with alert
icon and file path detail using umb-entity-item-ref.

Also adds standalone property support for proper single-item styling.

Fixes #19329

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Show file path in static file remove confirmation dialog

Override requestRemoveItem in UmbStaticFilePickerInputContext to
display the file path instead of "Not found" in the confirmation
dialog when removing missing static files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Show GUID in document picker error state

Display the document GUID as errorDetail when a document is
not found (deleted/gone). This provides useful context for
editors to identify which document was referenced.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Show GUID in document picker remove confirmation dialog

Display the document GUID instead of "Not found" in the remove
confirmation dialog when the document no longer exists. This
provides useful context for editors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: apply the temp model which the context uses

* Refactor: Move requestRemoveItem logic to base UmbPickerInputContext

Eliminated duplicate code across three picker contexts by:
- Adding protected getItemDisplayName() method to base class
- Moving requestRemoveItem implementation to base class
- Removing duplicate implementations from document, member, and static file pickers
- Static file picker overrides getItemDisplayName() to show file path

Net reduction: 19 lines of code (69 removed, 50 added)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Document Type Picker: Show error state for missing items (fixes #20367)

Apply the same error state handling to the document type picker that was
implemented for static files, documents, and members. When a referenced
document type is missing or deleted:

- Show error state with the GUID as errorDetail
- Allow removal with proper confirmation dialog
- Use umb-entity-item-ref for error display
- Use uui-ref-node-document-type for successful items

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Additional pickers: Show error states for missing items in user, language, media-type, member-type, member-group, and user-group pickers

Apply the same error state handling pattern to six additional picker types:
- user-input: Users
- input-language: Languages
- input-media-type: Media types
- input-member-type: Member types
- input-member-group: Member groups
- user-group-input: User groups

All pickers now:
- Observe statuses from UmbRepositoryItemsManager
- Show error state with GUID when referenced item is missing/deleted
- Use umb-entity-item-ref for error display
- Use specialized components (uui-ref-node, umb-user-group-ref, etc.) for successful items
- Allow removal with proper confirmation dialog showing GUID

Maintains code reusability by using the base class requestRemoveItem method
with getItemDisplayName() for consistent error handling across all pickers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Lint: Remove unused 'when' imports from input-media-type and user-group-input

* Refactor: Add #renderItem helper method to all pickers for consistency

- Add #renderItem to user-input (extracted from inline repeat callback)
- Change _renderItem to #renderItem in user-group-input for consistency
- Change _renderItem to #renderItem in input-static-file for consistency

All 10 pickers now use consistent #renderItem helper method pattern,
improving code readability and maintainability as suggested by @nielslyngsoe

* `import` sorting

* Corrected (old) JSDoc typos

* Markup tidy-up

* exported `UmbPropertyEditorUIStaticFilePickerElement` as `element`

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: leekelleher <leekelleher@gmail.com>
2025-11-10 12:57:24 +00:00
Niels Lyngsø
afec900204 Merge branch 'release/17.0'
# Conflicts:
#	src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs
2025-11-10 12:46:47 +01:00
Jacob Overgaard
89989d60ce Templates: Fix "Discard changes?" dialog after creating template with master template (fixes #20262) (#20749)
Moves the _data.updateCurrent() call inside the updateLayoutBlock conditional
in setMasterTemplate(). This prevents spurious change detection when loading
templates from the server, while maintaining proper change tracking when users
actually modify the master template via the UI.

This completes the fix started in PR #20529 which added the updateLayoutBlock
parameter but inadvertently left the data model update outside the conditional.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 11:00:43 +00:00
Mathias Helsengren
73fd52aeea Login: Added custom validation for missing password and user/email on the login form (#20233)
* Added custom validation for missing password and user/email

* Changed some of the logic behind custom validation, so it now uses aria-errormessage

* fix: imports from src folder instead

* build(deps-dev): bump vite to 7.2.0

* formatting

* fix: moves the form into the login.page.element.ts component to better control submission

* fix: creates elements globally

* fix: adds id back to form

* fix: no need to store references to all form elements

* fix: errormessage should show with password field in a span as well

* fix: checks validity of form

* fix: constructs form in auth.element.ts anyway and append localization to validation and add oninput and onblur

* chore: fixes import paths

* fix: fixes special case where ?status was not reset

* fix: changes wording in english

* fix: removes duplicate en-us keys

* feat: adds ariaLive and role attributes

* fix: always clears the text

* fix: username required validation should switch between username and email

* package-lock.json updated on (re)install

* Renamed SVG eye icon filenames

to be conventional and kebab-cased.

---------

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Co-authored-by: leekelleher <leekelleher@gmail.com>
2025-11-10 10:21:33 +00:00
Niels Lyngsø
bce85e1e88 Package section: use command icon for migrations, remove prop (#20775)
change icon and remove ability to customize
2025-11-10 09:38:53 +00:00
Niels Lyngsø
e39b05f44d Property type: Vary in the same way as the owner Document Type (#20751)
set new property type preset to vary if document type varies
2025-11-10 10:28:40 +01:00
Niels Lyngsø
2067db1c3c Content Workspace: not displaying varying composition values in a not varying context (Fixes #20707) (#20758)
* only vary if context varies

* add controller aliases to these observations
2025-11-10 10:05:56 +01:00
Andy Butland
fcfaff9daa Querying: Restore ability to retrieve all children published in any culture (closes #20760) (#20766)
* Restore ability to retrieve all children published in any culture.

* Fixed typo in test name.
2025-11-10 11:02:10 +09:00
Luuk Peters
04918ec3d2 Slider property editor: Fix for preset value handling of enableRange (#20772)
Fix config value access in UmbSliderPropertyValuePreset

Updated the `UmbSliderPropertyValuePreset` class to ensure the `.value` property is accessed for configuration items. This change improves the accuracy of retrieving `enableRange`, `min`, `max`, and `step` values, addressing potential bugs in value processing.

Co-authored-by: Luuk Peters <Luuk.Peters@proudnerds.com>
2025-11-09 22:38:16 +01:00
Warren Buckley
aae316e17e Localization: Supply the display name to the localization key for the alt and title attributes of the 2FA QR code image (#20770)
Simple fix to supply the display name to the localization key for the 2FA QR Code Image
2025-11-09 13:41:41 +01:00
Andy Butland
ca08652a60 Installer: Fix issues with newsletter signup (#20705)
* Add setter to allow handling of requests to subscribe to newsletter on install.

* Correct serialization of newsletter subscription request.

* Fix serialization and use the Umbraco.EmailMarketing service for newsletter signup.

* Remove logging of user when setting telemetry level.

* Applied suggestions from code review.
2025-11-07 14:34:26 +01:00
NguyenThuyLan
b866c31105 Property action: Add tests for create and using Property Action UI Extension (#20291)
* add property action tests

* add extension property action code

* remove extension registry config

* update helper version

* Update tests/Umbraco.Tests.AcceptanceTest/tests/ExtensionRegistry/PropertyAction.spec.ts

Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>

* Update tests/Umbraco.Tests.AcceptanceTest/tests/ExtensionRegistry/PropertyAction.spec.ts

Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>

* Update tests/Umbraco.Tests.AcceptanceTest/tests/ExtensionRegistry/AdditionalSetup/App_Plugins/my-property-action/write-property-action.api.js

Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>

* Update tests/Umbraco.Tests.AcceptanceTest/tests/ExtensionRegistry/AdditionalSetup/App_Plugins/my-property-action/read-property-action.api.js

Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>

* change tab space size

---------

Co-authored-by: Lan Nguyen Thuy <lnt@umbraco.dk>
Co-authored-by: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com>
2025-11-07 15:02:21 +07:00