diff --git a/src-tauri/gen/schemas/acl-manifests.json b/src-tauri/gen/schemas/acl-manifests.json index 4e71cbfd..d1747390 100644 --- a/src-tauri/gen/schemas/acl-manifests.json +++ b/src-tauri/gen/schemas/acl-manifests.json @@ -1 +1 @@ -{"__app-acl__":{"default_permission":null,"permissions":{"dmnote-allow-all":{"identifier":"dmnote-allow-all","description":"Full DM Note command access for renderer","commands":{"allow":["app_auto_update","app_bootstrap","app_open_external","app_quit","app_restart","counter_animation_create","counter_animation_delete","counter_animation_list","counter_animation_update","css_get","css_get_use","css_load","css_reset","css_set_content","css_tab_clear","css_tab_get","css_tab_get_all","css_tab_load","css_tab_set","css_tab_toggle","css_toggle","custom_tabs_create","custom_tabs_delete","custom_tabs_list","custom_tabs_restore","custom_tabs_select","font_load","get_cursor_settings","graph_positions_get","graph_positions_update","image_load","js_get","js_get_use","js_load","js_reload","js_remove_plugin","js_reset","js_set_content","js_set_plugin_enabled","js_toggle","key_sound_get_output_state","key_sound_get_status","key_sound_list_output_devices","key_sound_load_soundpack","key_sound_set_enabled","key_sound_set_latency_logging","key_sound_set_output_backend","key_sound_set_volume","key_sound_unload_soundpack","keys_get","keys_get_counters","keys_reset_all","keys_reset_counters","keys_reset_counters_mode","keys_reset_mode","keys_reset_single_counter","keys_set_counters","keys_set_mode","keys_update","knob_positions_get","knob_positions_update","layer_groups_get","layer_groups_update","note_tab_clear","note_tab_get","note_tab_get_all","note_tab_set","obs_regenerate_token","obs_start","obs_status","obs_stop","overlay_get","overlay_resize","overlay_set_anchor","overlay_set_lock","overlay_set_visible","plugin_bridge_send","plugin_bridge_send_to","plugin_storage_clear","plugin_storage_clear_by_prefix","plugin_storage_get","plugin_storage_has_data","plugin_storage_keys","plugin_storage_remove","plugin_storage_set","positions_get","positions_update","preset_load","preset_load_tab","preset_save","preset_save_tab","raw_input_subscribe","raw_input_unsubscribe","settings_get","settings_update","sound_delete","sound_list","sound_load","sound_load_original","sound_save_processed_wav","sound_set_enabled","sound_update_processed_wav","stat_positions_get","stat_positions_update","window_close","window_minimize","window_open_devtools_all","window_show_main"],"deny":[]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file +{"__app-acl__":{"default_permission":null,"permissions":{"dmnote-allow-all":{"identifier":"dmnote-allow-all","description":"Full DM Note command access for renderer","commands":{"allow":["app_auto_update","app_bootstrap","app_open_external","app_quit","app_restart","counter_animation_create","counter_animation_delete","counter_animation_list","counter_animation_update","css_get","css_get_use","css_load","css_reset","css_set_content","css_tab_clear","css_tab_get","css_tab_get_all","css_tab_load","css_tab_set","css_tab_toggle","css_toggle","custom_tabs_create","custom_tabs_delete","custom_tabs_list","custom_tabs_restore","custom_tabs_select","font_load","get_cursor_settings","graph_positions_get","graph_positions_update","image_load","js_get","js_get_use","js_load","js_reload","js_remove_plugin","js_reset","js_set_content","js_set_plugin_enabled","js_toggle","key_sound_get_output_state","key_sound_get_status","key_sound_list_output_devices","key_sound_load_soundpack","key_sound_set_enabled","key_sound_set_latency_logging","key_sound_set_output_backend","key_sound_set_volume","key_sound_unload_soundpack","keys_get","keys_get_counters","keys_reset_all","keys_reset_counters","keys_reset_counters_mode","keys_reset_mode","keys_reset_single_counter","keys_set_counters","keys_set_mode","keys_update","knob_positions_get","knob_positions_update","layer_groups_get","layer_groups_update","note_tab_clear","note_tab_get","note_tab_get_all","note_tab_set","obs_regenerate_token","obs_start","obs_status","obs_stop","overlay_get","overlay_resize","overlay_set_anchor","overlay_set_lock","overlay_set_visible","plugin_bridge_send","plugin_bridge_send_to","plugin_storage_clear","plugin_storage_clear_by_prefix","plugin_storage_get","plugin_storage_has_data","plugin_storage_keys","plugin_storage_remove","plugin_storage_set","positions_get","positions_update","preset_load","preset_load_tab","preset_save","preset_save_tab","raw_input_subscribe","raw_input_unsubscribe","settings_get","settings_update","sound_delete","sound_list","sound_load","sound_load_original","sound_rename","sound_save_processed_wav","sound_update_processed_wav","stat_positions_get","stat_positions_update","window_close","window_minimize","window_open_devtools_all","window_show_main"],"deny":[]}}},"permission_sets":{},"global_scope_schema":null},"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file diff --git a/src-tauri/permissions/dmnote-allow-all.json b/src-tauri/permissions/dmnote-allow-all.json index d8560d52..b9e66679 100644 --- a/src-tauri/permissions/dmnote-allow-all.json +++ b/src-tauri/permissions/dmnote-allow-all.json @@ -105,8 +105,8 @@ "sound_list", "sound_load", "sound_load_original", + "sound_rename", "sound_save_processed_wav", - "sound_set_enabled", "sound_update_processed_wav", "stat_positions_get", "stat_positions_update", diff --git a/src-tauri/src/commands/keys/sound.rs b/src-tauri/src/commands/keys/sound.rs index e51e0912..85aa832a 100644 --- a/src-tauri/src/commands/keys/sound.rs +++ b/src-tauri/src/commands/keys/sound.rs @@ -35,7 +35,6 @@ pub struct SoundListItem { pub size_bytes: u64, #[serde(skip_serializing_if = "Option::is_none")] pub modified_at_ms: Option, - pub enabled: bool, pub source: SoundSource, #[serde(skip_serializing_if = "Option::is_none")] pub original_path: Option, @@ -70,16 +69,15 @@ pub struct SoundSaveProcessedWavResponse { #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SoundSetEnabledResponse { +pub struct SoundDeleteResponse { pub success: bool, - pub sound_path: String, - pub enabled: bool, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] -pub struct SoundDeleteResponse { +pub struct SoundRenameResponse { pub success: bool, + pub display_name: String, } /// 로컬 사운드 파일을 선택하고 appData/sounds 디렉토리로 복사한 뒤 경로 반환 @@ -116,7 +114,6 @@ pub fn sound_load( s.sound_library.insert( dest_path_str.clone(), SoundLibraryEntry { - enabled: true, source: SoundSource::Local, ..Default::default() }, @@ -190,7 +187,6 @@ pub fn sound_list( file_name, size_bytes: metadata.len(), modified_at_ms, - enabled: entry_meta.enabled, source: entry_meta.source, original_path: entry_meta.original_path, trim_start_ratio: entry_meta.trim_start_ratio, @@ -235,27 +231,49 @@ pub fn sound_list( } #[tauri::command] -pub fn sound_set_enabled( +pub fn sound_rename( app: tauri::AppHandle, state: State<'_, AppState>, sound_path: String, - enabled: bool, -) -> CmdResult { + display_name: String, +) -> CmdResult { let sounds_dir = ensure_sounds_dir(&app)?; let validated_path = validate_sound_path(&sounds_dir, &sound_path)?; if !validated_path.exists() { return Err(CommandError::msg("대상 사운드 파일이 존재하지 않습니다.")); } - let path_key = normalize_path_string(&validated_path); + + let trimmed = display_name.trim(); + if trimmed.is_empty() { + return Err(CommandError::msg("사운드 이름이 비어 있습니다.")); + } + + // 내장 사운드 이름 변경 차단 (재시딩 시 원복됨) + let is_builtin = state.store.with_state(|s| { + s.sound_library + .get(&path_key) + .map(|entry| entry.source == SoundSource::Builtin) + }); + let Some(is_builtin) = is_builtin else { + return Err(CommandError::msg("대상 사운드가 존재하지 않습니다.")); + }; + if is_builtin { + return Err(CommandError::msg( + "내장 사운드는 이름을 변경할 수 없습니다.", + )); + } + + let next_name = trimmed.to_string(); state.store.update(|s| { - s.sound_library.entry(path_key.clone()).or_default().enabled = enabled; + if let Some(entry) = s.sound_library.get_mut(&path_key) { + entry.display_name = Some(next_name.clone()); + } })?; - Ok(SoundSetEnabledResponse { + Ok(SoundRenameResponse { success: true, - sound_path: path_key, - enabled, + display_name: next_name, }) } @@ -441,7 +459,6 @@ pub fn sound_save_processed_wav( s.sound_library.insert( dest_path_str.clone(), SoundLibraryEntry { - enabled: true, source: SoundSource::Local, original_path: original_rel_path.clone(), trim_start_ratio: request.trim_start_ratio, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 6448b504..506ddb6d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -220,7 +220,7 @@ fn main() { commands::keys::key_sound::key_sound_get_output_state, commands::keys::sound::sound_load, commands::keys::sound::sound_list, - commands::keys::sound::sound_set_enabled, + commands::keys::sound::sound_rename, commands::keys::sound::sound_delete, commands::keys::sound::sound_save_processed_wav, commands::keys::sound::sound_load_original, diff --git a/src-tauri/src/models/mod.rs b/src-tauri/src/models/mod.rs index e6f66249..89a4adf1 100644 --- a/src-tauri/src/models/mod.rs +++ b/src-tauri/src/models/mod.rs @@ -62,15 +62,9 @@ fn default_sound_source() -> SoundSource { SoundSource::Local } -fn default_sound_enabled() -> bool { - true -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct SoundLibraryEntry { - #[serde(default = "default_sound_enabled")] - pub enabled: bool, #[serde(default = "default_sound_source")] pub source: SoundSource, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -86,7 +80,6 @@ pub struct SoundLibraryEntry { impl Default for SoundLibraryEntry { fn default() -> Self { Self { - enabled: true, source: SoundSource::Local, original_path: None, trim_start_ratio: None, diff --git a/src-tauri/src/state/builtin_sounds.rs b/src-tauri/src/state/builtin_sounds.rs index 99234f1c..588e0175 100644 --- a/src-tauri/src/state/builtin_sounds.rs +++ b/src-tauri/src/state/builtin_sounds.rs @@ -44,7 +44,7 @@ pub(crate) fn seed_builtin_sounds(app_data_dir: &Path, data: &mut AppStoreData) let key = dest.to_string_lossy().to_string(); match data.sound_library.get_mut(&key) { Some(entry) => { - // enabled(사용자 토글)는 보존, source/표시 이름만 갱신 + // source/표시 이름만 갱신, 트림 메타데이터는 보존 if entry.source != SoundSource::Builtin || entry.display_name.as_deref() != Some(sound.display_name) { @@ -98,19 +98,11 @@ mod tests { .expect("library entry missing"); assert_eq!(entry.source, SoundSource::Builtin); assert_eq!(entry.display_name.as_deref(), Some(sound.display_name)); - assert!(entry.enabled); } // 재실행: 변경 없음 (멱등) assert!(!seed_builtin_sounds(&dir, &mut data)); - // 사용자 토글(enabled=false)은 재시딩에도 보존 - for entry in data.sound_library.values_mut() { - entry.enabled = false; - } - assert!(!seed_builtin_sounds(&dir, &mut data)); - assert!(data.sound_library.values().all(|entry| !entry.enabled)); - // Local로 오염된 source는 자가 치유 for entry in data.sound_library.values_mut() { entry.source = SoundSource::Local; diff --git a/src/renderer/api/modules/resourceApi.ts b/src/renderer/api/modules/resourceApi.ts index c60d860a..5baa97d6 100644 --- a/src/renderer/api/modules/resourceApi.ts +++ b/src/renderer/api/modules/resourceApi.ts @@ -16,11 +16,11 @@ export const soundApi = { invoke('sound_load'), list: () => invoke('sound_list'), - setEnabled: (soundPath: string, enabled: boolean) => - invoke( - 'sound_set_enabled', - { soundPath, enabled }, - ), + rename: (soundPath: string, displayName: string) => + invoke('sound_rename', { + soundPath, + displayName, + }), remove: (soundPath: string) => invoke('sound_delete', { soundPath, diff --git a/src/renderer/components/main/Grid/PropertiesPanel/batch/BatchCounterTabContent.tsx b/src/renderer/components/main/Grid/PropertiesPanel/batch/BatchCounterTabContent.tsx index 6d84a61a..1dba0ef2 100644 --- a/src/renderer/components/main/Grid/PropertiesPanel/batch/BatchCounterTabContent.tsx +++ b/src/renderer/components/main/Grid/PropertiesPanel/batch/BatchCounterTabContent.tsx @@ -9,7 +9,6 @@ import { import Checkbox from '@components/main/common/Checkbox'; import Dropdown from '@components/main/common/Dropdown'; import FontPicker from '@components/main/Modal/content/pickers/FontPicker'; -import FontManagerModal from '@components/main/Modal/content/managers/FontManagerModal'; import CounterAnimationPicker from '@components/main/Modal/content/pickers/CounterAnimationPicker'; interface BatchKeyVisual { @@ -78,7 +77,6 @@ const BatchCounterTabContent: React.FC = ({ const fontButtonRef = useRef(null); const animationButtonRef = useRef(null); const [showFontPicker, setShowFontPicker] = useState(false); - const [showFontManager, setShowFontManager] = useState(false); const [showAnimationPicker, setShowAnimationPicker] = useState(false); const handleAnimationUpdate = ( @@ -335,22 +333,10 @@ const BatchCounterTabContent: React.FC = ({ handleBatchCounterUpdate({ fontFamily }); }} onClose={() => setShowFontPicker(false)} - onOpenManager={() => { - setShowFontManager(true); - }} interactiveRefs={[fontButtonRef]} /> )} - {/* FontManagerModal */} - {showFontManager && ( - setShowFontManager(false)} - t={t} - /> - )} - {showAnimationPicker && ( = ({ } }; }, []); - const [showFontManager, setShowFontManager] = useState(false); const fontButtonRef = useRef(null); const soundButtonRef = useRef(null); @@ -945,9 +943,6 @@ const BatchStyleTabContent: React.FC = ({ handleBatchStyleChangeComplete('fontFamily', fontName); }} onClose={() => setShowFontPicker(false)} - onOpenManager={() => { - setShowFontManager(true); - }} interactiveRefs={[fontButtonRef]} /> )} @@ -977,15 +972,6 @@ const BatchStyleTabContent: React.FC = ({ } /> )} - - {/* FontManagerModal */} - {!hideFontControls && showFontManager && ( - setShowFontManager(false)} - t={t} - /> - )} ); }; diff --git a/src/renderer/components/main/Grid/PropertiesPanel/single/CounterTabContent.tsx b/src/renderer/components/main/Grid/PropertiesPanel/single/CounterTabContent.tsx index 7c57889b..b481cfa3 100644 --- a/src/renderer/components/main/Grid/PropertiesPanel/single/CounterTabContent.tsx +++ b/src/renderer/components/main/Grid/PropertiesPanel/single/CounterTabContent.tsx @@ -16,7 +16,6 @@ import Checkbox from '@components/main/common/Checkbox'; import Dropdown from '@components/main/common/Dropdown'; import ColorPicker from '@components/main/Modal/content/pickers/ColorPicker'; import FontPicker from '@components/main/Modal/content/pickers/FontPicker'; -import FontManagerModal from '@components/main/Modal/content/managers/FontManagerModal'; import CounterAnimationPicker from '@components/main/Modal/content/pickers/CounterAnimationPicker'; type PickerTarget = 'fill' | 'stroke' | 'font' | null; @@ -39,7 +38,6 @@ const CounterTabContent: React.FC = ({ const [pickerFor, setPickerFor] = useState(null); const pickerOpen = pickerFor !== null && pickerFor !== 'font'; const [colorState, setColorState] = useState('idle'); - const [showFontManager, setShowFontManager] = useState(false); const [showAnimationPicker, setShowAnimationPicker] = useState(false); const counterSettings = normalizeCounterSettings(keyPosition.counter); @@ -405,22 +403,10 @@ const CounterTabContent: React.FC = ({ handleCounterUpdate({ fontFamily: fontName }); }} onClose={() => setPickerFor(null)} - onOpenManager={() => { - setShowFontManager(true); - }} interactiveRefs={[fontBtnRef]} /> )} - {/* FontManagerModal */} - {showFontManager && ( - setShowFontManager(false)} - t={t} - /> - )} - {showAnimationPicker && ( = ({ // 폰트 버튼 ref const fontButtonRef = useRef(null); const soundButtonRef = useRef(null); - // 폰트 관리 모달 상태 - const [showFontManager, setShowFontManager] = useState(false); const [showSoundPicker, setShowSoundPicker] = useState(false); const borderColorBtnRef = useRef(null); const fontColorBtnRef = useRef(null); @@ -795,9 +792,6 @@ const StyleTabContent: React.FC = ({ handleStyleChangeComplete('fontFamily', fontName); }} onClose={() => setPickerFor(null)} - onOpenManager={() => { - setShowFontManager(true); - }} interactiveRefs={[fontButtonRef]} /> )} @@ -819,15 +813,6 @@ const StyleTabContent: React.FC = ({ previewVolume={keyPosition.soundVolume ?? 100} /> )} - - {/* FontManagerModal */} - {showFontManager && ( - setShowFontManager(false)} - t={t} - /> - )} ); }; diff --git a/src/renderer/components/main/Modal/content/managers/FontManagerModal.tsx b/src/renderer/components/main/Modal/content/managers/FontManagerModal.tsx deleted file mode 100644 index c30d139d..00000000 --- a/src/renderer/components/main/Modal/content/managers/FontManagerModal.tsx +++ /dev/null @@ -1,449 +0,0 @@ -import { Suspense, lazy, useState, useRef, useEffect } from 'react'; -import Modal from '@components/main/Modal/Modal'; -import ManagerModalLayout from '@components/main/Modal/ManagerModalLayout'; -import TabSwitch from '@components/main/common/TabSwitch'; -import Checkbox from '@components/main/common/Checkbox'; -import TrashIcon from '@assets/svgs/trash.svg'; -import { useFontStore, syncFontCSS } from '@stores/useFontStore'; -import type { CustomFont } from '@src/types/settings/fonts'; -import { - extractFontFamilyFromCSS, - generateFontId, - normalizeFontFamilyName, -} from '@src/types/settings/fonts'; -import { convertFileSrc } from '@tauri-apps/api/core'; - -interface FontManagerModalProps { - isOpen: boolean; - onClose: () => void; - t: (key: string, options?: Record) => string; -} - -type TabType = 'local' | 'web'; - -let webFontInputModalPreloadPromise: Promise< - typeof import('../pickers/WebFontInputModal') -> | null = null; - -const preloadWebFontInputModal = () => { - if (!webFontInputModalPreloadPromise) { - webFontInputModalPreloadPromise = import('../pickers/WebFontInputModal'); - } - return webFontInputModalPreloadPromise; -}; - -const LazyWebFontInputModal = lazy(preloadWebFontInputModal); - -const FontManagerModal = ({ isOpen, onClose, t }: FontManagerModalProps) => { - const [activeTab, setActiveTab] = useState('web'); - const [isAdding, setIsAdding] = useState(false); - const [showWebFontModal, setShowWebFontModal] = useState(false); - const [editingWebFontId, setEditingWebFontId] = useState(null); - - const { customFonts, setAll } = useFontStore(); - - // 현재 탭에 해당하는 폰트 목록 - const currentFonts = customFonts.filter((f) => f.type === activeTab); - - const editingWebFont = - customFonts.find( - (font) => font.type === 'web' && font.id === editingWebFontId, - ) || null; - - // 주입된 preview CSS ID들을 추적하는 ref - const previewIdsRef = useRef>(new Set()); - const previewCssCacheRef = useRef>(new Map()); - - // preview용 font-family 이름 생성 (syncFontCSS의 영향을 받지 않도록 별도 이름 사용) - const getPreviewFontFamily = (fontName: string) => `${fontName}__preview`; - - // preview CSS 주입 (syncFontCSS의 'font-' prefix와 다른 'fontpreview-' prefix 사용) - const injectPreviewCSS = (id: string, css: string) => { - const styleId = `fontpreview-${id}`; - const existing = document.getElementById(styleId); - if (existing) { - existing.textContent = css; - } else { - const style = document.createElement('style'); - style.id = styleId; - style.textContent = css; - document.head.appendChild(style); - } - }; - - // preview CSS 제거 - const removePreviewCSS = (id: string) => { - const style = document.getElementById(`fontpreview-${id}`); - if (style) style.remove(); - }; - - // 모달이 열려있는 동안 모든 폰트의 CSS를 임시로 주입 (enabled 상태와 상관없이 미리보기 가능) - // 폰트가 변경될 때 CSS가 실제로 달라진 항목만 갱신하여 폰트가 많아도 부담을 줄임 - useEffect(() => { - if (!isOpen) return; - - const nextPreviewIds = new Set(); - - currentFonts.forEach((font) => { - const previewId = font.id; - - // preview용 font-family 이름 사용 (원본 font-family와 분리) - const previewFontFamily = getPreviewFontFamily(font.name); - - let css: string | null = null; - if (font.type === 'local' && font.localPath) { - const url = convertFileSrc(font.localPath); - const ext = font.localPath.split('.').pop()?.toLowerCase() ?? ''; - const format = - ext === 'otf' - ? 'opentype' - : ext === 'woff' - ? 'woff' - : ext === 'woff2' - ? 'woff2' - : 'truetype'; - css = `@font-face {\n font-family: '${previewFontFamily}';\n src: url('${url}') format('${format}');\n font-weight: normal;\n font-style: normal;\n font-display: swap;\n}`; - } else if (font.type === 'web' && font.cssContent) { - // 웹폰트 CSS에서 font-family를 preview 이름으로 교체 - css = font.cssContent.replace( - /font-family:\s*['"]?([^'";]+)['"]?\s*;/i, - `font-family: '${previewFontFamily}';`, - ); - } - - if (css) { - nextPreviewIds.add(previewId); - - if (previewCssCacheRef.current.get(previewId) !== css) { - // CSS가 실제로 바뀐 경우에만 갱신하여 reflow/repaint를 줄임 - injectPreviewCSS(previewId, css); - previewCssCacheRef.current.set(previewId, css); - } - } - }); - - previewIdsRef.current.forEach((id) => { - if (!nextPreviewIds.has(id)) { - removePreviewCSS(id); - previewCssCacheRef.current.delete(id); - } - }); - - previewIdsRef.current = nextPreviewIds; - }, [isOpen, currentFonts]); - - // 모달이 닫힐 때만 모든 preview CSS 제거 - useEffect(() => { - if (isOpen) return; - - // 모달이 닫히면 모든 preview CSS 제거 - previewIdsRef.current.forEach((id) => removePreviewCSS(id)); - previewIdsRef.current.clear(); - previewCssCacheRef.current.clear(); - }, [isOpen]); - - // 폰트 매니저가 열려 있는 동안 WebFontInputModal 코드를 미리 로드 - useEffect(() => { - if (!isOpen) return; - - const timer = window.setTimeout(() => { - void preloadWebFontInputModal(); - }, 120); - - return () => window.clearTimeout(timer); - }, [isOpen]); - - const persistFonts = (nextFonts: CustomFont[]) => { - setAll(nextFonts); - // Note: syncFontCSS()는 모달이 닫힐 때 한 번만 호출 (깜빡임 방지) - window.api.settings - .update({ fontSettings: { customFonts: nextFonts } }) - .catch((error) => { - console.error('Failed to persist font settings:', error); - }); - }; - - const isDuplicateFontFamily = ( - fontFamily: string, - options?: { excludeId?: string | null }, - ) => { - const normalizedFamily = normalizeFontFamilyName(fontFamily); - if (!normalizedFamily) return false; - - const allFonts = useFontStore.getState().getAllFonts(); - return allFonts.some((font) => { - if (options?.excludeId && font.id === options.excludeId) { - return false; - } - return normalizeFontFamilyName(font.name) === normalizedFamily; - }); - }; - - const showDuplicateFontFamilyAlert = (fontFamily: string) => { - const message = - t('webFontInput.duplicateFontFamilyAlert', { name: fontFamily }) || - `"${fontFamily}" 폰트가 이미 등록되어 있습니다.`; - - void window.api.ui.dialog - .alert(message, { confirmText: t('common.ok') || '확인' }) - .catch((error) => { - console.error('Failed to open duplicate font alert:', error); - }); - }; - - // 로컬 폰트 파일 선택 - const handleAddLocalFont = async () => { - setIsAdding(true); - try { - // Tauri font_load 명령어 사용 - const result = await window.api.font.load(); - - if (result.success && result.fontName && result.fontPath) { - if (isDuplicateFontFamily(result.fontName)) { - showDuplicateFontFamilyAlert(result.fontName); - return; - } - - const newFont: CustomFont = { - id: generateFontId(), - type: 'local', - name: result.fontName, - displayName: result.fontName, - enabled: true, - localPath: result.fontPath, - }; - const nextFonts = [...useFontStore.getState().customFonts, newFont]; - persistFonts(nextFonts); - } else if (result.error) { - console.error('Failed to load font:', result.error); - } - } catch (error) { - console.error('Failed to add local font:', error); - } finally { - setIsAdding(false); - } - }; - - // 웹폰트 추가 버튼 클릭 - const handleAddWebFont = () => { - void preloadWebFontInputModal(); - setEditingWebFontId(null); - setShowWebFontModal(true); - }; - - const handleEditWebFont = (fontId: string) => { - void preloadWebFontInputModal(); - setEditingWebFontId(fontId); - setShowWebFontModal(true); - }; - - const handleCloseWebFontModal = () => { - setShowWebFontModal(false); - setEditingWebFontId(null); - }; - - // 웹폰트 CSS 추가 완료 - const handleWebFontSubmit = (css: string, displayName: string) => { - const fontFamily = extractFontFamilyFromCSS(css); - if (!fontFamily) { - console.error('Failed to extract font-family from CSS'); - return; - } - - if (isDuplicateFontFamily(fontFamily, { excludeId: editingWebFontId })) { - showDuplicateFontFamilyAlert(fontFamily); - return; - } - - const currentCustomFonts = useFontStore.getState().customFonts; - const newWebFont: CustomFont = { - id: generateFontId(), - type: 'web', - name: fontFamily, - displayName: displayName || fontFamily, - enabled: true, - cssContent: css, - }; - - const nextFonts: CustomFont[] = editingWebFontId - ? currentCustomFonts.map((font) => - font.id === editingWebFontId - ? { - ...font, - name: fontFamily, - displayName: displayName || fontFamily, - cssContent: css, - } - : font, - ) - : [...currentCustomFonts, newWebFont]; - - persistFonts(nextFonts); - handleCloseWebFontModal(); - }; - - // 폰트 삭제 - const handleRemoveFont = (id: string) => { - const nextFonts = useFontStore - .getState() - .customFonts.filter((font) => font.id !== id); - persistFonts(nextFonts); - }; - - // 폰트 토글 - const handleToggleFont = (id: string, enabled: boolean) => { - const nextFonts = useFontStore - .getState() - .customFonts.map((font) => - font.id === id ? { ...font, enabled } : font, - ); - persistFonts(nextFonts); - }; - - // 추가 버튼 클릭 - const handleAdd = () => { - if (activeTab === 'local') { - handleAddLocalFont(); - } else { - handleAddWebFont(); - } - }; - - // 모달 닫기 핸들러 (닫힐 때 syncFontCSS 호출) - const handleClose = () => { - syncFontCSS(); - onClose(); - }; - - return ( - <> - setActiveTab(tab as TabType)} - className="mb-[19px]" - /> - } - footer={ - <> - - - - } - > - {currentFonts.length === 0 ? ( -
- {activeTab === 'local' - ? t('fontManager.noLocalFonts') || '로컬 폰트가 없습니다' - : t('fontManager.noWebFonts') || '웹폰트가 없습니다'} -
- ) : ( - currentFonts.map((font) => ( -
-
- - {font.type === 'web' ? ( - - ) : ( - - {font.displayName} - - )} -
-
- handleToggleFont(font.id, !font.enabled)} - /> -
-
- )) - )} -
- - {/* 웹폰트 CSS 입력 모달 */} - {showWebFontModal ? ( - -
event.stopPropagation()} - > -

- 로딩 중... -

-
- - } - > - - isDuplicateFontFamily(fontFamily, { excludeId: editingWebFontId }) - } - t={t} - /> -
- ) : null} - - ); -}; - -export default FontManagerModal; diff --git a/src/renderer/components/main/Modal/content/managers/SoundManagerModal.tsx b/src/renderer/components/main/Modal/content/managers/SoundManagerModal.tsx deleted file mode 100644 index d5590e19..00000000 --- a/src/renderer/components/main/Modal/content/managers/SoundManagerModal.tsx +++ /dev/null @@ -1,398 +0,0 @@ -import React, { - type ChangeEvent, - useEffect, - useLayoutEffect, - useRef, - useState, -} from 'react'; -import Modal from '../../Modal'; -import { useTranslation } from '@contexts/useTranslation'; -import type { SoundListItem } from '@src/types/plugin/api'; -import { useLenis } from '@hooks/useLenis'; -import { getScrollShadowState } from '@utils/grid/scrollShadow'; -import SoundTrimModal from './SoundTrimModal'; -import Checkbox from '@components/main/common/Checkbox'; -import TrashIcon from '@assets/svgs/trash.svg'; - -interface SoundManagerModalProps { - isOpen: boolean; - selectedSound: string | null; - onSelectSound: (soundPath: string | null) => void; - onClose: () => void; - previewVolume?: number; -} - -const MAX_SCROLL_HEIGHT = 195; - -const SoundManagerModal = ({ - isOpen, - selectedSound, - onSelectSound, - onClose, - previewVolume, -}: SoundManagerModalProps) => { - const { t } = useTranslation(); - const [sounds, setSounds] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [isSaving, setIsSaving] = useState(false); - const [loadError, setLoadError] = useState(''); - const [showTrimModal, setShowTrimModal] = useState(false); - const [editingSoundPath, setEditingSoundPath] = useState(null); - - const addFileInputRef = useRef(null); - const [pendingFile, setPendingFile] = useState(null); - - const contentRef = useRef(null); - const [scrollState, setScrollState] = useState({ - hasTopShadow: false, - hasBottomShadow: false, - }); - const [skipShadowTransition, setSkipShadowTransition] = useState(true); - const [containerHeight, setContainerHeight] = useState(null); - const [isScrollable, setIsScrollable] = useState(false); - const isFirstRender = useRef(true); - const hasLoadedRef = useRef(false); - - const normalizedSelectedSound = (selectedSound || '').trim(); - - const editingSoundItem = editingSoundPath - ? sounds.find((s) => s.soundPath === editingSoundPath) ?? null - : null; - - const loadSounds = async () => { - setIsLoading(true); - setLoadError(''); - try { - const nextSounds = await window.api.sound.list(); - setSounds(nextSounds); - } catch (error) { - console.error('Failed to load sound list', error); - setLoadError(t('soundManager.loadFailed') || '사운드 목록 로드 실패'); - } finally { - hasLoadedRef.current = true; - setIsLoading(false); - } - }; - - useEffect(() => { - if (!isOpen) return; - void loadSounds(); - }, [isOpen]); // eslint-disable-line react-hooks/exhaustive-deps - - const updateScrollState = (el: HTMLElement | null) => { - if (!el) return; - const nextState = getScrollShadowState(el, contentRef.current); - setScrollState((prev) => - prev.hasTopShadow === nextState.hasTopShadow && - prev.hasBottomShadow === nextState.hasBottomShadow - ? prev - : nextState, - ); - }; - - const { scrollContainerRef: scrollRef, wrapperElement } = useLenis({ - onScroll: () => updateScrollState(wrapperElement), - }); - - useLayoutEffect(() => { - if (!isOpen) { - isFirstRender.current = true; - hasLoadedRef.current = false; - return; - } - - setSkipShadowTransition(true); - setScrollState({ hasTopShadow: false, hasBottomShadow: false }); - setIsScrollable(false); - - const el = wrapperElement; - const contentEl = contentRef.current; - if (!el) return; - - const updateHeight = () => { - if (contentEl) { - const contentHeight = contentEl.scrollHeight; - setContainerHeight(Math.min(contentHeight, MAX_SCROLL_HEIGHT)); - setIsScrollable(contentHeight > MAX_SCROLL_HEIGHT); - } - }; - - const resizeObserver = new ResizeObserver(() => { - updateScrollState(el); - updateHeight(); - }); - - if (contentEl) { - resizeObserver.observe(contentEl); - } - resizeObserver.observe(el); - - updateScrollState(el); - updateHeight(); - - const rafId = requestAnimationFrame(() => { - setSkipShadowTransition(false); - if (hasLoadedRef.current) { - isFirstRender.current = false; - } - }); - - return () => { - resizeObserver.disconnect(); - cancelAnimationFrame(rafId); - }; - }, [isOpen, sounds, wrapperElement]); - - const handleToggle = async (item: SoundListItem, nextEnabled: boolean) => { - if (isSaving) return; - setIsSaving(true); - setSounds((prev) => - prev.map((s) => - s.soundPath === item.soundPath ? { ...s, enabled: nextEnabled } : s, - ), - ); - try { - await window.api.sound.setEnabled(item.soundPath, nextEnabled); - } catch (error) { - console.error('Failed to toggle sound enabled state', error); - setSounds((prev) => - prev.map((s) => - s.soundPath === item.soundPath ? { ...s, enabled: !nextEnabled } : s, - ), - ); - setLoadError( - t('soundManager.stateChangeFailed') || '사운드 상태 변경 실패', - ); - } finally { - setIsSaving(false); - } - }; - - const handleDelete = async (item: SoundListItem) => { - if (isSaving) return; - setIsSaving(true); - setSounds((prev) => prev.filter((s) => s.soundPath !== item.soundPath)); - if (normalizedSelectedSound === item.soundPath) { - onSelectSound(null); - } - try { - await window.api.sound.remove(item.soundPath); - } catch (error) { - console.error('Failed to delete sound', error); - setLoadError(t('soundManager.deleteFailed') || '사운드 삭제 실패'); - await loadSounds(); - } finally { - setIsSaving(false); - } - }; - - const handleAddFileChange = (event: ChangeEvent) => { - const file = event.target.files?.[0]; - if (addFileInputRef.current) { - addFileInputRef.current.value = ''; - } - if (!file) return; - setPendingFile(file); - setEditingSoundPath(null); - setShowTrimModal(true); - }; - - const handleEditSound = (item: SoundListItem) => { - if (!item.originalPath) return; - setEditingSoundPath(item.soundPath); - setShowTrimModal(true); - }; - - const handleCloseTrimModal = () => { - setShowTrimModal(false); - setEditingSoundPath(null); - setPendingFile(null); - }; - - const handleTrimSaved = (soundPath: string) => { - onSelectSound(soundPath); - setShowTrimModal(false); - setEditingSoundPath(null); - setPendingFile(null); - void loadSounds(); - }; - - if (!isOpen) return null; - - return ( - <> - -
event.stopPropagation()} - > -
-
- -
-
- {sounds.length === 0 && !isLoading ? ( -
- {t('soundManager.noSounds') || '사운드 없음'} -
- ) : ( - sounds.map((item) => ( - - ) : ( - - )} - {item.originalPath ? ( - - ) : ( - - {item.displayName || item.fileName} - - )} -
-
- { - void handleToggle(item, !item.enabled); - }} - /> -
- - )) - )} -
-
- -
-
- -
- -
- - - -
- - {isLoading ? ( -

- {t('propertiesPanel.loading') || '로딩...'} -

- ) : null} - - {loadError ? ( -

{loadError}

- ) : null} -
- - - - - ); -}; - -export default SoundManagerModal; diff --git a/src/renderer/components/main/Modal/content/managers/SoundTrimModal.tsx b/src/renderer/components/main/Modal/content/managers/SoundTrimModal.tsx index 553fc167..77aee6cc 100644 --- a/src/renderer/components/main/Modal/content/managers/SoundTrimModal.tsx +++ b/src/renderer/components/main/Modal/content/managers/SoundTrimModal.tsx @@ -640,7 +640,7 @@ const SoundTrimModal = ({ t, ]); - // initialFile 제공 시 처리 (SoundManagerModal 파일 선택기에서) + // initialFile 제공 시 처리 (SoundPicker 파일 선택기에서) useEffect(() => { if (!isOpen || !initialFile || isEditMode) return; const signal = { cancelled: false }; diff --git a/src/renderer/components/main/Modal/content/pickers/CommonListPickerPopup.tsx b/src/renderer/components/main/Modal/content/pickers/CommonListPickerPopup.tsx index 1a1fc5ea..12bbb977 100644 --- a/src/renderer/components/main/Modal/content/pickers/CommonListPickerPopup.tsx +++ b/src/renderer/components/main/Modal/content/pickers/CommonListPickerPopup.tsx @@ -42,8 +42,10 @@ interface CommonListPickerPopupProps { loadingText?: string; errorText?: string; listHeightClass?: string; - onAdd: () => void; + onAdd: (event: React.MouseEvent) => void; addButtonContent: React.ReactNode; + // + 버튼에 앵커된 메뉴가 열릴 때 외부 클릭 판정 제외용 + addButtonRef?: React.RefObject; } export default function CommonListPickerPopup({ @@ -73,6 +75,7 @@ export default function CommonListPickerPopup({ listHeightClass = 'min-h-[120px] h-[120px]', onAdd, addButtonContent, + addButtonRef, }: CommonListPickerPopupProps) { const containerRef = useRef(null); const [containerEl, setContainerEl] = useState(null); @@ -314,6 +317,7 @@ export default function CommonListPickerPopup({
- ); - }} - emptyText={t('fontPicker.noFonts') || '폰트 없음'} - onAdd={onOpenManager} - addButtonContent={} - /> + <> + + open={open} + referenceRef={referenceRef} + panelElement={panelElement} + interactiveRefs={interactiveRefs} + onClose={handlePickerClose} + widthClass="w-[156px]" + estimatedWidth={164} + estimatedHeight={280} + searchQuery={searchQuery} + onSearchQueryChange={setSearchQuery} + searchPlaceholder={t('fontPicker.searchPlaceholder') || '검색...'} + filterOptions={filterOptions} + filterValue={filterType} + onFilterChange={(value) => setFilterType(value as FilterType)} + items={filteredFonts} + getItemKey={(font) => font.id} + renderItem={(font) => { + const isSelected = effectiveSelectedFont + ? effectiveSelectedFont === font.name + : font.name === 'SUIT-Regular'; + const isCustom = font.type !== 'builtin'; + const isDisabled = !font.enabled; + const fontFamily = isDisabled + ? `${getPreviewFontFamily(font.name)}, ${font.name}` + : font.name; + + return ( +
{ + if (!isDisabled) onFontSelect(font.name); + }} + onKeyDown={(event) => { + if (event.target !== event.currentTarget) return; + if (event.key === 'Enter' || event.key === ' ') { + event.preventDefault(); + if (!isDisabled) onFontSelect(font.name); + } + }} + onContextMenu={ + isCustom + ? (event) => menu.openFromContextMenu(event, font.id) + : undefined + } + className={`w-full h-[24px] px-[8px] rounded-[7px] text-style-4 transition-colors flex items-center gap-[4px] group ${ + isSelected + ? 'bg-[#2E2D33] text-[#FFFFFF] cursor-pointer' + : isDisabled + ? 'text-[#6F6E7A] hover:bg-[#26262C] cursor-default' + : 'text-[#DBDEE8] hover:bg-[#26262C] cursor-pointer' + }`} + title={font.displayName} + > + {renamingFontId === font.id ? ( + setRenameValue(event.target.value)} + onBlur={() => { + if (!renameCancelledRef.current) commitRename(font); + renameCancelledRef.current = false; + }} + onKeyDown={(event) => { + event.stopPropagation(); + if (event.key === 'Enter') { + event.preventDefault(); + event.currentTarget.blur(); + } else if (event.key === 'Escape') { + event.preventDefault(); + renameCancelledRef.current = true; + setRenamingFontId(null); + } + }} + onMouseDown={(event) => event.stopPropagation()} + onClick={(event) => event.stopPropagation()} + /> + ) : ( + + {font.displayName} + + )} + + {isCustom ? ( + + ) : null} +
+ ); + }} + emptyText={t('fontPicker.noFonts') || '폰트 없음'} + onAdd={(event) => { + if (addMenuPosition) { + setAddMenuPosition(null); + return; + } + const rect = event.currentTarget.getBoundingClientRect(); + setAddMenuPosition({ x: rect.right + 4, y: rect.top - 2 }); + }} + addButtonContent={} + addButtonRef={addButtonRef} + /> + + {addMenuPosition !== null && ( + setAddMenuPosition(null)} + textAlign="center" + items={addMenuItems} + onSelect={(id) => { + setAddMenuPosition(null); + if (id === 'local') { + void fontLibrary.addLocalFont(); + } else if (id === 'web') { + openWebFontModal(null); + } + }} + className="z-[60]" + offsetX={0} + offsetY={0} + /> + )} + + {menu.menuKey !== null && ( + { + const font = menuTargetFont; + menu.close(); + if (!font) return; + if (id === 'edit') { + openWebFontModal(font.id); + } else if (id === 'rename') { + renameCancelledRef.current = false; + setRenameValue(font.displayName); + setRenamingFontId(font.id); + } else if (id === 'toggle') { + fontLibrary.toggleFont(font.id, !font.enabled); + } else if (id === 'delete') { + void handleDelete(font); + } + }} + className="z-[60]" + offsetX={0} + offsetY={0} + /> + )} + + {/* 웹폰트 CSS 입력 모달 */} + {webFontModal ? ( + setWebFontModal(null)}> +
event.stopPropagation()} + > +

