opentui 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opentui-0.1.0/.github/workflows/create-release.yml +91 -0
- opentui-0.1.0/.github/workflows/quality.yml +72 -0
- opentui-0.1.0/.github/workflows/release.yml +206 -0
- opentui-0.1.0/.gitignore +58 -0
- opentui-0.1.0/LICENSE +21 -0
- opentui-0.1.0/PKG-INFO +350 -0
- opentui-0.1.0/README.md +289 -0
- opentui-0.1.0/benchmarks/__init__.py +1 -0
- opentui-0.1.0/benchmarks/bench_layout_pipeline.py +98 -0
- opentui-0.1.0/benchmarks/bench_reactivity.py +1728 -0
- opentui-0.1.0/benchmarks/bench_render_matrix.py +662 -0
- opentui-0.1.0/benchmarks/bench_text_render.py +56 -0
- opentui-0.1.0/benchmarks/bench_yoga_layout_shapes.py +185 -0
- opentui-0.1.0/benchmarks/harness.py +307 -0
- opentui-0.1.0/benchmarks/run_all.py +158 -0
- opentui-0.1.0/examples/counter.py +44 -0
- opentui-0.1.0/examples/dashboard.py +642 -0
- opentui-0.1.0/pyproject.toml +178 -0
- opentui-0.1.0/scripts/download_opentui.py +198 -0
- opentui-0.1.0/src/opentui/__init__.py +374 -0
- opentui-0.1.0/src/opentui/_signal_types.py +427 -0
- opentui-0.1.0/src/opentui/_signals_runtime.py +85 -0
- opentui-0.1.0/src/opentui/animation/__init__.py +20 -0
- opentui-0.1.0/src/opentui/animation/_runtime.py +230 -0
- opentui-0.1.0/src/opentui/animation/easing.py +141 -0
- opentui-0.1.0/src/opentui/animation/timeline.py +391 -0
- opentui-0.1.0/src/opentui/app.py +66 -0
- opentui-0.1.0/src/opentui/attachments.py +76 -0
- opentui-0.1.0/src/opentui/components/__init__.py +99 -0
- opentui-0.1.0/src/opentui/components/_control_flow_branching.py +381 -0
- opentui-0.1.0/src/opentui/components/_control_flow_for.py +271 -0
- opentui-0.1.0/src/opentui/components/_control_flow_region.py +275 -0
- opentui-0.1.0/src/opentui/components/_raster_cache.py +122 -0
- opentui-0.1.0/src/opentui/components/_reactive_binding.py +267 -0
- opentui-0.1.0/src/opentui/components/_renderable_base.py +735 -0
- opentui-0.1.0/src/opentui/components/_renderable_constants.py +104 -0
- opentui-0.1.0/src/opentui/components/_renderable_init.py +437 -0
- opentui-0.1.0/src/opentui/components/_renderable_layout.py +166 -0
- opentui-0.1.0/src/opentui/components/_scrollbox_state.py +358 -0
- opentui-0.1.0/src/opentui/components/_simple_variants.py +460 -0
- opentui-0.1.0/src/opentui/components/_syntax_highlight.py +370 -0
- opentui-0.1.0/src/opentui/components/_textnode.py +388 -0
- opentui-0.1.0/src/opentui/components/base.py +560 -0
- opentui-0.1.0/src/opentui/components/box.py +455 -0
- opentui-0.1.0/src/opentui/components/code_renderable.py +505 -0
- opentui-0.1.0/src/opentui/components/control_flow.py +422 -0
- opentui-0.1.0/src/opentui/components/diff/__init__.py +5 -0
- opentui-0.1.0/src/opentui/components/diff/diff_config.py +141 -0
- opentui-0.1.0/src/opentui/components/diff/diff_parser.py +142 -0
- opentui-0.1.0/src/opentui/components/diff/diff_renderable.py +857 -0
- opentui-0.1.0/src/opentui/components/diff/diff_views.py +242 -0
- opentui-0.1.0/src/opentui/components/framebuffer.py +160 -0
- opentui-0.1.0/src/opentui/components/image.py +387 -0
- opentui-0.1.0/src/opentui/components/input.py +106 -0
- opentui-0.1.0/src/opentui/components/input_renderable.py +553 -0
- opentui-0.1.0/src/opentui/components/line_number_gutter.py +394 -0
- opentui-0.1.0/src/opentui/components/line_number_renderable.py +425 -0
- opentui-0.1.0/src/opentui/components/line_types.py +26 -0
- opentui-0.1.0/src/opentui/components/markdown/__init__.py +16 -0
- opentui-0.1.0/src/opentui/components/markdown/markdown_blocks.py +539 -0
- opentui-0.1.0/src/opentui/components/markdown/markdown_parser.py +286 -0
- opentui-0.1.0/src/opentui/components/markdown/markdown_renderable.py +397 -0
- opentui-0.1.0/src/opentui/components/markdown/markdown_renderable_blocks.py +218 -0
- opentui-0.1.0/src/opentui/components/markdown/markdown_renderable_planning.py +158 -0
- opentui-0.1.0/src/opentui/components/scrollbar.py +343 -0
- opentui-0.1.0/src/opentui/components/scrollbox.py +464 -0
- opentui-0.1.0/src/opentui/components/select.py +125 -0
- opentui-0.1.0/src/opentui/components/select_renderable.py +435 -0
- opentui-0.1.0/src/opentui/components/slider_renderable.py +367 -0
- opentui-0.1.0/src/opentui/components/structural.py +406 -0
- opentui-0.1.0/src/opentui/components/tab_select_renderable.py +264 -0
- opentui-0.1.0/src/opentui/components/template.py +302 -0
- opentui-0.1.0/src/opentui/components/text.py +670 -0
- opentui-0.1.0/src/opentui/components/text_renderable.py +816 -0
- opentui-0.1.0/src/opentui/components/text_table/__init__.py +5 -0
- opentui-0.1.0/src/opentui/components/text_table/text_table_borders.py +247 -0
- opentui-0.1.0/src/opentui/components/text_table/text_table_config.py +94 -0
- opentui-0.1.0/src/opentui/components/text_table/text_table_fitting.py +186 -0
- opentui-0.1.0/src/opentui/components/text_table/text_table_renderable.py +859 -0
- opentui-0.1.0/src/opentui/components/text_table/text_table_selection.py +304 -0
- opentui-0.1.0/src/opentui/components/textarea/__init__.py +6 -0
- opentui-0.1.0/src/opentui/components/textarea/_text_edit_mixin.py +103 -0
- opentui-0.1.0/src/opentui/components/textarea/_textarea_init.py +118 -0
- opentui-0.1.0/src/opentui/components/textarea/_textarea_mouse.py +279 -0
- opentui-0.1.0/src/opentui/components/textarea/_textarea_navigation.py +375 -0
- opentui-0.1.0/src/opentui/components/textarea/_textarea_selection.py +177 -0
- opentui-0.1.0/src/opentui/components/textarea/textarea.py +206 -0
- opentui-0.1.0/src/opentui/components/textarea/textarea_keymap.py +146 -0
- opentui-0.1.0/src/opentui/components/textarea/textarea_renderable.py +817 -0
- opentui-0.1.0/src/opentui/components/textarea/textarea_text_utils.py +123 -0
- opentui-0.1.0/src/opentui/context.py +96 -0
- opentui-0.1.0/src/opentui/diagnostics.py +267 -0
- opentui-0.1.0/src/opentui/editor/__init__.py +35 -0
- opentui-0.1.0/src/opentui/editor/edit_buffer.py +152 -0
- opentui-0.1.0/src/opentui/editor/edit_buffer_native.py +384 -0
- opentui-0.1.0/src/opentui/editor/editor_view_native.py +302 -0
- opentui-0.1.0/src/opentui/editor/extmarks.py +479 -0
- opentui-0.1.0/src/opentui/editor/extmarks_wrappers.py +381 -0
- opentui-0.1.0/src/opentui/editor/syntax_style.py +270 -0
- opentui-0.1.0/src/opentui/editor/text_buffer_native.py +348 -0
- opentui-0.1.0/src/opentui/editor/text_view_native.py +167 -0
- opentui-0.1.0/src/opentui/enums.py +96 -0
- opentui-0.1.0/src/opentui/events.py +298 -0
- opentui-0.1.0/src/opentui/expr.py +338 -0
- opentui-0.1.0/src/opentui/ffi.py +144 -0
- opentui-0.1.0/src/opentui/hooks.py +349 -0
- opentui-0.1.0/src/opentui/image/__init__.py +34 -0
- opentui-0.1.0/src/opentui/image/encoding.py +639 -0
- opentui-0.1.0/src/opentui/image/filters.py +446 -0
- opentui-0.1.0/src/opentui/image/loader.py +121 -0
- opentui-0.1.0/src/opentui/image/types.py +113 -0
- opentui-0.1.0/src/opentui/input/__init__.py +37 -0
- opentui-0.1.0/src/opentui/input/_capability_parsing.py +69 -0
- opentui-0.1.0/src/opentui/input/_escape_parser.py +702 -0
- opentui-0.1.0/src/opentui/input/_mouse_protocol.py +73 -0
- opentui-0.1.0/src/opentui/input/event_loop.py +202 -0
- opentui-0.1.0/src/opentui/input/handler.py +265 -0
- opentui-0.1.0/src/opentui/input/key_handler.py +312 -0
- opentui-0.1.0/src/opentui/input/key_maps.py +314 -0
- opentui-0.1.0/src/opentui/input/keymapping.py +165 -0
- opentui-0.1.0/src/opentui/input/stdin_buffer.py +277 -0
- opentui-0.1.0/src/opentui/layout.py +434 -0
- opentui-0.1.0/src/opentui/native.py +271 -0
- opentui-0.1.0/src/opentui/palette/__init__.py +14 -0
- opentui-0.1.0/src/opentui/palette/common.py +81 -0
- opentui-0.1.0/src/opentui/palette/detector.py +322 -0
- opentui-0.1.0/src/opentui/py.typed +0 -0
- opentui-0.1.0/src/opentui/reconciler.py +478 -0
- opentui-0.1.0/src/opentui/renderer/__init__.py +34 -0
- opentui-0.1.0/src/opentui/renderer/_config.py +291 -0
- opentui-0.1.0/src/opentui/renderer/_cursor.py +102 -0
- opentui-0.1.0/src/opentui/renderer/_debug.py +77 -0
- opentui-0.1.0/src/opentui/renderer/_eventing.py +94 -0
- opentui-0.1.0/src/opentui/renderer/_frame_pipeline.py +166 -0
- opentui-0.1.0/src/opentui/renderer/_mouse_hit_testing.py +226 -0
- opentui-0.1.0/src/opentui/renderer/_mouse_selection.py +519 -0
- opentui-0.1.0/src/opentui/renderer/_native_render.py +216 -0
- opentui-0.1.0/src/opentui/renderer/_session.py +177 -0
- opentui-0.1.0/src/opentui/renderer/buffer.py +413 -0
- opentui-0.1.0/src/opentui/renderer/console.py +131 -0
- opentui-0.1.0/src/opentui/renderer/core.py +813 -0
- opentui-0.1.0/src/opentui/renderer/layout.py +152 -0
- opentui-0.1.0/src/opentui/renderer/mouse.py +367 -0
- opentui-0.1.0/src/opentui/renderer/native.py +227 -0
- opentui-0.1.0/src/opentui/renderer/repaint.py +141 -0
- opentui-0.1.0/src/opentui/renderer/repaint_plan.py +195 -0
- opentui-0.1.0/src/opentui/resource.py +173 -0
- opentui-0.1.0/src/opentui/selection.py +244 -0
- opentui-0.1.0/src/opentui/signals.py +166 -0
- opentui-0.1.0/src/opentui/structs.py +300 -0
- opentui-0.1.0/src/opentui/testing/__init__.py +9 -0
- opentui-0.1.0/src/opentui/testing/capture.py +365 -0
- opentui-0.1.0/src/opentui/testing/input.py +624 -0
- opentui-0.1.0/src/opentui/testing/setup.py +277 -0
- opentui-0.1.0/src/opentui/testing/sgr.py +413 -0
- opentui-0.1.0/src/opentui/text_utils.py +189 -0
- opentui-0.1.0/src/opentui/tree_sitter_client.py +280 -0
- opentui-0.1.0/src/opentui/tree_sitter_queries/javascript/highlights.scm +205 -0
- opentui-0.1.0/src/opentui/tree_sitter_queries/markdown/highlights.scm +150 -0
- opentui-0.1.0/src/opentui/tree_sitter_queries/markdown_inline/highlights.scm +128 -0
- opentui-0.1.0/src/opentui/tree_sitter_queries/typescript/highlights.scm +604 -0
- opentui-0.1.0/src/opentui/tree_sitter_queries/zig/highlights.scm +284 -0
- opentui-0.1.0/src/opentui/viewport.py +146 -0
- opentui-0.1.0/src/opentui_bindings/CMakeLists.txt +89 -0
- opentui-0.1.0/src/opentui_bindings/bindings.cpp +52 -0
- opentui-0.1.0/src/opentui_bindings/border_draw.h +93 -0
- opentui-0.1.0/src/opentui_bindings/buffer.cpp +351 -0
- opentui-0.1.0/src/opentui_bindings/common_render.cpp +538 -0
- opentui-0.1.0/src/opentui_bindings/edit_buffer.cpp +205 -0
- opentui-0.1.0/src/opentui_bindings/editor_view.cpp +301 -0
- opentui-0.1.0/src/opentui_bindings/graphics.cpp +70 -0
- opentui-0.1.0/src/opentui_bindings/hit_grid.cpp +31 -0
- opentui-0.1.0/src/opentui_bindings/native_signals.cpp +295 -0
- opentui-0.1.0/src/opentui_bindings/native_signals.h +64 -0
- opentui-0.1.0/src/opentui_bindings/reconciler_patch.cpp +208 -0
- opentui-0.1.0/src/opentui_bindings/renderer.cpp +207 -0
- opentui-0.1.0/src/opentui_bindings/slot_utils.h +31 -0
- opentui-0.1.0/src/opentui_bindings/text_buffer.cpp +390 -0
- opentui-0.1.0/src/opentui_bindings/types.cpp +134 -0
- opentui-0.1.0/src/opentui_bindings/yoga_configure.cpp +822 -0
- opentui-0.1.0/src/opentui_bindings/yoga_configure.h +129 -0
- opentui-0.1.0/tests/__init__.py +0 -0
- opentui-0.1.0/tests/conftest.py +73 -0
- opentui-0.1.0/tests/integration/__init__.py +0 -0
- opentui-0.1.0/tests/integration/test_absolute_positioning.py +898 -0
- opentui-0.1.0/tests/integration/test_buffer_diff.py +100 -0
- opentui-0.1.0/tests/integration/test_destroy_during_render.py +290 -0
- opentui-0.1.0/tests/integration/test_framebuffer.py +39 -0
- opentui-0.1.0/tests/integration/test_hover_cursor.py +126 -0
- opentui-0.1.0/tests/integration/test_opacity.py +95 -0
- opentui-0.1.0/tests/integration/test_renderable.py +1072 -0
- opentui-0.1.0/tests/integration/test_renderable_snapshot.py +312 -0
- opentui-0.1.0/tests/integration/test_renderer_control.py +558 -0
- opentui-0.1.0/tests/integration/test_renderer_destroy_during_render.py +179 -0
- opentui-0.1.0/tests/integration/test_renderer_focus.py +452 -0
- opentui-0.1.0/tests/integration/test_renderer_focus_restore.py +306 -0
- opentui-0.1.0/tests/integration/test_renderer_idle.py +439 -0
- opentui-0.1.0/tests/integration/test_renderer_input.py +2008 -0
- opentui-0.1.0/tests/integration/test_renderer_kitty_flags.py +156 -0
- opentui-0.1.0/tests/integration/test_renderer_mouse.py +1277 -0
- opentui-0.1.0/tests/integration/test_renderer_palette.py +827 -0
- opentui-0.1.0/tests/integration/test_renderer_selection.py +51 -0
- opentui-0.1.0/tests/integration/test_renderer_use_mouse.py +46 -0
- opentui-0.1.0/tests/integration/test_scrollbox.py +2127 -0
- opentui-0.1.0/tests/integration/test_scrollbox_culling_bug.py +116 -0
- opentui-0.1.0/tests/integration/test_scrollbox_hitgrid.py +1117 -0
- opentui-0.1.0/tests/integration/test_selection_overlay.py +230 -0
- opentui-0.1.0/tests/integration/test_terminal_lifecycle.py +36 -0
- opentui-0.1.0/tests/integration/test_text_component.py +339 -0
- opentui-0.1.0/tests/integration/test_wrap_resize_perf.py +162 -0
- opentui-0.1.0/tests/integration/test_yoga_setters.py +1098 -0
- opentui-0.1.0/tests/lib/__init__.py +0 -0
- opentui-0.1.0/tests/lib/test_border.py +77 -0
- opentui-0.1.0/tests/lib/test_clipboard.py +136 -0
- opentui-0.1.0/tests/lib/test_detect_links.py +84 -0
- opentui-0.1.0/tests/lib/test_extmarks.py +2564 -0
- opentui-0.1.0/tests/lib/test_extmarks_multiwidth.py +226 -0
- opentui-0.1.0/tests/lib/test_key_handler.py +484 -0
- opentui-0.1.0/tests/lib/test_key_handler_integration.py +248 -0
- opentui-0.1.0/tests/lib/test_key_handler_stop_propagation.py +251 -0
- opentui-0.1.0/tests/lib/test_keymapping.py +249 -0
- opentui-0.1.0/tests/lib/test_objects_in_viewport.py +605 -0
- opentui-0.1.0/tests/lib/test_palette.py +1291 -0
- opentui-0.1.0/tests/lib/test_parse_keypress.py +1832 -0
- opentui-0.1.0/tests/lib/test_parse_keypress_kitty.py +927 -0
- opentui-0.1.0/tests/lib/test_parse_mouse.py +814 -0
- opentui-0.1.0/tests/lib/test_renderable_validations.py +78 -0
- opentui-0.1.0/tests/lib/test_rgba.py +804 -0
- opentui-0.1.0/tests/lib/test_selection.py +595 -0
- opentui-0.1.0/tests/lib/test_stdin_buffer.py +819 -0
- opentui-0.1.0/tests/lib/test_tree_sitter_client.py +327 -0
- opentui-0.1.0/tests/lib/test_tree_sitter_queries.py +103 -0
- opentui-0.1.0/tests/lib/test_tree_sitter_styled_text.py +544 -0
- opentui-0.1.0/tests/lib/test_yoga_options.py +267 -0
- opentui-0.1.0/tests/renderables/__init__.py +0 -0
- opentui-0.1.0/tests/renderables/test_base_dirty_paths.py +62 -0
- opentui-0.1.0/tests/renderables/test_box.py +131 -0
- opentui-0.1.0/tests/renderables/test_code.py +2595 -0
- opentui-0.1.0/tests/renderables/test_diff.py +1787 -0
- opentui-0.1.0/tests/renderables/test_diff_regression.py +142 -0
- opentui-0.1.0/tests/renderables/test_input.py +705 -0
- opentui-0.1.0/tests/renderables/test_line_number.py +1356 -0
- opentui-0.1.0/tests/renderables/test_line_number_scrollbox.py +654 -0
- opentui-0.1.0/tests/renderables/test_line_number_scrollbox_simple.py +164 -0
- opentui-0.1.0/tests/renderables/test_line_number_wrapping.py +100 -0
- opentui-0.1.0/tests/renderables/test_markdown.py +1552 -0
- opentui-0.1.0/tests/renderables/test_markdown_parser.py +232 -0
- opentui-0.1.0/tests/renderables/test_multi_renderable_selection.py +112 -0
- opentui-0.1.0/tests/renderables/test_select.py +753 -0
- opentui-0.1.0/tests/renderables/test_slider.py +581 -0
- opentui-0.1.0/tests/renderables/test_tab_select.py +178 -0
- opentui-0.1.0/tests/renderables/test_text.py +1875 -0
- opentui-0.1.0/tests/renderables/test_text_dirty_paths.py +45 -0
- opentui-0.1.0/tests/renderables/test_text_selection_buffer.py +133 -0
- opentui-0.1.0/tests/renderables/test_text_table.py +1468 -0
- opentui-0.1.0/tests/renderables/test_textarea_buffer.py +568 -0
- opentui-0.1.0/tests/renderables/test_textarea_destroyed_events.py +465 -0
- opentui-0.1.0/tests/renderables/test_textarea_editing.py +1115 -0
- opentui-0.1.0/tests/renderables/test_textarea_error_handling.py +24 -0
- opentui-0.1.0/tests/renderables/test_textarea_events.py +628 -0
- opentui-0.1.0/tests/renderables/test_textarea_highlights.py +619 -0
- opentui-0.1.0/tests/renderables/test_textarea_keybinding.py +1993 -0
- opentui-0.1.0/tests/renderables/test_textarea_paste.py +234 -0
- opentui-0.1.0/tests/renderables/test_textarea_rendering.py +1807 -0
- opentui-0.1.0/tests/renderables/test_textarea_scroll.py +927 -0
- opentui-0.1.0/tests/renderables/test_textarea_selection.py +1885 -0
- opentui-0.1.0/tests/renderables/test_textarea_stress.py +518 -0
- opentui-0.1.0/tests/renderables/test_textarea_undo_redo.py +270 -0
- opentui-0.1.0/tests/renderables/test_textarea_visual_lines.py +247 -0
- opentui-0.1.0/tests/renderables/test_textnode.py +1032 -0
- opentui-0.1.0/tests/solid/__init__.py +0 -0
- opentui-0.1.0/tests/solid/test_box.py +105 -0
- opentui-0.1.0/tests/solid/test_context.py +255 -0
- opentui-0.1.0/tests/solid/test_control_flow.py +2226 -0
- opentui-0.1.0/tests/solid/test_cursor_behavior.py +643 -0
- opentui-0.1.0/tests/solid/test_diff.py +342 -0
- opentui-0.1.0/tests/solid/test_dynamic_collections.py +590 -0
- opentui-0.1.0/tests/solid/test_error_boundary.py +636 -0
- opentui-0.1.0/tests/solid/test_events.py +922 -0
- opentui-0.1.0/tests/solid/test_layout.py +429 -0
- opentui-0.1.0/tests/solid/test_lazy_and_switch_direct.py +334 -0
- opentui-0.1.0/tests/solid/test_line_number.py +137 -0
- opentui-0.1.0/tests/solid/test_line_number_scrollbox.py +614 -0
- opentui-0.1.0/tests/solid/test_link.py +551 -0
- opentui-0.1.0/tests/solid/test_portal.py +662 -0
- opentui-0.1.0/tests/solid/test_scrollbox_cleanchildren.py +848 -0
- opentui-0.1.0/tests/solid/test_scrollbox_content.py +437 -0
- opentui-0.1.0/tests/solid/test_sticky_scroll.py +233 -0
- opentui-0.1.0/tests/solid/test_text_elements.py +182 -0
- opentui-0.1.0/tests/solid/test_textarea.py +1183 -0
- opentui-0.1.0/tests/test_attachment_normalization.py +75 -0
- opentui-0.1.0/tests/test_buffer.py +462 -0
- opentui-0.1.0/tests/test_console.py +735 -0
- opentui-0.1.0/tests/test_diagnostics.py +400 -0
- opentui-0.1.0/tests/test_edit_buffer.py +1479 -0
- opentui-0.1.0/tests/test_editor_view.py +1265 -0
- opentui-0.1.0/tests/test_expr.py +445 -0
- opentui-0.1.0/tests/test_ffi.py +355 -0
- opentui-0.1.0/tests/test_ffi_behavior.py +246 -0
- opentui-0.1.0/tests/test_filters.py +241 -0
- opentui-0.1.0/tests/test_graphics.py +406 -0
- opentui-0.1.0/tests/test_hooks_registration.py +138 -0
- opentui-0.1.0/tests/test_image_api.py +58 -0
- opentui-0.1.0/tests/test_image_cache.py +63 -0
- opentui-0.1.0/tests/test_image_component.py +889 -0
- opentui-0.1.0/tests/test_image_loader.py +137 -0
- opentui-0.1.0/tests/test_new_features.py +234 -0
- opentui-0.1.0/tests/test_paste_events.py +47 -0
- opentui-0.1.0/tests/test_reactive_props.py +1423 -0
- opentui-0.1.0/tests/test_reconciler.py +335 -0
- opentui-0.1.0/tests/test_render_strategy.py +128 -0
- opentui-0.1.0/tests/test_scrollbar.py +250 -0
- opentui-0.1.0/tests/test_select_component.py +209 -0
- opentui-0.1.0/tests/test_signals.py +1275 -0
- opentui-0.1.0/tests/test_syntax_style.py +635 -0
- opentui-0.1.0/tests/test_text_buffer.py +379 -0
- opentui-0.1.0/tests/test_text_buffer_view.py +613 -0
- opentui-0.1.0/tests/test_text_selection.py +220 -0
- opentui-0.1.0/tests/test_text_utils.py +80 -0
- opentui-0.1.0/tests/test_timeline.py +2852 -0
- opentui-0.1.0/tests/test_viewport.py +200 -0
- opentui-0.1.0/tests/testing/__init__.py +0 -0
- opentui-0.1.0/tests/testing/test_capture_spans.py +192 -0
- opentui-0.1.0/tests/testing/test_integration.py +225 -0
- opentui-0.1.0/tests/testing/test_mock_keys.py +1105 -0
- opentui-0.1.0/tests/testing/test_mock_mouse.py +177 -0
- opentui-0.1.0/tests/testing/test_test_recorder.py +428 -0
- opentui-0.1.0/uv.lock +458 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Create Release Tag
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
release_type:
|
|
7
|
+
description: 'Release type'
|
|
8
|
+
required: true
|
|
9
|
+
type: choice
|
|
10
|
+
options:
|
|
11
|
+
- patch
|
|
12
|
+
- minor
|
|
13
|
+
- major
|
|
14
|
+
default: patch
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
create-tag:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
token: ${{ secrets.RELEASE_TOKEN }}
|
|
27
|
+
|
|
28
|
+
- name: Configure Git
|
|
29
|
+
run: |
|
|
30
|
+
git config user.name "${{ github.actor }}"
|
|
31
|
+
git config user.email "${{ github.actor }}@users.noreply.github.com"
|
|
32
|
+
|
|
33
|
+
- name: Get current version and calculate next version
|
|
34
|
+
id: version
|
|
35
|
+
run: |
|
|
36
|
+
CURRENT_VERSION=$(grep "^version = " pyproject.toml | cut -d'"' -f2)
|
|
37
|
+
echo "Current version: $CURRENT_VERSION"
|
|
38
|
+
|
|
39
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
40
|
+
echo "Error: Could not extract version"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
|
|
45
|
+
|
|
46
|
+
RELEASE_TYPE="${{ inputs.release_type }}"
|
|
47
|
+
case $RELEASE_TYPE in
|
|
48
|
+
major)
|
|
49
|
+
NEW_MAJOR=$((MAJOR + 1)); NEW_MINOR=0; NEW_PATCH=0
|
|
50
|
+
;;
|
|
51
|
+
minor)
|
|
52
|
+
NEW_MAJOR=$MAJOR; NEW_MINOR=$((MINOR + 1)); NEW_PATCH=0
|
|
53
|
+
;;
|
|
54
|
+
patch)
|
|
55
|
+
NEW_MAJOR=$MAJOR; NEW_MINOR=$MINOR; NEW_PATCH=$((PATCH + 1))
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
|
|
59
|
+
NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
|
|
60
|
+
|
|
61
|
+
echo "Current: $CURRENT_VERSION -> New: $NEW_VERSION ($RELEASE_TYPE)"
|
|
62
|
+
echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
|
63
|
+
echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
64
|
+
|
|
65
|
+
- name: Check if version already exists
|
|
66
|
+
run: |
|
|
67
|
+
VERSION="v${{ steps.version.outputs.new }}"
|
|
68
|
+
if git rev-parse "$VERSION" >/dev/null 2>&1; then
|
|
69
|
+
echo "Tag $VERSION already exists!"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
echo "Tag $VERSION does not exist"
|
|
73
|
+
|
|
74
|
+
- name: Update version in pyproject.toml
|
|
75
|
+
run: |
|
|
76
|
+
VERSION="${{ steps.version.outputs.new }}"
|
|
77
|
+
sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
|
|
78
|
+
grep "^version = " pyproject.toml
|
|
79
|
+
|
|
80
|
+
- name: Commit and push
|
|
81
|
+
run: |
|
|
82
|
+
git add pyproject.toml
|
|
83
|
+
git commit -m "chore: bump version to ${{ steps.version.outputs.new }}"
|
|
84
|
+
git push origin main
|
|
85
|
+
|
|
86
|
+
- name: Create and push tag
|
|
87
|
+
run: |
|
|
88
|
+
VERSION="v${{ steps.version.outputs.new }}"
|
|
89
|
+
git tag -a "$VERSION" -m "Release $VERSION"
|
|
90
|
+
git push origin "$VERSION"
|
|
91
|
+
echo "Created tag $VERSION - this will trigger release workflow"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Code Quality
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
quality:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
run: uv python install ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Download OpenTUI native library
|
|
26
|
+
run: python scripts/download_opentui.py
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv sync --all-extras
|
|
30
|
+
|
|
31
|
+
- name: Lint with ruff
|
|
32
|
+
run: |
|
|
33
|
+
uv run ruff check
|
|
34
|
+
uv run ruff format --check
|
|
35
|
+
|
|
36
|
+
- name: Type check with ty
|
|
37
|
+
run: uv run ty check
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: uv run pytest tests/ -v --tb=short
|
|
41
|
+
|
|
42
|
+
quality-check:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
needs: quality
|
|
45
|
+
steps:
|
|
46
|
+
- name: All quality checks passed
|
|
47
|
+
run: echo "All quality checks passed!"
|
|
48
|
+
|
|
49
|
+
release-build-smoke:
|
|
50
|
+
name: Release build (sdist + Linux wheel)
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- name: Install uv
|
|
56
|
+
uses: astral-sh/setup-uv@v4
|
|
57
|
+
- name: Build sdist
|
|
58
|
+
run: pip install -q build validate-pyproject && validate-pyproject pyproject.toml && python -m build --sdist
|
|
59
|
+
- name: Build one Linux wheel (cibuildwheel smoke)
|
|
60
|
+
uses: pypa/cibuildwheel@v2.22.0
|
|
61
|
+
env:
|
|
62
|
+
CIBW_BUILD: "cp312-*"
|
|
63
|
+
CIBW_SKIP: "*-win* *-macos* *-manylinux_i686 *-musllinux_*"
|
|
64
|
+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
|
|
65
|
+
CIBW_BEFORE_ALL_LINUX: "dnf install -y git && python {project}/scripts/download_opentui.py && cp {project}/src/opentui/opentui-libs/libopentui.so /usr/local/lib/ && ldconfig"
|
|
66
|
+
CIBW_ENVIRONMENT_LINUX: "LD_LIBRARY_PATH={project}/src/opentui/opentui-libs"
|
|
67
|
+
CIBW_BUILD_FRONTEND: "build[uv]"
|
|
68
|
+
CIBW_BUILD_VERBOSITY: "3"
|
|
69
|
+
CIBW_ENVIRONMENT_PASS_LINUX: "GIT_TERMINAL_PROMPT"
|
|
70
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
71
|
+
- name: List artifacts
|
|
72
|
+
run: ls -la wheelhouse/ dist/
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
name: Release to PyPI and GitHub
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: "Version to release (e.g., 0.1.0)"
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build_wheels:
|
|
19
|
+
name: Build wheels (${{ matrix.os }})
|
|
20
|
+
runs-on: ${{ matrix.runs-on }}
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
include:
|
|
25
|
+
- os: linux-x86_64
|
|
26
|
+
runs-on: ubuntu-22.04
|
|
27
|
+
cibw_archs: x86_64
|
|
28
|
+
- os: linux-aarch64
|
|
29
|
+
runs-on: ubuntu-22.04
|
|
30
|
+
cibw_archs: aarch64
|
|
31
|
+
- os: macos-arm64
|
|
32
|
+
runs-on: macos-14
|
|
33
|
+
cibw_archs: arm64
|
|
34
|
+
- os: macos-x86_64
|
|
35
|
+
runs-on: macos-14
|
|
36
|
+
cibw_archs: x86_64
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
with:
|
|
41
|
+
fetch-depth: 0
|
|
42
|
+
|
|
43
|
+
- name: Set up QEMU (Linux aarch64)
|
|
44
|
+
if: matrix.cibw_archs == 'aarch64'
|
|
45
|
+
uses: docker/setup-qemu-action@v3
|
|
46
|
+
|
|
47
|
+
- name: Install uv
|
|
48
|
+
uses: astral-sh/setup-uv@v4
|
|
49
|
+
|
|
50
|
+
- name: Build wheels
|
|
51
|
+
uses: pypa/cibuildwheel@v2.22.0
|
|
52
|
+
env:
|
|
53
|
+
CIBW_BUILD: "cp312-* cp313-*"
|
|
54
|
+
CIBW_SKIP: "*-manylinux_i686 *-musllinux_*"
|
|
55
|
+
CIBW_ARCHS_LINUX: ${{ matrix.cibw_archs }}
|
|
56
|
+
CIBW_ARCHS_MACOS: ${{ matrix.cibw_archs }}
|
|
57
|
+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
|
|
58
|
+
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
|
|
59
|
+
CIBW_BEFORE_ALL_LINUX: "dnf install -y git && python {project}/scripts/download_opentui.py && cp {project}/src/opentui/opentui-libs/libopentui.so /usr/local/lib/ && ldconfig"
|
|
60
|
+
CIBW_BEFORE_ALL_MACOS: "python {project}/scripts/download_opentui.py --force --arch ${{ matrix.cibw_archs }} && sudo mkdir -p /usr/local/lib && sudo cp {project}/src/opentui/opentui-libs/libopentui.dylib /usr/local/lib/"
|
|
61
|
+
CIBW_ENVIRONMENT_LINUX: "LD_LIBRARY_PATH={project}/src/opentui/opentui-libs"
|
|
62
|
+
CIBW_ENVIRONMENT_MACOS: "MACOSX_DEPLOYMENT_TARGET=13.0"
|
|
63
|
+
CIBW_TEST_REQUIRES: "pytest pytest-asyncio"
|
|
64
|
+
CIBW_TEST_COMMAND: "pytest {project}/tests -v --tb=short -x"
|
|
65
|
+
CIBW_TEST_SKIP: "*-macosx_x86_64"
|
|
66
|
+
CIBW_ENVIRONMENT_PASS_LINUX: "GIT_TERMINAL_PROMPT"
|
|
67
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
68
|
+
CIBW_BUILD_FRONTEND: "build[uv]"
|
|
69
|
+
CIBW_BUILD_VERBOSITY: "1"
|
|
70
|
+
|
|
71
|
+
- uses: actions/upload-artifact@v4
|
|
72
|
+
with:
|
|
73
|
+
name: wheels-${{ matrix.os }}
|
|
74
|
+
path: wheelhouse/*.whl
|
|
75
|
+
|
|
76
|
+
build_sdist:
|
|
77
|
+
name: Build sdist
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/checkout@v4
|
|
81
|
+
with:
|
|
82
|
+
fetch-depth: 0
|
|
83
|
+
|
|
84
|
+
- name: Install build
|
|
85
|
+
run: pip install -q build
|
|
86
|
+
|
|
87
|
+
- name: Validate pyproject.toml
|
|
88
|
+
run: pip install -q validate-pyproject && validate-pyproject pyproject.toml
|
|
89
|
+
|
|
90
|
+
- name: Build sdist
|
|
91
|
+
run: python -m build --sdist
|
|
92
|
+
|
|
93
|
+
- uses: actions/upload-artifact@v4
|
|
94
|
+
with:
|
|
95
|
+
name: sdist
|
|
96
|
+
path: dist/*.tar.gz
|
|
97
|
+
|
|
98
|
+
publish-to-pypi:
|
|
99
|
+
name: Publish to PyPI
|
|
100
|
+
needs: [build_wheels, build_sdist]
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
103
|
+
environment:
|
|
104
|
+
name: pypi
|
|
105
|
+
url: https://pypi.org/p/opentui
|
|
106
|
+
permissions:
|
|
107
|
+
id-token: write
|
|
108
|
+
contents: write
|
|
109
|
+
|
|
110
|
+
steps:
|
|
111
|
+
- name: Download all artifacts
|
|
112
|
+
uses: actions/download-artifact@v4
|
|
113
|
+
with:
|
|
114
|
+
path: dist
|
|
115
|
+
merge-multiple: true
|
|
116
|
+
|
|
117
|
+
- name: Flatten dist
|
|
118
|
+
run: |
|
|
119
|
+
mkdir -p dist/merged
|
|
120
|
+
find dist -maxdepth 3 -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} dist/merged/ \;
|
|
121
|
+
rm -rf dist/wheels-* dist/sdist
|
|
122
|
+
mv dist/merged/* dist/
|
|
123
|
+
rmdir dist/merged
|
|
124
|
+
ls -la dist/
|
|
125
|
+
|
|
126
|
+
- name: Publish to PyPI
|
|
127
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
128
|
+
with:
|
|
129
|
+
print-hash: true
|
|
130
|
+
|
|
131
|
+
publish-to-testpypi:
|
|
132
|
+
name: Publish to TestPyPI
|
|
133
|
+
needs: [build_wheels, build_sdist]
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
if: github.event_name == 'workflow_dispatch'
|
|
136
|
+
environment:
|
|
137
|
+
name: test-pypi
|
|
138
|
+
url: https://test.pypi.org/p/opentui
|
|
139
|
+
permissions:
|
|
140
|
+
id-token: write
|
|
141
|
+
|
|
142
|
+
steps:
|
|
143
|
+
- name: Download all artifacts
|
|
144
|
+
uses: actions/download-artifact@v4
|
|
145
|
+
with:
|
|
146
|
+
path: dist
|
|
147
|
+
merge-multiple: true
|
|
148
|
+
|
|
149
|
+
- name: Flatten dist
|
|
150
|
+
run: |
|
|
151
|
+
mkdir -p dist/merged
|
|
152
|
+
find dist -maxdepth 3 -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} dist/merged/ \;
|
|
153
|
+
rm -rf dist/wheels-* dist/sdist
|
|
154
|
+
mv dist/merged/* dist/
|
|
155
|
+
rmdir dist/merged
|
|
156
|
+
ls -la dist/
|
|
157
|
+
|
|
158
|
+
- name: Publish to TestPyPI
|
|
159
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
160
|
+
with:
|
|
161
|
+
repository-url: https://test.pypi.org/legacy/
|
|
162
|
+
print-hash: true
|
|
163
|
+
|
|
164
|
+
create-github-release:
|
|
165
|
+
name: Create GitHub Release
|
|
166
|
+
needs: [publish-to-pypi]
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
169
|
+
permissions:
|
|
170
|
+
contents: write
|
|
171
|
+
|
|
172
|
+
steps:
|
|
173
|
+
- uses: actions/checkout@v4
|
|
174
|
+
with:
|
|
175
|
+
fetch-depth: 0
|
|
176
|
+
|
|
177
|
+
- name: Download all artifacts
|
|
178
|
+
uses: actions/download-artifact@v4
|
|
179
|
+
with:
|
|
180
|
+
path: dist
|
|
181
|
+
merge-multiple: true
|
|
182
|
+
|
|
183
|
+
- name: Flatten dist for release upload
|
|
184
|
+
run: |
|
|
185
|
+
mkdir -p release_assets
|
|
186
|
+
find dist -maxdepth 3 -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} release_assets/ \;
|
|
187
|
+
ls -la release_assets/
|
|
188
|
+
|
|
189
|
+
- name: Determine release type
|
|
190
|
+
id: release-type
|
|
191
|
+
run: |
|
|
192
|
+
if [[ ${{ github.ref_name }} =~ -alpha|-beta|-rc ]]; then
|
|
193
|
+
echo "prerelease=true" >> $GITHUB_OUTPUT
|
|
194
|
+
else
|
|
195
|
+
echo "prerelease=false" >> $GITHUB_OUTPUT
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
- name: Create GitHub Release
|
|
199
|
+
run: |
|
|
200
|
+
gh release create ${{ github.ref_name }} \
|
|
201
|
+
--title "opentui ${{ github.ref_name }}" \
|
|
202
|
+
--generate-notes \
|
|
203
|
+
${{ steps.release-type.outputs.prerelease == 'true' && '--prerelease' || '--latest' }} \
|
|
204
|
+
release_assets/*
|
|
205
|
+
env:
|
|
206
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
opentui-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
|
|
12
|
+
# IDE
|
|
13
|
+
.idea/
|
|
14
|
+
.vscode/
|
|
15
|
+
*.swp
|
|
16
|
+
*.swo
|
|
17
|
+
.claude/
|
|
18
|
+
# Build artifacts
|
|
19
|
+
src/opentui/opentui-libs/
|
|
20
|
+
src/opentui_bindings/build/
|
|
21
|
+
*.so
|
|
22
|
+
*.dylib
|
|
23
|
+
*.pyd
|
|
24
|
+
_skbuild/
|
|
25
|
+
CMakeCache.txt
|
|
26
|
+
CMakeFiles/
|
|
27
|
+
|
|
28
|
+
# Coverage
|
|
29
|
+
.coverage
|
|
30
|
+
htmlcov/
|
|
31
|
+
|
|
32
|
+
# Cache
|
|
33
|
+
.ruff_cache/
|
|
34
|
+
.mypy_cache/
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
|
|
37
|
+
# OS
|
|
38
|
+
.DS_Store
|
|
39
|
+
|
|
40
|
+
# Reference upstream source (not for distribution)
|
|
41
|
+
reference/
|
|
42
|
+
|
|
43
|
+
# Internal docs and planning (not for distribution)
|
|
44
|
+
docs/
|
|
45
|
+
AGENTS.md
|
|
46
|
+
PLAN.md
|
|
47
|
+
progress.md
|
|
48
|
+
buffer_dump/
|
|
49
|
+
|
|
50
|
+
# Diagnostics
|
|
51
|
+
opentui-debug.log
|
|
52
|
+
|
|
53
|
+
# Benchmark baselines (machine-specific)
|
|
54
|
+
benchmarks/baselines/
|
|
55
|
+
|
|
56
|
+
# Issue tracking
|
|
57
|
+
.beads/
|
|
58
|
+
|
opentui-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 firefly
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|