+ 로딩 중... +

+
+ + } + > + setWebFontModal(null)} + onSubmit={handleWebFontSubmit} + initialCss={editingWebFont?.cssContent || ''} + isDuplicateFontFamily={(fontFamily) => + fontLibrary.isDuplicateFontFamily(fontFamily, { + excludeId: webFontModal.editingId, + }) + } + t={t} + /> +
+ ) : null} + ); }; diff --git a/src/renderer/components/main/Modal/content/pickers/MoreVerticalIcon.tsx b/src/renderer/components/main/Modal/content/pickers/MoreVerticalIcon.tsx new file mode 100644 index 00000000..e2e7d4e1 --- /dev/null +++ b/src/renderer/components/main/Modal/content/pickers/MoreVerticalIcon.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +const MoreVerticalIcon: React.FC = () => ( + +); + +export default MoreVerticalIcon; diff --git a/src/renderer/components/main/Modal/content/pickers/SoundPicker.tsx b/src/renderer/components/main/Modal/content/pickers/SoundPicker.tsx index 7874b7b5..5c7551ac 100644 --- a/src/renderer/components/main/Modal/content/pickers/SoundPicker.tsx +++ b/src/renderer/components/main/Modal/content/pickers/SoundPicker.tsx @@ -1,9 +1,12 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from '@contexts/useTranslation'; import type { SoundListItem } from '@src/types/plugin/api'; import PlusIcon from '@assets/svgs/plus2.svg'; +import ListPopup, { type ListItem } from '@components/main/Modal/ListPopup'; import CommonListPickerPopup from './CommonListPickerPopup'; -import SoundManagerModal from '../managers/SoundManagerModal'; +import MoreVerticalIcon from './MoreVerticalIcon'; +import { usePickerItemMenu } from '@hooks/usePickerItemMenu'; +import SoundTrimModal from '../managers/SoundTrimModal'; interface SoundPickerProps { open: boolean; @@ -16,6 +19,10 @@ interface SoundPickerProps { previewVolume?: number; } +type TrimState = + | { mode: 'create'; file: File } + | { mode: 'edit'; item: SoundListItem }; + const SoundPicker = ({ open, referenceRef, @@ -32,7 +39,13 @@ const SoundPicker = ({ const [sounds, setSounds] = useState([]); const [isLoading, setIsLoading] = useState(false); const [loadError, setLoadError] = useState(''); - const [showManager, setShowManager] = useState(false); + const [trimState, setTrimState] = useState(null); + const [renamingPath, setRenamingPath] = useState(null); + const [renameValue, setRenameValue] = useState(''); + const renameInputRef = useRef(null); + const renameCancelledRef = useRef(false); + const addFileInputRef = useRef(null); + const menu = usePickerItemMenu(); const normalizedSelectedSound = (selectedSound || '').trim(); @@ -44,7 +57,7 @@ const SoundPicker = ({ setSounds(nextSounds); } catch (error) { console.error('Failed to load sound list', error); - setLoadError('사운드 목록 로드 실패'); + setLoadError(t('soundPicker.loadFailed') || '사운드 목록 로드 실패'); } finally { setIsLoading(false); } @@ -53,7 +66,19 @@ const SoundPicker = ({ useEffect(() => { if (!open) return; void loadSounds(); - }, [open]); + }, [open]); // eslint-disable-line react-hooks/exhaustive-deps + + useEffect(() => { + if (open) return; + menu.close(); + }, [open]); // eslint-disable-line react-hooks/exhaustive-deps + + // 이름 변경 시작 시 입력에 포커스 + useEffect(() => { + if (renamingPath === null) return; + renameInputRef.current?.focus(); + renameInputRef.current?.select(); + }, [renamingPath]); const filterOptions = [ { value: 'all', label: t('soundPicker.filterAll') || '전체' }, @@ -64,7 +89,6 @@ const SoundPicker = ({ const query = searchQuery.trim().toLowerCase(); return sounds.filter((item) => { - if (!item.enabled) return false; if (filterType === 'local' && item.source !== 'local') { return false; } @@ -76,6 +100,94 @@ const SoundPicker = ({ }); })(); + const menuTargetItem = + menu.menuKey !== null + ? sounds.find((item) => item.soundPath === menu.menuKey) ?? null + : null; + + const menuItems: ListItem[] = [ + { + id: 'edit', + label: t('soundPicker.edit') || '편집', + disabled: !menuTargetItem?.originalPath, + }, + { + id: 'rename', + label: t('soundPicker.rename') || '이름 변경', + }, + { + id: 'delete', + label: t('soundPicker.delete') || '삭제', + }, + ]; + + const moreMenuLabel = (() => { + const translated = t('common.more'); + return translated && translated !== 'common.more' ? translated : '더보기'; + })(); + + const handleAddFileChange = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (addFileInputRef.current) { + addFileInputRef.current.value = ''; + } + if (!file) return; + setTrimState({ mode: 'create', file }); + }; + + const handleDelete = async (item: SoundListItem) => { + const confirmed = await window.api.ui.dialog.confirm( + t('soundPicker.deleteConfirm') || + '사운드를 삭제하시겠습니까? 파일이 삭제되고 이 사운드를 사용하는 모든 요소에서 해제됩니다.', + { + confirmText: t('contextMenu.delete') || '삭제', + cancelText: t('common.cancel') || '취소', + danger: true, + }, + ); + + if (!confirmed) return; + + try { + await window.api.sound.remove(item.soundPath); + if (normalizedSelectedSound === item.soundPath) { + onSoundSelect(null); + } + await loadSounds(); + } catch (error) { + console.error('Failed to delete sound', error); + // loadSounds가 loadError를 초기화하므로 reload 후에 실패 메시지 설정 + await loadSounds(); + setLoadError(t('soundPicker.deleteFailed') || '사운드 삭제 실패'); + } + }; + + const commitRename = async (item: SoundListItem) => { + const trimmed = renameValue.trim(); + setRenamingPath(null); + if (!trimmed || trimmed === (item.displayName || item.fileName)) return; + try { + await window.api.sound.rename(item.soundPath, trimmed); + await loadSounds(); + } catch (error) { + console.error('Failed to rename sound', error); + // loadSounds가 loadError를 초기화하므로 reload 후에 실패 메시지 설정 + await loadSounds(); + setLoadError(t('soundPicker.renameFailed') || '사운드 이름 변경 실패'); + } + }; + + const handleTrimSaved = (soundPath: string) => { + onSoundSelect(soundPath); + setTrimState(null); + void loadSounds(); + }; + + const handlePickerClose = () => { + if (menu.menuKey !== null) return; + onClose(); + }; + return ( <> @@ -83,7 +195,7 @@ const SoundPicker = ({ referenceRef={referenceRef} panelElement={panelElement} interactiveRefs={interactiveRefs} - onClose={onClose} + onClose={handlePickerClose} widthClass="w-[156px]" estimatedWidth={164} estimatedHeight={276} @@ -94,44 +206,157 @@ const SoundPicker = ({ filterValue={filterType} onFilterChange={(value) => setFilterType(value as 'all' | 'local')} items={filteredSounds} + getItemKey={(item) => item.soundPath} renderItem={(item) => { const isSelected = item.soundPath === normalizedSelectedSound; + const isLocal = item.source === 'local'; + const displayName = item.displayName || item.fileName; + return ( - + {renamingPath === item.soundPath ? ( + setRenameValue(event.target.value)} + onBlur={() => { + if (!renameCancelledRef.current) void commitRename(item); + renameCancelledRef.current = false; + }} + onKeyDown={(event) => { + event.stopPropagation(); + if (event.key === 'Enter') { + event.preventDefault(); + event.currentTarget.blur(); + } else if (event.key === 'Escape') { + event.preventDefault(); + renameCancelledRef.current = true; + setRenamingPath(null); + } + }} + onMouseDown={(event) => event.stopPropagation()} + onClick={(event) => event.stopPropagation()} + /> + ) : ( + + {displayName} + + )} + + {isLocal ? ( + + ) : null} +
); }} emptyText={t('soundPicker.noSounds') || '사운드 없음'} isLoading={isLoading} loadingText={t('propertiesPanel.loading') || '로딩...'} errorText={loadError} - onAdd={() => setShowManager(true)} + onAdd={() => addFileInputRef.current?.click()} addButtonContent={} /> - { - onSoundSelect(path); - void loadSounds(); - }} - onClose={() => { - setShowManager(false); - void loadSounds(); - }} + + + {menu.menuKey !== null && ( + { + const item = menuTargetItem; + menu.close(); + if (!item) return; + if (id === 'edit') { + setTrimState({ mode: 'edit', item }); + } else if (id === 'rename') { + renameCancelledRef.current = false; + setRenameValue(item.displayName || item.fileName); + setRenamingPath(item.soundPath); + } else if (id === 'delete') { + void handleDelete(item); + } + }} + className="z-[60]" + offsetX={0} + offsetY={0} + /> + )} + + setTrimState(null)} + onSaved={handleTrimSaved} previewVolume={previewVolume} + editingSoundPath={ + trimState?.mode === 'edit' ? trimState.item.soundPath : null + } + editingTrimStartRatio={ + trimState?.mode === 'edit' ? trimState.item.trimStartRatio : undefined + } + editingTrimEndRatio={ + trimState?.mode === 'edit' ? trimState.item.trimEndRatio : undefined + } + editingDisplayName={ + trimState?.mode === 'edit' ? trimState.item.displayName : undefined + } + initialFile={trimState?.mode === 'create' ? trimState.file : null} /> ); diff --git a/src/renderer/hooks/useFontLibrary.ts b/src/renderer/hooks/useFontLibrary.ts new file mode 100644 index 00000000..38249aef --- /dev/null +++ b/src/renderer/hooks/useFontLibrary.ts @@ -0,0 +1,183 @@ +import { useState } from 'react'; +import { useTranslation } from '@contexts/useTranslation'; +import { useFontStore, syncFontCSS } from '@stores/useFontStore'; +import type { CustomFont } from '@src/types/settings/fonts'; +import { + extractFontFamilyFromCSS, + generateFontId, + normalizeFontFamilyName, +} from '@src/types/settings/fonts'; + +// 폰트 라이브러리 CRUD — 낙관적 스토어 갱신 + 설정 영속화 +// CSS 반영은 settings:changed 라운드트립(useAppBootstrap의 syncFontCSS)이 담당 +export const useFontLibrary = () => { + const { t } = useTranslation(); + const { setAll } = useFontStore(); + const [isAdding, setIsAdding] = useState(false); + + const persistFonts = (nextFonts: CustomFont[]) => { + const prevFonts = useFontStore.getState().customFonts; + setAll(nextFonts); + window.api.settings + .update({ fontSettings: { customFonts: nextFonts } }) + .catch(async (error) => { + console.error('Failed to persist font settings:', error); + // 저장 실패 시 백엔드 실제 상태로 재조정 (디스크 실패여도 백엔드 + // 메모리에는 반영됐을 수 있어 단순 롤백으로는 어긋날 수 있음) + try { + const settings = await window.api.settings.get(); + useFontStore.getState().setAll(settings.fontSettings.customFonts); + } catch { + useFontStore.getState().setAll(prevFonts); + } + syncFontCSS(); + void window.api.ui.dialog + .alert( + t('fontPicker.saveFailed') || '폰트 설정 저장에 실패했습니다.', + { confirmText: t('common.ok') || '확인' }, + ) + .catch(() => {}); + }); + }; + + const isDuplicateFontFamily = ( + fontFamily: string, + options?: { excludeId?: string | null }, + ) => { + const normalizedFamily = normalizeFontFamilyName(fontFamily); + if (!normalizedFamily) return false; + + const allFonts = useFontStore.getState().getAllFonts(); + return allFonts.some((font) => { + if (options?.excludeId && font.id === options.excludeId) { + return false; + } + return normalizeFontFamilyName(font.name) === normalizedFamily; + }); + }; + + const showDuplicateFontFamilyAlert = (fontFamily: string) => { + const message = + t('webFontInput.duplicateFontFamilyAlert', { name: fontFamily }) || + `"${fontFamily}" 폰트가 이미 등록되어 있습니다.`; + + void window.api.ui.dialog + .alert(message, { confirmText: t('common.ok') || '확인' }) + .catch((error) => { + console.error('Failed to open duplicate font alert:', error); + }); + }; + + const addLocalFont = async () => { + if (isAdding) return; + setIsAdding(true); + try { + const result = await window.api.font.load(); + + if (result.success && result.fontName && result.fontPath) { + if (isDuplicateFontFamily(result.fontName)) { + showDuplicateFontFamilyAlert(result.fontName); + return; + } + + const newFont: CustomFont = { + id: generateFontId(), + type: 'local', + name: result.fontName, + displayName: result.fontName, + enabled: true, + localPath: result.fontPath, + }; + const nextFonts = [...useFontStore.getState().customFonts, newFont]; + persistFonts(nextFonts); + } else if (result.error) { + console.error('Failed to load font:', result.error); + } + } catch (error) { + console.error('Failed to add local font:', error); + } finally { + setIsAdding(false); + } + }; + + // 성공 시 true 반환 (호출부에서 모달 닫기 판단) + const submitWebFont = ( + css: string, + displayName: string, + editingWebFontId: string | null, + ): boolean => { + const fontFamily = extractFontFamilyFromCSS(css); + if (!fontFamily) { + console.error('Failed to extract font-family from CSS'); + return false; + } + + if (isDuplicateFontFamily(fontFamily, { excludeId: editingWebFontId })) { + showDuplicateFontFamilyAlert(fontFamily); + return false; + } + + const currentCustomFonts = useFontStore.getState().customFonts; + const newWebFont: CustomFont = { + id: generateFontId(), + type: 'web', + name: fontFamily, + displayName: displayName || fontFamily, + enabled: true, + cssContent: css, + }; + + const nextFonts: CustomFont[] = editingWebFontId + ? currentCustomFonts.map((font) => + font.id === editingWebFontId + ? { + ...font, + name: fontFamily, + displayName: displayName || fontFamily, + cssContent: css, + } + : font, + ) + : [...currentCustomFonts, newWebFont]; + + persistFonts(nextFonts); + return true; + }; + + const removeFont = (id: string) => { + const nextFonts = useFontStore + .getState() + .customFonts.filter((font) => font.id !== id); + persistFonts(nextFonts); + }; + + const toggleFont = (id: string, enabled: boolean) => { + const nextFonts = useFontStore + .getState() + .customFonts.map((font) => + font.id === id ? { ...font, enabled } : font, + ); + persistFonts(nextFonts); + }; + + // 표시 이름만 변경 (font-family 참조는 유지) + const renameFont = (id: string, displayName: string) => { + const trimmed = displayName.trim(); + if (!trimmed) return; + const nextFonts = useFontStore + .getState() + .customFonts.map((font) => + font.id === id ? { ...font, displayName: trimmed } : font, + ); + persistFonts(nextFonts); + }; + + return { + addLocalFont, + submitWebFont, + removeFont, + toggleFont, + renameFont, + isDuplicateFontFamily, + }; +}; diff --git a/src/renderer/hooks/usePickerItemMenu.ts b/src/renderer/hooks/usePickerItemMenu.ts new file mode 100644 index 00000000..28f3d7d4 --- /dev/null +++ b/src/renderer/hooks/usePickerItemMenu.ts @@ -0,0 +1,58 @@ +import React, { useRef, useState } from 'react'; + +// 피커 행의 ⋮ 버튼/우클릭으로 여는 컨텍스트 메뉴 상태 관리 +export const usePickerItemMenu = () => { + const [menuKey, setMenuKey] = useState(null); + const [menuPosition, setMenuPosition] = useState<{ + x: number; + y: number; + } | null>(null); + // 메뉴가 열린 상태에서 ⋮를 다시 누르면 문서 outside-click이 pointerdown에 + // 메뉴를 먼저 닫아버려 click 핸들러가 다시 여는 깜빡임이 생긴다. + // pointerdown 시점의 열림 상태를 key와 함께 기록해 click에서 토글로 판정한다 + const pressedWhileOpenKeyRef = useRef(null); + + const close = () => { + setMenuKey(null); + setMenuPosition(null); + }; + + // ⋮ 버튼의 onPointerDown에 연결 + const capturePressState = (key: TKey) => { + pressedWhileOpenKeyRef.current = menuKey === key ? key : null; + }; + + const openFromButton = (event: React.MouseEvent, key: TKey) => { + event.preventDefault(); + event.stopPropagation(); + const pressedWhileOpen = pressedWhileOpenKeyRef.current === key; + pressedWhileOpenKeyRef.current = null; + if (pressedWhileOpen || menuKey === key) { + close(); + return; + } + const rect = event.currentTarget.getBoundingClientRect(); + setMenuPosition({ x: rect.right + 4, y: rect.top - 2 }); + setMenuKey(key); + }; + + const openFromContextMenu = ( + event: React.MouseEvent, + key: TKey, + ) => { + event.preventDefault(); + event.stopPropagation(); + pressedWhileOpenKeyRef.current = null; + setMenuPosition({ x: event.clientX, y: event.clientY }); + setMenuKey(key); + }; + + return { + menuKey, + menuPosition, + capturePressState, + openFromButton, + openFromContextMenu, + close, + }; +}; diff --git a/src/renderer/locales/en.json b/src/renderer/locales/en.json index afd71344..e5e9fb12 100644 --- a/src/renderer/locales/en.json +++ b/src/renderer/locales/en.json @@ -551,22 +551,28 @@ "filterBuiltin": "Built-in", "filterLocal": "Local", "filterWeb": "Web", - "noFonts": "No fonts" + "noFonts": "No fonts", + "addLocalFont": "Add Local Font", + "addWebFont": "Add Web Font", + "edit": "Edit", + "rename": "Rename", + "delete": "Delete", + "enabledToggle": "Enabled", + "saveFailed": "Failed to save font settings.", + "deleteConfirm": "Delete this font? Elements using it will fall back to the default font." }, "soundPicker": { "searchPlaceholder": "Search...", "filterAll": "All", "filterLocal": "Local Sounds", - "noSounds": "No sounds" - }, - "soundManager": { - "title": "Sounds", "noSounds": "No sounds", - "addSound": "Add", "loadFailed": "Failed to load sound list", - "stateChangeFailed": "Failed to change sound state", + "edit": "Edit", + "rename": "Rename", + "delete": "Delete", "deleteFailed": "Failed to delete sound", - "editSound": "Edit" + "renameFailed": "Failed to rename sound", + "deleteConfirm": "Delete this sound? The file will be deleted and unassigned from every element using it." }, "soundTrimModal": { "defaultTitle": "Add Sound", @@ -590,15 +596,6 @@ "saveErrorDefault": "Failed to save the processed sound.", "saveErrorFailed": "Failed to save the processed sound." }, - "fontManager": { - "localTab": "Local Fonts", - "webTab": "Web Fonts", - "noLocalFonts": "No local fonts", - "noWebFonts": "No web fonts", - "removeFont": "Remove font", - "adding": "Adding...", - "addFont": "Add" - }, "webFontInput": { "cssLabel": "@font-face CSS", "submit": "Save", diff --git a/src/renderer/locales/ko.json b/src/renderer/locales/ko.json index 990162ec..c9a3b51e 100644 --- a/src/renderer/locales/ko.json +++ b/src/renderer/locales/ko.json @@ -256,7 +256,6 @@ "resetKeyCounter": "[{{name}}] 키의 카운터를 초기화하시겠습니까?", "reset": "초기화", "removeKey": "[{{name}}] 키를 제거하시겠습니까?", - "removeStat": "[{{name}}] 통계 항목을 제거하시겠습니까?", "removeGraph": "[{{name}}] 그래프를 제거하시겠습니까?", "removeKnob": "[{{name}}] 노브를 제거하시겠습니까?", @@ -552,22 +551,28 @@ "filterBuiltin": "내장 폰트", "filterLocal": "로컬 폰트", "filterWeb": "웹 폰트", - "noFonts": "폰트 없음" + "noFonts": "폰트 없음", + "addLocalFont": "로컬 폰트 추가", + "addWebFont": "웹폰트 추가", + "edit": "편집", + "rename": "이름 변경", + "delete": "삭제", + "enabledToggle": "활성화", + "saveFailed": "폰트 설정 저장에 실패했습니다.", + "deleteConfirm": "폰트를 삭제하시겠습니까? 이 폰트를 사용 중인 요소는 기본 폰트로 표시됩니다." }, "soundPicker": { "searchPlaceholder": "검색", "filterAll": "전체", "filterLocal": "로컬 사운드", - "noSounds": "사운드 없음" - }, - "soundManager": { - "title": "사운드", - "noSounds": "사운드가 없습니다", - "addSound": "추가", + "noSounds": "사운드 없음", "loadFailed": "사운드 목록 로드 실패", - "stateChangeFailed": "사운드 상태 변경 실패", + "edit": "편집", + "rename": "이름 변경", + "delete": "삭제", "deleteFailed": "사운드 삭제 실패", - "editSound": "편집" + "renameFailed": "사운드 이름 변경 실패", + "deleteConfirm": "사운드를 삭제하시겠습니까? 파일이 삭제되고 이 사운드를 사용하는 모든 요소에서 해제됩니다." }, "soundTrimModal": { "defaultTitle": "사운드 추가", @@ -591,15 +596,6 @@ "saveErrorDefault": "편집된 사운드를 저장하지 못했습니다.", "saveErrorFailed": "편집된 사운드 저장에 실패했습니다." }, - "fontManager": { - "localTab": "로컬 폰트", - "webTab": "웹 폰트", - "noLocalFonts": "로컬 폰트가 없습니다", - "noWebFonts": "웹 폰트가 없습니다", - "removeFont": "폰트 삭제", - "adding": "추가 중...", - "addFont": "추가" - }, "webFontInput": { "cssLabel": "@font-face CSS", "submit": "저장", diff --git a/src/renderer/locales/ru.json b/src/renderer/locales/ru.json index 34e6d4c9..1c5428e9 100644 --- a/src/renderer/locales/ru.json +++ b/src/renderer/locales/ru.json @@ -551,22 +551,28 @@ "filterBuiltin": "Встроенные", "filterLocal": "Локальные", "filterWeb": "Веб", - "noFonts": "Нет шрифтов" + "noFonts": "Нет шрифтов", + "addLocalFont": "Добавить локальный шрифт", + "addWebFont": "Добавить веб-шрифт", + "edit": "Редактировать", + "rename": "Переименовать", + "delete": "Удалить", + "enabledToggle": "Включён", + "saveFailed": "Не удалось сохранить настройки шрифтов.", + "deleteConfirm": "Удалить шрифт? Элементы, использующие его, будут отображаться шрифтом по умолчанию." }, "soundPicker": { "searchPlaceholder": "Поиск...", "filterAll": "Все", "filterLocal": "Локальные звуки", - "noSounds": "Звуков нет" - }, - "soundManager": { - "title": "Звуки", "noSounds": "Звуков нет", - "addSound": "Добавить", "loadFailed": "Не удалось загрузить список звуков", - "stateChangeFailed": "Не удалось изменить состояние звука", + "edit": "Редактировать", + "rename": "Переименовать", + "delete": "Удалить", "deleteFailed": "Не удалось удалить звук", - "editSound": "Редактировать" + "renameFailed": "Не удалось переименовать звук", + "deleteConfirm": "Удалить звук? Файл будет удалён, и звук будет снят со всех элементов, где он используется." }, "soundTrimModal": { "defaultTitle": "Добавить звук", @@ -590,15 +596,6 @@ "saveErrorDefault": "Не удалось сохранить обработанный звук.", "saveErrorFailed": "Не удалось сохранить обработанный звук." }, - "fontManager": { - "localTab": "Локальные", - "webTab": "Веб-шрифты", - "noLocalFonts": "Нет локальных", - "noWebFonts": "Нет веб-шрифтов", - "removeFont": "Удалить шрифт", - "adding": "Добавление...", - "addFont": "Добавить" - }, "webFontInput": { "cssLabel": "@font-face CSS", "submit": "Сохранить", diff --git a/src/renderer/locales/zh-Hant.json b/src/renderer/locales/zh-Hant.json index 5dae4998..de695cd1 100644 --- a/src/renderer/locales/zh-Hant.json +++ b/src/renderer/locales/zh-Hant.json @@ -256,7 +256,6 @@ "resetKeyCounter": "重置 [{{name}}] 鍵的計數器?", "reset": "重置", "removeKey": "移除 [{{name}}] 鍵?", - "removeStat": "移除 [{{name}}] 統計?", "removeGraph": "移除 [{{name}}] 圖表?", "removeKnob": "移除 [{{name}}] 旋鈕?", @@ -552,22 +551,28 @@ "filterBuiltin": "內建字體", "filterLocal": "本地字體", "filterWeb": "網路字體", - "noFonts": "無字體" + "noFonts": "無字體", + "addLocalFont": "新增本地字體", + "addWebFont": "新增網路字體", + "edit": "編輯", + "rename": "重新命名", + "delete": "刪除", + "enabledToggle": "啟用", + "saveFailed": "字體設定儲存失敗。", + "deleteConfirm": "確定刪除該字體?使用它的元素將以預設字體顯示。" }, "soundPicker": { "searchPlaceholder": "搜尋", "filterAll": "全部", "filterLocal": "本地音效", - "noSounds": "無音效" - }, - "soundManager": { - "title": "音效", "noSounds": "無音效", - "addSound": "添加", "loadFailed": "音效清單載入失敗", - "stateChangeFailed": "音效狀態變更失敗", + "edit": "編輯", + "rename": "重新命名", + "delete": "刪除", "deleteFailed": "音效刪除失敗", - "editSound": "編輯" + "renameFailed": "音效重新命名失敗", + "deleteConfirm": "確定刪除該音效?檔案將被刪除,並從所有使用它的元素中移除。" }, "soundTrimModal": { "defaultTitle": "新增音效", @@ -591,15 +596,6 @@ "saveErrorDefault": "無法儲存處理後的音效。", "saveErrorFailed": "儲存處理後的音效失敗。" }, - "fontManager": { - "localTab": "本地字體", - "webTab": "網路字體", - "noLocalFonts": "無本地字體", - "noWebFonts": "無網路字體", - "removeFont": "刪除字體", - "adding": "添加中...", - "addFont": "添加" - }, "webFontInput": { "cssLabel": "@font-face CSS", "submit": "儲存", diff --git a/src/renderer/locales/zh-cn.json b/src/renderer/locales/zh-cn.json index 87c5510b..a00f47d1 100644 --- a/src/renderer/locales/zh-cn.json +++ b/src/renderer/locales/zh-cn.json @@ -256,7 +256,6 @@ "resetKeyCounter": "重置 [{{name}}] 键的计数器?", "reset": "重置", "removeKey": "移除 [{{name}}] 键?", - "removeStat": "移除 [{{name}}] 统计?", "removeGraph": "移除 [{{name}}] 图表?", "removeKnob": "移除 [{{name}}] 旋钮?", @@ -303,9 +302,7 @@ "deleteKey": "删除按键", "duplicateSelected": "复制选中项", "deleteSelected": "删除选中项", - "duplicateStat": "复制统计", - "deleteStat": "删除统计", "duplicateGraph": "复制图表", "deleteGraph": "删除图表", @@ -554,22 +551,28 @@ "filterBuiltin": "内置字体", "filterLocal": "本地字体", "filterWeb": "网络字体", - "noFonts": "无字体" + "noFonts": "无字体", + "addLocalFont": "添加本地字体", + "addWebFont": "添加网络字体", + "edit": "编辑", + "rename": "重命名", + "delete": "删除", + "enabledToggle": "启用", + "saveFailed": "字体设置保存失败。", + "deleteConfirm": "确定删除该字体?使用它的元素将以默认字体显示。" }, "soundPicker": { "searchPlaceholder": "搜索", "filterAll": "全部", "filterLocal": "本地音频", - "noSounds": "无音频" - }, - "soundManager": { - "title": "音频", "noSounds": "无音频", - "addSound": "添加", "loadFailed": "音频列表加载失败", - "stateChangeFailed": "音频状态变更失败", + "edit": "编辑", + "rename": "重命名", + "delete": "删除", "deleteFailed": "音频删除失败", - "editSound": "编辑" + "renameFailed": "音频重命名失败", + "deleteConfirm": "确定删除该音频?文件将被删除,并从所有使用它的元素中移除。" }, "soundTrimModal": { "defaultTitle": "添加音频", @@ -593,15 +596,6 @@ "saveErrorDefault": "无法保存处理后的音频。", "saveErrorFailed": "保存处理后的音频失败。" }, - "fontManager": { - "localTab": "本地字体", - "webTab": "网络字体", - "noLocalFonts": "无本地字体", - "noWebFonts": "无网络字体", - "removeFont": "删除字体", - "adding": "添加中...", - "addFont": "添加" - }, "webFontInput": { "cssLabel": "@font-face CSS", "submit": "保存", diff --git a/src/types/plugin/api.ts b/src/types/plugin/api.ts index 8a5aa5ee..ed04c1e3 100644 --- a/src/types/plugin/api.ts +++ b/src/types/plugin/api.ts @@ -101,7 +101,6 @@ export type SoundListItem = { fileName: string; sizeBytes: number; modifiedAtMs?: number; - enabled: boolean; source: 'local' | 'builtin'; originalPath?: string; trimStartRatio?: number; @@ -115,10 +114,9 @@ export type SoundSaveProcessedWavResult = { soundPath?: string; }; -export type SoundSetEnabledResult = { +export type SoundRenameResult = { success: boolean; - soundPath: string; - enabled: boolean; + displayName: string; }; export type SoundDeleteResult = { @@ -881,10 +879,7 @@ export interface DMNoteAPI { sound: { load(): Promise; list(): Promise; - setEnabled( - soundPath: string, - enabled: boolean, - ): Promise; + rename(soundPath: string, displayName: string): Promise; remove(soundPath: string): Promise; saveProcessedWav( wavBase64: string,