From fd444e396c44ac707e3a6c8c450db1d6697aab20 Mon Sep 17 00:00:00 2001 From: FelixSe Date: Tue, 23 Jan 2018 22:58:40 +0100 Subject: [PATCH] initial commit --- .gitignore | 3 + FluentTerminal.App/App.xaml | 12 + FluentTerminal.App/App.xaml.cs | 134 + .../Assets/AppIcons/LargeTile.scale-100.png | Bin 0 -> 2770 bytes .../Assets/AppIcons/LargeTile.scale-125.png | Bin 0 -> 3185 bytes .../Assets/AppIcons/LargeTile.scale-150.png | Bin 0 -> 4348 bytes .../Assets/AppIcons/LargeTile.scale-200.png | Bin 0 -> 6348 bytes .../Assets/AppIcons/LargeTile.scale-400.png | Bin 0 -> 15541 bytes .../Assets/AppIcons/SmallTile.scale-100.png | Bin 0 -> 789 bytes .../Assets/AppIcons/SmallTile.scale-125.png | Bin 0 -> 920 bytes .../Assets/AppIcons/SmallTile.scale-150.png | Bin 0 -> 1265 bytes .../Assets/AppIcons/SmallTile.scale-200.png | Bin 0 -> 1609 bytes .../Assets/AppIcons/SmallTile.scale-400.png | Bin 0 -> 2836 bytes .../AppIcons/SplashScreen.scale-100.png | Bin 0 -> 2802 bytes .../AppIcons/SplashScreen.scale-125.png | Bin 0 -> 4128 bytes .../AppIcons/SplashScreen.scale-150.png | Bin 0 -> 4703 bytes .../AppIcons/SplashScreen.scale-200.png | Bin 0 -> 7462 bytes .../AppIcons/SplashScreen.scale-400.png | Bin 0 -> 21076 bytes .../AppIcons/Square150x150Logo.scale-100.png | Bin 0 -> 1411 bytes .../AppIcons/Square150x150Logo.scale-125.png | Bin 0 -> 1742 bytes .../AppIcons/Square150x150Logo.scale-150.png | Bin 0 -> 2092 bytes .../AppIcons/Square150x150Logo.scale-200.png | Bin 0 -> 2354 bytes .../AppIcons/Square150x150Logo.scale-400.png | Bin 0 -> 5889 bytes ...x44Logo.altform-unplated_targetsize-16.png | Bin 0 -> 315 bytes ...x44Logo.altform-unplated_targetsize-24.png | Bin 0 -> 456 bytes ...44Logo.altform-unplated_targetsize-256.png | Bin 0 -> 4453 bytes ...x44Logo.altform-unplated_targetsize-32.png | Bin 0 -> 494 bytes ...x44Logo.altform-unplated_targetsize-48.png | Bin 0 -> 762 bytes .../AppIcons/Square44x44Logo.scale-100.png | Bin 0 -> 594 bytes .../AppIcons/Square44x44Logo.scale-125.png | Bin 0 -> 871 bytes .../AppIcons/Square44x44Logo.scale-150.png | Bin 0 -> 1057 bytes .../AppIcons/Square44x44Logo.scale-200.png | Bin 0 -> 1393 bytes .../AppIcons/Square44x44Logo.scale-400.png | Bin 0 -> 2261 bytes .../Square44x44Logo.targetsize-16.png | Bin 0 -> 252 bytes .../Square44x44Logo.targetsize-24.png | Bin 0 -> 381 bytes .../Square44x44Logo.targetsize-256.png | Bin 0 -> 3527 bytes .../Square44x44Logo.targetsize-32.png | Bin 0 -> 478 bytes .../Square44x44Logo.targetsize-48.png | Bin 0 -> 777 bytes .../Assets/AppIcons/StoreLogo.scale-100.png | Bin 0 -> 962 bytes .../Assets/AppIcons/StoreLogo.scale-125.png | Bin 0 -> 1195 bytes .../Assets/AppIcons/StoreLogo.scale-150.png | Bin 0 -> 1446 bytes .../Assets/AppIcons/StoreLogo.scale-200.png | Bin 0 -> 1423 bytes .../Assets/AppIcons/StoreLogo.scale-400.png | Bin 0 -> 3162 bytes .../AppIcons/Wide310x150Logo.scale-100.png | Bin 0 -> 1542 bytes .../AppIcons/Wide310x150Logo.scale-125.png | Bin 0 -> 1923 bytes .../AppIcons/Wide310x150Logo.scale-150.png | Bin 0 -> 2353 bytes .../AppIcons/Wide310x150Logo.scale-200.png | Bin 0 -> 2802 bytes .../AppIcons/Wide310x150Logo.scale-400.png | Bin 0 -> 7462 bytes .../Assets/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Assets/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes FluentTerminal.App/Assets/StoreLogo.png | Bin 0 -> 1451 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes FluentTerminal.App/FluentTerminal.App.csproj | 264 + FluentTerminal.App/Package.appxmanifest | 41 + FluentTerminal.App/Properties/AssemblyInfo.cs | 29 + FluentTerminal.App/Properties/Default.rd.xml | 31 + FluentTerminal.App/Styles/Custom.xaml | 71 + FluentTerminal.App/Views/MainPage.xaml | 45 + FluentTerminal.App/Views/MainPage.xaml.cs | 97 + FluentTerminal.App/Views/SettingsPage.xaml | 13 + FluentTerminal.App/Views/SettingsPage.xaml.cs | 12 + FluentTerminal.App/Views/TerminalPage.xaml | 9 + FluentTerminal.App/Views/TerminalPage.xaml.cs | 65 + FluentTerminal.Client/.gitignore | 1 + FluentTerminal.Client/dist/bundle.js | 6618 +++++++ FluentTerminal.Client/dist/index.html | 12 + FluentTerminal.Client/dist/style.css | 24 + FluentTerminal.Client/dist/xterm.css | 125 + FluentTerminal.Client/package-lock.json | 3104 ++++ FluentTerminal.Client/package.json | 16 + FluentTerminal.Client/src/index.js | 58 + FluentTerminal.Client/webpack.config.js | 9 + FluentTerminal.SystemTray/App.config | 9 + .../BinaryDependencies/x64/winpty-agent.exe | Bin 0 -> 726528 bytes .../x64/winpty-debugserver.exe | Bin 0 -> 581120 bytes .../BinaryDependencies/x64/winpty.dll | Bin 0 -> 640000 bytes .../BinaryDependencies/x86/winpty-agent.exe | Bin 0 -> 580608 bytes .../x86/winpty-debugserver.exe | Bin 0 -> 463872 bytes .../BinaryDependencies/x86/winpty.dll | Bin 0 -> 508928 bytes FluentTerminal.SystemTray/Client/bundle.js | 6618 +++++++ FluentTerminal.SystemTray/Client/index.html | 12 + FluentTerminal.SystemTray/Client/style.css | 24 + FluentTerminal.SystemTray/Client/xterm.css | 125 + .../Controllers/TerminalsController.cs | 33 + .../DataTransferObjects/TerminalOptions.cs | 10 + .../FluentTerminal.SystemTray.csproj | 199 + FluentTerminal.SystemTray/LoopbackEnabler.cs | 330 + FluentTerminal.SystemTray/Program.cs | 36 + .../Properties/AssemblyInfo.cs | 36 + .../Properties/Resources.Designer.cs | 73 + .../Properties/Resources.resx | 124 + .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + .../Resources/Square44x44Logo.scale-100.ico | Bin 0 -> 101611 bytes .../Services/Terminal.cs | 174 + .../Services/TerminalsManager.cs | 32 + FluentTerminal.SystemTray/Startup.cs | 25 + .../SystemTrayApplicationContext.cs | 79 + FluentTerminal.SystemTray/Utilities.cs | 37 + FluentTerminal.SystemTray/app.manifest | 59 + FluentTerminal.sln | 68 + xterm.js/.dockerignore | 16 + xterm.js/.editorconfig | 17 + xterm.js/.gitattributes | 1 + xterm.js/.github/ISSUE_TEMPLATE.md | 11 + xterm.js/.gitignore | 28 + xterm.js/.gitmodules | 0 xterm.js/.mailmap | 7 + xterm.js/.npmignore | 16 + xterm.js/.travis.yml | 20 + xterm.js/AUTHORS | 92 + xterm.js/CONTRIBUTING.md | 52 + xterm.js/Dockerfile | 19 + xterm.js/LICENSE | 20 + xterm.js/Procfile | 1 + xterm.js/README.md | 170 + xterm.js/demo/app.js | 88 + xterm.js/demo/index.html | 70 + xterm.js/demo/main.js | 179 + xterm.js/demo/style.css | 16 + xterm.js/docker-compose.yml | 9 + xterm.js/fixtures/escape_sequence_files/NOTES | 21 + .../t0001-all_printable.in | 6 + .../t0001-all_printable.text | 25 + .../escape_sequence_files/t0002-history.in | 95 + .../escape_sequence_files/t0002-history.text | 25 + .../t0002j-simple_string.in | 1 + .../t0002j-simple_string.text | 25 + .../escape_sequence_files/t0003-line_wrap.in | 83 + .../t0003-line_wrap.text | 25 + .../escape_sequence_files/t0003j-LF.in | 26 + .../escape_sequence_files/t0003j-LF.text | 25 + .../escape_sequence_files/t0004-LF.in | 83 + .../escape_sequence_files/t0004-LF.text | 25 + .../escape_sequence_files/t0004j-CR.in | 7 + .../escape_sequence_files/t0004j-CR.text | 25 + .../escape_sequence_files/t0005-CR.in | 82 + .../escape_sequence_files/t0005-CR.text | 25 + .../escape_sequence_files/t0006-IND.in | 1 + .../escape_sequence_files/t0006-IND.text | 25 + .../t0007-space_at_end.in | 8 + .../t0007-space_at_end.text | 25 + .../escape_sequence_files/t0008-BS.in | 7 + .../escape_sequence_files/t0008-BS.text | 25 + .../escape_sequence_files/t0009-NEL.in | 1 + .../escape_sequence_files/t0009-NEL.text | 25 + .../escape_sequence_files/t0010-RI.in | 10 + .../escape_sequence_files/t0010-RI.text | 25 + .../escape_sequence_files/t0011-RI_scroll.in | 47 + .../t0011-RI_scroll.text | 25 + .../escape_sequence_files/t0012-VT.in | 1 + .../escape_sequence_files/t0012-VT.text | 25 + .../escape_sequence_files/t0013-FF.in | 1 + .../escape_sequence_files/t0013-FF.text | 25 + .../escape_sequence_files/t0014-CAN.in | 8 + .../escape_sequence_files/t0014-CAN.text | 25 + .../escape_sequence_files/t0015-SUB.in | 8 + .../escape_sequence_files/t0015-SUB.text | 25 + .../escape_sequence_files/t0016-SU.in | 17 + .../escape_sequence_files/t0016-SU.text | 25 + .../escape_sequence_files/t0017-SD.in | 54 + .../escape_sequence_files/t0017-SD.text | 25 + .../escape_sequence_files/t0020-CUF.in | 14 + .../escape_sequence_files/t0020-CUF.text | 25 + .../escape_sequence_files/t0021-CUB.in | 8 + .../escape_sequence_files/t0021-CUB.text | 25 + .../escape_sequence_files/t0022-CUU.in | 25 + .../escape_sequence_files/t0022-CUU.text | 25 + .../escape_sequence_files/t0023-CUU_scroll.in | 50 + .../t0023-CUU_scroll.text | 25 + .../escape_sequence_files/t0024-CUD.in | 24 + .../escape_sequence_files/t0024-CUD.text | 25 + .../escape_sequence_files/t0025-CUP.in | 1 + .../escape_sequence_files/t0025-CUP.text | 25 + .../escape_sequence_files/t0026-CNL.in | 2 + .../escape_sequence_files/t0026-CNL.text | 25 + .../escape_sequence_files/t0027-CPL.in | 6 + .../escape_sequence_files/t0027-CPL.text | 25 + .../escape_sequence_files/t0030-HPR.in | 14 + .../escape_sequence_files/t0030-HPR.text | 25 + .../escape_sequence_files/t0031-HPB.in_ | 8 + .../escape_sequence_files/t0031-HPB.text | 25 + .../escape_sequence_files/t0032-VPB.in | 25 + .../escape_sequence_files/t0032-VPB.text | 25 + .../escape_sequence_files/t0033-VPB_scroll.in | 50 + .../t0033-VPB_scroll.text | 25 + .../escape_sequence_files/t0034-VPR.in | 24 + .../escape_sequence_files/t0034-VPR.text | 25 + .../escape_sequence_files/t0035-HVP.in | 1 + .../escape_sequence_files/t0035-HVP.text | 25 + .../escape_sequence_files/t0040-REP.in | 7 + .../escape_sequence_files/t0040-REP.text | 25 + .../escape_sequence_files/t0050-ICH.in | 23 + .../escape_sequence_files/t0050-ICH.text | 25 + .../escape_sequence_files/t0051-IL.in | 23 + .../escape_sequence_files/t0051-IL.text | 25 + .../escape_sequence_files/t0052-DL.in | 15 + .../escape_sequence_files/t0052-DL.text | 25 + .../escape_sequence_files/t0053-DCH.in | 12 + .../escape_sequence_files/t0053-DCH.text | 25 + .../escape_sequence_files/t0054-ECH.in | 12 + .../escape_sequence_files/t0054-ECH.text | 25 + .../escape_sequence_files/t0055-EL.in | 8 + .../escape_sequence_files/t0055-EL.text | 25 + .../escape_sequence_files/t0056-ED.in | 62 + .../escape_sequence_files/t0056-ED.text | 25 + .../escape_sequence_files/t0057-ED3.in | 55 + .../escape_sequence_files/t0057-ED3.note | 6 + .../escape_sequence_files/t0057-ED3.text | 25 + .../escape_sequence_files/t0060-DECSC.in | 9 + .../escape_sequence_files/t0060-DECSC.text | 25 + .../escape_sequence_files/t0061-CSI_s.in | 9 + .../escape_sequence_files/t0061-CSI_s.text | 25 + .../escape_sequence_files/t0070-DECSTBM_LF.in | 31 + .../t0070-DECSTBM_LF.text | 25 + .../t0071-DECSTBM_IND.in | 3 + .../t0071-DECSTBM_IND.text | 25 + .../t0072-DECSTBM_NEL.in | 2 + .../t0072-DECSTBM_NEL.text | 25 + .../escape_sequence_files/t0073-DECSTBM_RI.in | 43 + .../t0073-DECSTBM_RI.text | 25 + .../t0074-DECSTBM_SU_SD.in | 24 + .../t0074-DECSTBM_SU_SD.text | 24 + .../t0075-DECSTBM_CUU_CUD.in | 24 + .../t0075-DECSTBM_CUU_CUD.text | 25 + .../t0076-DECSTBM_IL_DL.in | 33 + .../t0076-DECSTBM_IL_DL.text | 25 + .../t0077-DECSTBM_quirks.in | 32 + .../t0077-DECSTBM_quirks.text | 25 + .../escape_sequence_files/t0080-HT.in | 14 + .../escape_sequence_files/t0080-HT.text | 25 + .../escape_sequence_files/t0081-TBC.in | 19 + .../escape_sequence_files/t0081-TBC.text | 25 + .../escape_sequence_files/t0082-HTS.in | 8 + .../escape_sequence_files/t0082-HTS.text | 25 + .../escape_sequence_files/t0083-CHT.in | 18 + .../escape_sequence_files/t0083-CHT.text | 25 + .../escape_sequence_files/t0084-CBT.in | 16 + .../escape_sequence_files/t0084-CBT.text | 25 + .../t0084-CBT.text-xterm | 20 + .../escape_sequence_files/t0090-alt_screen.in | 55 + .../t0090-alt_screen.text | 25 + .../t0091-alt_screen_ED3.in | 46 + .../t0091-alt_screen_ED3.text | 25 + .../t0092-alt_screen_DECSC.in | 15 + .../t0092-alt_screen_DECSC.text | 25 + .../escape_sequence_files/t0100-IRM.in | 13 + .../escape_sequence_files/t0100-IRM.text | 25 + .../escape_sequence_files/t0101-NLM.in | 10 + .../escape_sequence_files/t0101-NLM.text | 25 + .../escape_sequence_files/t0102-DECAWM.in | 4 + .../escape_sequence_files/t0102-DECAWM.text | 25 + .../t0103-reverse_wrap.in | 6 + .../t0103-reverse_wrap.text | 25 + .../escape_sequence_files/t0200-SGR.html | 35 + .../escape_sequence_files/t0200-SGR.in_ | 33 + .../t0220-SGR_inverse.html | 6 + .../t0220-SGR_inverse.in_ | 4 + .../t0500-bash_long_line.in | 7 + .../t0500-bash_long_line.text | 25 + .../escape_sequence_files/t0501-bash_ls.in | 12 + .../escape_sequence_files/t0501-bash_ls.text | 25 + .../t0502-bash_ls_color.in | 10 + .../t0502-bash_ls_color.text | 25 + .../t0503-zsh_ls_color.in | 9 + .../t0503-zsh_ls_color.text | 25 + .../escape_sequence_files/t0504-vim.in | 56 + .../escape_sequence_files/t0504-vim.text | 25 + xterm.js/fixtures/typings-test/tsconfig.json | 9 + .../fixtures/typings-test/typings-test.ts | 234 + xterm.js/gulpfile.js | 213 + xterm.js/jsdoc.json | 26 + xterm.js/logo-full.png | Bin 0 -> 11635 bytes xterm.js/package-lock.json | 15284 ++++++++++++++++ xterm.js/package.json | 91 + xterm.js/src/Buffer.test.ts | 191 + xterm.js/src/Buffer.ts | 312 + xterm.js/src/BufferSet.test.ts | 51 + xterm.js/src/BufferSet.ts | 102 + xterm.js/src/CharWidth.ts | 161 + xterm.js/src/Charsets.ts | 255 + xterm.js/src/CompositionHelper.test.ts | 251 + xterm.js/src/CompositionHelper.ts | 230 + xterm.js/src/EscapeSequences.ts | 79 + xterm.js/src/EventEmitter.test.ts | 89 + xterm.js/src/EventEmitter.ts | 71 + xterm.js/src/InputHandler.test.ts | 82 + xterm.js/src/InputHandler.ts | 1455 ++ xterm.js/src/Interfaces.ts | 355 + xterm.js/src/Linkifier.test.ts | 220 + xterm.js/src/Linkifier.ts | 297 + xterm.js/src/Parser.ts | 673 + xterm.js/src/SelectionManager.test.ts | 344 + xterm.js/src/SelectionManager.ts | 739 + xterm.js/src/SelectionModel.test.ts | 141 + xterm.js/src/SelectionModel.ts | 132 + xterm.js/src/Terminal.integration.ts | 163 + xterm.js/src/Terminal.test.ts | 1037 ++ xterm.js/src/Terminal.ts | 2263 +++ xterm.js/src/Types.ts | 35 + xterm.js/src/Viewport.ts | 145 + xterm.js/src/addons/attach/attach.test.ts | 20 + xterm.js/src/addons/attach/attach.ts | 122 + xterm.js/src/addons/attach/index.html | 93 + xterm.js/src/addons/attach/package.json | 5 + xterm.js/src/addons/attach/tsconfig.json | 10 + xterm.js/src/addons/fit/fit.test.ts | 20 + xterm.js/src/addons/fit/fit.ts | 55 + xterm.js/src/addons/fit/package.json | 5 + xterm.js/src/addons/fit/tsconfig.json | 10 + xterm.js/src/addons/fullscreen/fullscreen.css | 10 + .../src/addons/fullscreen/fullscreen.test.ts | 19 + xterm.js/src/addons/fullscreen/fullscreen.ts | 29 + xterm.js/src/addons/fullscreen/package.json | 5 + xterm.js/src/addons/fullscreen/tsconfig.json | 10 + xterm.js/src/addons/search/SearchHelper.ts | 140 + xterm.js/src/addons/search/package.json | 5 + xterm.js/src/addons/search/search.ts | 43 + xterm.js/src/addons/search/tsconfig.json | 10 + xterm.js/src/addons/terminado/package.json | 5 + .../src/addons/terminado/terminado.test.ts | 20 + xterm.js/src/addons/terminado/terminado.ts | 111 + xterm.js/src/addons/terminado/tsconfig.json | 10 + xterm.js/src/addons/winptyCompat/package.json | 5 + .../src/addons/winptyCompat/tsconfig.json | 10 + .../addons/winptyCompat/winptyCompat.test.ts | 19 + .../src/addons/winptyCompat/winptyCompat.ts | 38 + xterm.js/src/addons/zmodem/demo/app.js | 87 + xterm.js/src/addons/zmodem/demo/index.html | 128 + xterm.js/src/addons/zmodem/demo/main.js | 383 + xterm.js/src/addons/zmodem/package.json | 5 + xterm.js/src/addons/zmodem/tsconfig.json | 10 + xterm.js/src/addons/zmodem/zmodem.test.ts | 20 + xterm.js/src/addons/zmodem/zmodem.ts | 90 + xterm.js/src/handlers/Clipboard.test.ts | 27 + xterm.js/src/handlers/Clipboard.ts | 125 + xterm.js/src/input/Interfaces.ts | 19 + xterm.js/src/input/MouseZoneManager.ts | 197 + xterm.js/src/renderer/BaseRenderLayer.ts | 336 + xterm.js/src/renderer/CharAtlas.ts | 222 + xterm.js/src/renderer/ColorManager.test.ts | 295 + xterm.js/src/renderer/ColorManager.ts | 110 + xterm.js/src/renderer/CursorRenderLayer.ts | 354 + xterm.js/src/renderer/GridCache.test.ts | 62 + xterm.js/src/renderer/GridCache.ts | 33 + xterm.js/src/renderer/Interfaces.ts | 99 + xterm.js/src/renderer/LinkRenderLayer.ts | 49 + xterm.js/src/renderer/Renderer.ts | 276 + xterm.js/src/renderer/SelectionRenderLayer.ts | 89 + xterm.js/src/renderer/TextRenderLayer.ts | 249 + xterm.js/src/renderer/Types.ts | 16 + xterm.js/src/utils/Browser.ts | 22 + xterm.js/src/utils/CharMeasure.test.ts | 54 + xterm.js/src/utils/CharMeasure.ts | 59 + xterm.js/src/utils/CircularList.test.ts | 264 + xterm.js/src/utils/CircularList.ts | 213 + xterm.js/src/utils/Generic.ts | 13 + xterm.js/src/utils/MouseHelper.test.ts | 70 + xterm.js/src/utils/MouseHelper.ts | 95 + xterm.js/src/utils/ScreenDprMonitor.ts | 55 + xterm.js/src/utils/Sounds.ts | 10 + xterm.js/src/utils/TestUtils.test.ts | 278 + xterm.js/src/xterm.css | 125 + xterm.js/src/xterm.ts | 10 + xterm.js/tsconfig.json | 16 + xterm.js/tslint.json | 62 + xterm.js/webpack.config.js | 10 + 370 files changed, 54374 insertions(+) create mode 100644 FluentTerminal.App/App.xaml create mode 100644 FluentTerminal.App/App.xaml.cs create mode 100644 FluentTerminal.App/Assets/AppIcons/LargeTile.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/LargeTile.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/LargeTile.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/LargeTile.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/LargeTile.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SmallTile.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SmallTile.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SmallTile.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SmallTile.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SmallTile.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-16.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-24.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-256.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-32.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-48.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-16.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-24.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-256.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-32.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-48.png create mode 100644 FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-400.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-100.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-125.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-150.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-200.png create mode 100644 FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-400.png create mode 100644 FluentTerminal.App/Assets/LockScreenLogo.scale-200.png create mode 100644 FluentTerminal.App/Assets/SplashScreen.scale-200.png create mode 100644 FluentTerminal.App/Assets/Square150x150Logo.scale-200.png create mode 100644 FluentTerminal.App/Assets/Square44x44Logo.scale-200.png create mode 100644 FluentTerminal.App/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 FluentTerminal.App/Assets/StoreLogo.png create mode 100644 FluentTerminal.App/Assets/Wide310x150Logo.scale-200.png create mode 100644 FluentTerminal.App/FluentTerminal.App.csproj create mode 100644 FluentTerminal.App/Package.appxmanifest create mode 100644 FluentTerminal.App/Properties/AssemblyInfo.cs create mode 100644 FluentTerminal.App/Properties/Default.rd.xml create mode 100644 FluentTerminal.App/Styles/Custom.xaml create mode 100644 FluentTerminal.App/Views/MainPage.xaml create mode 100644 FluentTerminal.App/Views/MainPage.xaml.cs create mode 100644 FluentTerminal.App/Views/SettingsPage.xaml create mode 100644 FluentTerminal.App/Views/SettingsPage.xaml.cs create mode 100644 FluentTerminal.App/Views/TerminalPage.xaml create mode 100644 FluentTerminal.App/Views/TerminalPage.xaml.cs create mode 100644 FluentTerminal.Client/.gitignore create mode 100644 FluentTerminal.Client/dist/bundle.js create mode 100644 FluentTerminal.Client/dist/index.html create mode 100644 FluentTerminal.Client/dist/style.css create mode 100644 FluentTerminal.Client/dist/xterm.css create mode 100644 FluentTerminal.Client/package-lock.json create mode 100644 FluentTerminal.Client/package.json create mode 100644 FluentTerminal.Client/src/index.js create mode 100644 FluentTerminal.Client/webpack.config.js create mode 100644 FluentTerminal.SystemTray/App.config create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-agent.exe create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-debugserver.exe create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x64/winpty.dll create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-agent.exe create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-debugserver.exe create mode 100644 FluentTerminal.SystemTray/BinaryDependencies/x86/winpty.dll create mode 100644 FluentTerminal.SystemTray/Client/bundle.js create mode 100644 FluentTerminal.SystemTray/Client/index.html create mode 100644 FluentTerminal.SystemTray/Client/style.css create mode 100644 FluentTerminal.SystemTray/Client/xterm.css create mode 100644 FluentTerminal.SystemTray/Controllers/TerminalsController.cs create mode 100644 FluentTerminal.SystemTray/DataTransferObjects/TerminalOptions.cs create mode 100644 FluentTerminal.SystemTray/FluentTerminal.SystemTray.csproj create mode 100644 FluentTerminal.SystemTray/LoopbackEnabler.cs create mode 100644 FluentTerminal.SystemTray/Program.cs create mode 100644 FluentTerminal.SystemTray/Properties/AssemblyInfo.cs create mode 100644 FluentTerminal.SystemTray/Properties/Resources.Designer.cs create mode 100644 FluentTerminal.SystemTray/Properties/Resources.resx create mode 100644 FluentTerminal.SystemTray/Properties/Settings.Designer.cs create mode 100644 FluentTerminal.SystemTray/Properties/Settings.settings create mode 100644 FluentTerminal.SystemTray/Resources/Square44x44Logo.scale-100.ico create mode 100644 FluentTerminal.SystemTray/Services/Terminal.cs create mode 100644 FluentTerminal.SystemTray/Services/TerminalsManager.cs create mode 100644 FluentTerminal.SystemTray/Startup.cs create mode 100644 FluentTerminal.SystemTray/SystemTrayApplicationContext.cs create mode 100644 FluentTerminal.SystemTray/Utilities.cs create mode 100644 FluentTerminal.SystemTray/app.manifest create mode 100644 FluentTerminal.sln create mode 100644 xterm.js/.dockerignore create mode 100644 xterm.js/.editorconfig create mode 100644 xterm.js/.gitattributes create mode 100644 xterm.js/.github/ISSUE_TEMPLATE.md create mode 100644 xterm.js/.gitignore create mode 100644 xterm.js/.gitmodules create mode 100644 xterm.js/.mailmap create mode 100644 xterm.js/.npmignore create mode 100644 xterm.js/.travis.yml create mode 100644 xterm.js/AUTHORS create mode 100644 xterm.js/CONTRIBUTING.md create mode 100644 xterm.js/Dockerfile create mode 100644 xterm.js/LICENSE create mode 100644 xterm.js/Procfile create mode 100644 xterm.js/README.md create mode 100644 xterm.js/demo/app.js create mode 100644 xterm.js/demo/index.html create mode 100644 xterm.js/demo/main.js create mode 100644 xterm.js/demo/style.css create mode 100644 xterm.js/docker-compose.yml create mode 100644 xterm.js/fixtures/escape_sequence_files/NOTES create mode 100644 xterm.js/fixtures/escape_sequence_files/t0001-all_printable.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0001-all_printable.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0002-history.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0002-history.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0003j-LF.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0003j-LF.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0004-LF.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0004-LF.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0004j-CR.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0004j-CR.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0005-CR.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0005-CR.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0006-IND.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0006-IND.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0008-BS.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0008-BS.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0009-NEL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0009-NEL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0010-RI.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0010-RI.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0012-VT.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0012-VT.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0013-FF.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0013-FF.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0014-CAN.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0014-CAN.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0015-SUB.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0015-SUB.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0016-SU.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0016-SU.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0017-SD.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0017-SD.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0020-CUF.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0020-CUF.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0021-CUB.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0021-CUB.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0022-CUU.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0022-CUU.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0024-CUD.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0024-CUD.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0025-CUP.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0025-CUP.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0026-CNL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0026-CNL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0027-CPL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0027-CPL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0030-HPR.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0030-HPR.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0031-HPB.in_ create mode 100644 xterm.js/fixtures/escape_sequence_files/t0031-HPB.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0032-VPB.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0032-VPB.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0034-VPR.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0034-VPR.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0035-HVP.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0035-HVP.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0040-REP.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0040-REP.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0050-ICH.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0050-ICH.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0051-IL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0051-IL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0052-DL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0052-DL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0053-DCH.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0053-DCH.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0054-ECH.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0054-ECH.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0055-EL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0055-EL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0056-ED.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0056-ED.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0057-ED3.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0057-ED3.note create mode 100644 xterm.js/fixtures/escape_sequence_files/t0057-ED3.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0060-DECSC.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0060-DECSC.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0080-HT.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0080-HT.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0081-TBC.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0081-TBC.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0082-HTS.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0082-HTS.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0083-CHT.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0083-CHT.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0084-CBT.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0084-CBT.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0084-CBT.text-xterm create mode 100644 xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0100-IRM.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0100-IRM.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0101-NLM.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0101-NLM.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0200-SGR.html create mode 100644 xterm.js/fixtures/escape_sequence_files/t0200-SGR.in_ create mode 100644 xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.html create mode 100644 xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.in_ create mode 100644 xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.text create mode 100644 xterm.js/fixtures/escape_sequence_files/t0504-vim.in create mode 100644 xterm.js/fixtures/escape_sequence_files/t0504-vim.text create mode 100644 xterm.js/fixtures/typings-test/tsconfig.json create mode 100644 xterm.js/fixtures/typings-test/typings-test.ts create mode 100644 xterm.js/gulpfile.js create mode 100644 xterm.js/jsdoc.json create mode 100644 xterm.js/logo-full.png create mode 100644 xterm.js/package-lock.json create mode 100644 xterm.js/package.json create mode 100644 xterm.js/src/Buffer.test.ts create mode 100644 xterm.js/src/Buffer.ts create mode 100644 xterm.js/src/BufferSet.test.ts create mode 100644 xterm.js/src/BufferSet.ts create mode 100644 xterm.js/src/CharWidth.ts create mode 100644 xterm.js/src/Charsets.ts create mode 100644 xterm.js/src/CompositionHelper.test.ts create mode 100644 xterm.js/src/CompositionHelper.ts create mode 100644 xterm.js/src/EscapeSequences.ts create mode 100644 xterm.js/src/EventEmitter.test.ts create mode 100644 xterm.js/src/EventEmitter.ts create mode 100644 xterm.js/src/InputHandler.test.ts create mode 100644 xterm.js/src/InputHandler.ts create mode 100644 xterm.js/src/Interfaces.ts create mode 100644 xterm.js/src/Linkifier.test.ts create mode 100644 xterm.js/src/Linkifier.ts create mode 100644 xterm.js/src/Parser.ts create mode 100644 xterm.js/src/SelectionManager.test.ts create mode 100644 xterm.js/src/SelectionManager.ts create mode 100644 xterm.js/src/SelectionModel.test.ts create mode 100644 xterm.js/src/SelectionModel.ts create mode 100644 xterm.js/src/Terminal.integration.ts create mode 100644 xterm.js/src/Terminal.test.ts create mode 100644 xterm.js/src/Terminal.ts create mode 100644 xterm.js/src/Types.ts create mode 100644 xterm.js/src/Viewport.ts create mode 100644 xterm.js/src/addons/attach/attach.test.ts create mode 100644 xterm.js/src/addons/attach/attach.ts create mode 100644 xterm.js/src/addons/attach/index.html create mode 100644 xterm.js/src/addons/attach/package.json create mode 100644 xterm.js/src/addons/attach/tsconfig.json create mode 100644 xterm.js/src/addons/fit/fit.test.ts create mode 100644 xterm.js/src/addons/fit/fit.ts create mode 100644 xterm.js/src/addons/fit/package.json create mode 100644 xterm.js/src/addons/fit/tsconfig.json create mode 100644 xterm.js/src/addons/fullscreen/fullscreen.css create mode 100644 xterm.js/src/addons/fullscreen/fullscreen.test.ts create mode 100644 xterm.js/src/addons/fullscreen/fullscreen.ts create mode 100644 xterm.js/src/addons/fullscreen/package.json create mode 100644 xterm.js/src/addons/fullscreen/tsconfig.json create mode 100644 xterm.js/src/addons/search/SearchHelper.ts create mode 100644 xterm.js/src/addons/search/package.json create mode 100644 xterm.js/src/addons/search/search.ts create mode 100644 xterm.js/src/addons/search/tsconfig.json create mode 100644 xterm.js/src/addons/terminado/package.json create mode 100644 xterm.js/src/addons/terminado/terminado.test.ts create mode 100644 xterm.js/src/addons/terminado/terminado.ts create mode 100644 xterm.js/src/addons/terminado/tsconfig.json create mode 100644 xterm.js/src/addons/winptyCompat/package.json create mode 100644 xterm.js/src/addons/winptyCompat/tsconfig.json create mode 100644 xterm.js/src/addons/winptyCompat/winptyCompat.test.ts create mode 100644 xterm.js/src/addons/winptyCompat/winptyCompat.ts create mode 100644 xterm.js/src/addons/zmodem/demo/app.js create mode 100644 xterm.js/src/addons/zmodem/demo/index.html create mode 100644 xterm.js/src/addons/zmodem/demo/main.js create mode 100644 xterm.js/src/addons/zmodem/package.json create mode 100644 xterm.js/src/addons/zmodem/tsconfig.json create mode 100644 xterm.js/src/addons/zmodem/zmodem.test.ts create mode 100644 xterm.js/src/addons/zmodem/zmodem.ts create mode 100644 xterm.js/src/handlers/Clipboard.test.ts create mode 100644 xterm.js/src/handlers/Clipboard.ts create mode 100644 xterm.js/src/input/Interfaces.ts create mode 100644 xterm.js/src/input/MouseZoneManager.ts create mode 100644 xterm.js/src/renderer/BaseRenderLayer.ts create mode 100644 xterm.js/src/renderer/CharAtlas.ts create mode 100644 xterm.js/src/renderer/ColorManager.test.ts create mode 100644 xterm.js/src/renderer/ColorManager.ts create mode 100644 xterm.js/src/renderer/CursorRenderLayer.ts create mode 100644 xterm.js/src/renderer/GridCache.test.ts create mode 100644 xterm.js/src/renderer/GridCache.ts create mode 100644 xterm.js/src/renderer/Interfaces.ts create mode 100644 xterm.js/src/renderer/LinkRenderLayer.ts create mode 100644 xterm.js/src/renderer/Renderer.ts create mode 100644 xterm.js/src/renderer/SelectionRenderLayer.ts create mode 100644 xterm.js/src/renderer/TextRenderLayer.ts create mode 100644 xterm.js/src/renderer/Types.ts create mode 100644 xterm.js/src/utils/Browser.ts create mode 100644 xterm.js/src/utils/CharMeasure.test.ts create mode 100644 xterm.js/src/utils/CharMeasure.ts create mode 100644 xterm.js/src/utils/CircularList.test.ts create mode 100644 xterm.js/src/utils/CircularList.ts create mode 100644 xterm.js/src/utils/Generic.ts create mode 100644 xterm.js/src/utils/MouseHelper.test.ts create mode 100644 xterm.js/src/utils/MouseHelper.ts create mode 100644 xterm.js/src/utils/ScreenDprMonitor.ts create mode 100644 xterm.js/src/utils/Sounds.ts create mode 100644 xterm.js/src/utils/TestUtils.test.ts create mode 100644 xterm.js/src/xterm.css create mode 100644 xterm.js/src/xterm.ts create mode 100644 xterm.js/tsconfig.json create mode 100644 xterm.js/tslint.json create mode 100644 xterm.js/webpack.config.js diff --git a/.gitignore b/.gitignore index 940794e..878de66 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Project specific +FluentTerminal.App/Win32 + ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## diff --git a/FluentTerminal.App/App.xaml b/FluentTerminal.App/App.xaml new file mode 100644 index 0000000..061c2b0 --- /dev/null +++ b/FluentTerminal.App/App.xaml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/FluentTerminal.App/App.xaml.cs b/FluentTerminal.App/App.xaml.cs new file mode 100644 index 0000000..b52c062 --- /dev/null +++ b/FluentTerminal.App/App.xaml.cs @@ -0,0 +1,134 @@ +using FluentTerminal.App.Views; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.ApplicationModel.AppService; +using Windows.ApplicationModel.Background; +using Windows.ApplicationModel.Core; +using Windows.UI.Core; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; + +namespace FluentTerminal.App +{ + sealed partial class App : Application + { + public App() + { + InitializeComponent(); + Instance = this; + } + + public static BackgroundTaskDeferral AppServiceDeferral = null; + public static AppServiceConnection Connection = null; + public static App Instance; + int? _settingsWindowId; + int idCreate = 0; + List idSaved = new List(); + + protected override async void OnLaunched(LaunchActivatedEventArgs e) + { + var launch = FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync().AsTask(); + var clearCache = WebView.ClearTemporaryWebDataAsync().AsTask(); + + await Task.WhenAll(launch, clearCache); + + Frame rootFrame = Window.Current.Content as Frame; + if (rootFrame == null) + { + rootFrame = new Frame(); + rootFrame.NavigationFailed += OnNavigationFailed; + Window.Current.Content = rootFrame; + } + + if (rootFrame.Content == null) + { + CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; + rootFrame.Navigate(typeof(MainPage), e.Arguments); + idSaved.Add(ApplicationView.GetForCurrentView().Id); + } + else if (false) //todo: add option to create new windows on launch + { + await CreateNewWindow(typeof(MainPage), true); + } + Window.Current.Activate(); + } + + protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args) + { + // connection established from the fulltrust process + base.OnBackgroundActivated(args); + if (args.TaskInstance.TriggerDetails is AppServiceTriggerDetails details) + { + AppServiceDeferral = args.TaskInstance.GetDeferral(); + args.TaskInstance.Canceled += OnTaskCanceled; + Connection = details.AppServiceConnection; + Connection.RequestReceived += OnRequestReceived; + } + } + + private void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) + { + if (args.Request.Message.ContainsKey("exit")) + { + App.Current.Exit(); + } + } + + private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) + { + if (AppServiceDeferral != null) + { + AppServiceDeferral.Complete(); + } + } + + public async Task CreateNewWindow(Type pageType, bool ExtendViewIntoTitleBar) + { + var create = CoreApplication.CreateNewView(); + await create.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = ExtendViewIntoTitleBar; + var frame = new Frame(); + frame.Navigate(pageType, null); + Window.Current.Content = frame; + Window.Current.Activate(); + + idCreate = ApplicationView.GetForCurrentView().Id; + }); + + for (int i = idSaved.Count - 1; i >= 0; i--) + if (await ApplicationViewSwitcher.TryShowAsStandaloneAsync( + idCreate, ViewSizePreference.Default, + idSaved[i], ViewSizePreference.Default) + ) break; + + idSaved.Add(idCreate); + return idCreate; + } + + public async Task ShowNew() + { + var id = await CreateNewWindow(typeof(MainPage), true); + bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(id); + } + + public async Task ShowSettings() + { + if (_settingsWindowId == null) + { + _settingsWindowId = await CreateNewWindow(typeof(Views.SettingsPage), false); + } + bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(_settingsWindowId.Value); + } + + void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + } +} diff --git a/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-100.png b/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..005c556eb450f126cf3513bf6fe5a95ef4c66fe1 GIT binary patch literal 2770 zcmeHJ`B#%y8irC?4Pa@2Lqs+~8)dO#R47K-u_b^Ah><1Gx@1ByLZF1rBBKyUuxDlj zg&@Kxi4cf|EI@#QN}P@aDcQ_N1Z5N?6EYT(U}9jt*#BY9{Lmlnx#zz3xzBT-_niCQ zw>A+K1F?0pH8V4V#KlIQFf%hpn1;0_7*X;^7~o`cF*d!x%*@%>G|b~p?EH_JnQe7k zmazR%;BXbNHZkgLZb@=w8<~T|iaZZ>& zlKiFmL#yyifdFvplbw*JT2 zaO(f*r%P?9Qswu#?tvo0wqY?4N=l+W4=NeI_H7}#jUq8mGT*@zS){fF~XBgUF+fG1+S>YlB* zBr8q2eW@64bvDSk{uYZeH(@u-dZqnG#iF+MhQ*l723Q|X6odw>y&?llqfjL&@)_fS zr&F4aq;>wqLdv__0QgfTs*;>IKX&ad?`tna(?$$RpNV!1e!#sOs-)Ed!x~n2N=`_}n>!2eT61$#fLb(o{TabxxnIAo;kOvSB$OcsEV!Q!8X_@PZa}r-%EXwuZ z!ocOKAI?dlp1tArC@;%{TMm+yfWpcJiE7r~A-%I_6hkBu2ZW_2s5j0Wj@M}jL;3S3 zO7;1>`OA}gG4N{t$j3_?8yDWT@x+=TL+9Ng5UY%rRjm<}MR*-ZGL)R}!9Ads+2#7; zFz{%HwNUOI0w5Ns`1ngU;C+7hXvxZCN&WB5$-EfQX_z&dPM*GE6y}|u<>-)G`Nr^- zf7z{i;>LalUjxBeLxY2)BzLK3L7cie)@_aEk%1p877@XC^d1~+S>}hYr?LDmAHgex zswdZp%lfW8xLrya9AAHvVQi0 zq!rT|sABNKW(BI3ru?R934k}gp2G5PBLj_kkC(241;81MA$7FCP~7!Cdp8E12r0&^ zds)QM*YgKHcZFck*+wDLu=3`mt;pBn#`4Oe(ln;dklHuqIL?`eM>m}O>x*=Uz;(6* zoUCwAj|}Xvg>`u1?0VXZQfM5+spF!L98k7DQ6H`1-2mMWv7OkfhK!B}*+C|`4s99p zrSAtcxff%Xm;@wwk#bDR zYGRLz`NkF=nUT%_`Q+2%Y zU8@0uq9E*C50T#WYG8~CtPEB*9QJ_?&i#!!^*T+n{^0fN?~uH& zE{!A1AsrIMXMBUI+BuiWI9rii&i9ZANWfF1EQB%jU4qN9eio53yYZE}DMLJCc;{ab)=yn#03g8v)4C;Q1~0Zia!?Y|1{PZN#xbYM&cZhY?0SUWX7# zI#N0RFfZqY1q%VP$i4W)CmJYw7ijJDWC1mEXzjOAM%4YyU5!smEhT<9pEL}KF>*b# z@(1aTF1iXIHuJo2E|1v|CeHu7C8ZoY(rmhXg~H+0i;58!vCG^vS+3dNWEGtNmf0fY zZANUy=|x?u@_=R|i%D1Ae0eGeJC3-daL1*krXte1N0J*3(jNLYq=~e`GS&f6w}P7~ zRRO&P*FOwIIdW{4Dm?ph2ynbQbjBbCJeWEKx3!OUthn*ItTGq<%f_s?H4s^Nu(JDN z#`8_;;_KeBQseu^Jy^ryK46cytdd?*fp%D^pfYvMB@RE!!Kw+qWS3=RvE;!6DpK+; zHcHj=9;K^Plq;6su8xt`*ZAiyFgI3)vN{KIUlf2zYHr#Xxxf{>$Y?}d_vXfoYt|E9 zxZ#_}%u;z7oywIGrdwj%?hj??dzEUvFr@XiE~qrP} l``#UYG#CGWtyasXc}pGtQ0C8t7GRTV78iwz>FF z6}$3s&~W%P+PXEd!%7!v8Idj0Evder-tTroml0JuHLdbJdD8#-T=99{?6Qk0Nj`FA zGvr>gecq?7ZTCGbrhu;sCCMpL2Z8^C$A%y_mK8t+f^)# zBF5H~+Ap=vD2+~F;5DiJwI&{Cn=V_?`^DIjoe1t6+?Z0$7d5}Pk_2W@%*p|hN!`3CE=b}4CVl>h#b(U#y;y!`B4#3Nf`bWb`Z-KRU- zih1`IVGXEF1ae3%V_~;-TX-IIGb495_gWf;es=16fB|?^DMi^<%`cRXZ+0xp4D4xr z$|tC2qDZ~4p$$;;r>_=dq=u+Ld&DVp`DrqOEMtk-;h+qFPCrhxENcRo9=sAW8xNua zD6P=m!y}{?YeI2!Vbi8^s;`^7VCKti`3OgXU3xwdA3Y1r?zFC;o~t4-cjHDb8N9mR z3n$^mK90wfbUfmj)bb`a!fi=SDTnl1KnvpZg1eii?HdY27MmPwm)k%C=b_o>Uvy!Y zYA50qgQmukcss-&$&FQ7Jsy$nZB%IokAIC~{-m?qCZJYohac2uS6D!uYGx-YB)Ag$ z9OJ!rFkE{ObFgUf2OiOW`5@ZmFfqE{)kle67oh(Iq*;JwkG}wzCtO>8nXkBo&2O*L zazHa);9OVoMay{|(LT_j&}?&XsxBtF$0Ok&I@y)@=yq>FieBW#WP?6D#KQFXtFVXT zm1T6SrwQFN1SIWa5}0g0D7=H|`>?S>d-p;8xvCA&2QhXCTaHBKT(6T8$n5kKe) z&3^K-n{`BuJ)B~PkPE;uObj>p@BQtcsIb^H>Kbkt%>eb9yAvD*?m?(>YOJ^NQ=W)T z>bPxH0ko>Fy^1JNEoe#<$R#bbhrq!pM{69 zIn2cY^Kp;B#01U$&3qg&dSmH%ZE4Y>%sla2xCQhtT zy{k|ef@Jbpq+uk@=?j!Dd^7eBo&JZN1o8 zUpeF7;)zjo%AnH?&{^abMvbz5l-4H7p-!obLK3?vh7+>_)^&@Z4E z?Se8h8w}j>&5yDUxfr!nF&D2erwgy4_gT!j67+GJ`Sd-M&!+$v2XMjnhf3Xwd%7SG zJb}T6ULCTnMeT{adesdb%3h6ADY7j%QCiy*9@@Fl)EMm~j&96e`ffhn9-7GB2jgbY zg*U(F6ML4AXv#c_dkpW=oTy23AwIm(Z(uu2E}OQ&-}nn|EO|W3>fnvXmeW?z4iOdA zt`bF2QF;MN_#K+PeJX?XdG>&AO$>xX1YBx*$*>Ul)tn9*NeXlF0Yc>&?qdY8;*+eN zGJR&8)j=TM&3sa%zWu;H*|&lFV??*5@ZW-ya1O=IYdp`E5)~= z(x`QP1Nf9aREy+fs?8q723~38*sMUV`}8iz773E(kam3iX_(AUMc&jb$53yj;T&qQ z5g}v6g?^cP{Z4^$Y*fhY&dXaTvzjK`xcqRCqU(7{u;iL}K=PdKQ0or>Q1dijb@q9r zL$yXGt9Sk@H^^3)m!=zS%mUg^3mKq5MZ(i!SZbEYCaSZi6iZN_$W5GR2_Z%=bOp^X{>$;8G zxq8Bs+9M!}b_XSt?SLP}eWX2S*8 zca_y~RJ4||m2w=w_^?X(tqGtDOM@-5Lf0(;OitlW#9YgXsnmU=#&}fYJ)XPseN*s4 z<~6Qd$`_sSX{tKSUKvC&p1pXKL7OrO4RH3$TuqRoBfTue-9DX#zq>Egvg-vvW+)~RRaZNkG^w|y;IK!uut4{FcFdNsw!jmHm>+3MaUvm@6UDBrxoXIc|( zc9SNaj8AaQ#$3h07ja@db6FM~OO^b6Oe;2#3w N>wWTQ?U88ue*x`lygUE^ literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-150.png b/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..36fd0413d5d9c4d9f9b27af2e8df41e0d2dc4cff GIT binary patch literal 4348 zcmeHL>sON58V6l8MQL6_D?`)i;+T`89mgxkD6L3K!%^^V3JR8-7yQp~~22%4IDw&yQ6ALm0K-u15ayuau6d-i^wz2B@e z-Y0b6d*KiWMCT+9>kENEdpDo0TY$vA;pB`mJl(##H>KD5w z@3GmZMd;~vVH}z7N}8=-Dm(_+pEw~s41sieVxjvFltT0j@Q|%pmXIH?yCCisaEQ4+ zjK*YWVQ`;6f2QT1v>dGSdU|@QNlRYb(10N)E|Q~qmxFYv;i%qxCDM6^wditpO!;eI z54Ww|efjp`t5dJJZO{0N3y1-#iHS)`$seB}>oyi$e_Ao4WGN9ab=AF*a{l7YS}1=N#rJeqQez@m9t`=DZ5PR%T|x6 zoR7Y&)WfH(zE`2o($zOwnAg&HxjPf=EIi}g#DB05l7-2mDzx=ixLWp%TR^)rwZqpVFYt3>%H|^YL;cF|8Q~D^H8UdM9xrcjO+Aq`^lOI zlq+<#;il$E>{QK-#lEpex18zf^cYI&jwwN~P)i25%d#yi$T6oTk6*Sailry{^sFs( z*3;}QN>4qzu{bbiB_C_)mYH+L+gTICPPfz%o8~;Qh0<*WDZ!cQWe*&QR~nbm0HQ!K zEbo~R%LF#6^@Q%gp zPy}Ni)sKAqJ3T4&mtInkuxi|mvh`wY`t%|dIIKR24RrLt9l7K(Ju$-NUc3ErQpz5> zXPzQTN;`dINnGt^By};8h-jNnFN@ju$3YWiD1_4h_XHYhC@w$UEk3>Q1f*~kvQ#`M=>oG9p9J-n<-Pf}cvLh4Kx5LNspjWx?nKT`F3s2u6O zvZA|it#$&*VJe2wjKl?uy8KQrUI7s|Tk)SYzs$Ssf%Rdb_58QzjKo=ty2c6jv}R3q zLr%t+UT^DiWj>k4$L4Vf=4*u4s&Y~~%bkKBzg%0CWy#(JJosZWMf<52Gx0vjKSPra zl(M;?8;&iD$FB5}gN2o6GI$qUhZDDmOMvCh?&hW@U8NG!vz)0*rsV*$en-S5d$do)zj7i*6uru4Tpx7rx|^tqaPXThq0*{ ziACCs=|b0d05Zj}Bt6zzspq;#zhZ?K#lqCH!6L0^2TR#6Y*`&}bqgm71e*ZR=Rqyh zptj#qwl$r=WO_9f_+fGzLCv;+n)yo=XNDeoL#YiDA-+Ryn_^JPgMD!Iq}8P_Twv<$ z_LII)y5`GLc9A)&o@1p3EADjP((%&_!|+@a(=(pnK;I>O4`jO;MjVtyD(-%P%D zL4sLPY#RfIxqi<8pYIM!S^^*xfmOnG;*nN^0E1xL8!2{+#|&niHksY1ng}_>+8hT) z@?m(x35;3A$aAf=G=Pi>^&Tj#MUXTe1;&HIGJvXpvwv?$wr)U{)*)7Bo17xEth* z`d{_}!6c?+6NCbwLf#KUU$Qdr+Qke+`b|d7c~gDYXzaG?0;?r*E0wzkt?hB)ug_tOX-)kgoUgYNWc9} zJ;WKn^}>EInGyFKU^TK zK2H0j2--NUs%D}cHQRm(!{*I&62}x^(Jtv85zE)BHEchWsj=*eVqog0Mb9e13_`P8 z5tjSD+Nuog`X~;YSM$MmWT}7gmA8#WYk3M$#@>iSP5*1Hl~&A8+YwIK5RMWYM$wv< z=jcsr!SK*@!AJ{oVqc|`2c{$jHJv2wntCA*b=6#9Gso^LEIb{+ypE4Xv9!{NuNSJ0 z?^G&pIQ!K8Hi8DMXt9m;pEenDT~lG|1l29tx=**$P;|rx!vI^CXK1MGHbXMx5Ov2r z2#Q>nj@baVWvK<2HGG%OZ`1<-X_YMq|0Y2YEgEoLGH0nmo((?P`4!wLSlT1ites3<=OPbmE?Z+!~q-`q&BYv zF-yglgH1GKGd45K&$jtOqo(pGfO>nKZDw!0UvV?-SUtFrPqTyR(_wi1)P|IHXU!Ez qx%cO*)aR?zKj|v?)kBb@ecgXfSf$;jjeG%d*i=}fB7Q- literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-200.png b/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..502c729f8e78b9a373fbf3864ff10a6fa360b1d3 GIT binary patch literal 6348 zcmeHM{Xf(D`+uWQ8LBfmsY$vyM|5vuAxX$-DR(o;l9RD572C;{XgZOcR;SO=4Mysa zj1Aj}=B7v`)-uC;ZgQMsSZ_P$$W~N7ul4wT|AX)Mw|?-L$NRe8*Uj^~uIF{JOM!S_ z)WYQpAqYbG`|UXdL55WQkEt1 zOdc{2Cy0rSZ2O11DCZE{vC7nn9ekef&E-`QkC*JZ{=6ZLTJF1Rn)8D7=jScJ4Scqp{ULerlH!YtoeC>&^qws%8 z3Z(tVtNZSVxPdMfrSy8@5TEW}UeoPHi;Y!XcUKv$xqB zEnY$u#GoTwO2^zvPGA@U-NAx66S`+N71!AK=s9G)q1iY<9$k)A^)UY~(uK&hZ-@Pq z)yoRZ(zYz63f5Hjy)71XmcJtIP-shMXCy$V*{Jp~u(k#71>Rv)6IG7e^rEwhllPGD z_J#!Lsh6Oc4bL}za!q7X9&bw@lCCI1Zk53%(8GB)j+63`r?7{J6KhuDThK6(VsO<* z&}`^XXkK=8rksxOwe%Oj(0}O2(zMS&eKbxzc+^Mv+*_FcXfnmSn;u7s`gS2T&s^F&PU4OEVGUy_iwNL5_5uBQhFF)id zXe{$UnfA}&cVh{IfszQRc z?W{cB7o@&agd$a&VhK&1ot@~eaiQcYqGm~72j6!;8Yb*uN{yOM18Ja-G8|2l-rqHo zF<8Cbxou=aFC*Ulh|qv)tjA5pi1$&h`3}ao>`{*Fv1xh_Qux&lK92S)(QE3M691UA0!HcYYoe z&CpvY>bkpW%sn6|F;BPwZcysgvq2x0l3Bwi?>Vi7@t`CJK_-Xi+3;Rj(hw)pBXU+w z@#u~_Y=rLo`fj|qLX*C*=`*kvjo!NngXc8V>KylXocd@p){=XYjl_Yo zM>XNMv&19uTrIniV@ZQP0IU8uC$|-G0j}=MAAFQH@$N+@QtNd)p~D~}$~R}2@5ZcX zpjZjhT$420{etG(AYyN!?iNkhrBus%tH=L(GA_HJRlE1=9)OeOvX4o&`=EEQ0^6Y-DljR)mqwZfh#8UmKRekshQ%qfwRdz zuko7X_=_fCg8VSGwai%H!A3m}5lV`jBYY0+6Rspy=S8W>;5mkk+Dpn5GwdFZOJd_3 z{${shwU)!#Ul24R3Q@jr#RPD-ZYg#1YETF(8vjeb z^f$5*_U-Yp+sF%jCJxQU_CZJAz4$;kz24=`?P4@)^RU398}LZZ6l?LJvGaVC4feFK zcU%)vmnqh|bm84FR2WBWPjeY_KhSY<==NVlMBi>?6R0%lI#8⋘xbhhYWfP5i|{I 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-400.png b/FluentTerminal.App/Assets/AppIcons/LargeTile.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..5cfc27a8d90ef18df15aefc46b635a36d456eb8e GIT binary patch literal 15541 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
jUNjd+W+Db?XAks zhZKm5LuI1-#0#e=fUeax_$3-FwnX5|J3u)cyBcR&bsS?FITih`n2wJ1~PX|t2}*LADT{`6)djbgTLPMospl! zyxed};t4RPtHN$}IJo8yg?{8QwQtJH0sU|qbM>RJ>sAmCZIkv%Zz}kyhwlEuqsAx3 z#132-YKdsv4Q%T*yj`%LC!0)mc*1 zQ&O+CmNSCISc$`YpH8B#VJ9QecGJ^$W5A$otcxpY-S_@GJ&OJDqF9sjO-f&$ zC$s!~e7*vzL46XmMQsoJ`)quLQQb5jozfK@S1E%R(Y85g+nJM`(N2bo>{~ZJ@KZs% zAq75z8b&}CQ;E`Pq0XbRSDh)^{NXdp22rz6B0<3ds7k~2>yAkRd8~f_uzsjWCU9Wc zy^bX8wpjJZ=V^HCv6@;RS&ZAQxI-(~gIbfd(7a*g{NN*t2NC*D4^(lhqu~87bAh%G z)}jGN(116}`4`7G`r=diF7WZCpg&YpZ8H!gm9?Wzj;kKo9X5DVHIgov_K zaOIVC9#=NFR?7HP+`&}=we_PW`%ZvE=K*2#VT2e;tE&xd%RQ}-T!;V z6IWX?1M{j#;2DAoNS$hMrQI{V=Zrl|J4aOoojq46(vWw`vLCrLJZAEDCr2C8Ba1|ww;yYm94CDso;1yb~VQk5jf@E$nu}~@_ zo0gxCD0^8uUN(#?3j}|4-#q>As?Td%{q2XZ$e-+hZaT$TZhnDcq-u8|pSxT*EtknQ zz7LVvVqS)*qL+}C zTnAU&8V*#jYkg(U38_K&3=h~ueH#j^!)#F%!6HsP~X5=l^|tBlnMWh11cb>1Y2? zI)yVo(R$qdCWPCA9CVAOp0)}d6_>=U4u)=5R8*0w#wwJq*o<)y!E5YpR6TIx!f)zV z6^}BbNzr+IvkHYQ-o0*MG0*X+%xU|{gSxk;*qs)uLW@+gB8DnUFj1evOxuyF6$B?Z z^7d1tXd0~t=(;@^U+n8tDae-<=fxD|`8f?{DyD1wB#OWjB#&bCy@nX?U+rGiF*g2s zj+YmAW9r_8`z&qx5d*(a&d>6#oIy-eFz7DAs0)Ts5xZk>siW$& zllhvAqLdsNC2}7pwK%WMN0x``A-Xfh^j=P@S}7B6pyXWYo0;kC30&%U$2adt@uA|V zLjJmk)S|rQj9Y?G59V?CMLQ3(;;8Q=_psgsGw-~IL+Pk+`_I^XfYvYr5Qa2Uw7yaH>J@HrN7Omdze)AU3@rCq_2<)k73A)lvPZoe%J;Sad?r1Ia1qIZr7YV1jJ>573Gzj0JIeU)dccS#%?huHwGTZN#$1!G%##JJbHw_QztoQzg$!e~z|f*>Wh%%IQMV znFX$|XTD6oZw`#f)w z>7Om|`HFE}=$$7nhPyM5sfa(R?5KPObcDF&iLT8WyKT2!(m7)Dy(7DK=bYptcN%7h zUo+fmFje?yOZJ(k%IAEY&v>7%xEHaHQ>L|nU!Ztp4d37EiqAx)``^d7NUq<|qNBt7 z)HvzyDg%FUV935yOylaVJpAo@a)&!WNv8?*sc=%=*?lp1HkW=HKls*#}#$x=bswORSD*o$@;)Z~ljq->r|; zI>tVoC9DxprgiS((O;%7zopr0H2~+fdBvi literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SmallTile.scale-125.png b/FluentTerminal.App/Assets/AppIcons/SmallTile.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..de32d181b85a9795e7d4655509f1e4ab9be8b619 GIT binary patch literal 920 zcmeAS@N?(olHy`uVBq!ia0vp^ks!>$1|&ndJJtg!&H|6fVg?2=RS;(M3{v^Pz`*R~ z>EaktG3V{9-Fa6WMB3h}dMsoNY7k(R^$_Xkif-0W_$~Lvq{PEv+SycQuAl{u9vxOf z{0CfZn4Ds`RHR(I8~T`7cK_LI=`{Pq=A0Xr`+L9tUvlw=-Mx<|pLg2IRci^q^O-vL zfQrIN7L}O|D#8;|m?rr+Oycw~V)RraRdDr_yzRUBuS%T?oO0D|apCFD6`@Ccjac5h zf7Lnv`SG@wYTMqnyl`Eg942~x-k%JI0{J!i4kc!pi)>ZrYuw6MRNN6)U{kjA!;~7< z)U6r}7eA|2-TU}s>Or6p_g;Rjx*QRs*X3MtTTgbY_*<)84JQgVzizb>%75%)5^(>+ znZ-GGj-O1t!8Wl{?B&G;trcPE7pJrfzP`BPlV8g8sP1L99~Zjo&wjD=gr4qh$!!sq z8yDDxIVY&!d6TqgW9>PY^M;>4wb_*?E^_YIt5G=k?X}sf6}>Nl)H)OjPF8&}xOii2 zVej18>`Tuc>Q(r)>g$XDaV0B*=c@f;7rQ-SS9bOtm--`h{9YdVlA$yF_jMO>J`GT* z6LX#PU$m$9`yw0HeqE8C8{r|^Pqs`7o|VFJC%MVr?U7@F@boV8Cs!r~cRgv8`(u7k z|HR6j4%2O%`2RKC&^hH@mKPVG>c8j#126>MnH^lN^znR$>1#C$hlw^_2_fPF^+!*% z_wG&+{=>rL@BXOv;Et15g9;9WerkANJn@Iss+(5ad^t>v7ocU)~mW= z&pgLc$)^rKDi4Jmj-H*b@x5@QB>G9Z~x8DeK1P z-QBJ+?#mCCq(;cQZ}@As$Io-tW3jRd(>GSTIE3E`{AKJu9`G*l?_Y_tr3zMOuANx*2cZm!ZkW)l|g2FHRY)iny4R`=O(EZM^tpG0kax|r>mdK II;Vst0POIX`v3p{ literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SmallTile.scale-150.png b/FluentTerminal.App/Assets/AppIcons/SmallTile.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..a7ba7e0459e636168adc5a975fae0926ba7ec05d GIT binary patch literal 1265 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-100.png b/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..7c928b3750f1d636d24d9dd15b9fcf70de9f1be2 GIT binary patch literal 2802 zcmeHJ{aaJ#89v8groiE&Tqzy#W4HlZt0HrRBBE3S5vyP&LL_{oQA0`yVrMJ^g#c49 z6fAWVFalj@fj|-x!vTTTB*hFWVwM?_EPQBm7ny_zs7WPU343XO-(TPl=Q`&+?|aU3 z-}iIB&-GkAmPA54gFGP!LJ|)Vk3-P9JP3lfZ@_{`Nyvf@+%^^*I{9Y^dOKw8f)kJb zZV`e!zeyy1KrXy#oBpu+bk63HrLKE-BW}P^&TUh|-=8*z233SUS-Ja|y z1=$*lW{K@>YWmX9Ct(=lj&kJo-#yU)H0!3u^3%eKqnLH+{6I#DTwr@aY=h@FsjwLx z2W*aD{qrHM#=6q*u4xv>ZXm?sl{??cQ%3q!quq0s!1qiH0YYr{r(fiFjqvMglGQvO(x?;Ssoz{&~t4i8V{OIB4y(_-gfv zqF3~>0q8So%0t+U80<5`>7I_UmbKSCYH7EA$JXK?IfB+Zl%PaQa>B?PdcZa{B`KO5o${!~4Qs@8v( zpS5M6o{6E9(J-~&D1IR9?Xdl8R19;7 z1TJO+f!53Gs~-09PasV$mMsO|@WvJ#*+BUEYOpCmp-69DHTtoyp*IlP*E;$)kcfiW`55oXt_QD`=6Wm?BW^C=M#FMa8O|7XTlwreDLV*Ddb zJb-={*e3mz=8QGl9t~dG06n&o*=-yYUz60WR1s($AR=~-2DLoYZ!^vO_mQYy%Y>*0 zr7$asNL`&By!QFjT%F0{i$2=V_r^*?fI0keCtbK(tGaP7Tz=TKTcqaCNCwVlhVhQc zq+fk;R0{K7^`wv06;I93{kZIHMs5vdXG3exaQN)Y<+{~{^O=T`nK4`YI-^fHLK)(r znhA3Qj@4f?H8%-#JG+Ci&KL?-y1|OxyeyOHIn&ELv=U#lUU~v#C*WAEEoe2myXGJ3 zjC;Vw>R^3I)TRL*DrbXKSwOAaDm3tJP+SanY^U4q zG*K{2&{>c6^3YHF=(ddNCaBg+h5fuQTt5@>X}27$q+nj}FGt?_mTpUtW7l9bsp;qL zXerPL4^&-5w_TSLWR7Vbx)2%U_1FkZQs*sm(AB0NBUY*+xx*U?kH0!0nvMxzLHOSS z=lt=m>FnJg3yLPCsQ^(Y%ksOH#Ci>+mIaesw9?^6Jqt(0~ zi@%EASbo0eqBM0?=rtYsTrT^IIEv*Oa5KV>#(IAdFNF=AqfUxARo3T7tI)e{itI&VtSRZ_P#1e`#8v!`VHh#Vl7zJ=3cSU6$6iJ#`ktq@TM=r>pqqXo*aGdr9Uu5^YGr{y|e|O4k&(^)6zR(#^d4_x}OT2&aJ3B#-6cqVy{~`YaM=} za=viMZEl4lRjkkzb-EvfCxZ%{;;+hJ{PB-orEkvS7u8niE~d>DoSBP;^q@9x=72Zj f&;J<&Z?D32{T1PYuj(Iy!4XP~Pa;YV(8~V@&bwMV literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-125.png b/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..b7609d728ac3cc8926d59c87973cfb07367a5ca0 GIT binary patch literal 4128 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-150.png b/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5121696126e5f6f8b80962e9b2db396c5f9f18 GIT binary patch literal 4703 zcmeHL`B&3d7JmsP@zE*tg{of*9EgSI+x})HTG`Pb%}r6i!{8rHOtwW#waW zXFl}KIsSbWkU8f`NKu2QVOW|aJg6i+giQq=%)$7O^)&#bGrC6%t8JO-(xG*+x{g1={Z&iL`|2IWllN;jTYmsPzNg$Joq(VjbIiyWa-C{BL2m3@RgpDPz$3*Z>3 z$7`cNTasQXZ=)wEo50;!R{1n6?5AL&(4}fO3fF)Ul2ualZhKO4+?P0ck^DEdgl!$6 zhw=_&U>SjKX;KSrae^czoiOJ`k!?R6iCT_+UW6Xk%sa!n%t+FdlAc2)YN9`~bytO- zuMm5dO1f{7MVH$w(HkXDUwr0^`5<*4kIU#^A&xg)7FwXHMp)mJNIMnZ{(`g+Bx{Jb zH^B1{BVQGGQNF=$bA-UfpsAu=fk~Y^&-sjz&v?4w>`2GCq4nZ3JPyGjVF zQeR|1kc!OKz1Hi!?gcjTrt?iH%Q^kA!MzxC*G-i>KD}`6EB5=RxhJeBl}4VFc1vWq z2BIDCz4HEHW?PMLVuI;u%o{3-4XDXiLmV$Sd06&q?g^Co zt%}>7-`_|x+jcN)S?(i}NdHQ@!x}_TsWxyir~m3OG5Dk`;fP9yI2i76UAjC)3MC=d z=_?Mlg$M(#DjLr#G%y-CCNJoJkizT}&38a#6I0EW+O-P?v}0`BVA)Tn-w*9*2!Rxi z1JSWP`J9ThKecQGDNG=%DswlE)Ph%63-l&;w}~oL?4+=Fum88qF^27Lj+C97j0S*3 zRU52onNl#RJwRvMVSCDQXX4IS;7nJ=@rF1H22FRS^M%Sg9~IqdPR0b*XSRl<6Pg}Q z8-gdgJu7fp|lL@qTkp$19t@>TE{nenNkFTo;;%ntY@tD9a$D7D%eUle&Md{NAC>^L;)LNo& zBN$`=U$kz}(Tjt1EdVbZz1W$!Oc8t%M&7P7eV6l8yc1<>1m zhVzvNPgm@7^4>3hu;I(s&Ba60kAuBx>s=57-Zffm>&u6uYeEP9={k~BTr0HuxO%%M zrg~&}`pVGIPz=tIdG{@J=6AsM!9{iUJ+q~IDyZdSJ@0AV27htbMHcb+=825-$*r2m zK}A1EpSuv}TrL)F8Xg|jsVz`Ljbz~e1)i%&+3$m6MY@XuLi#XB2gJRVHSJ+!SllLIPlo8iCbLnCYQF zpz_4mU1TkOchHhlS+1^NsR*m=blt#A;G)6y5(nYABmQY;c&gB^AoP(f=7QN$bwx}# z@Ib)hf>vQ#s1HugABO&H2d3Kwg|f6vZxjyhZ+YZPCj}GG;nm=vdHqytAjtjXk^@Uqn^G+M_ubEF4RP_*8 zkTIjVNfunlVst&=Rma}^ zx_ndeULQ#uKWt?3MRjDtXQ?yL{D#9qb%ksAaFn?~Dyt$3GNmc6 z7Z!W(%djoGV7k66%VWCRkaqIvAE;u7G3x##%G^SL#IZ4cwrSgC7C$uTTHi>ltV5nM z?kqin@}OERtMQ>0gYx#bM%?qu?jq@+_+)ass8u3cu2w}AsP5Df`)5A5x7?O|j{|h~ z!5<}#rxnpSJU|6 zdoq3D_I*3XTKjKjwULc8sFNJSk8dR7ep|E-KG_?q-m+S?b|y?LaG$8c3bMxzfjkd> zS;nGnD4R_myJlbg^Axy=U1)EdF{xX(K%H*6)a3WX7>CekO;N?N;8W|Zps-31?Xe$D zSZ?;NO;}Jjp0XClx-x05f$l+R^UAS_{-()4|Ei@Nef%LraR#S}456yetE?#H77bdl z{P^i8LG#LotNIh4Takh`|CPn_jEjWvr7n>!SK%R2>#-Y|DD0SMAwFM-OhBnK;7!9J zVNU-Fed$~)o2ImnXRka8cJZ38yefAnxK}u1oa7u0HMrl|If2js+!3QcBoXD;aV zZ1c(=KMH60ea^ccNw1d_PFGexoz;>|>32?a+m}euQ6G!RITEwax9Ox(r-<{mQxNjI;^-@uP2=H2XiHzLjIfofBFgF&|`B z7r%ZtIJ$hWwD43|J6)MEGgLD{72m#6w=4Q=g@nv+5GO6Sj^4n8UkA82lKas4q-4e{ t8@1er3H0fA*QZ~kpG@$7`L{%g5?zg|yWLlpya##!dANI$D@ftz{tJih_t*dc literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-200.png b/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..0a15bf94ccc6e4fad2be07836d924493e24cb168 GIT binary patch literal 7462 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-400.png b/FluentTerminal.App/Assets/AppIcons/SplashScreen.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..f85486735770de73c2cb50af37d61e03af772738 GIT binary patch literal 21076 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 XK55F5m<36|QkB8e)z4*}Q$iB}d60WO literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-125.png b/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..1d671874d667adb75e4fc2195ff93b72fea27077 GIT binary patch literal 1742 zcmds2`BTyf9HoiWFf~_cTO-KK(r9aEz0dD@d_!ha(H6-gF)cIMQnx%4Pzn!PukCPC zcT`eWQ*VkBiDmeyb>KvJkWqNND*B6H=23x^L}{qJ~MCTGxN#D`C#;5CNKyD zqKEbJ^w((H7wTwf<|}MRtwwgodIesGK=zq`;SQ|-5h(&ne+khg zdpMa@p5Ml_$9bB93-YVq>&vPk*M!V-|b z7+N0w)@}H3kmo9GkyrAsN*#auLTrC8d%=0(l|-4Ix$qx5?>cf`Y@a)D5R(BhGrJlC z@yedLK>ylsDJ5ldkN2tQkUCkPR4Pr$K?Mu?)s%0 zjzCkZ!*IW25=hRS6+RjpDBfrhx)Smvz0B=;ma3d0;P$>>8O!6(T^`6%PYxgOuzGik zb3}p#Ii7q8etpz(^L33aUDTq@363}slgS$m&N|F57g^7fg`gKz~G1qbo z;>lOJ6L)8a4uRB1%<01DyhRjupe%nopaTtGQ?`Z%{F6{1AXj{fU{HKDNdOAmnRQ|2 zV{C+HhtVGe%NumrF&dMD1+Eb^b|RFDfNh}Y&Q-GddW^21f3(%WSk=d%U^J#36wszS zSLS!wJX=a>3tMgbY~;po2w0yyyJ|RMn5s{AX5|yEv{j0OVS?PKDJKRchdKQ~(=}s8 z*WzOQyYs9@{3r<~NU&zJ7LOULinE_(!F1Z8bi`1QX0JH=8}anugdqrwZ+*b+;u6Zz zMlbQFLz@Cfp}kD115b$4=MpN?B;8C-Z4^t;R?!TsnfG$tq%OFZiRkw{n4=;pE|RUq zHPE3+(!)6+L!f!#T6E10cPZRbUTe)WeF}o47gHZD7uni!(Dy(o+(KSiG#fkqirFkn zIp>X@I}*9(ct8_}x#cxr;ifJ2G2aALis{@uP)K?k}rYKF8(gNoT{7enTvXsmK=XsKC$D~a(sg3j?_kY5N`j5WL6&oYpP zTZq|~hAMmO1b6<#isw8l?!!^8U{IR|}OLf#Bx z4`VSr*Y7ZTMM9%x52=-fJf5NY^dkwbM8|cMExDA3YL4QitYCBG4-yf#qOf~mW}QBh zsaAGV1_rmcP2Ej-?O-D?EPXJzS2+V$k~ghI8(-p)JasHe;pjKC)1<2%Onlt1yyvpQ z5dn-Qv9B?e`UvsNQ{RX;o$c60;B6P%ahw!!o%0DZ)Rd`fGc_qfPP|8Mb*{|cq>GJ} z8LlzUD^|y>WZ^exc6bpHR~oRAC%U7gWe(t{1#D<3owm!{%| zi;Y!&yw5AYXWA{wT8TC5wajf$;lL6pf=7J6pXT7@Tx}jZkdJyhUui2e{tp Q9?gS-U_l?xdiOBe|M*&zPyhe` literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-150.png b/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..23dcdb7764921f6b112ee7418cd6aa79aa8e02be GIT binary patch literal 2092 zcmd^A|5FkO7Dpw8-7`hDoC;08+HQt*t|H~aWfYK?<*qxPm*1vVoIBkjImPfBwp^)r zYT5cF1g5Rj*%(sn5Fy25+0Yd9v`bAwrBhS{WYrZ-b0aly@E+Fl(J6Sx0tEs|fF$4k{`TlUxFJ=0NqhdvZyyTKs-Jv*Aui!L z5KVn82^*`eytNQ}w|%hchlSr|N&4Rr{IsgHwjrBxbtvmxdU!zr&Glh>XVv-Bi;X6} z3zmP_GtqL*4^Web;QSU6+XQ;}d(I_H>=7vZeue)l5-9V3xUC9$t6Pn1c`R1hdq}II?A`%cd)Gu7mAl?c@Xj0lPmE-*0UJIvid~ z0g?DA+#m(neV*7SViB;~zOi$pczEv#xZ&hRQBEjiFC}p!v@HoOI+eTGh#rRt z-d}$u$AzkSCc#|`Qgs@<*Z^LVoh{d3J24uI&YnIj|EhE6Wp~y$igLP7!05BRAp3zq z(ZG#6nO#KnAzJX=V+d8yd5SVkAL&fU*Z%L8d=uev82E(bv6xFb1X!)k3vyi=0x)$!medG ztZ*HnemdV=qs6H9Q7KB|OqFAMciquI=7n$}gAmmKN;(2}!XZ{7vNvNg5C7{RH^P|7 z&}nD^vz6#JB3kvnvl!Qq9^GyoJzL%|gg?w9b0QjJo6{T$ko~Ne8SAFsLw6GnLo`!k zw-|_`3sM_O92l;^YD!8VMgiV*l~GPV2VM$yYq?jJ7Z_%JARxMhctdnyr=7}cC9PMM zJrTzDm1?)Rv_sXOLBt8h4<=((K`~Ys)4o=h%$)n=mzSdf(zt+(=YkCv-IVyFu%#2hdg@2JJxQ-{7hybRQ#Nv4QZF7`bA2(MlCvM8LwN{LIbJ7s4Sl}<5QP&# zVF#if*Hnq9>@J%2)5)DvZa4-a{)4B!u9grZp|PHBi*9};^)Wr*YSF5F=h?zIN^6Z9 zj-zQWODz0sY!nZagz`wcUrRVHTfQyAM^1%BbOe!Po?!ac%E(5IXyCw#JXMk3lP7N4 z{WJ=AWfbTz+>HdUyahU>-Lxx;@|6%&UpTsN<2P6Z#-q2mzHH(=LjMq0@bd!nDZ~54 zXCA!__i#KyU$(eM3SJ39W(Um7f$3|aO-e)zUeTJxGwfWM{;}5m<>O6g~g(q%PGc zTZPVy#5LCc{W=Ty&BrHm{Ms*&qBB^yXog ztRRjTuN@R;w_eNMJt8|Zma0?J&tQXjmfr16Q?}foG#zHw<-QwpU2G-8af{Z)wQ2yf ziqPbAYxIHRq=gbi*1K_@zfEhE<)w$O`u`tz%YS#!Ux^W1%+a>E@F2JS1E^=?N#fXy GTmJ!fVZIjt literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-200.png b/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..1b0d9a64ba6ae28db5a852d3cf54b5d8786d6431 GIT binary patch literal 2354 zcmeH}`&ZIu9LKRB#YT(A66-_E{S)Bih%<`o}wv)ytsXV?7SfzwxRq)*;Cbu?2 ziskF-dTS5+Yd{yIC<@iO(%awXiWkhN5V zMU!7Yz>59-FQer+p!WLxRB?ZPgK%=b`fu%GLR)dMPz5^BiUYO{`>4-9PYx0Ay>mq1wirksJw)OdrFgWnd*wKl@-4;T`EKBi&AWNdh! zH%9!_DxDfnY_nDK8B)2-14`W8Rx~1njeYNVA|mpSUViY`I|rJ?;4F%4B*1-MS=N|= znu{44g3|G$d0ZJ*oK&aA(f!;Y)S4)3Gnu7bTT3ny*k4X-x*I++NfG* zWf=-MrX<)?NiQ|Xo2N+g{d+M*84Dd%mSW0^Z0kpjAuClWp5UOS?&5{Cbi4VcV#z?Tw zivY#3?k~H_1Ze#-DirmzJDwITSxV7SgQL9!Rq*2GBmBM%fRYZSLBL?>+eFXTYe2FE ziKnVybtNF(#>d#wY?Ol8NW87ecgtob`T^VHavCsAohiM?w-Mn2X+gE``iQNo@cYoT z5;T*0NChjGG!F=Y5rv0>D88;8E2=BOIM5#3JU@%&95G)g)1~-(J00-_YO|!?YG`Py zamQT6{+{_WPdk3mk2@NV`B=iF-_Q$N&40|YbH5nb> zcfEN12tI18#l)+Up97ZqLye=Z4j-MTpM8=fB;-NxVlnH|N~7GGd_&uczsTS=5zUQ1 zkyxVu!TRiQn%}25C9D+-brh&5%)0NFRMC~OE4+)zIoYFjH*0L&jQqNaJ`4@`w3>3z z%CW2h1;{-yIo@p}8HY68i1@xlMCpx^Xv4ikT2eef{!QvEj&rLMg3Y-IR8{2hZu9uxj&D mSRC$X7!dmZSo`mXymguT3qI;}%p08T6NI3U<4G+<2LB&Cwdtb( literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-400.png b/FluentTerminal.App/Assets/AppIcons/Square150x150Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..3d2f2716b6d4a0fc443ccc54694ea6759e99fa16 GIT binary patch literal 5889 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 IpNU!j0S0sdU;qFB literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-16.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-16.png new file mode 100644 index 0000000000000000000000000000000000000000..1e25e8cae4e56ac8f3fdb27fb4746e1e503e49ab GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9E$svykh8Km+7DEQXX z#WAE}PIBS`feisU2lm(hf5wo>tne)*DXGf0kNb>-q-5#;|Nr+(XUx!E+19{Qz?OB7 z)8vSN$NNU9PhAkNb)aGcR|%!avU`KPI+4y6bZ3VN^V9l<7=}%OQYUUQrZh9X6Q9&n>Trs&pLt#*&kW9x z3=R_&nU4C!nh8xwF%5!K_+}NJWO`cjF@ufyl(FzqU{G9jD(`M$^H>M;ID@CFpUXO@ GgeCwU{%rLC literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-24.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-24.png new file mode 100644 index 0000000000000000000000000000000000000000..1b9aa88f3786779f2d9328af5192d288adc76430 GIT binary patch literal 456 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 It$dUI3(PAmmjD0& literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-32.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.altform-unplated_targetsize-32.png new file mode 100644 index 0000000000000000000000000000000000000000..6771f2d4e2e00111ac0b2caa29c28b9228567915 GIT binary patch literal 494 zcmVpQ6{0`kZ}2ER&UxgzI^pP2Djrz)q{| zSfG{ATv44w(WrpD=p?uR_J+`V9Pmg1cDW5`Ed+mM zY=*oyDxiVCFqS6I;)1so(7`FP^Yb|2KLj-JXMuCmUBnIlCZK^oDfp!c_?JKgd>Z(b zu9?0GN=i51Aw1UpkOz{@Ht@QFUq`?fC|l%suL7)bEGMuUff$^>*m}v$3v9kWsr~&SZsk$ z!f_3Omqy}OAU0J*;B;CA;A2K&qL(FN;Fj6Wq*YQkioh!)@w2;Vy2uF30k{LelW7e& ze@rB}S0+j*$^)0C%p!5rNR0QIMDiE~5WeQ5k(f+t$oUcKSCFXplEnHK z8Gx0Rk;sxbLj7w>o&E3K!_3ZxZ(^myu#u?sf<)V^gi_)#^{Y&$8q;a5c+Bjiz6&WO z4vB;riEqVXW+(GyPAPHFNQ{M&u)d8dB@VE8Lz~eM5*=TsH4581_OoY3YgFrj z7KtSer#K!+X|s>|1$NJRX0%4Vpb-hK@Xg9!z%~Js-Cn42L@faPE;g%(3|g99bw|n< zm4Ltl{*K+9S#6j;SD61xzQDBUD4>L&2mY22WSIpa#H_?#OeFl1?P4)}-v(YI|hy+!7c2+UKSY_0@;8u;aIfVdtxyazk_c!Li>J`g*~3k96-$nVzqd>#aX*3A8JC60@v4 s;iIok*&6?1Ds%b*q0<)#oze^Z0Tp_5*0uQYK>z>%07*qoM6N<$f|V_0(EtDd literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-100.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..52e04e08d1046652daad4358b95b5485e6a5b390 GIT binary patch literal 594 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 bKM@=OyFi5Pd=(S800000NkvXXu0mjf&+45_ literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-256.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-256.png new file mode 100644 index 0000000000000000000000000000000000000000..2fef7e892c7842a087098fa73e254c6954f800af GIT binary patch literal 3527 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-32.png b/FluentTerminal.App/Assets/AppIcons/Square44x44Logo.targetsize-32.png new file mode 100644 index 0000000000000000000000000000000000000000..81abab6b33a2dabeec2388ed5737309dd13d8d74 GIT binary patch literal 478 zcmV<40U`d0P)n5Gv|uk-#Egsb{DzXcl$u=^U| z`OiK(Kj2j6auEQ&5Bv)z?+D-vX~7c(fFH?=C1O!PvjRp6EAJWi;CP-lL-e9VN;GgquNktjgv4z-u$g%q=34`Y1>;JCG8 z1%}ww91 zogkV*@vliR#KJ^D17akQG%8B)2NZ)AVwo!1*w~0*VWS{K@XqIhU09Z#*_ribhlF|I z%Y5_A?#=Vw?C#B`ZOsZ-n{R;sRWRUN!GLcC1HKgu_}1z+&}cNy(+m>}wOZ{YQ4N)a zlm>vm2=G|kJ<)77+liyp{#L|hB;5*(${(N`Ku1JB`E%kh`Eo^kh0+-qCoTzmQXt=l zftRe#!6=G;yT>b*(g1*$0hMq6O1e(J2NSP}1LQy5BkHBSi7{~%56gg#r0eu|V&Dz2 zpZtegM7;_hqnH@Q#2-M%({=jWF|a`Nk$-oGsF%_2048q4D>0d_)9=Q>TgLWs%vU#v zdKv$a0eCB3iM#1K{cV_dNA!|^X+5G|R=>oUn2J|oTKe*cm6rY%F~L|b$9#4Hs*?3q z0>B5d5~MSL*ONMVM{J^xW0qPIK$*jm-Lqx5DD$Q?9M z&d|s5IQA-KfXif>Z}?QUj;UwVhpOE4SsMU;Rv;x$_DOLrm(w88Y&E1##s&ba5f1?z zNNOqgIqr+&E&z*UWB|ZA@dV&QIb-*MKizsXGZh-(l354jyzE4?W7O{ef5r`(nTp=X zHqgk8*^?au{wDCl&d3ai*B%N>DK1Tfu;D1p~en4ERS{1%00000NkvXX Hu0mjflACcF literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-100.png b/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..b2de5ead4ea43e611df5367744daacedfa4f973b GIT binary patch literal 962 zcmV;z13mnSP)AVeiV{(@&<2818Kl@$1}Qd`9!N5oJWjKTcom66dWf%uvt_O{ z2oPs5zEzFQO{G$g7;C7kto%|yZ$^q@cpw8JE&g7X0rR;~=1e44WV_P@FtxxuChF;b z3fY&j1Z0S4bD9KTNe0ZvaIKk1K(=7?Hbz%FB{062`6t|F_1tD3LiXodQOqSUxlX~< zIVCY(BUeVjybs%?AEj3<%>BS<3vtH|GAO-wgBZNT{ajHUT?I5xdCu0+A;FHE*!_6GeXr;Qk&Con`K z{g?J_ddsoa;!OX>WIJ&kqs>k^jL%{IA<&KFzp!i5TiT)#qkk~kK@8Gw)#S`pFipTb zw`bE^uGKF_M=-jcxJJKSlQWCvfr5Ev#ib8Lcdd!Hj@~VRS%e_!CLeu zU+*ITBmwCnF4OPQx=YR=O@9!^OyvuNE3rz|Vb!`EwHS1(TQGEaf?#lss=ubW zp^1$u2qPf#|hk%}kCUQrW5s zc#>{I=FbAL&7L(gjROH$>^9js+f)&Y=-OJBu^dUrrz-i<*usF6 z>2537F(CGs9D!|W)I+p3Z@cct8HVAom_O|SaTJJsIUHcKZ3vO9tQ>2v0F1hrIReD~ z9FL)0Ff3>!3Q?~rL9(71j2!}^FOQvvS+7I{M81Z!st4c{HPH{m!8~{VJzsYQN~V7s z0>ckR%Jgpjj015g-#xR>bMjS^?(zz|S0_RAjs3_mAE${2wRb?i(Kxj{00009a7bBm000&x z000&x0ZCFM@Bjb=T}ebiRCt{2np7<`FsP2`uOKh4ZQ0sN-~1(-tt?(0cQj|BWZBE`%^0mP4CumE?pWTru0 zz;ZdVjkH6;c$0}b3NV)f+|iMoY6J`upOm#Xpa6H`S-9M(r+d0eKrJ zfH(z4m<^=A55B8J2HQ<)(^R8Q*Y*_Po#8iNq}gEldy4|#&tP1Gx-``&vrnj^}eFSJ` zpa5gSczfczgg=u4T(vh%H41w_56CA&0mhnn=}*9SkyylbjeTjVk<`Ns3h>!bfRHyq zLDBEUSA{>Dan<&usYcRIasc@PRImW!&AjyYz*j*mX1g-_G}S1g$5?=T4SWN{gO7<} zydIhg{5ce^JgO`eDdJ~%fP4cemCbr$QaC?FIFG-TaaC3lR4GdjFai0_(N85V0GBE; z#36Er?)`=0H~48u<(HgB1vriAMk*$18T2~7w|H?@2sw+N|xXO&j;q9 zj2G~0G|TZ@SxTuQh6j8DAp2#!fM3SDkZ6rOHT8-J9`FJ{_Q`m~r7m7^rT52LYU(8o z56niIJ(AvPptFcJ%b97A6g)?KGfk0<7w}4;vk6~RnQ2g1c)+&+vRh^{z{~OGbjKgJ zP%?!Fd>bIUWF``S&bWwKVozFn)FnLNg@EsrnFR2&faltmmL7$K2WC6X4w(t?mIA)a z#+nmKGx3M_-ge`z<$xG^6Ae60-&r`s@x9hxehwEm(1$!0D*hXBvFY0>U-z27R% z`SnCuR}R1r0A66@qTS`1-{%GF9Oq#oNB?xEUY~Ct{Zgkz1WK@ZKC4OyzMN1(0mOax zDe+GSu@CSf_HR|N=tCk)!Mu^`rSav2GZf$n&{O#MoX^dQ7Cp=w;_Z*LxY&FP#A)Y$ z!?fee2`w}&DpzKW-!$FglGuIm*r{^iohldJsdC|+Di_|V`U`R7=cSwZ7y1AI002ov JPDHLkV1gNuFo6I7 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-150.png b/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..5d518c11814991547fe8a7c1210c6d774a091997 GIT binary patch literal 1446 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 y1#6XmIW82WCe*|_Q?Ee9LZ-_Vm literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-400.png b/FluentTerminal.App/Assets/AppIcons/StoreLogo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..9685d99a3a757479d27dd26472769ec289270d0f GIT binary patch literal 3162 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-100.png b/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b3f7c061906aa63f0d279b297114e3b845beea GIT binary patch literal 1542 zcmds1`%}^h5Xb8>A7htVr-@xx_?#gVP0Ht0;`y%B97Dxq&@7Ndzh{UKyt!!ddy0=N z6+tcE*Cd*0;-R95=w()p6$na~bTEZjN}y%hef=};e%Sr&>}Th*yE8iro;ek4VP^({qomF>J5W$R!t!6t%jvB)ZuAUOsWH);!v*!n|U&4`mw{<{ISU z3Od9^BRW0RYaKHIZNTHC^+o@*CqABE0~&JUHH-Ql1Ar=!KaeO$hZDXz^SFB~2{t_9 zlz!Y>XnYg#-vu#JsZ{!Q&sHtRikSogL4aJjk(?qF_h7WFmhkG!?>A_lMIzCX-$S3w zby}2-F~SP%}|E_ zoBTZWmvS;MljP=-FW1}Q&p{)J-jy*(IB^0fy-NpH)@D7qRrDE%vlWVwrjiEFg@=Ep zKEZCO%|lr?p_p#P6m(fC6f4wc2zyb=-o?%g77$-rSkA-M@d{q*?e6Ty6K*p|5bLUZv6zw0 z0*Ix8SBbHaa{=01=7&O|m}A8)FqL@i?Mx|*ndHQD&)(v7K!bvgeFJZv-~121t?LZ@jrvVE4nS4rh5F)+AA&T$LuA{|XiI#H|X|I+v z6zo>xo^LgcB~h#_BXv;~w{(dM$FcJB zH172WLpy9%Xvh3a;4$^J2x6I&9d+L@t?$q;&+VpyO7GprHgp|GkB}ezTZ#Z>^E+}B zFU@zECudxLI(8sJT5~hb@8~KWNqaf&yCMw)W&S#Eyx%=~U8oLFzP6SF>?rH_q$|c~$F5Rj>Z~Ev=#UK( zD~-z#r14^{Dj7^{uHd`eXLQ67^|}{(NDyvj9whxWi(%ms{67HoPx&n+HN%^R{m^5F Ng$A9%a8D-x_Aggp;Qjyr literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-125.png b/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-125.png new file mode 100644 index 0000000000000000000000000000000000000000..70c3d3145d1eb84fc43bbed9325dad6cac26b444 GIT binary patch literal 1923 zcmds&=~L1P7{`CQgedA-FnFv5UTC}Kfs;v=MCmGu7}Zv0DQ4=rS{_s$D6W{f*L4OwAU7sq!l&Lew0vwRX}Rs@)`@a(sONE+mzy47U|XJA z?RLD-S%NZScr>Vur}kW><_vXQw;>LUZBOJ1hOR4rL?mB(suT?Sdx`Ya{@&~_^#TB8 zxp4smRDg2Xta$;)fBef;H}frL)KXotc@zAwS+!nWG@YZnauX zrLLwVCr=lZ6nk{bzMwa7!{KYE>naK@Tp`3?5xNhFb7Ft*X3Z;^b`DBnN|2U+(0Nm! zg3Z{qPMfPN87DIoPRA`hQxOfkuCOmT7;-a;-0Vuu%4^WH9j;*b6rsFaGT-|(4gVSV zHj*hBuqH3hglHK)43w8`Fz&-Bxq%{?~pB20}YQb-43E z0VTQ!s;=85j??;=0v*_y6IrjL<6uQvSdlP8Wwv|5#sSUBJzUjW8w`-jrm>WMTKGh{} zw8SNZ!ac&^>W#_eyd(pnd$*qBKF?0z>tpYGMq`#lr7Hv}k^on4GAs~41%#e=YkLu2 zdoo6=g7lhi8c#Yh;Y>;Ge0FB})?hiD(KZoZpYI3NU9!h@F1`?Gw64$qWl4w<3>AoPu9=lYuHhDDW$%)TrNy;Ai9azz9sn4EjPdufnsV%0m zXe|(-yTdN)t4>Y)T%X%N=RFCgx#%%d+2mK?HID~43w z5Mx1=jc9vgEKH=WDpM#F8-2wqqhAx(X`Kyv$J5B9j>*gq9zXeukW>=e(*K|P`3YVT zj5c?R)cTr1-jo8{BSnKd5;EDYV12Z{m(prbAeeh}O%25=8{*@NPx7gDzCzmXI-kO9 z!%gvWOaI2$3ZZ~qc1+aX|1y>;T7L^HaE0_rHPI$mi`q9^bTpydV@1x>zl7{BEJHzh zCA@2ANFBG%MjY`y%Xj(|WxcY==$8#3bgEpsy|LE1_VvtW@8)b8ZRMmB5$aox@=9X1 z|7O}A>R*Wl%Zl&05AAf7A7HedZ~+fHgOx|(Q;usEW1%Hy226cxP+o*cRWWx#%zr26 zI)i6pW=knrQ{#$?S@W@q!SFk!;pV4^<^c~TH@Dm3t*TkiRC!TRQ8Cd5NZOv`nzw_^ z!}~M7?ka~yv`)bC?#Ysp)43++anl<5ODBc(k~4%TeJ2aNBUOEUrgCab=gvH*`5@^H zTs{(09Lpa1vT4Fz<&39bn*5^K>vAg7IT7XoIaeMFRdsQ^w9oE%ilf21k?*%%#MRp5 zuAWY14ck6y_2YMYw%n^hT6^0v+E}?58GF-om-{;o$vog8a+@8!B%6oip1E?%%f#&) zTCQvs2&g2)wC9fbCwCQ`PAzAIOMAcg=->z}3ADfZ2bQ>$7>dwM!-|Rphx6xH#keXN z_sxeW-A?jylv>-HM_0(EJxy}+myvi%M$@v=VEUigo;`E5xw%R^^&Ewfwx|(T&cCHD ztt=i|kl7=5)X_Th>p|$v&?OyKA?~M52n%T$IWM=*8c`h~01E}|WdOTOjRBYMe0Y^_ Yl%6K{{~M8!V)&{6A&3-se>a8kKWbqYfdBvi literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-150.png b/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-150.png new file mode 100644 index 0000000000000000000000000000000000000000..11f708126c416feff04c59730a5be634c692aab6 GIT binary patch literal 2353 zcmeHJYgE$N76%`9Bzq{hMyD7NA3&ofH}ASGO+^VuOozlCHe-rrL(^E=l|lzo8Pmka zI5s)~YNALnYeiB++L8j)oY5HwF|XyQ$g)yV3AAwV0eJs@yx-^JeAwrlwSVXA$JyuX zy{nQ*@w;~H-2noDb|nxADIgGd1X$0w`~w)->hH^d337?}ISmB*FkqX&2`T=|Adt)J z1VZfb!j`w%V%C>eJ|6r}K@%Zi!we_3yr_<@PUv z(?s{if+RuCVM#0Prysnit}fH>iR-tkFx9O?hCcsu8}JC_PNl&Zu9GQ>h6k3MD{1HE zuFjXti^D8xl}tGZ0tF~*GC-hz2f8~megCGv@D3_=iA16&C}DayNxhY^jqeR44G7oIJ?~a_3rtGD9*T*_8N?<_= z=23#py(Z_RMixFK>j^f?nxP&>6xts2*p21pC*|hp7n|TwKfWf>1Ci)PVPlQMZyP>P zM~1%CaeLmwoW_fTh@k_aoAs>+&!S!i&u<*cHw?W!w2fA>`eUKbDPq?J z*GknJ>FpLdx91VnzVEwKClsEL9i`cxV(2th=!bMh8>6SkCXz>VyML0YqY89oBB z7l0_nalSS@fULvFUdUK0ZL6e1n=>cRADCJ#CR!d&?&gHKSKNU1E8dLgU%>bH*9o^3 z@l1fg3){!s$rz&BRufC!UesZnDj8$-44aYKF~F^8f=4xUU=TJU*{GK@2Bw6YLOKor z+M?VmI_iDw!LbG)lDWL-GscEuqWJ3`gytrzpM1oHM=7U=n zsuKJe3!_TLubnMhlT5*3Bd~lp`!FG^!JW)$cQXGFxkJWyGaglC;xz?1{VRZv^@Hed zL-ao>y3^CsZ3)x^7rJ2EhVArkV+UMEAVM3Mc8pLGI)DE3xPahMmvW{sj+9yl-;8~= zK4%m&_KBQSRe&Euei~zGWC*ZdAI&MuRj!CX%>mPV`N@q;W0DIlf_kTPUl%Rk`gkm( z*UG|p__w8^%Ml-ij>>+`B~6A}j(2o1!-1ge2g^`M>oSLH|FKs6Y=w8S2>c$+$KoBN zfk>-{!*wznRW0n-3jn_c$;T!;FfQT?SGM_TRSPfsHX!~L3$wGHX(YMm!txD&stiLT zXVIA}fbBkDZG)TqoGQut+v)Cy56#^t4}nL0_?NsO`c;TNE}II~q`@?g9!)?vyWJ}e z6Jzp-F}f%!3M>l%7subd#XRp$9*=QgydL+wel$kW#FR_MNWEqj1}-SNW^lTEd?!p3 zf^IW4&FmijZNWMGrbM|YlINW$ksHMwt*Qfi)+wo{w*MSPI{Ga9fLD0IVTXuC%bm&w zraVBn1id@2UM%vy=UAH6!dtyzc;tsOb+~3gP_cw|cFg6F*@C_y?h>@oqW-$lY4Mxz z;;14x?yf03@sFkdT2*0la|<=o&Ua!6Sk>U>j!6}) z{-!?hCymUEW@a5@U4iVrP?ky^8a9rx+t5H}p@q}E7x;uXO~6C>&{ae)?UO(vqzt*kdwUBw9)zX<-Ja|y z1=$*lW{K@>YWmX9Ct(=lj&kJo-#yU)H0!3u^3%eKqnLH+{6I#DTwr@aY=h@FsjwLx z2W*aD{qrHM#=6q*u4xv>ZXm?sl{??cQ%3q!quq0s!1qiH0YYr{r(fiFjqvMglGQvO(x?;Ssoz{&~t4i8V{OIB4y(_-gfv zqF3~>0q8So%0t+U80<5`>7I_UmbKSCYH7EA$JXK?IfB+Zl%PaQa>B?PdcZa{B`KO5o${!~4Qs@8v( zpS5M6o{6E9(J-~&D1IR9?Xdl8R19;7 z1TJO+f!53Gs~-09PasV$mMsO|@WvJ#*+BUEYOpCmp-69DHTtoyp*IlP*E;$)kcfiW`55oXt_QD`=6Wm?BW^C=M#FMa8O|7XTlwreDLV*Ddb zJb-={*e3mz=8QGl9t~dG06n&o*=-yYUz60WR1s($AR=~-2DLoYZ!^vO_mQYy%Y>*0 zr7$asNL`&By!QFjT%F0{i$2=V_r^*?fI0keCtbK(tGaP7Tz=TKTcqaCNCwVlhVhQc zq+fk;R0{K7^`wv06;I93{kZIHMs5vdXG3exaQN)Y<+{~{^O=T`nK4`YI-^fHLK)(r znhA3Qj@4f?H8%-#JG+Ci&KL?-y1|OxyeyOHIn&ELv=U#lUU~v#C*WAEEoe2myXGJ3 zjC;Vw>R^3I)TRL*DrbXKSwOAaDm3tJP+SanY^U4q zG*K{2&{>c6^3YHF=(ddNCaBg+h5fuQTt5@>X}27$q+nj}FGt?_mTpUtW7l9bsp;qL zXerPL4^&-5w_TSLWR7Vbx)2%U_1FkZQs*sm(AB0NBUY*+xx*U?kH0!0nvMxzLHOSS z=lt=m>FnJg3yLPCsQ^(Y%ksOH#Ci>+mIaesw9?^6Jqt(0~ zi@%EASbo0eqBM0?=rtYsTrT^IIEv*Oa5KV>#(IAdFNF=AqfUxARo3T7tI)e{itI&VtSRZ_P#1e`#8v!`VHh#Vl7zJ=3cSU6$6iJ#`ktq@TM=r>pqqXo*aGdr9Uu5^YGr{y|e|O4k&(^)6zR(#^d4_x}OT2&aJ3B#-6cqVy{~`YaM=} za=viMZEl4lRjkkzb-EvfCxZ%{;;+hJ{PB-orEkvS7u8niE~d>DoSBP;^q@9x=72Zj f&;J<&Z?D32{T1PYuj(Iy!4XP~Pa;YV(8~V@&bwMV literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-400.png b/FluentTerminal.App/Assets/AppIcons/Wide310x150Logo.scale-400.png new file mode 100644 index 0000000000000000000000000000000000000000..0a15bf94ccc6e4fad2be07836d924493e24cb168 GIT binary patch literal 7462 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/LockScreenLogo.scale-200.png b/FluentTerminal.App/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..735f57adb5dfc01886d137b4e493d7e97cf13af3 GIT binary patch literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/SplashScreen.scale-200.png b/FluentTerminal.App/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..023e7f1feda78d5100569825acedfd213a0d84e9 GIT binary patch literal 7700 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/Square150x150Logo.scale-200.png b/FluentTerminal.App/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..af49fec1a5484db1d52a7f9b5ec90a27c7030186 GIT binary patch literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/Square44x44Logo.scale-200.png b/FluentTerminal.App/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..ce342a2ec8a61291ba76c54604aea7e9d20af11b GIT binary patch literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/FluentTerminal.App/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c02ce97e0a802b85f6021e822c89f8bf57d5cd GIT binary patch literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/StoreLogo.png b/FluentTerminal.App/Assets/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 diff --git a/FluentTerminal.App/Assets/Wide310x150Logo.scale-200.png b/FluentTerminal.App/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000000000000000000000000000000000..288995b397fdbef1fb7e85afd71445d5de1952c5 GIT binary patch literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA + + + + Debug + x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8} + AppContainerExe + Properties + FluentTerminal.App + FluentTerminal.App + en-US + UAP + 10.0.16299.0 + 10.0.16299.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + FluentTerminal.App_StoreKey.pfx + 8FA8EF727E767FAE5409DDD1694C1CEE054A2962 + True + Always + x86|x64 + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + MainPage.xaml + + + + SettingsPage.xaml + + + TerminalPage.xaml + + + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + PreserveNewest + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + 6.0.6 + + + + + Windows Desktop Extensions for the UWP + + + + 14.0 + + + + mkdir "$(SolutionDir)\FluentTerminal.App\bin\$(PlatformName)\$(ConfigurationName)\AppX\Win32" 2> NULL +xcopy /y /s "$(SolutionDir)FluentTerminal.SystemTray\bin\$(PlatformName)\$(ConfigurationName)" "$(SolutionDir)\FluentTerminal.App\bin\$(PlatformName)\$(ConfigurationName)\AppX\Win32" + + + + \ No newline at end of file diff --git a/FluentTerminal.App/Package.appxmanifest b/FluentTerminal.App/Package.appxmanifest new file mode 100644 index 0000000..d49b8a5 --- /dev/null +++ b/FluentTerminal.App/Package.appxmanifest @@ -0,0 +1,41 @@ + + + + + + Fluent Terminal + FS Apps + Assets\AppIcons\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FluentTerminal.App/Properties/AssemblyInfo.cs b/FluentTerminal.App/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..259c9b0 --- /dev/null +++ b/FluentTerminal.App/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FluentTerminal.App")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FluentTerminal.App")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/FluentTerminal.App/Properties/Default.rd.xml b/FluentTerminal.App/Properties/Default.rd.xml new file mode 100644 index 0000000..cde328f --- /dev/null +++ b/FluentTerminal.App/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/FluentTerminal.App/Styles/Custom.xaml b/FluentTerminal.App/Styles/Custom.xaml new file mode 100644 index 0000000..44f41fb --- /dev/null +++ b/FluentTerminal.App/Styles/Custom.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + diff --git a/FluentTerminal.App/Views/MainPage.xaml b/FluentTerminal.App/Views/MainPage.xaml new file mode 100644 index 0000000..776f3b6 --- /dev/null +++ b/FluentTerminal.App/Views/MainPage.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FluentTerminal.App/Views/MainPage.xaml.cs b/FluentTerminal.App/Views/MainPage.xaml.cs new file mode 100644 index 0000000..51e4651 --- /dev/null +++ b/FluentTerminal.App/Views/MainPage.xaml.cs @@ -0,0 +1,97 @@ +using System.ComponentModel; +using Windows.ApplicationModel.Core; +using Windows.UI; +using Windows.UI.Core; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace FluentTerminal.App.Views +{ + public sealed partial class MainPage : Page, INotifyPropertyChanged + { + private readonly CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar; + + public event PropertyChangedEventHandler PropertyChanged; + + public double CoreTitleBarHeight => coreTitleBar.Height; + + public Thickness CoreTitleBarPadding + { + get + { + if (FlowDirection == FlowDirection.LeftToRight) + { + return new Thickness { Left = coreTitleBar.SystemOverlayLeftInset, Right = coreTitleBar.SystemOverlayRightInset }; + } + else + { + return new Thickness { Left = coreTitleBar.SystemOverlayRightInset, Right = coreTitleBar.SystemOverlayLeftInset }; + } + } + } + + public MainPage() + { + InitializeComponent(); + Root.DataContext = this; + SetTitleBarColors(); + Window.Current.SetTitleBar(TitleBar); + Loaded += OnLoaded; + Unloaded += OnUnloaded; + Window.Current.Activated += OnWindowActivated; + } + + private async void OnWindowActivated(object sender, WindowActivatedEventArgs e) + { + if (e.WindowActivationState != CoreWindowActivationState.Deactivated && RootFrame.Content is TerminalPage terminal) + { + await terminal.FocusWebView(); + } + } + + private void OnUnloaded(object sender, RoutedEventArgs e) + { + coreTitleBar.LayoutMetricsChanged -= OnLayoutMetricsChanged; + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + coreTitleBar.LayoutMetricsChanged += OnLayoutMetricsChanged; + UpdateLayoutMetrics(); + RootFrame.Navigate(typeof(TerminalPage)); + } + + private void OnLayoutMetricsChanged(CoreApplicationViewTitleBar sender, object e) + { + UpdateLayoutMetrics(); + } + + private void SetTitleBarColors() + { + var titleBar = ApplicationView.GetForCurrentView().TitleBar; + titleBar.ButtonBackgroundColor = Colors.Transparent; + titleBar.ButtonInactiveBackgroundColor = Colors.Transparent; + titleBar.ButtonForegroundColor = Colors.White; + titleBar.ButtonInactiveForegroundColor = Colors.White; + titleBar.ButtonPressedForegroundColor = Colors.White; + titleBar.ButtonHoverForegroundColor = Colors.White; + titleBar.ButtonHoverBackgroundColor = Color.FromArgb(24, 255, 255, 255); + titleBar.ButtonPressedBackgroundColor = Color.FromArgb(48, 255, 255, 255); + } + + private void UpdateLayoutMetrics() + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(nameof(CoreTitleBarHeight))); + PropertyChanged(this, new PropertyChangedEventArgs(nameof(CoreTitleBarPadding))); + } + } + + private async void OnSettingsButtonClick(object sender, RoutedEventArgs e) + { + await App.Instance.ShowSettings(); + } + } +} diff --git a/FluentTerminal.App/Views/SettingsPage.xaml b/FluentTerminal.App/Views/SettingsPage.xaml new file mode 100644 index 0000000..69ec4c4 --- /dev/null +++ b/FluentTerminal.App/Views/SettingsPage.xaml @@ -0,0 +1,13 @@ + + + + + + diff --git a/FluentTerminal.App/Views/SettingsPage.xaml.cs b/FluentTerminal.App/Views/SettingsPage.xaml.cs new file mode 100644 index 0000000..758e541 --- /dev/null +++ b/FluentTerminal.App/Views/SettingsPage.xaml.cs @@ -0,0 +1,12 @@ +using Windows.UI.Xaml.Controls; + +namespace FluentTerminal.App.Views +{ + public sealed partial class SettingsPage : Page + { + public SettingsPage() + { + this.InitializeComponent(); + } + } +} diff --git a/FluentTerminal.App/Views/TerminalPage.xaml b/FluentTerminal.App/Views/TerminalPage.xaml new file mode 100644 index 0000000..661876d --- /dev/null +++ b/FluentTerminal.App/Views/TerminalPage.xaml @@ -0,0 +1,9 @@ + + + diff --git a/FluentTerminal.App/Views/TerminalPage.xaml.cs b/FluentTerminal.App/Views/TerminalPage.xaml.cs new file mode 100644 index 0000000..7743cec --- /dev/null +++ b/FluentTerminal.App/Views/TerminalPage.xaml.cs @@ -0,0 +1,65 @@ +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Windows.UI; +using Windows.UI.Core.Preview; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace FluentTerminal.App.Views +{ + public sealed partial class TerminalPage : Page + { + private WebView _webView; + + public TerminalPage() + { + InitializeComponent(); + Loaded += OnLoaded; + SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequested; + } + + public async Task FocusWebView() + { + if (_webView != null) + { + _webView.Focus(FocusState.Programmatic); + await ExecuteScriptAsync("document.focus();"); + } + } + + private void OnCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e) + { + _webView.Navigate(new Uri("about:blank")); + _webView = null; + } + + public Task ExecuteScriptAsync(string script) + { + try + { + return _webView.InvokeScriptAsync("eval", new[] + { + "try {" + script + "} catch(error) {}" + }).AsTask(); + } + catch (Exception e) + { + Debug.WriteLine($"Exception while running:\n \"{script}\"\n\n {e}"); + } + return Task.FromResult(string.Empty); + } + + private async void OnLoaded(object sender, RoutedEventArgs e) + { + _webView = new WebView(WebViewExecutionMode.SeparateThread) + { + DefaultBackgroundColor = Colors.Transparent + }; + WebViewContainer.Children.Add(_webView); + + _webView.Navigate(new Uri("http://localhost:9000/Client/index.html")); + _webView.Focus(FocusState.Programmatic); + } + } +} diff --git a/FluentTerminal.Client/.gitignore b/FluentTerminal.Client/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/FluentTerminal.Client/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/FluentTerminal.Client/dist/bundle.js b/FluentTerminal.Client/dist/bundle.js new file mode 100644 index 0000000..04f280a --- /dev/null +++ b/FluentTerminal.Client/dist/bundle.js @@ -0,0 +1,6618 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__ = __webpack_require__(1); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__xterm_js_build_addons_attach_attach__ = __webpack_require__(2); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__xterm_js_build_addons_attach_attach___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__xterm_js_build_addons_attach_attach__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__xterm_js_build_addons_fit_fit__ = __webpack_require__(3); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__xterm_js_build_addons_fit_fit___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2__xterm_js_build_addons_fit_fit__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__xterm_js_build_addons_winptyCompat_winptyCompat__ = __webpack_require__(4); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__xterm_js_build_addons_winptyCompat_winptyCompat___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3__xterm_js_build_addons_winptyCompat_winptyCompat__); + + + + + +__WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__["applyAddon"](__WEBPACK_IMPORTED_MODULE_1__xterm_js_build_addons_attach_attach__); +__WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__["applyAddon"](__WEBPACK_IMPORTED_MODULE_2__xterm_js_build_addons_fit_fit__); +__WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__["applyAddon"](__WEBPACK_IMPORTED_MODULE_3__xterm_js_build_addons_winptyCompat_winptyCompat__); + +var term, protocol, socketURL, socket; +var terminalContainer = document.getElementById('terminal-container'); + +createTerminal(); + +function createTerminal() { + while (terminalContainer.children.length) { + terminalContainer.removeChild(terminalContainer.children[0]); + } + term = new __WEBPACK_IMPORTED_MODULE_0__xterm_js_build_xterm__({ + cursorBlink: true, + fontFamily: 'consolas', + fontSize: 13, + allowTransparency: true, + theme: { + background: "transparent" + } + }); + window.term = term; // Expose `term` to window for debugging purposes + term.on('resize', function (size) { + if (!socketURL) { + return; + } + var cols = size.cols, + rows = size.rows, + url = 'http://localhost:9000/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; + fetch(url, {method: 'POST'}); + }); + protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; + + term.open(terminalContainer); + term.winptyCompatInit(); + term.fit(); + term.focus(); + + fetch('http://localhost:9000/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { + console.log("got response"); + res.text().then(function (url) { + socketURL = JSON.parse(url); + socket = new WebSocket(socketURL); + socket.onopen = runRealTerminal; + }); + }); +} + +function runRealTerminal() { + term.attach(socket); + term._initialized = true; +} + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +var require;var require;(function(f){if(true){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Terminal = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o this._terminal.rows; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Buffer.prototype, "isCursorInViewport", { + get: function () { + var absoluteY = this.ybase + this.y; + var relativeY = absoluteY - this.ydisp; + return (relativeY >= 0 && relativeY < this._terminal.rows); + }, + enumerable: true, + configurable: true + }); + Buffer.prototype._getCorrectBufferLength = function (rows) { + if (!this._hasScrollback) { + return rows; + } + var correctBufferLength = rows + this._terminal.options.scrollback; + return correctBufferLength > exports.MAX_BUFFER_SIZE ? exports.MAX_BUFFER_SIZE : correctBufferLength; + }; + Buffer.prototype.fillViewportRows = function () { + if (this._lines.length === 0) { + var i = this._terminal.rows; + while (i--) { + this.lines.push(this._terminal.blankLine()); + } + } + }; + Buffer.prototype.clear = function () { + this.ydisp = 0; + this.ybase = 0; + this.y = 0; + this.x = 0; + this._lines = new CircularList_1.CircularList(this._getCorrectBufferLength(this._terminal.rows)); + this.scrollTop = 0; + this.scrollBottom = this._terminal.rows - 1; + this.setupTabStops(); + }; + Buffer.prototype.resize = function (newCols, newRows) { + var newMaxLength = this._getCorrectBufferLength(newRows); + if (newMaxLength > this._lines.maxLength) { + this._lines.maxLength = newMaxLength; + } + if (this._lines.length > 0) { + if (this._terminal.cols < newCols) { + var ch = [this._terminal.defAttr, ' ', 1, 32]; + for (var i = 0; i < this._lines.length; i++) { + if (this._lines.get(i) === undefined) { + this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols)); + } + while (this._lines.get(i).length < newCols) { + this._lines.get(i).push(ch); + } + } + } + var addToY = 0; + if (this._terminal.rows < newRows) { + for (var y = this._terminal.rows; y < newRows; y++) { + if (this._lines.length < newRows + this.ybase) { + if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) { + this.ybase--; + addToY++; + if (this.ydisp > 0) { + this.ydisp--; + } + } + else { + this._lines.push(this._terminal.blankLine(undefined, undefined, newCols)); + } + } + } + } + else { + for (var y = this._terminal.rows; y > newRows; y--) { + if (this._lines.length > newRows + this.ybase) { + if (this._lines.length > this.ybase + this.y + 1) { + this._lines.pop(); + } + else { + this.ybase++; + this.ydisp++; + } + } + } + } + if (newMaxLength < this._lines.maxLength) { + var amountToTrim = this._lines.length - newMaxLength; + if (amountToTrim > 0) { + this._lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + } + this._lines.maxLength = newMaxLength; + } + if (this.y >= newRows) { + this.y = newRows - 1; + } + if (addToY) { + this.y += addToY; + } + if (this.x >= newCols) { + this.x = newCols - 1; + } + this.scrollTop = 0; + } + this.scrollBottom = newRows - 1; + }; + Buffer.prototype.translateBufferLineToString = function (lineIndex, trimRight, startCol, endCol) { + if (startCol === void 0) { startCol = 0; } + if (endCol === void 0) { endCol = null; } + var lineString = ''; + var line = this.lines.get(lineIndex); + if (!line) { + return ''; + } + var startIndex = startCol; + endCol = endCol || line.length; + var endIndex = endCol; + for (var i = 0; i < line.length; i++) { + var char = line[i]; + lineString += char[exports.CHAR_DATA_CHAR_INDEX]; + if (char[exports.CHAR_DATA_WIDTH_INDEX] === 0) { + if (startCol >= i) { + startIndex--; + } + if (endCol >= i) { + endIndex--; + } + } + else { + if (char[exports.CHAR_DATA_CHAR_INDEX].length > 1) { + if (startCol > i) { + startIndex += char[exports.CHAR_DATA_CHAR_INDEX].length - 1; + } + if (endCol > i) { + endIndex += char[exports.CHAR_DATA_CHAR_INDEX].length - 1; + } + } + } + } + if (trimRight) { + var rightWhitespaceIndex = lineString.search(/\s+$/); + if (rightWhitespaceIndex !== -1) { + endIndex = Math.min(endIndex, rightWhitespaceIndex); + } + if (endIndex <= startIndex) { + return ''; + } + } + return lineString.substring(startIndex, endIndex); + }; + Buffer.prototype.setupTabStops = function (i) { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } + else { + this.tabs = {}; + i = 0; + } + for (; i < this._terminal.cols; i += this._terminal.options.tabStopWidth) { + this.tabs[i] = true; + } + }; + Buffer.prototype.prevStop = function (x) { + if (x == null) { + x = this.x; + } + while (!this.tabs[--x] && x > 0) + ; + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + }; + Buffer.prototype.nextStop = function (x) { + if (x == null) { + x = this.x; + } + while (!this.tabs[++x] && x < this._terminal.cols) + ; + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + }; + return Buffer; +}()); +exports.Buffer = Buffer; + + + +},{"./utils/CircularList":30}],2:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("./Buffer"); +var EventEmitter_1 = require("./EventEmitter"); +var BufferSet = (function (_super) { + __extends(BufferSet, _super); + function BufferSet(_terminal) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._normal = new Buffer_1.Buffer(_this._terminal, true); + _this._normal.fillViewportRows(); + _this._alt = new Buffer_1.Buffer(_this._terminal, false); + _this._activeBuffer = _this._normal; + _this.setupTabStops(); + return _this; + } + Object.defineProperty(BufferSet.prototype, "alt", { + get: function () { + return this._alt; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BufferSet.prototype, "active", { + get: function () { + return this._activeBuffer; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BufferSet.prototype, "normal", { + get: function () { + return this._normal; + }, + enumerable: true, + configurable: true + }); + BufferSet.prototype.activateNormalBuffer = function () { + this._alt.clear(); + this._activeBuffer = this._normal; + this.emit('activate', this._normal); + }; + BufferSet.prototype.activateAltBuffer = function () { + this._alt.fillViewportRows(); + this._activeBuffer = this._alt; + this.emit('activate', this._alt); + }; + BufferSet.prototype.resize = function (newCols, newRows) { + this._normal.resize(newCols, newRows); + this._alt.resize(newCols, newRows); + }; + BufferSet.prototype.setupTabStops = function (i) { + this._normal.setupTabStops(i); + this._alt.setupTabStops(i); + }; + return BufferSet; +}(EventEmitter_1.EventEmitter)); +exports.BufferSet = BufferSet; + + + +},{"./Buffer":1,"./EventEmitter":7}],3:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.wcwidth = (function (opts) { + var COMBINING_BMP = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + ]; + var COMBINING_HIGH = [ + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + function bisearch(ucs, data) { + var min = 0; + var max = data.length - 1; + var mid; + if (ucs < data[0][0] || ucs > data[max][1]) + return false; + while (max >= min) { + mid = (min + max) >> 1; + if (ucs > data[mid][1]) + min = mid + 1; + else if (ucs < data[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidthBMP(ucs) { + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + if (bisearch(ucs, COMBINING_BMP)) + return 0; + if (isWideBMP(ucs)) { + return 2; + } + return 1; + } + function isWideBMP(ucs) { + return (ucs >= 0x1100 && (ucs <= 0x115f || + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || + (ucs >= 0xac00 && ucs <= 0xd7a3) || + (ucs >= 0xf900 && ucs <= 0xfaff) || + (ucs >= 0xfe10 && ucs <= 0xfe19) || + (ucs >= 0xfe30 && ucs <= 0xfe6f) || + (ucs >= 0xff00 && ucs <= 0xff60) || + (ucs >= 0xffe0 && ucs <= 0xffe6))); + } + function wcwidthHigh(ucs) { + if (bisearch(ucs, COMBINING_HIGH)) + return 0; + if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) { + return 2; + } + return 1; + } + var control = opts.control | 0; + var table = null; + function init_table() { + var CODEPOINTS = 65536; + var BITWIDTH = 2; + var ITEMSIZE = 32; + var CONTAINERSIZE = CODEPOINTS * BITWIDTH / ITEMSIZE; + var CODEPOINTS_PER_ITEM = ITEMSIZE / BITWIDTH; + table = (typeof Uint32Array === 'undefined') + ? new Array(CONTAINERSIZE) + : new Uint32Array(CONTAINERSIZE); + for (var i = 0; i < CONTAINERSIZE; ++i) { + var num = 0; + var pos = CODEPOINTS_PER_ITEM; + while (pos--) + num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos); + table[i] = num; + } + return table; + } + return function (num) { + num = num | 0; + if (num < 32) + return control | 0; + if (num < 127) + return 1; + var t = table || init_table(); + if (num < 65536) + return t[num >> 4] >> ((num & 15) << 1) & 3; + return wcwidthHigh(num); + }; +})({ nul: 0, control: 0 }); + + + +},{}],4:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CHARSETS = {}; +exports.DEFAULT_CHARSET = exports.CHARSETS['B']; +exports.CHARSETS['0'] = { + '`': '\u25c6', + 'a': '\u2592', + 'b': '\u0009', + 'c': '\u000c', + 'd': '\u000d', + 'e': '\u000a', + 'f': '\u00b0', + 'g': '\u00b1', + 'h': '\u2424', + 'i': '\u000b', + 'j': '\u2518', + 'k': '\u2510', + 'l': '\u250c', + 'm': '\u2514', + 'n': '\u253c', + 'o': '\u23ba', + 'p': '\u23bb', + 'q': '\u2500', + 'r': '\u23bc', + 's': '\u23bd', + 't': '\u251c', + 'u': '\u2524', + 'v': '\u2534', + 'w': '\u252c', + 'x': '\u2502', + 'y': '\u2264', + 'z': '\u2265', + '{': '\u03c0', + '|': '\u2260', + '}': '\u00a3', + '~': '\u00b7' +}; +exports.CHARSETS['A'] = { + '#': '£' +}; +exports.CHARSETS['B'] = null; +exports.CHARSETS['4'] = { + '#': '£', + '@': '¾', + '[': 'ij', + '\\': '½', + ']': '|', + '{': '¨', + '|': 'f', + '}': '¼', + '~': '´' +}; +exports.CHARSETS['C'] = + exports.CHARSETS['5'] = { + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['R'] = { + '#': '£', + '@': 'à', + '[': '°', + '\\': 'ç', + ']': '§', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': '¨' +}; +exports.CHARSETS['Q'] = { + '@': 'à', + '[': 'â', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '`': 'ô', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': 'û' +}; +exports.CHARSETS['K'] = { + '@': '§', + '[': 'Ä', + '\\': 'Ö', + ']': 'Ü', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'ß' +}; +exports.CHARSETS['Y'] = { + '#': '£', + '@': '§', + '[': '°', + '\\': 'ç', + ']': 'é', + '`': 'ù', + '{': 'à', + '|': 'ò', + '}': 'è', + '~': 'ì' +}; +exports.CHARSETS['E'] = + exports.CHARSETS['6'] = { + '@': 'Ä', + '[': 'Æ', + '\\': 'Ø', + ']': 'Å', + '^': 'Ü', + '`': 'ä', + '{': 'æ', + '|': 'ø', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['Z'] = { + '#': '£', + '@': '§', + '[': '¡', + '\\': 'Ñ', + ']': '¿', + '{': '°', + '|': 'ñ', + '}': 'ç' +}; +exports.CHARSETS['H'] = + exports.CHARSETS['7'] = { + '@': 'É', + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['='] = { + '#': 'ù', + '@': 'à', + '[': 'é', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '_': 'è', + '`': 'ô', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'û' +}; + + + +},{}],5:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var CompositionHelper = (function () { + function CompositionHelper(textarea, compositionView, terminal) { + this.textarea = textarea; + this.compositionView = compositionView; + this.terminal = terminal; + this.isComposing = false; + this.isSendingComposition = false; + this.compositionPosition = { start: null, end: null }; + } + CompositionHelper.prototype.compositionstart = function () { + this.isComposing = true; + this.compositionPosition.start = this.textarea.value.length; + this.compositionView.textContent = ''; + this.compositionView.classList.add('active'); + }; + CompositionHelper.prototype.compositionupdate = function (ev) { + var _this = this; + this.compositionView.textContent = ev.data; + this.updateCompositionElements(); + setTimeout(function () { + _this.compositionPosition.end = _this.textarea.value.length; + }, 0); + }; + CompositionHelper.prototype.compositionend = function () { + this.finalizeComposition(true); + }; + CompositionHelper.prototype.keydown = function (ev) { + if (this.isComposing || this.isSendingComposition) { + if (ev.keyCode === 229) { + return false; + } + else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { + return false; + } + else { + this.finalizeComposition(false); + } + } + if (ev.keyCode === 229) { + this.handleAnyTextareaChanges(); + return false; + } + return true; + }; + CompositionHelper.prototype.finalizeComposition = function (waitForPropogation) { + var _this = this; + this.compositionView.classList.remove('active'); + this.isComposing = false; + this.clearTextareaPosition(); + if (!waitForPropogation) { + this.isSendingComposition = false; + var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); + this.terminal.handler(input); + } + else { + var currentCompositionPosition_1 = { + start: this.compositionPosition.start, + end: this.compositionPosition.end, + }; + this.isSendingComposition = true; + setTimeout(function () { + if (_this.isSendingComposition) { + _this.isSendingComposition = false; + var input = void 0; + if (_this.isComposing) { + input = _this.textarea.value.substring(currentCompositionPosition_1.start, currentCompositionPosition_1.end); + } + else { + input = _this.textarea.value.substring(currentCompositionPosition_1.start); + } + _this.terminal.handler(input); + } + }, 0); + } + }; + CompositionHelper.prototype.handleAnyTextareaChanges = function () { + var _this = this; + var oldValue = this.textarea.value; + setTimeout(function () { + if (!_this.isComposing) { + var newValue = _this.textarea.value; + var diff = newValue.replace(oldValue, ''); + if (diff.length > 0) { + _this.terminal.handler(diff); + } + } + }, 0); + }; + CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) { + var _this = this; + if (!this.isComposing) { + return; + } + if (this.terminal.buffer.isCursorInViewport) { + var cellHeight = Math.ceil(this.terminal.charMeasure.height * this.terminal.options.lineHeight); + var cursorTop = this.terminal.buffer.y * cellHeight; + var cursorLeft = this.terminal.buffer.x * this.terminal.charMeasure.width; + this.compositionView.style.left = cursorLeft + 'px'; + this.compositionView.style.top = cursorTop + 'px'; + this.compositionView.style.height = cellHeight + 'px'; + this.compositionView.style.lineHeight = cellHeight + 'px'; + var compositionViewBounds = this.compositionView.getBoundingClientRect(); + this.textarea.style.left = cursorLeft + 'px'; + this.textarea.style.top = cursorTop + 'px'; + this.textarea.style.width = compositionViewBounds.width + 'px'; + this.textarea.style.height = compositionViewBounds.height + 'px'; + this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; + } + if (!dontRecurse) { + setTimeout(function () { return _this.updateCompositionElements(true); }, 0); + } + }; + ; + CompositionHelper.prototype.clearTextareaPosition = function () { + this.textarea.style.left = ''; + this.textarea.style.top = ''; + }; + ; + return CompositionHelper; +}()); +exports.CompositionHelper = CompositionHelper; + + + +},{}],6:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var C0; +(function (C0) { + C0.NUL = '\x00'; + C0.SOH = '\x01'; + C0.STX = '\x02'; + C0.ETX = '\x03'; + C0.EOT = '\x04'; + C0.ENQ = '\x05'; + C0.ACK = '\x06'; + C0.BEL = '\x07'; + C0.BS = '\x08'; + C0.HT = '\x09'; + C0.LF = '\x0a'; + C0.VT = '\x0b'; + C0.FF = '\x0c'; + C0.CR = '\x0d'; + C0.SO = '\x0e'; + C0.SI = '\x0f'; + C0.DLE = '\x10'; + C0.DC1 = '\x11'; + C0.DC2 = '\x12'; + C0.DC3 = '\x13'; + C0.DC4 = '\x14'; + C0.NAK = '\x15'; + C0.SYN = '\x16'; + C0.ETB = '\x17'; + C0.CAN = '\x18'; + C0.EM = '\x19'; + C0.SUB = '\x1a'; + C0.ESC = '\x1b'; + C0.FS = '\x1c'; + C0.GS = '\x1d'; + C0.RS = '\x1e'; + C0.US = '\x1f'; + C0.SP = '\x20'; + C0.DEL = '\x7f'; +})(C0 = exports.C0 || (exports.C0 = {})); +; + + + +},{}],7:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter = (function () { + function EventEmitter() { + this._events = this._events || {}; + } + EventEmitter.prototype.on = function (type, listener) { + this._events[type] = this._events[type] || []; + this._events[type].push(listener); + }; + EventEmitter.prototype.off = function (type, listener) { + if (!this._events[type]) { + return; + } + var obj = this._events[type]; + var i = obj.length; + while (i--) { + if (obj[i] === listener || obj[i].listener === listener) { + obj.splice(i, 1); + return; + } + } + }; + EventEmitter.prototype.removeAllListeners = function (type) { + if (this._events[type]) { + delete this._events[type]; + } + }; + EventEmitter.prototype.once = function (type, listener) { + function on() { + var args = Array.prototype.slice.call(arguments); + this.off(type, on); + listener.apply(this, args); + } + on.listener = listener; + this.on(type, on); + }; + EventEmitter.prototype.emit = function (type) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (!this._events[type]) { + return; + } + var obj = this._events[type]; + for (var i = 0; i < obj.length; i++) { + obj[i].apply(this, args); + } + }; + EventEmitter.prototype.listeners = function (type) { + return this._events[type] || []; + }; + EventEmitter.prototype.destroy = function () { + this._events = {}; + }; + return EventEmitter; +}()); +exports.EventEmitter = EventEmitter; + + + +},{}],8:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var Buffer_1 = require("./Buffer"); +var Types_1 = require("./renderer/Types"); +var CharWidth_1 = require("./CharWidth"); +var InputHandler = (function () { + function InputHandler(_terminal) { + this._terminal = _terminal; + } + InputHandler.prototype.addChar = function (char, code) { + if (char >= ' ') { + var ch_width = CharWidth_1.wcwidth(code); + if (this._terminal.charset && this._terminal.charset[char]) { + char = this._terminal.charset[char]; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + if (!ch_width && this._terminal.buffer.x) { + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1]) { + if (!this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][Buffer_1.CHAR_DATA_WIDTH_INDEX]) { + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2]) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][Buffer_1.CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][3] = char.charCodeAt(0); + } + } + else { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][Buffer_1.CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][3] = char.charCodeAt(0); + } + this._terminal.updateRange(this._terminal.buffer.y); + } + return; + } + if (this._terminal.buffer.x + ch_width - 1 >= this._terminal.cols) { + if (this._terminal.wraparoundMode) { + this._terminal.buffer.x = 0; + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(true); + } + else { + this._terminal.buffer.lines.get(this._terminal.buffer.y).isWrapped = true; + } + } + else { + if (ch_width === 2) + return; + } + } + row = this._terminal.buffer.y + this._terminal.buffer.ybase; + if (this._terminal.insertMode) { + for (var moves = 0; moves < ch_width; ++moves) { + var removed = this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).pop(); + if (removed[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0 + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]; + } + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 0, [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]); + } + } + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, ch_width, char.charCodeAt(0)]; + this._terminal.buffer.x++; + this._terminal.updateRange(this._terminal.buffer.y); + if (ch_width === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, '', 0, undefined]; + this._terminal.buffer.x++; + } + } + }; + InputHandler.prototype.bell = function () { + this._terminal.bell(); + }; + InputHandler.prototype.lineFeed = function () { + if (this._terminal.convertEol) { + this._terminal.buffer.x = 0; + } + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(); + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + this._terminal.emit('linefeed'); + }; + InputHandler.prototype.carriageReturn = function () { + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.backspace = function () { + if (this._terminal.buffer.x > 0) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.tab = function () { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + }; + InputHandler.prototype.shiftOut = function () { + this._terminal.setgLevel(1); + }; + InputHandler.prototype.shiftIn = function () { + this._terminal.setgLevel(0); + }; + InputHandler.prototype.insertChars = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j = this._terminal.buffer.x; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row).splice(j++, 0, ch); + this._terminal.buffer.lines.get(row).pop(); + } + }; + InputHandler.prototype.cursorUp = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + }; + InputHandler.prototype.cursorDown = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.cursorForward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.cursorBackward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + this._terminal.buffer.x -= param; + if (this._terminal.buffer.x < 0) { + this._terminal.buffer.x = 0; + } + }; + InputHandler.prototype.cursorNextLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.cursorPrecedingLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.cursorCharAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + }; + InputHandler.prototype.cursorPosition = function (params) { + var col; + var row = params[0] - 1; + if (params.length >= 2) { + col = params[1] - 1; + } + else { + col = 0; + } + if (row < 0) { + row = 0; + } + else if (row >= this._terminal.rows) { + row = this._terminal.rows - 1; + } + if (col < 0) { + col = 0; + } + else if (col >= this._terminal.cols) { + col = this._terminal.cols - 1; + } + this._terminal.buffer.x = col; + this._terminal.buffer.y = row; + }; + InputHandler.prototype.cursorForwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + } + }; + InputHandler.prototype.eraseInDisplay = function (params) { + var j; + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y + 1; + for (; j < this._terminal.rows; j++) { + this._terminal.eraseLine(j); + } + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y; + while (j--) { + this._terminal.eraseLine(j); + } + break; + case 2: + j = this._terminal.rows; + while (j--) + this._terminal.eraseLine(j); + break; + case 3: + var scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows; + if (scrollBackSize > 0) { + this._terminal.buffer.lines.trimStart(scrollBackSize); + this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0); + this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0); + this._terminal.emit('scroll', 0); + } + break; + } + }; + InputHandler.prototype.eraseInLine = function (params) { + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 2: + this._terminal.eraseLine(this._terminal.buffer.y); + break; + } + }; + InputHandler.prototype.insertLines = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var scrollBottomRowsOffset = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + var scrollBottomAbsolute = this._terminal.rows - 1 + this._terminal.buffer.ybase - scrollBottomRowsOffset + 1; + while (param--) { + this._terminal.buffer.lines.splice(scrollBottomAbsolute - 1, 1); + this._terminal.buffer.lines.splice(row, 0, this._terminal.blankLine(true)); + } + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.deleteLines = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j; + j = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.buffer.ybase - j; + while (param--) { + this._terminal.buffer.lines.splice(row, 1); + this._terminal.buffer.lines.splice(j, 0, this._terminal.blankLine(true)); + } + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.deleteChars = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param--) { + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 1); + this._terminal.buffer.lines.get(row).push(ch); + } + this._terminal.updateRange(this._terminal.buffer.y); + }; + InputHandler.prototype.scrollUp = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.scrollDown = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.eraseChars = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j = this._terminal.buffer.x; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row)[j++] = ch; + } + }; + InputHandler.prototype.cursorBackwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.prevStop(); + } + }; + InputHandler.prototype.charPosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.HPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.repeatPrecedingCharacter = function (params) { + var param = params[0] || 1; + var line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + this._terminal.buffer.y); + var ch = line[this._terminal.buffer.x - 1] || [this._terminal.defAttr, ' ', 1, 32]; + while (param--) { + line[this._terminal.buffer.x++] = ch; + } + }; + InputHandler.prototype.sendDeviceAttributes = function (params) { + if (params[0] > 0) { + return; + } + if (!this._terminal.prefix) { + if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?1;2c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?6c'); + } + } + else if (this._terminal.prefix === '>') { + if (this._terminal.is('xterm')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>0;276;0c'); + } + else if (this._terminal.is('rxvt-unicode')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>85;95;0c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(params[0] + 'c'); + } + else if (this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>83;40003;0c'); + } + } + }; + InputHandler.prototype.linePosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y = param - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + }; + InputHandler.prototype.VPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.HVPosition = function (params) { + if (params[0] < 1) + params[0] = 1; + if (params[1] < 1) + params[1] = 1; + this._terminal.buffer.y = params[0] - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + this._terminal.buffer.x = params[1] - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.tabClear = function (params) { + var param = params[0]; + if (param <= 0) { + delete this._terminal.buffer.tabs[this._terminal.buffer.x]; + } + else if (param === 3) { + this._terminal.buffer.tabs = {}; + } + }; + InputHandler.prototype.setMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.setMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = true; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = true; + break; + case 2: + this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(1, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(2, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(3, Charsets_1.DEFAULT_CHARSET); + break; + case 3: + this._terminal.savedCols = this._terminal.cols; + this._terminal.resize(132, this._terminal.rows); + break; + case 6: + this._terminal.originMode = true; + break; + case 7: + this._terminal.wraparoundMode = true; + break; + case 12: + break; + case 66: + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = params[0] === 9; + this._terminal.vt200Mouse = params[0] === 1000; + this._terminal.normalMouse = params[0] > 1000; + this._terminal.mouseEvents = true; + this._terminal.element.classList.add('enable-mouse-events'); + this._terminal.selectionManager.disable(); + this._terminal.log('Binding to mouse events.'); + break; + case 1004: + this._terminal.sendFocus = true; + break; + case 1005: + this._terminal.utfMouse = true; + break; + case 1006: + this._terminal.sgrMouse = true; + break; + case 1015: + this._terminal.urxvtMouse = true; + break; + case 25: + this._terminal.cursorHidden = false; + break; + case 1049: + case 47: + case 1047: + this._terminal.buffers.activateAltBuffer(); + this._terminal.selectionManager.setBuffer(this._terminal.buffer); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + break; + case 2004: + this._terminal.bracketedPasteMode = true; + break; + } + } + }; + InputHandler.prototype.resetMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.resetMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = false; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = false; + break; + case 3: + if (this._terminal.cols === 132 && this._terminal.savedCols) { + this._terminal.resize(this._terminal.savedCols, this._terminal.rows); + } + delete this._terminal.savedCols; + break; + case 6: + this._terminal.originMode = false; + break; + case 7: + this._terminal.wraparoundMode = false; + break; + case 12: + break; + case 66: + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = false; + this._terminal.vt200Mouse = false; + this._terminal.normalMouse = false; + this._terminal.mouseEvents = false; + this._terminal.element.classList.remove('enable-mouse-events'); + this._terminal.selectionManager.enable(); + break; + case 1004: + this._terminal.sendFocus = false; + break; + case 1005: + this._terminal.utfMouse = false; + break; + case 1006: + this._terminal.sgrMouse = false; + break; + case 1015: + this._terminal.urxvtMouse = false; + break; + case 25: + this._terminal.cursorHidden = true; + break; + case 1049: + case 47: + case 1047: + this._terminal.buffers.activateNormalBuffer(); + this._terminal.selectionManager.setBuffer(this._terminal.buffer); + this._terminal.refresh(0, this._terminal.rows - 1); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + break; + case 2004: + this._terminal.bracketedPasteMode = false; + break; + } + } + }; + InputHandler.prototype.charAttributes = function (params) { + if (params.length === 1 && params[0] === 0) { + this._terminal.curAttr = this._terminal.defAttr; + return; + } + var l = params.length; + var flags = this._terminal.curAttr >> 18; + var fg = (this._terminal.curAttr >> 9) & 0x1ff; + var bg = this._terminal.curAttr & 0x1ff; + var p; + for (var i = 0; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + fg = p - 30; + } + else if (p >= 40 && p <= 47) { + bg = p - 40; + } + else if (p >= 90 && p <= 97) { + p += 8; + fg = p - 90; + } + else if (p >= 100 && p <= 107) { + p += 8; + bg = p - 100; + } + else if (p === 0) { + flags = this._terminal.defAttr >> 18; + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 1) { + flags |= Types_1.FLAGS.BOLD; + } + else if (p === 4) { + flags |= Types_1.FLAGS.UNDERLINE; + } + else if (p === 5) { + flags |= Types_1.FLAGS.BLINK; + } + else if (p === 7) { + flags |= Types_1.FLAGS.INVERSE; + } + else if (p === 8) { + flags |= Types_1.FLAGS.INVISIBLE; + } + else if (p === 2) { + flags |= Types_1.FLAGS.DIM; + } + else if (p === 22) { + flags &= ~Types_1.FLAGS.BOLD; + flags &= ~Types_1.FLAGS.DIM; + } + else if (p === 24) { + flags &= ~Types_1.FLAGS.UNDERLINE; + } + else if (p === 25) { + flags &= ~Types_1.FLAGS.BLINK; + } + else if (p === 27) { + flags &= ~Types_1.FLAGS.INVERSE; + } + else if (p === 28) { + flags &= ~Types_1.FLAGS.INVISIBLE; + } + else if (p === 39) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + } + else if (p === 49) { + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 38) { + if (params[i + 1] === 2) { + i += 2; + fg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (fg === -1) + fg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } + else if (p === 48) { + if (params[i + 1] === 2) { + i += 2; + bg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (bg === -1) + bg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } + else if (p === 100) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else { + this._terminal.error('Unknown SGR attribute: %d.', p); + } + } + this._terminal.curAttr = (flags << 18) | (fg << 9) | bg; + }; + InputHandler.prototype.deviceStatus = function (params) { + if (!this._terminal.prefix) { + switch (params[0]) { + case 5: + this._terminal.send(EscapeSequences_1.C0.ESC + '[0n'); + break; + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[?' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + case 15: + break; + case 25: + break; + case 26: + break; + case 53: + break; + } + } + }; + InputHandler.prototype.softReset = function (params) { + this._terminal.cursorHidden = false; + this._terminal.insertMode = false; + this._terminal.originMode = false; + this._terminal.wraparoundMode = true; + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + this._terminal.applicationCursor = false; + this._terminal.buffer.scrollTop = 0; + this._terminal.buffer.scrollBottom = this._terminal.rows - 1; + this._terminal.curAttr = this._terminal.defAttr; + this._terminal.buffer.x = this._terminal.buffer.y = 0; + this._terminal.charset = null; + this._terminal.glevel = 0; + this._terminal.charsets = [null]; + }; + InputHandler.prototype.setCursorStyle = function (params) { + var param = params[0] < 1 ? 1 : params[0]; + switch (param) { + case 1: + case 2: + this._terminal.setOption('cursorStyle', 'block'); + break; + case 3: + case 4: + this._terminal.setOption('cursorStyle', 'underline'); + break; + case 5: + case 6: + this._terminal.setOption('cursorStyle', 'bar'); + break; + } + var isBlinking = param % 2 === 1; + this._terminal.setOption('cursorBlink', isBlinking); + }; + InputHandler.prototype.setScrollRegion = function (params) { + if (this._terminal.prefix) + return; + this._terminal.buffer.scrollTop = (params[0] || 1) - 1; + this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1; + this._terminal.buffer.x = 0; + this._terminal.buffer.y = 0; + }; + InputHandler.prototype.saveCursor = function (params) { + this._terminal.buffer.savedX = this._terminal.buffer.x; + this._terminal.buffer.savedY = this._terminal.buffer.y; + }; + InputHandler.prototype.restoreCursor = function (params) { + this._terminal.buffer.x = this._terminal.buffer.savedX || 0; + this._terminal.buffer.y = this._terminal.buffer.savedY || 0; + }; + return InputHandler; +}()); +exports.InputHandler = InputHandler; + + + +},{"./Buffer":1,"./CharWidth":3,"./Charsets":4,"./EscapeSequences":6,"./renderer/Types":27}],9:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Types_1 = require("./Types"); +var MouseZoneManager_1 = require("./input/MouseZoneManager"); +var EventEmitter_1 = require("./EventEmitter"); +var protocolClause = '(https?:\\/\\/)'; +var domainCharacterSet = '[\\da-z\\.-]+'; +var negatedDomainCharacterSet = '[^\\da-z\\.-]+'; +var domainBodyClause = '(' + domainCharacterSet + ')'; +var tldClause = '([a-z\\.]{2,6})'; +var ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +var localHostClause = '(localhost)'; +var portClause = '(:\\d{1,5})'; +var hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; +var pathClause = '(\\/[\\/\\w\\.\\-%~]*)*'; +var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; +var queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; +var hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; +var negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; +var bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; +var start = '(?:^|' + negatedDomainCharacterSet + ')('; +var end = ')($|' + negatedPathCharacterSet + ')'; +var strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); +var HYPERTEXT_LINK_MATCHER_ID = 0; +var Linkifier = (function (_super) { + __extends(Linkifier, _super); + function Linkifier(_terminal) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._linkMatchers = []; + _this._nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; + _this._rowsToLinkify = { + start: null, + end: null + }; + _this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); + return _this; + } + Linkifier.prototype.attachToDom = function (mouseZoneManager) { + this._mouseZoneManager = mouseZoneManager; + }; + Linkifier.prototype.linkifyRows = function (start, end) { + var _this = this; + if (!this._mouseZoneManager) { + return; + } + if (!this._rowsToLinkify.start) { + this._rowsToLinkify.start = start; + this._rowsToLinkify.end = end; + } + else { + this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start; + this._rowsToLinkify.end = this._rowsToLinkify.end > end ? this._rowsToLinkify.end : end; + } + this._mouseZoneManager.clearAll(start, end); + if (this._rowsTimeoutId) { + clearTimeout(this._rowsTimeoutId); + } + this._rowsTimeoutId = setTimeout(function () { return _this._linkifyRows(); }, Linkifier.TIME_BEFORE_LINKIFY); + }; + Linkifier.prototype._linkifyRows = function () { + this._rowsTimeoutId = null; + for (var i = this._rowsToLinkify.start; i <= this._rowsToLinkify.end; i++) { + this._linkifyRow(i); + } + this._rowsToLinkify.start = null; + this._rowsToLinkify.end = null; + }; + Linkifier.prototype.setHypertextLinkHandler = function (handler) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; + }; + Linkifier.prototype.setHypertextValidationCallback = function (callback) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback; + }; + Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) { + if (options === void 0) { options = {}; } + if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + throw new Error('handler must be defined'); + } + var matcher = { + id: this._nextLinkMatcherId++, + regex: regex, + handler: handler, + matchIndex: options.matchIndex, + validationCallback: options.validationCallback, + hoverTooltipCallback: options.tooltipCallback, + hoverLeaveCallback: options.leaveCallback, + priority: options.priority || 0 + }; + this._addLinkMatcherToList(matcher); + return matcher.id; + }; + Linkifier.prototype._addLinkMatcherToList = function (matcher) { + if (this._linkMatchers.length === 0) { + this._linkMatchers.push(matcher); + return; + } + for (var i = this._linkMatchers.length - 1; i >= 0; i--) { + if (matcher.priority <= this._linkMatchers[i].priority) { + this._linkMatchers.splice(i + 1, 0, matcher); + return; + } + } + this._linkMatchers.splice(0, 0, matcher); + }; + Linkifier.prototype.deregisterLinkMatcher = function (matcherId) { + for (var i = 1; i < this._linkMatchers.length; i++) { + if (this._linkMatchers[i].id === matcherId) { + this._linkMatchers.splice(i, 1); + return true; + } + } + return false; + }; + Linkifier.prototype._linkifyRow = function (rowIndex) { + var absoluteRowIndex = this._terminal.buffer.ydisp + rowIndex; + if (absoluteRowIndex >= this._terminal.buffer.lines.length) { + return; + } + var text = this._terminal.buffer.translateBufferLineToString(absoluteRowIndex, false); + for (var i = 0; i < this._linkMatchers.length; i++) { + this._doLinkifyRow(rowIndex, text, this._linkMatchers[i]); + } + }; + Linkifier.prototype._doLinkifyRow = function (rowIndex, text, matcher, offset) { + var _this = this; + if (offset === void 0) { offset = 0; } + var result = []; + var isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID; + var match = text.match(matcher.regex); + if (!match || match.length === 0) { + return; + } + var uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + var index = text.indexOf(uri); + if (matcher.validationCallback) { + matcher.validationCallback(uri, function (isValid) { + if (_this._rowsTimeoutId) { + return; + } + if (isValid) { + _this._addLink(offset + index, rowIndex, uri, matcher); + } + }); + } + else { + this._addLink(offset + index, rowIndex, uri, matcher); + } + var remainingStartIndex = index + uri.length; + var remainingText = text.substr(remainingStartIndex); + if (remainingText.length > 0) { + this._doLinkifyRow(rowIndex, remainingText, matcher, offset + remainingStartIndex); + } + }; + Linkifier.prototype._addLink = function (x, y, uri, matcher) { + var _this = this; + this._mouseZoneManager.add(new MouseZoneManager_1.MouseZone(x + 1, x + 1 + uri.length, y + 1, function (e) { + if (matcher.handler) { + return matcher.handler(e, uri); + } + window.open(uri, '_blank'); + }, function (e) { + _this.emit(Types_1.LinkHoverEventTypes.HOVER, { x: x, y: y, length: uri.length }); + _this._terminal.element.style.cursor = 'pointer'; + }, function (e) { + _this.emit(Types_1.LinkHoverEventTypes.TOOLTIP, { x: x, y: y, length: uri.length }); + if (matcher.hoverTooltipCallback) { + matcher.hoverTooltipCallback(e, uri); + } + }, function () { + _this.emit(Types_1.LinkHoverEventTypes.LEAVE, { x: x, y: y, length: uri.length }); + _this._terminal.element.style.cursor = ''; + if (matcher.hoverLeaveCallback) { + matcher.hoverLeaveCallback(); + } + })); + }; + Linkifier.TIME_BEFORE_LINKIFY = 200; + return Linkifier; +}(EventEmitter_1.EventEmitter)); +exports.Linkifier = Linkifier; + + + +},{"./EventEmitter":7,"./Types":14,"./input/MouseZoneManager":17}],10:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var normalStateHandler = {}; +normalStateHandler[EscapeSequences_1.C0.BEL] = function (parser, handler) { return handler.bell(); }; +normalStateHandler[EscapeSequences_1.C0.LF] = function (parser, handler) { return handler.lineFeed(); }; +normalStateHandler[EscapeSequences_1.C0.VT] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.FF] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.CR] = function (parser, handler) { return handler.carriageReturn(); }; +normalStateHandler[EscapeSequences_1.C0.BS] = function (parser, handler) { return handler.backspace(); }; +normalStateHandler[EscapeSequences_1.C0.HT] = function (parser, handler) { return handler.tab(); }; +normalStateHandler[EscapeSequences_1.C0.SO] = function (parser, handler) { return handler.shiftOut(); }; +normalStateHandler[EscapeSequences_1.C0.SI] = function (parser, handler) { return handler.shiftIn(); }; +normalStateHandler[EscapeSequences_1.C0.ESC] = function (parser, handler) { return parser.setState(ParserState.ESCAPED); }; +var escapedStateHandler = {}; +escapedStateHandler['['] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.CSI_PARAM); +}; +escapedStateHandler[']'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.OSC); +}; +escapedStateHandler['P'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.DCS); +}; +escapedStateHandler['_'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['^'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['c'] = function (parser, terminal) { + terminal.reset(); +}; +escapedStateHandler['E'] = function (parser, terminal) { + terminal.buffer.x = 0; + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['D'] = function (parser, terminal) { + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['M'] = function (parser, terminal) { + terminal.reverseIndex(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['%'] = function (parser, terminal) { + terminal.setgLevel(0); + terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + parser.setState(ParserState.NORMAL); + parser.skipNextChar(); +}; +escapedStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiParamStateHandler = {}; +csiParamStateHandler['?'] = function (parser) { return parser.setPrefix('?'); }; +csiParamStateHandler['>'] = function (parser) { return parser.setPrefix('>'); }; +csiParamStateHandler['!'] = function (parser) { return parser.setPrefix('!'); }; +csiParamStateHandler['0'] = function (parser) { return parser.setParam(parser.getParam() * 10); }; +csiParamStateHandler['1'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 1); }; +csiParamStateHandler['2'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 2); }; +csiParamStateHandler['3'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 3); }; +csiParamStateHandler['4'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 4); }; +csiParamStateHandler['5'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 5); }; +csiParamStateHandler['6'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 6); }; +csiParamStateHandler['7'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 7); }; +csiParamStateHandler['8'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 8); }; +csiParamStateHandler['9'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 9); }; +csiParamStateHandler['$'] = function (parser) { return parser.setPostfix('$'); }; +csiParamStateHandler['"'] = function (parser) { return parser.setPostfix('"'); }; +csiParamStateHandler[' '] = function (parser) { return parser.setPostfix(' '); }; +csiParamStateHandler['\''] = function (parser) { return parser.setPostfix('\''); }; +csiParamStateHandler[';'] = function (parser) { return parser.finalizeParam(); }; +csiParamStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiStateHandler = {}; +csiStateHandler['@'] = function (handler, params, prefix) { return handler.insertChars(params); }; +csiStateHandler['A'] = function (handler, params, prefix) { return handler.cursorUp(params); }; +csiStateHandler['B'] = function (handler, params, prefix) { return handler.cursorDown(params); }; +csiStateHandler['C'] = function (handler, params, prefix) { return handler.cursorForward(params); }; +csiStateHandler['D'] = function (handler, params, prefix) { return handler.cursorBackward(params); }; +csiStateHandler['E'] = function (handler, params, prefix) { return handler.cursorNextLine(params); }; +csiStateHandler['F'] = function (handler, params, prefix) { return handler.cursorPrecedingLine(params); }; +csiStateHandler['G'] = function (handler, params, prefix) { return handler.cursorCharAbsolute(params); }; +csiStateHandler['H'] = function (handler, params, prefix) { return handler.cursorPosition(params); }; +csiStateHandler['I'] = function (handler, params, prefix) { return handler.cursorForwardTab(params); }; +csiStateHandler['J'] = function (handler, params, prefix) { return handler.eraseInDisplay(params); }; +csiStateHandler['K'] = function (handler, params, prefix) { return handler.eraseInLine(params); }; +csiStateHandler['L'] = function (handler, params, prefix) { return handler.insertLines(params); }; +csiStateHandler['M'] = function (handler, params, prefix) { return handler.deleteLines(params); }; +csiStateHandler['P'] = function (handler, params, prefix) { return handler.deleteChars(params); }; +csiStateHandler['S'] = function (handler, params, prefix) { return handler.scrollUp(params); }; +csiStateHandler['T'] = function (handler, params, prefix) { + if (params.length < 2 && !prefix) { + handler.scrollDown(params); + } +}; +csiStateHandler['X'] = function (handler, params, prefix) { return handler.eraseChars(params); }; +csiStateHandler['Z'] = function (handler, params, prefix) { return handler.cursorBackwardTab(params); }; +csiStateHandler['`'] = function (handler, params, prefix) { return handler.charPosAbsolute(params); }; +csiStateHandler['a'] = function (handler, params, prefix) { return handler.HPositionRelative(params); }; +csiStateHandler['b'] = function (handler, params, prefix) { return handler.repeatPrecedingCharacter(params); }; +csiStateHandler['c'] = function (handler, params, prefix) { return handler.sendDeviceAttributes(params); }; +csiStateHandler['d'] = function (handler, params, prefix) { return handler.linePosAbsolute(params); }; +csiStateHandler['e'] = function (handler, params, prefix) { return handler.VPositionRelative(params); }; +csiStateHandler['f'] = function (handler, params, prefix) { return handler.HVPosition(params); }; +csiStateHandler['g'] = function (handler, params, prefix) { return handler.tabClear(params); }; +csiStateHandler['h'] = function (handler, params, prefix) { return handler.setMode(params); }; +csiStateHandler['l'] = function (handler, params, prefix) { return handler.resetMode(params); }; +csiStateHandler['m'] = function (handler, params, prefix) { return handler.charAttributes(params); }; +csiStateHandler['n'] = function (handler, params, prefix) { return handler.deviceStatus(params); }; +csiStateHandler['p'] = function (handler, params, prefix) { + switch (prefix) { + case '!': + handler.softReset(params); + break; + } +}; +csiStateHandler['q'] = function (handler, params, prefix, postfix) { + if (postfix === ' ') { + handler.setCursorStyle(params); + } +}; +csiStateHandler['r'] = function (handler, params) { return handler.setScrollRegion(params); }; +csiStateHandler['s'] = function (handler, params) { return handler.saveCursor(params); }; +csiStateHandler['u'] = function (handler, params) { return handler.restoreCursor(params); }; +csiStateHandler[EscapeSequences_1.C0.CAN] = function (handler, params, prefix, postfix, parser) { return parser.setState(ParserState.NORMAL); }; +var ParserState; +(function (ParserState) { + ParserState[ParserState["NORMAL"] = 0] = "NORMAL"; + ParserState[ParserState["ESCAPED"] = 1] = "ESCAPED"; + ParserState[ParserState["CSI_PARAM"] = 2] = "CSI_PARAM"; + ParserState[ParserState["CSI"] = 3] = "CSI"; + ParserState[ParserState["OSC"] = 4] = "OSC"; + ParserState[ParserState["CHARSET"] = 5] = "CHARSET"; + ParserState[ParserState["DCS"] = 6] = "DCS"; + ParserState[ParserState["IGNORE"] = 7] = "IGNORE"; +})(ParserState = exports.ParserState || (exports.ParserState = {})); +var Parser = (function () { + function Parser(_inputHandler, _terminal) { + this._inputHandler = _inputHandler; + this._terminal = _terminal; + this._state = ParserState.NORMAL; + } + Parser.prototype.parse = function (data) { + var l = data.length; + var j; + var cs; + var ch; + var code; + var low; + var cursorStartX = this._terminal.buffer.x; + var cursorStartY = this._terminal.buffer.y; + if (this._terminal.debug) { + this._terminal.log('data: ' + data); + } + this._position = 0; + if (this._terminal.surrogate_high) { + data = this._terminal.surrogate_high + data; + this._terminal.surrogate_high = ''; + } + for (; this._position < l; this._position++) { + ch = data[this._position]; + code = data.charCodeAt(this._position); + if (0xD800 <= code && code <= 0xDBFF) { + low = data.charCodeAt(this._position + 1); + if (isNaN(low)) { + this._terminal.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(this._position + 1); + } + if (0xDC00 <= code && code <= 0xDFFF) + continue; + switch (this._state) { + case ParserState.NORMAL: + if (ch in normalStateHandler) { + normalStateHandler[ch](this, this._inputHandler); + } + else { + this._inputHandler.addChar(ch, code); + } + break; + case ParserState.ESCAPED: + if (ch in escapedStateHandler) { + escapedStateHandler[ch](this, this._terminal); + break; + } + switch (ch) { + case '(': + case ')': + case '*': + case '+': + case '-': + case '.': + switch (ch) { + case '(': + this._terminal.gcharset = 0; + break; + case ')': + this._terminal.gcharset = 1; + break; + case '*': + this._terminal.gcharset = 2; + break; + case '+': + this._terminal.gcharset = 3; + break; + case '-': + this._terminal.gcharset = 1; + break; + case '.': + this._terminal.gcharset = 2; + break; + } + this._state = ParserState.CHARSET; + break; + case '/': + this._terminal.gcharset = 3; + this._state = ParserState.CHARSET; + this._position--; + break; + case 'N': + this._state = ParserState.NORMAL; + break; + case 'O': + this._state = ParserState.NORMAL; + break; + case 'n': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + case 'o': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + case '|': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + case '}': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + case '~': + this._terminal.setgLevel(1); + this._state = ParserState.NORMAL; + break; + case '7': + this._inputHandler.saveCursor(); + this._state = ParserState.NORMAL; + break; + case '8': + this._inputHandler.restoreCursor(); + this._state = ParserState.NORMAL; + break; + case '#': + this._state = ParserState.NORMAL; + this._position++; + break; + case 'H': + this._terminal.tabSet(); + this._state = ParserState.NORMAL; + break; + case '=': + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + case '>': + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + default: + this._state = ParserState.NORMAL; + this._terminal.error('Unknown ESC control: %s.', ch); + break; + } + break; + case ParserState.CHARSET: + if (ch in Charsets_1.CHARSETS) { + cs = Charsets_1.CHARSETS[ch]; + if (ch === '/') { + this.skipNextChar(); + } + } + else { + cs = Charsets_1.DEFAULT_CHARSET; + } + this._terminal.setgCharset(this._terminal.gcharset, cs); + this._terminal.gcharset = null; + this._state = ParserState.NORMAL; + break; + case ParserState.OSC: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._terminal.params.push(this._terminal.currentParam); + switch (this._terminal.params[0]) { + case 0: + case 1: + case 2: + if (this._terminal.params[1]) { + this._terminal.title = this._terminal.params[1]; + this._terminal.handleTitle(this._terminal.title); + } + break; + case 3: + break; + case 4: + case 5: + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + break; + case 46: + break; + case 50: + break; + case 51: + break; + case 52: + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + break; + } + this._terminal.params = []; + this._terminal.currentParam = 0; + this._state = ParserState.NORMAL; + } + else { + if (!this._terminal.params.length) { + if (ch >= '0' && ch <= '9') { + this._terminal.currentParam = + this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; + } + else if (ch === ';') { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = ''; + } + } + else { + this._terminal.currentParam += ch; + } + } + break; + case ParserState.CSI_PARAM: + if (ch in csiParamStateHandler) { + csiParamStateHandler[ch](this); + break; + } + this.finalizeParam(); + this._state = ParserState.CSI; + case ParserState.CSI: + if (ch in csiStateHandler) { + if (this._terminal.debug) { + this._terminal.log("CSI " + (this._terminal.prefix ? this._terminal.prefix : '') + " " + (this._terminal.params ? this._terminal.params.join(';') : '') + " " + (this._terminal.postfix ? this._terminal.postfix : '') + " " + ch); + } + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this); + } + else { + this._terminal.error('Unknown CSI code: %s.', ch); + } + this._state = ParserState.NORMAL; + this._terminal.prefix = ''; + this._terminal.postfix = ''; + break; + case ParserState.DCS: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + var pt = void 0; + var valid = void 0; + switch (this._terminal.prefix) { + case '': + break; + case '$q': + pt = this._terminal.currentParam; + valid = false; + switch (pt) { + case '"q': + pt = '0"q'; + break; + case '"p': + pt = '61"p'; + break; + case 'r': + pt = '' + + (this._terminal.buffer.scrollTop + 1) + + ';' + + (this._terminal.buffer.scrollBottom + 1) + + 'r'; + break; + case 'm': + pt = '0m'; + break; + default: + this._terminal.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '$r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + case '+p': + break; + case '+q': + pt = this._terminal.currentParam; + valid = false; + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '+r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + default: + this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix); + break; + } + this._terminal.currentParam = 0; + this._terminal.prefix = ''; + this._state = ParserState.NORMAL; + } + else if (!this._terminal.currentParam) { + if (!this._terminal.prefix && ch !== '$' && ch !== '+') { + this._terminal.currentParam = ch; + } + else if (this._terminal.prefix.length === 2) { + this._terminal.currentParam = ch; + } + else { + this._terminal.prefix += ch; + } + } + else { + this._terminal.currentParam += ch; + } + break; + case ParserState.IGNORE: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._state = ParserState.NORMAL; + } + break; + } + } + if (this._terminal.buffer.x !== cursorStartX || this._terminal.buffer.y !== cursorStartY) { + this._terminal.emit('cursormove'); + } + return this._state; + }; + Parser.prototype.setState = function (state) { + this._state = state; + }; + Parser.prototype.setPrefix = function (prefix) { + this._terminal.prefix = prefix; + }; + Parser.prototype.setPostfix = function (postfix) { + this._terminal.postfix = postfix; + }; + Parser.prototype.setParam = function (param) { + this._terminal.currentParam = param; + }; + Parser.prototype.getParam = function () { + return this._terminal.currentParam; + }; + Parser.prototype.finalizeParam = function () { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; + }; + Parser.prototype.skipNextChar = function () { + this._position++; + }; + return Parser; +}()); +exports.Parser = Parser; + + + +},{"./Charsets":4,"./EscapeSequences":6}],11:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var MouseHelper_1 = require("./utils/MouseHelper"); +var Browser = require("./utils/Browser"); +var EventEmitter_1 = require("./EventEmitter"); +var SelectionModel_1 = require("./SelectionModel"); +var Buffer_1 = require("./Buffer"); +var DRAG_SCROLL_MAX_THRESHOLD = 50; +var DRAG_SCROLL_MAX_SPEED = 15; +var DRAG_SCROLL_INTERVAL = 50; +var WORD_SEPARATORS = ' ()[]{}\'"'; +var NON_BREAKING_SPACE_CHAR = String.fromCharCode(160); +var ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g'); +var SelectionMode; +(function (SelectionMode) { + SelectionMode[SelectionMode["NORMAL"] = 0] = "NORMAL"; + SelectionMode[SelectionMode["WORD"] = 1] = "WORD"; + SelectionMode[SelectionMode["LINE"] = 2] = "LINE"; +})(SelectionMode || (SelectionMode = {})); +var SelectionManager = (function (_super) { + __extends(SelectionManager, _super); + function SelectionManager(_terminal, _buffer, _charMeasure) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._buffer = _buffer; + _this._charMeasure = _charMeasure; + _this._enabled = true; + _this._initListeners(); + _this.enable(); + _this._model = new SelectionModel_1.SelectionModel(_terminal); + _this._activeSelectionMode = SelectionMode.NORMAL; + return _this; + } + SelectionManager.prototype._initListeners = function () { + var _this = this; + this._mouseMoveListener = function (event) { return _this._onMouseMove(event); }; + this._mouseUpListener = function (event) { return _this._onMouseUp(event); }; + this._buffer.lines.on('trim', function (amount) { return _this._onTrim(amount); }); + }; + SelectionManager.prototype.disable = function () { + this.clearSelection(); + this._enabled = false; + }; + SelectionManager.prototype.enable = function () { + this._enabled = true; + }; + SelectionManager.prototype.setBuffer = function (buffer) { + this._buffer = buffer; + this.clearSelection(); + }; + Object.defineProperty(SelectionManager.prototype, "selectionStart", { + get: function () { return this._model.finalSelectionStart; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "selectionEnd", { + get: function () { return this._model.finalSelectionEnd; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "hasSelection", { + get: function () { + var start = this._model.finalSelectionStart; + var end = this._model.finalSelectionEnd; + if (!start || !end) { + return false; + } + return start[0] !== end[0] || start[1] !== end[1]; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "selectionText", { + get: function () { + var start = this._model.finalSelectionStart; + var end = this._model.finalSelectionEnd; + if (!start || !end) { + return ''; + } + var startRowEndCol = start[1] === end[1] ? end[0] : null; + var result = []; + result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol)); + for (var i = start[1] + 1; i <= end[1] - 1; i++) { + var bufferLine = this._buffer.lines.get(i); + var lineText = this._buffer.translateBufferLineToString(i, true); + if (bufferLine.isWrapped) { + result[result.length - 1] += lineText; + } + else { + result.push(lineText); + } + } + if (start[1] !== end[1]) { + var bufferLine = this._buffer.lines.get(end[1]); + var lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]); + if (bufferLine.isWrapped) { + result[result.length - 1] += lineText; + } + else { + result.push(lineText); + } + } + var formattedResult = result.map(function (line) { + return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' '); + }).join(Browser.isMSWindows ? '\r\n' : '\n'); + return formattedResult; + }, + enumerable: true, + configurable: true + }); + SelectionManager.prototype.clearSelection = function () { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this.refresh(); + }; + SelectionManager.prototype.refresh = function (isNewSelection) { + var _this = this; + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(function () { return _this._refresh(); }); + } + if (Browser.isLinux && isNewSelection) { + var selectionText = this.selectionText; + if (selectionText.length) { + this.emit('newselection', this.selectionText); + } + } + }; + SelectionManager.prototype._refresh = function () { + this._refreshAnimationFrame = null; + this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd }); + }; + SelectionManager.prototype.selectAll = function () { + this._model.isSelectAllActive = true; + this.refresh(); + this._terminal.emit('selection'); + }; + SelectionManager.prototype._onTrim = function (amount) { + var needsRefresh = this._model.onTrim(amount); + if (needsRefresh) { + this.refresh(); + } + }; + SelectionManager.prototype._getMouseBufferCoords = function (event) { + var coords = this._terminal.mouseHelper.getCoords(event, this._terminal.element, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true); + if (!coords) { + return null; + } + coords[0]--; + coords[1]--; + coords[1] += this._terminal.buffer.ydisp; + return coords; + }; + SelectionManager.prototype._getMouseEventScrollAmount = function (event) { + var offset = MouseHelper_1.MouseHelper.getCoordsRelativeToElement(event, this._terminal.element)[1]; + var terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight); + if (offset >= 0 && offset <= terminalHeight) { + return 0; + } + if (offset > terminalHeight) { + offset -= terminalHeight; + } + offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD); + offset /= DRAG_SCROLL_MAX_THRESHOLD; + return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1)); + }; + SelectionManager.prototype.shouldForceSelection = function (event) { + return Browser.isMac ? event.altKey : event.shiftKey; + }; + SelectionManager.prototype.onMouseDown = function (event) { + if (event.button === 2 && this.hasSelection) { + return; + } + if (event.button !== 0) { + return; + } + if (!this._enabled) { + if (!this.shouldForceSelection(event)) { + return; + } + event.stopPropagation(); + } + event.preventDefault(); + this._dragScrollAmount = 0; + if (this._enabled && event.shiftKey) { + this._onIncrementalClick(event); + } + else { + if (event.detail === 1) { + this._onSingleClick(event); + } + else if (event.detail === 2) { + this._onDoubleClick(event); + } + else if (event.detail === 3) { + this._onTripleClick(event); + } + } + this._addMouseDownListeners(); + this.refresh(true); + }; + SelectionManager.prototype._addMouseDownListeners = function () { + var _this = this; + this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener); + this._dragScrollIntervalTimer = setInterval(function () { return _this._dragScroll(); }, DRAG_SCROLL_INTERVAL); + }; + SelectionManager.prototype._removeMouseDownListeners = function () { + this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener); + clearInterval(this._dragScrollIntervalTimer); + this._dragScrollIntervalTimer = null; + }; + SelectionManager.prototype._onIncrementalClick = function (event) { + if (this._model.selectionStart) { + this._model.selectionEnd = this._getMouseBufferCoords(event); + } + }; + SelectionManager.prototype._onSingleClick = function (event) { + this._model.selectionStartLength = 0; + this._model.isSelectAllActive = false; + this._activeSelectionMode = SelectionMode.NORMAL; + this._model.selectionStart = this._getMouseBufferCoords(event); + if (!this._model.selectionStart) { + return; + } + this._model.selectionEnd = null; + var line = this._buffer.lines.get(this._model.selectionStart[1]); + if (!line) { + return; + } + if (line.length >= this._model.selectionStart[0]) { + return; + } + var char = line[this._model.selectionStart[0]]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionStart[0]++; + } + }; + SelectionManager.prototype._onDoubleClick = function (event) { + var coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.WORD; + this._selectWordAt(coords); + } + }; + SelectionManager.prototype._onTripleClick = function (event) { + var coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.LINE; + this._selectLineAt(coords[1]); + } + }; + SelectionManager.prototype._onMouseMove = function (event) { + event.stopImmediatePropagation(); + var previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null; + this._model.selectionEnd = this._getMouseBufferCoords(event); + if (!this._model.selectionEnd) { + this.refresh(true); + return; + } + if (this._activeSelectionMode === SelectionMode.LINE) { + if (this._model.selectionEnd[1] < this._model.selectionStart[1]) { + this._model.selectionEnd[0] = 0; + } + else { + this._model.selectionEnd[0] = this._terminal.cols; + } + } + else if (this._activeSelectionMode === SelectionMode.WORD) { + this._selectToWordAt(this._model.selectionEnd); + } + this._dragScrollAmount = this._getMouseEventScrollAmount(event); + if (this._dragScrollAmount > 0) { + this._model.selectionEnd[0] = this._terminal.cols; + } + else if (this._dragScrollAmount < 0) { + this._model.selectionEnd[0] = 0; + } + if (this._model.selectionEnd[1] < this._buffer.lines.length) { + var char = this._buffer.lines.get(this._model.selectionEnd[1])[this._model.selectionEnd[0]]; + if (char && char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionEnd[0]++; + } + } + if (!previousSelectionEnd || + previousSelectionEnd[0] !== this._model.selectionEnd[0] || + previousSelectionEnd[1] !== this._model.selectionEnd[1]) { + this.refresh(true); + } + }; + SelectionManager.prototype._dragScroll = function () { + if (this._dragScrollAmount) { + this._terminal.scrollLines(this._dragScrollAmount, false); + if (this._dragScrollAmount > 0) { + this._model.selectionEnd = [this._terminal.cols - 1, Math.min(this._terminal.buffer.ydisp + this._terminal.rows, this._terminal.buffer.lines.length - 1)]; + } + else { + this._model.selectionEnd = [0, this._terminal.buffer.ydisp]; + } + this.refresh(); + } + }; + SelectionManager.prototype._onMouseUp = function (event) { + this._removeMouseDownListeners(); + if (this.hasSelection) + this._terminal.emit('selection'); + }; + SelectionManager.prototype._convertViewportColToCharacterIndex = function (bufferLine, coords) { + var charIndex = coords[0]; + for (var i = 0; coords[0] >= i; i++) { + var char = bufferLine[i]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + charIndex--; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1 && coords[0] !== i) { + charIndex += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + } + return charIndex; + }; + SelectionManager.prototype.setSelection = function (col, row, length) { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this._model.selectionStart = [col, row]; + this._model.selectionStartLength = length; + this.refresh(); + }; + SelectionManager.prototype._getWordAt = function (coords) { + var bufferLine = this._buffer.lines.get(coords[1]); + if (!bufferLine) { + return null; + } + var line = this._buffer.translateBufferLineToString(coords[1], false); + var startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords); + var endIndex = startIndex; + var charOffset = coords[0] - startIndex; + var leftWideCharCount = 0; + var rightWideCharCount = 0; + var leftLongCharOffset = 0; + var rightLongCharOffset = 0; + if (line.charAt(startIndex) === ' ') { + while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') { + startIndex--; + } + while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') { + endIndex++; + } + } + else { + var startCol = coords[0]; + var endCol = coords[0]; + if (bufferLine[startCol][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + leftWideCharCount++; + startCol--; + } + if (bufferLine[endCol][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + rightWideCharCount++; + endCol++; + } + if (bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + rightLongCharOffset += bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine[startCol - 1])) { + var char = bufferLine[startCol - 1]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + leftWideCharCount++; + startCol--; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + leftLongCharOffset += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + startIndex -= char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + startIndex--; + startCol--; + } + while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine[endCol + 1])) { + var char = bufferLine[endCol + 1]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + rightWideCharCount++; + endCol++; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + rightLongCharOffset += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + endIndex++; + endCol++; + } + } + endIndex++; + var start = startIndex + + charOffset + - leftWideCharCount + + leftLongCharOffset; + var length = Math.min(this._terminal.cols, endIndex + - startIndex + + leftWideCharCount + + rightWideCharCount + - leftLongCharOffset + - rightLongCharOffset); + return { start: start, length: length }; + }; + SelectionManager.prototype._selectWordAt = function (coords) { + var wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionStart = [wordPosition.start, coords[1]]; + this._model.selectionStartLength = wordPosition.length; + } + }; + SelectionManager.prototype._selectToWordAt = function (coords) { + var wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; + } + }; + SelectionManager.prototype._isCharWordSeparator = function (charData) { + if (charData[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + return false; + } + return WORD_SEPARATORS.indexOf(charData[Buffer_1.CHAR_DATA_CHAR_INDEX]) >= 0; + }; + SelectionManager.prototype._selectLineAt = function (line) { + this._model.selectionStart = [0, line]; + this._model.selectionStartLength = this._terminal.cols; + }; + return SelectionManager; +}(EventEmitter_1.EventEmitter)); +exports.SelectionManager = SelectionManager; + + + +},{"./Buffer":1,"./EventEmitter":7,"./SelectionModel":12,"./utils/Browser":28,"./utils/MouseHelper":32}],12:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var SelectionModel = (function () { + function SelectionModel(_terminal) { + this._terminal = _terminal; + this.clearSelection(); + } + SelectionModel.prototype.clearSelection = function () { + this.selectionStart = null; + this.selectionEnd = null; + this.isSelectAllActive = false; + this.selectionStartLength = 0; + }; + Object.defineProperty(SelectionModel.prototype, "finalSelectionStart", { + get: function () { + if (this.isSelectAllActive) { + return [0, 0]; + } + if (!this.selectionEnd || !this.selectionStart) { + return this.selectionStart; + } + return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionModel.prototype, "finalSelectionEnd", { + get: function () { + if (this.isSelectAllActive) { + return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1]; + } + if (!this.selectionStart) { + return null; + } + if (!this.selectionEnd || this.areSelectionValuesReversed()) { + return [this.selectionStart[0] + this.selectionStartLength, this.selectionStart[1]]; + } + if (this.selectionStartLength) { + if (this.selectionEnd[1] === this.selectionStart[1]) { + return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]]; + } + } + return this.selectionEnd; + }, + enumerable: true, + configurable: true + }); + SelectionModel.prototype.areSelectionValuesReversed = function () { + var start = this.selectionStart; + var end = this.selectionEnd; + if (!start || !end) { + return false; + } + return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]); + }; + SelectionModel.prototype.onTrim = function (amount) { + if (this.selectionStart) { + this.selectionStart[1] -= amount; + } + if (this.selectionEnd) { + this.selectionEnd[1] -= amount; + } + if (this.selectionEnd && this.selectionEnd[1] < 0) { + this.clearSelection(); + return true; + } + if (this.selectionStart && this.selectionStart[1] < 0) { + this.selectionStart[1] = 0; + } + return false; + }; + return SelectionModel; +}()); +exports.SelectionModel = SelectionModel; + + + +},{}],13:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BufferSet_1 = require("./BufferSet"); +var Buffer_1 = require("./Buffer"); +var CompositionHelper_1 = require("./CompositionHelper"); +var EventEmitter_1 = require("./EventEmitter"); +var Viewport_1 = require("./Viewport"); +var Clipboard_1 = require("./handlers/Clipboard"); +var EscapeSequences_1 = require("./EscapeSequences"); +var InputHandler_1 = require("./InputHandler"); +var Parser_1 = require("./Parser"); +var Renderer_1 = require("./renderer/Renderer"); +var Linkifier_1 = require("./Linkifier"); +var SelectionManager_1 = require("./SelectionManager"); +var CharMeasure_1 = require("./utils/CharMeasure"); +var Browser = require("./utils/Browser"); +var MouseHelper_1 = require("./utils/MouseHelper"); +var Sounds_1 = require("./utils/Sounds"); +var ColorManager_1 = require("./renderer/ColorManager"); +var MouseZoneManager_1 = require("./input/MouseZoneManager"); +var CharAtlas_1 = require("./renderer/CharAtlas"); +var document = (typeof window !== 'undefined') ? window.document : null; +var WRITE_BUFFER_PAUSE_THRESHOLD = 5; +var WRITE_BATCH_SIZE = 300; +var DEFAULT_OPTIONS = { + cols: 80, + rows: 24, + convertEol: false, + termName: 'xterm', + cursorBlink: false, + cursorStyle: 'block', + bellSound: Sounds_1.BellSound, + bellStyle: 'none', + enableBold: true, + fontFamily: 'courier-new, courier, monospace', + fontSize: 15, + lineHeight: 1.0, + letterSpacing: 0, + scrollback: 1000, + screenKeys: false, + debug: false, + cancelEvents: false, + disableStdin: false, + useFlowControl: false, + allowTransparency: false, + tabStopWidth: 8, + theme: null +}; +var Terminal = (function (_super) { + __extends(Terminal, _super); + function Terminal(options) { + if (options === void 0) { options = {}; } + var _this = _super.call(this) || this; + _this.browser = Browser; + _this.options = options; + _this.setup(); + return _this; + } + Terminal.prototype.setup = function () { + var _this = this; + Object.keys(DEFAULT_OPTIONS).forEach(function (key) { + if (_this.options[key] == null) { + _this.options[key] = DEFAULT_OPTIONS[key]; + } + _this[key] = _this.options[key]; + }); + this.parent = document ? document.body : null; + this.cols = this.options.cols; + this.rows = this.options.rows; + if (this.options.handler) { + this.on('data', this.options.handler); + } + this.cursorState = 0; + this.cursorHidden = false; + this.sendDataQueue = ''; + this.customKeyEventHandler = null; + this.applicationKeypad = false; + this.applicationCursor = false; + this.originMode = false; + this.insertMode = false; + this.wraparoundMode = true; + this.bracketedPasteMode = false; + this.charset = null; + this.gcharset = null; + this.glevel = 0; + this.charsets = [null]; + this.readable = true; + this.writable = true; + this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.curAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.params = []; + this.currentParam = 0; + this.prefix = ''; + this.postfix = ''; + this.writeBuffer = []; + this.writeInProgress = false; + this.xoffSentToCatchUp = false; + this.writeStopped = false; + this.surrogate_high = ''; + this.userScrolling = false; + this.inputHandler = new InputHandler_1.InputHandler(this); + this.parser = new Parser_1.Parser(this.inputHandler, this); + this.renderer = this.renderer || null; + this.selectionManager = this.selectionManager || null; + this.linkifier = this.linkifier || new Linkifier_1.Linkifier(this); + this._mouseZoneManager = this._mouseZoneManager || null; + this.buffers = new BufferSet_1.BufferSet(this); + this.buffer = this.buffers.active; + this.buffers.on('activate', function (buffer) { + _this.buffer = buffer; + }); + if (this.selectionManager) { + this.selectionManager.setBuffer(this.buffer); + } + }; + Terminal.prototype.eraseAttr = function () { + return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); + }; + Terminal.prototype.focus = function () { + if (this.textarea) { + this.textarea.focus(); + } + }; + Object.defineProperty(Terminal.prototype, "isFocused", { + get: function () { + return document.activeElement === this.textarea; + }, + enumerable: true, + configurable: true + }); + Terminal.prototype.getOption = function (key) { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + if (typeof this.options[key] !== 'undefined') { + return this.options[key]; + } + return this[key]; + }; + Terminal.prototype.setOption = function (key, value) { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + switch (key) { + case 'bellStyle': + if (!value) { + value = 'none'; + } + break; + case 'cursorStyle': + if (!value) { + value = 'block'; + } + break; + case 'lineHeight': + if (value < 1) { + console.warn(key + " cannot be less than 1, value: " + value); + return; + } + case 'tabStopWidth': + if (value < 1) { + console.warn(key + " cannot be less than 1, value: " + value); + return; + } + break; + case 'theme': + if (this.renderer) { + this._setTheme(value); + return; + } + break; + case 'scrollback': + value = Math.min(value, Buffer_1.MAX_BUFFER_SIZE); + if (value < 0) { + console.warn(key + " cannot be less than 0, value: " + value); + return; + } + if (this.options[key] !== value) { + var newBufferLength = this.rows + value; + if (this.buffer.lines.length > newBufferLength) { + var amountToTrim = this.buffer.lines.length - newBufferLength; + var needsRefresh = (this.buffer.ydisp - amountToTrim < 0); + this.buffer.lines.trimStart(amountToTrim); + this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0); + this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0); + if (needsRefresh) { + this.refresh(0, this.rows - 1); + } + } + } + break; + } + this[key] = value; + this.options[key] = value; + switch (key) { + case 'fontFamily': + case 'fontSize': + this.renderer.clear(); + this.charMeasure.measure(this.options); + break; + case 'enableBold': + case 'letterSpacing': + case 'lineHeight': + this.renderer.clear(); + this.renderer.onResize(this.cols, this.rows, false); + this.refresh(0, this.rows - 1); + case 'scrollback': + this.buffers.resize(this.cols, this.rows); + this.viewport.syncScrollArea(); + break; + case 'tabStopWidth': + this.buffers.setupTabStops(); + break; + case 'bellSound': + case 'bellStyle': + this.syncBellSound(); + break; + } + if (this.renderer) { + this.renderer.onOptionsChanged(); + } + }; + Terminal.prototype._onTextAreaFocus = function () { + if (this.sendFocus) { + this.send(EscapeSequences_1.C0.ESC + '[I'); + } + this.element.classList.add('focus'); + this.showCursor(); + this.emit('focus'); + }; + ; + Terminal.prototype.blur = function () { + return this.textarea.blur(); + }; + Terminal.prototype._onTextAreaBlur = function () { + this.refresh(this.buffer.y, this.buffer.y); + if (this.sendFocus) { + this.send(EscapeSequences_1.C0.ESC + '[O'); + } + this.element.classList.remove('focus'); + this.emit('blur'); + }; + Terminal.prototype.initGlobal = function () { + var _this = this; + this.bindKeys(); + on(this.element, 'copy', function (event) { + if (!_this.hasSelection()) { + return; + } + Clipboard_1.copyHandler(event, _this, _this.selectionManager); + }); + var pasteHandlerWrapper = function (event) { return Clipboard_1.pasteHandler(event, _this); }; + on(this.textarea, 'paste', pasteHandlerWrapper); + on(this.element, 'paste', pasteHandlerWrapper); + if (Browser.isFirefox) { + on(this.element, 'mousedown', function (event) { + if (event.button === 2) { + Clipboard_1.rightClickHandler(event, _this.textarea, _this.selectionManager); + } + }); + } + else { + on(this.element, 'contextmenu', function (event) { + Clipboard_1.rightClickHandler(event, _this.textarea, _this.selectionManager); + }); + } + if (Browser.isLinux) { + on(this.element, 'auxclick', function (event) { + if (event.button === 1) { + Clipboard_1.moveTextAreaUnderMouseCursor(event, _this.textarea); + } + }); + } + }; + Terminal.prototype.bindKeys = function () { + var _this = this; + var self = this; + on(this.element, 'keydown', function (ev) { + if (document.activeElement !== this) { + return; + } + self._keyDown(ev); + }, true); + on(this.element, 'keypress', function (ev) { + if (document.activeElement !== this) { + return; + } + self._keyPress(ev); + }, true); + on(this.element, 'keyup', function (ev) { + if (!wasMondifierKeyOnlyEvent(ev)) { + _this.focus(); + } + }, true); + on(this.textarea, 'keydown', function (ev) { + _this._keyDown(ev); + }, true); + on(this.textarea, 'keypress', function (ev) { + _this._keyPress(ev); + _this.textarea.value = ''; + }, true); + on(this.textarea, 'compositionstart', function () { return _this.compositionHelper.compositionstart(); }); + on(this.textarea, 'compositionupdate', function (e) { return _this.compositionHelper.compositionupdate(e); }); + on(this.textarea, 'compositionend', function () { return _this.compositionHelper.compositionend(); }); + this.on('refresh', function () { return _this.compositionHelper.updateCompositionElements(); }); + this.on('refresh', function (data) { return _this.queueLinkification(data.start, data.end); }); + }; + Terminal.prototype.open = function (parent) { + var _this = this; + var i = 0; + var div; + this.parent = parent || this.parent; + if (!this.parent) { + throw new Error('Terminal requires a parent element.'); + } + this.context = this.parent.ownerDocument.defaultView; + this.document = this.parent.ownerDocument; + this.body = this.document.body; + CharAtlas_1.initialize(this.document, this.options.allowTransparency); + this.element = this.document.createElement('div'); + this.element.classList.add('terminal'); + this.element.classList.add('xterm'); + this.element.setAttribute('tabindex', '0'); + this.parent.appendChild(this.element); + var fragment = document.createDocumentFragment(); + this.viewportElement = document.createElement('div'); + this.viewportElement.classList.add('xterm-viewport'); + fragment.appendChild(this.viewportElement); + this.viewportScrollArea = document.createElement('div'); + this.viewportScrollArea.classList.add('xterm-scroll-area'); + this.viewportElement.appendChild(this.viewportScrollArea); + this._mouseZoneManager = new MouseZoneManager_1.MouseZoneManager(this); + this.on('scroll', function () { return _this._mouseZoneManager.clearAll(); }); + this.linkifier.attachToDom(this._mouseZoneManager); + this.helperContainer = document.createElement('div'); + this.helperContainer.classList.add('xterm-helpers'); + fragment.appendChild(this.helperContainer); + this.textarea = document.createElement('textarea'); + this.textarea.classList.add('xterm-helper-textarea'); + this.textarea.setAttribute('autocorrect', 'off'); + this.textarea.setAttribute('autocapitalize', 'off'); + this.textarea.setAttribute('spellcheck', 'false'); + this.textarea.tabIndex = 0; + this.textarea.addEventListener('focus', function () { return _this._onTextAreaFocus(); }); + this.textarea.addEventListener('blur', function () { return _this._onTextAreaBlur(); }); + this.helperContainer.appendChild(this.textarea); + this.compositionView = document.createElement('div'); + this.compositionView.classList.add('composition-view'); + this.compositionHelper = new CompositionHelper_1.CompositionHelper(this.textarea, this.compositionView, this); + this.helperContainer.appendChild(this.compositionView); + this.charSizeStyleElement = document.createElement('style'); + this.helperContainer.appendChild(this.charSizeStyleElement); + this.charMeasure = new CharMeasure_1.CharMeasure(document, this.helperContainer); + this.syncBellSound(); + this.element.appendChild(fragment); + this.renderer = new Renderer_1.Renderer(this, this.options.theme); + this.options.theme = null; + this.viewport = new Viewport_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); + this.viewport.onThemeChanged(this.renderer.colorManager.colors); + this.on('cursormove', function () { return _this.renderer.onCursorMove(); }); + this.on('resize', function () { return _this.renderer.onResize(_this.cols, _this.rows, false); }); + this.on('blur', function () { return _this.renderer.onBlur(); }); + this.on('focus', function () { return _this.renderer.onFocus(); }); + this.charMeasure.on('charsizechanged', function () { return _this.renderer.onResize(_this.cols, _this.rows, true); }); + this.renderer.on('resize', function (dimensions) { return _this.viewport.syncScrollArea(); }); + this.selectionManager = new SelectionManager_1.SelectionManager(this, this.buffer, this.charMeasure); + this.element.addEventListener('mousedown', function (e) { return _this.selectionManager.onMouseDown(e); }); + this.selectionManager.on('refresh', function (data) { return _this.renderer.onSelectionChanged(data.start, data.end); }); + this.selectionManager.on('newselection', function (text) { + _this.textarea.value = text; + _this.textarea.focus(); + _this.textarea.select(); + }); + this.on('scroll', function () { + _this.viewport.syncScrollArea(); + _this.selectionManager.refresh(); + }); + this.viewportElement.addEventListener('scroll', function () { return _this.selectionManager.refresh(); }); + this.mouseHelper = new MouseHelper_1.MouseHelper(this.renderer); + this.charMeasure.measure(this.options); + this.refresh(0, this.rows - 1); + this.initGlobal(); + this.bindMouse(); + }; + Terminal.prototype._setTheme = function (theme) { + var colors = this.renderer.setTheme(theme); + if (this.viewport) { + this.viewport.onThemeChanged(colors); + } + }; + Terminal.applyAddon = function (addon) { + addon.apply(Terminal); + }; + Terminal.prototype.bindMouse = function () { + var _this = this; + var el = this.element; + var self = this; + var pressed = 32; + function sendButton(ev) { + var button; + var pos; + button = getButton(ev); + pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) + return; + sendEvent(button, pos); + switch (ev.overrideType || ev.type) { + case 'mousedown': + pressed = button; + break; + case 'mouseup': + pressed = 32; + break; + case 'wheel': + break; + } + } + function sendMove(ev) { + var button = pressed; + var pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) + return; + button += 32; + sendEvent(button, pos); + } + function encode(data, ch) { + if (!self.utfMouse) { + if (ch === 255) { + data.push(0); + return; + } + if (ch > 127) + ch = 127; + data.push(ch); + } + else { + if (ch === 2047) { + data.push(0); + return; + } + if (ch < 127) { + data.push(ch); + } + else { + if (ch > 2047) + ch = 2047; + data.push(0xC0 | (ch >> 6)); + data.push(0x80 | (ch & 0x3F)); + } + } + } + function sendEvent(button, pos) { + if (self.vt300Mouse) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + var data_1 = EscapeSequences_1.C0.ESC + '[24'; + if (button === 0) + data_1 += '1'; + else if (button === 1) + data_1 += '3'; + else if (button === 2) + data_1 += '5'; + else if (button === 3) + return; + else + data_1 += '0'; + data_1 += '~[' + pos.x + ',' + pos.y + ']\r'; + self.send(data_1); + return; + } + if (self.decLocator) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + if (button === 0) + button = 2; + else if (button === 1) + button = 4; + else if (button === 2) + button = 6; + else if (button === 3) + button = 3; + self.send(EscapeSequences_1.C0.ESC + '[' + + button + + ';' + + (button === 3 ? 4 : 0) + + ';' + + pos.y + + ';' + + pos.x + + ';' + + pos.page || 0 + + '&w'); + return; + } + if (self.urxvtMouse) { + pos.x -= 32; + pos.y -= 32; + pos.x++; + pos.y++; + self.send(EscapeSequences_1.C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M'); + return; + } + if (self.sgrMouse) { + pos.x -= 32; + pos.y -= 32; + self.send(EscapeSequences_1.C0.ESC + '[<' + + (((button & 3) === 3 ? button & ~3 : button) - 32) + + ';' + + pos.x + + ';' + + pos.y + + ((button & 3) === 3 ? 'm' : 'M')); + return; + } + var data = []; + encode(data, button); + encode(data, pos.x); + encode(data, pos.y); + self.send(EscapeSequences_1.C0.ESC + '[M' + String.fromCharCode.apply(String, data)); + } + function getButton(ev) { + var button; + var shift; + var meta; + var ctrl; + var mod; + switch (ev.overrideType || ev.type) { + case 'mousedown': + button = ev.button != null + ? +ev.button + : ev.which != null + ? ev.which - 1 + : null; + if (Browser.isMSIE) { + button = button === 1 ? 0 : button === 4 ? 1 : button; + } + break; + case 'mouseup': + button = 3; + break; + case 'DOMMouseScroll': + button = ev.detail < 0 + ? 64 + : 65; + break; + case 'wheel': + button = ev.wheelDeltaY > 0 + ? 64 + : 65; + break; + } + shift = ev.shiftKey ? 4 : 0; + meta = ev.metaKey ? 8 : 0; + ctrl = ev.ctrlKey ? 16 : 0; + mod = shift | meta | ctrl; + if (self.vt200Mouse) { + mod &= ctrl; + } + else if (!self.normalMouse) { + mod = 0; + } + button = (32 + (mod << 2)) + button; + return button; + } + on(el, 'mousedown', function (ev) { + ev.preventDefault(); + _this.focus(); + if (!_this.mouseEvents || _this.selectionManager.shouldForceSelection(ev)) { + return; + } + sendButton(ev); + if (_this.vt200Mouse) { + ev.overrideType = 'mouseup'; + sendButton(ev); + return _this.cancel(ev); + } + if (_this.normalMouse) + on(_this.document, 'mousemove', sendMove); + if (!_this.x10Mouse) { + var handler_1 = function (ev) { + sendButton(ev); + if (_this.normalMouse) + off(_this.document, 'mousemove', sendMove); + off(_this.document, 'mouseup', handler_1); + return _this.cancel(ev); + }; + on(_this.document, 'mouseup', handler_1); + } + return _this.cancel(ev); + }); + on(el, 'wheel', function (ev) { + if (!_this.mouseEvents) + return; + if (_this.x10Mouse || _this.vt300Mouse || _this.decLocator) + return; + sendButton(ev); + ev.preventDefault(); + }); + on(el, 'wheel', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onWheel(ev); + return _this.cancel(ev); + }); + on(el, 'touchstart', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onTouchStart(ev); + return _this.cancel(ev); + }); + on(el, 'touchmove', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onTouchMove(ev); + return _this.cancel(ev); + }); + }; + Terminal.prototype.destroy = function () { + _super.prototype.destroy.call(this); + this.readable = false; + this.writable = false; + this.handler = function () { }; + this.write = function () { }; + if (this.element && this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } + }; + Terminal.prototype.refresh = function (start, end) { + if (this.renderer) { + this.renderer.queueRefresh(start, end); + } + }; + Terminal.prototype.queueLinkification = function (start, end) { + if (this.linkifier) { + this.linkifier.linkifyRows(start, end); + } + }; + Terminal.prototype.showCursor = function () { + if (!this.cursorState) { + this.cursorState = 1; + this.refresh(this.buffer.y, this.buffer.y); + } + }; + Terminal.prototype.scroll = function (isWrapped) { + var newLine = this.blankLine(undefined, isWrapped); + var topRow = this.buffer.ybase + this.buffer.scrollTop; + var bottomRow = this.buffer.ybase + this.buffer.scrollBottom; + if (this.buffer.scrollTop === 0) { + var willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength; + if (bottomRow === this.buffer.lines.length - 1) { + this.buffer.lines.push(newLine); + } + else { + this.buffer.lines.splice(bottomRow + 1, 0, newLine); + } + if (!willBufferBeTrimmed) { + this.buffer.ybase++; + if (!this.userScrolling) { + this.buffer.ydisp++; + } + } + else { + if (this.userScrolling) { + this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0); + } + } + } + else { + var scrollRegionHeight = bottomRow - topRow + 1; + this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1); + this.buffer.lines.set(bottomRow, newLine); + } + if (!this.userScrolling) { + this.buffer.ydisp = this.buffer.ybase; + } + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + this.emit('scroll', this.buffer.ydisp); + }; + Terminal.prototype.scrollLines = function (disp, suppressScrollEvent) { + if (disp < 0) { + if (this.buffer.ydisp === 0) { + return; + } + this.userScrolling = true; + } + else if (disp + this.buffer.ydisp >= this.buffer.ybase) { + this.userScrolling = false; + } + var oldYdisp = this.buffer.ydisp; + this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0); + if (oldYdisp === this.buffer.ydisp) { + return; + } + if (!suppressScrollEvent) { + this.emit('scroll', this.buffer.ydisp); + } + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.scrollPages = function (pageCount) { + this.scrollLines(pageCount * (this.rows - 1)); + }; + Terminal.prototype.scrollToTop = function () { + this.scrollLines(-this.buffer.ydisp); + }; + Terminal.prototype.scrollToBottom = function () { + this.scrollLines(this.buffer.ybase - this.buffer.ydisp); + }; + Terminal.prototype.write = function (data) { + var _this = this; + this.writeBuffer.push(data); + if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { + this.send(EscapeSequences_1.C0.DC3); + this.xoffSentToCatchUp = true; + } + if (!this.writeInProgress && this.writeBuffer.length > 0) { + this.writeInProgress = true; + setTimeout(function () { + _this.innerWrite(); + }); + } + }; + Terminal.prototype.innerWrite = function () { + var _this = this; + var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); + while (writeBatch.length > 0) { + var data = writeBatch.shift(); + if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) { + this.send(EscapeSequences_1.C0.DC1); + this.xoffSentToCatchUp = false; + } + this.refreshStart = this.buffer.y; + this.refreshEnd = this.buffer.y; + var state = this.parser.parse(data); + this.parser.setState(state); + this.updateRange(this.buffer.y); + this.refresh(this.refreshStart, this.refreshEnd); + } + if (this.writeBuffer.length > 0) { + setTimeout(function () { return _this.innerWrite(); }, 0); + } + else { + this.writeInProgress = false; + } + }; + Terminal.prototype.writeln = function (data) { + this.write(data + '\r\n'); + }; + Terminal.prototype.attachCustomKeyEventHandler = function (customKeyEventHandler) { + this.customKeyEventHandler = customKeyEventHandler; + }; + Terminal.prototype.setHypertextLinkHandler = function (handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); + } + this.linkifier.setHypertextLinkHandler(handler); + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.setHypertextValidationCallback = function (callback) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); + } + this.linkifier.setHypertextValidationCallback(callback); + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.registerLinkMatcher = function (regex, handler, options) { + if (this.linkifier) { + var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); + this.refresh(0, this.rows - 1); + return matcherId; + } + return 0; + }; + Terminal.prototype.deregisterLinkMatcher = function (matcherId) { + if (this.linkifier) { + if (this.linkifier.deregisterLinkMatcher(matcherId)) { + this.refresh(0, this.rows - 1); + } + } + }; + Terminal.prototype.hasSelection = function () { + return this.selectionManager ? this.selectionManager.hasSelection : false; + }; + Terminal.prototype.getSelection = function () { + return this.selectionManager ? this.selectionManager.selectionText : ''; + }; + Terminal.prototype.clearSelection = function () { + if (this.selectionManager) { + this.selectionManager.clearSelection(); + } + }; + Terminal.prototype.selectAll = function () { + if (this.selectionManager) { + this.selectionManager.selectAll(); + } + }; + Terminal.prototype._keyDown = function (ev) { + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + if (!this.compositionHelper.keydown(ev)) { + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + return false; + } + var result = this._evaluateKeyEscapeSequence(ev); + if (result.key === EscapeSequences_1.C0.DC3) { + this.writeStopped = true; + } + else if (result.key === EscapeSequences_1.C0.DC1) { + this.writeStopped = false; + } + if (result.scrollLines) { + this.scrollLines(result.scrollLines); + return this.cancel(ev, true); + } + if (isThirdLevelShift(this.browser, ev)) { + return true; + } + if (result.cancel) { + this.cancel(ev, true); + } + if (!result.key) { + return true; + } + this.emit('keydown', ev); + this.emit('key', result.key, ev); + this.showCursor(); + this.handler(result.key); + return this.cancel(ev, true); + }; + Terminal.prototype._evaluateKeyEscapeSequence = function (ev) { + var result = { + cancel: false, + key: undefined, + scrollLines: undefined + }; + var modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0); + switch (ev.keyCode) { + case 0: + if (ev.key === 'UIKeyInputUpArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OA'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[A'; + } + } + else if (ev.key === 'UIKeyInputLeftArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OD'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[D'; + } + } + else if (ev.key === 'UIKeyInputRightArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OC'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[C'; + } + } + else if (ev.key === 'UIKeyInputDownArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OB'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[B'; + } + } + break; + case 8: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.BS; + break; + } + else if (ev.altKey) { + result.key = EscapeSequences_1.C0.ESC + EscapeSequences_1.C0.DEL; + break; + } + result.key = EscapeSequences_1.C0.DEL; + break; + case 9: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.ESC + '[Z'; + break; + } + result.key = EscapeSequences_1.C0.HT; + result.cancel = true; + break; + case 13: + result.key = EscapeSequences_1.C0.CR; + result.cancel = true; + break; + case 27: + result.key = EscapeSequences_1.C0.ESC; + result.cancel = true; + break; + case 37: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'D'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3D') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'b' : EscapeSequences_1.C0.ESC + '[1;5D'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OD'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[D'; + } + break; + case 39: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'C'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3C') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'f' : EscapeSequences_1.C0.ESC + '[1;5C'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OC'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[C'; + } + break; + case 38: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'A'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3A') { + result.key = EscapeSequences_1.C0.ESC + '[1;5A'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OA'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[A'; + } + break; + case 40: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'B'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3B') { + result.key = EscapeSequences_1.C0.ESC + '[1;5B'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OB'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[B'; + } + break; + case 45: + if (!ev.shiftKey && !ev.ctrlKey) { + result.key = EscapeSequences_1.C0.ESC + '[2~'; + } + break; + case 46: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[3;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[3~'; + } + break; + case 36: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'H'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OH'; + else + result.key = EscapeSequences_1.C0.ESC + '[H'; + break; + case 35: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'F'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OF'; + else + result.key = EscapeSequences_1.C0.ESC + '[F'; + break; + case 33: + if (ev.shiftKey) { + result.scrollLines = -(this.rows - 1); + } + else { + result.key = EscapeSequences_1.C0.ESC + '[5~'; + } + break; + case 34: + if (ev.shiftKey) { + result.scrollLines = this.rows - 1; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[6~'; + } + break; + case 112: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'P'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OP'; + } + break; + case 113: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'Q'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OQ'; + } + break; + case 114: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'R'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OR'; + } + break; + case 115: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'S'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OS'; + } + break; + case 116: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[15;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[15~'; + } + break; + case 117: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[17;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[17~'; + } + break; + case 118: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[18;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[18~'; + } + break; + case 119: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[19;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[19~'; + } + break; + case 120: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[20;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[20~'; + } + break; + case 121: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[21;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[21~'; + } + break; + case 122: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[23;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[23~'; + } + break; + case 123: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[24;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[24~'; + } + break; + default: + if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = String.fromCharCode(ev.keyCode - 64); + } + else if (ev.keyCode === 32) { + result.key = String.fromCharCode(0); + } + else if (ev.keyCode >= 51 && ev.keyCode <= 55) { + result.key = String.fromCharCode(ev.keyCode - 51 + 27); + } + else if (ev.keyCode === 56) { + result.key = String.fromCharCode(127); + } + else if (ev.keyCode === 219) { + result.key = String.fromCharCode(27); + } + else if (ev.keyCode === 220) { + result.key = String.fromCharCode(28); + } + else if (ev.keyCode === 221) { + result.key = String.fromCharCode(29); + } + } + else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = EscapeSequences_1.C0.ESC + String.fromCharCode(ev.keyCode + 32); + } + else if (ev.keyCode === 192) { + result.key = EscapeSequences_1.C0.ESC + '`'; + } + else if (ev.keyCode >= 48 && ev.keyCode <= 57) { + result.key = EscapeSequences_1.C0.ESC + (ev.keyCode - 48); + } + } + else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { + if (ev.keyCode === 65) { + this.selectAll(); + } + } + break; + } + return result; + }; + Terminal.prototype.setgLevel = function (g) { + this.glevel = g; + this.charset = this.charsets[g]; + }; + Terminal.prototype.setgCharset = function (g, charset) { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } + }; + Terminal.prototype._keyPress = function (ev) { + var key; + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + this.cancel(ev); + if (ev.charCode) { + key = ev.charCode; + } + else if (ev.which == null) { + key = ev.keyCode; + } + else if (ev.which !== 0 && ev.charCode !== 0) { + key = ev.which; + } + else { + return false; + } + if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this.browser, ev))) { + return false; + } + key = String.fromCharCode(key); + this.emit('keypress', key, ev); + this.emit('key', key, ev); + this.showCursor(); + this.handler(key); + return true; + }; + Terminal.prototype.send = function (data) { + var _this = this; + if (!this.sendDataQueue) { + setTimeout(function () { + _this.handler(_this.sendDataQueue); + _this.sendDataQueue = ''; + }, 1); + } + this.sendDataQueue += data; + }; + Terminal.prototype.bell = function () { + var _this = this; + this.emit('bell'); + if (this.soundBell()) + this.bellAudioElement.play(); + if (this.visualBell()) { + this.element.classList.add('visual-bell-active'); + clearTimeout(this.visualBellTimer); + this.visualBellTimer = window.setTimeout(function () { + _this.element.classList.remove('visual-bell-active'); + }, 200); + } + }; + Terminal.prototype.log = function (text, data) { + if (!this.options.debug) + return; + if (!this.context.console || !this.context.console.log) + return; + this.context.console.log(text, data); + }; + Terminal.prototype.error = function (text, data) { + if (!this.options.debug) + return; + if (!this.context.console || !this.context.console.error) + return; + this.context.console.error(text, data); + }; + Terminal.prototype.resize = function (x, y) { + if (isNaN(x) || isNaN(y)) { + return; + } + if (x === this.cols && y === this.rows) { + if (!this.charMeasure.width || !this.charMeasure.height) { + this.charMeasure.measure(this.options); + } + return; + } + if (x < 1) + x = 1; + if (y < 1) + y = 1; + this.buffers.resize(x, y); + this.cols = x; + this.rows = y; + this.buffers.setupTabStops(this.cols); + this.charMeasure.measure(this.options); + this.refresh(0, this.rows - 1); + this.emit('resize', { cols: x, rows: y }); + }; + Terminal.prototype.updateRange = function (y) { + if (y < this.refreshStart) + this.refreshStart = y; + if (y > this.refreshEnd) + this.refreshEnd = y; + }; + Terminal.prototype.maxRange = function () { + this.refreshStart = 0; + this.refreshEnd = this.rows - 1; + }; + Terminal.prototype.eraseRight = function (x, y) { + var line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1, 32]; + for (; x < this.cols; x++) { + line[x] = ch; + } + this.updateRange(y); + }; + Terminal.prototype.eraseLeft = function (x, y) { + var line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1, 32]; + x++; + while (x--) { + line[x] = ch; + } + this.updateRange(y); + }; + Terminal.prototype.clear = function () { + if (this.buffer.ybase === 0 && this.buffer.y === 0) { + return; + } + this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)); + this.buffer.lines.length = 1; + this.buffer.ydisp = 0; + this.buffer.ybase = 0; + this.buffer.y = 0; + for (var i = 1; i < this.rows; i++) { + this.buffer.lines.push(this.blankLine()); + } + this.refresh(0, this.rows - 1); + this.emit('scroll', this.buffer.ydisp); + }; + Terminal.prototype.eraseLine = function (y) { + this.eraseRight(0, y); + }; + Terminal.prototype.blankLine = function (cur, isWrapped, cols) { + var attr = cur ? this.eraseAttr() : this.defAttr; + var ch = [attr, ' ', 1, 32]; + var line = []; + if (isWrapped) { + line.isWrapped = isWrapped; + } + cols = cols || this.cols; + for (var i = 0; i < cols; i++) { + line[i] = ch; + } + return line; + }; + Terminal.prototype.ch = function (cur) { + if (cur) { + return [this.eraseAttr(), ' ', 1, 32]; + } + return [this.defAttr, ' ', 1, 32]; + }; + Terminal.prototype.is = function (term) { + return (this.options.termName + '').indexOf(term) === 0; + }; + Terminal.prototype.handler = function (data) { + if (this.options.disableStdin) { + return; + } + if (this.selectionManager && this.selectionManager.hasSelection) { + this.selectionManager.clearSelection(); + } + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + this.emit('data', data); + }; + Terminal.prototype.handleTitle = function (title) { + this.emit('title', title); + }; + Terminal.prototype.index = function () { + this.buffer.y++; + if (this.buffer.y > this.buffer.scrollBottom) { + this.buffer.y--; + this.scroll(); + } + if (this.buffer.x >= this.cols) { + this.buffer.x--; + } + }; + Terminal.prototype.reverseIndex = function () { + if (this.buffer.y === this.buffer.scrollTop) { + var scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop; + this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1); + this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true)); + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + } + else { + this.buffer.y--; + } + }; + Terminal.prototype.reset = function () { + this.options.rows = this.rows; + this.options.cols = this.cols; + var customKeyEventHandler = this.customKeyEventHandler; + var inputHandler = this.inputHandler; + var buffers = this.buffers; + this.setup(); + this.customKeyEventHandler = customKeyEventHandler; + this.inputHandler = inputHandler; + this.buffers = buffers; + this.refresh(0, this.rows - 1); + this.viewport.syncScrollArea(); + }; + Terminal.prototype.tabSet = function () { + this.buffer.tabs[this.buffer.x] = true; + }; + Terminal.prototype.cancel = function (ev, force) { + if (!this.options.cancelEvents && !force) { + return; + } + ev.preventDefault(); + ev.stopPropagation(); + return false; + }; + Terminal.prototype.matchColor = function (r1, g1, b1) { + return matchColor_(r1, g1, b1); + }; + Terminal.prototype.visualBell = function () { + return this.options.bellStyle === 'visual' || + this.options.bellStyle === 'both'; + }; + Terminal.prototype.soundBell = function () { + return this.options.bellStyle === 'sound' || + this.options.bellStyle === 'both'; + }; + Terminal.prototype.syncBellSound = function () { + if (!this.element) { + return; + } + if (this.soundBell() && this.bellAudioElement) { + this.bellAudioElement.setAttribute('src', this.options.bellSound); + } + else if (this.soundBell()) { + this.bellAudioElement = document.createElement('audio'); + this.bellAudioElement.setAttribute('preload', 'auto'); + this.bellAudioElement.setAttribute('src', this.options.bellSound); + this.helperContainer.appendChild(this.bellAudioElement); + } + else if (this.bellAudioElement) { + this.helperContainer.removeChild(this.bellAudioElement); + } + }; + return Terminal; +}(EventEmitter_1.EventEmitter)); +exports.Terminal = Terminal; +function globalOn(el, type, handler, capture) { + if (!Array.isArray(el)) { + el = [el]; + } + el.forEach(function (element) { + element.addEventListener(type, handler, capture || false); + }); +} +var on = globalOn; +function off(el, type, handler, capture) { + if (capture === void 0) { capture = false; } + el.removeEventListener(type, handler, capture); +} +function isThirdLevelShift(browser, ev) { + var thirdLevelKey = (browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + if (ev.type === 'keypress') { + return thirdLevelKey; + } + return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); +} +function wasMondifierKeyOnlyEvent(ev) { + return ev.keyCode === 16 || + ev.keyCode === 17 || + ev.keyCode === 18; +} +var vcolors = (function () { + var result = ColorManager_1.DEFAULT_ANSI_COLORS.map(function (c) { + c = c.substring(1); + return [ + parseInt(c.substring(0, 2), 16), + parseInt(c.substring(2, 4), 16), + parseInt(c.substring(4, 6), 16) + ]; + }); + var r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (var i = 0; i < 216; i++) { + result.push([ + r[(i / 36) % 6 | 0], + r[(i / 6) % 6 | 0], + r[i % 6] + ]); + } + var c; + for (var i = 0; i < 24; i++) { + c = 8 + i * 10; + result.push([c, c, c]); + } + return result; +})(); +var matchColorCache = {}; +function matchColorDistance(r1, g1, b1, r2, g2, b2) { + return Math.pow(30 * (r1 - r2), 2) + + Math.pow(59 * (g1 - g2), 2) + + Math.pow(11 * (b1 - b2), 2); +} +; +function matchColor_(r1, g1, b1) { + var hash = (r1 << 16) | (g1 << 8) | b1; + if (matchColorCache[hash] != null) { + return matchColorCache[hash]; + } + var ldiff = Infinity; + var li = -1; + var i = 0; + var c; + var r2; + var g2; + var b2; + var diff; + for (; i < vcolors.length; i++) { + c = vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + diff = matchColorDistance(r1, g1, b1, r2, g2, b2); + if (diff === 0) { + li = i; + break; + } + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + return matchColorCache[hash] = li; +} + + + +},{"./Buffer":1,"./BufferSet":2,"./CompositionHelper":5,"./EscapeSequences":6,"./EventEmitter":7,"./InputHandler":8,"./Linkifier":9,"./Parser":10,"./SelectionManager":11,"./Viewport":15,"./handlers/Clipboard":16,"./input/MouseZoneManager":17,"./renderer/CharAtlas":19,"./renderer/ColorManager":20,"./renderer/Renderer":24,"./utils/Browser":28,"./utils/CharMeasure":29,"./utils/MouseHelper":32,"./utils/Sounds":34}],14:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LinkHoverEventTypes; +(function (LinkHoverEventTypes) { + LinkHoverEventTypes["HOVER"] = "linkhover"; + LinkHoverEventTypes["TOOLTIP"] = "linktooltip"; + LinkHoverEventTypes["LEAVE"] = "linkleave"; +})(LinkHoverEventTypes = exports.LinkHoverEventTypes || (exports.LinkHoverEventTypes = {})); +; + + + +},{}],15:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Viewport = (function () { + function Viewport(terminal, viewportElement, scrollArea, charMeasure) { + var _this = this; + this.terminal = terminal; + this.viewportElement = viewportElement; + this.scrollArea = scrollArea; + this.charMeasure = charMeasure; + this.currentRowHeight = 0; + this.lastRecordedBufferLength = 0; + this.lastRecordedViewportHeight = 0; + this.lastRecordedBufferHeight = 0; + this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); + setTimeout(function () { return _this.syncScrollArea(); }, 0); + } + Viewport.prototype.onThemeChanged = function (colors) { + this.viewportElement.style.backgroundColor = colors.background; + }; + Viewport.prototype.refresh = function () { + if (this.charMeasure.height > 0) { + this.currentRowHeight = this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio; + if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { + this.lastRecordedViewportHeight = this.terminal.renderer.dimensions.canvasHeight; + this.viewportElement.style.height = this.lastRecordedViewportHeight + 'px'; + } + var newBufferHeight = Math.round(this.currentRowHeight * this.lastRecordedBufferLength); + if (this.lastRecordedBufferHeight !== newBufferHeight) { + this.lastRecordedBufferHeight = newBufferHeight; + this.scrollArea.style.height = this.lastRecordedBufferHeight + 'px'; + } + } + }; + Viewport.prototype.syncScrollArea = function () { + if (this.lastRecordedBufferLength !== this.terminal.buffer.lines.length) { + this.lastRecordedBufferLength = this.terminal.buffer.lines.length; + this.refresh(); + } + else if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { + this.refresh(); + } + else { + if (this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this.currentRowHeight) { + this.refresh(); + } + } + var scrollTop = this.terminal.buffer.ydisp * this.currentRowHeight; + if (this.viewportElement.scrollTop !== scrollTop) { + this.viewportElement.scrollTop = scrollTop; + } + }; + Viewport.prototype.onScroll = function (ev) { + var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + var diff = newRow - this.terminal.buffer.ydisp; + this.terminal.scrollLines(diff, true); + }; + Viewport.prototype.onWheel = function (ev) { + if (ev.deltaY === 0) { + return; + } + var multiplier = 1; + if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { + multiplier = this.currentRowHeight; + } + else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + multiplier = this.currentRowHeight * this.terminal.rows; + } + this.viewportElement.scrollTop += ev.deltaY * multiplier; + ev.preventDefault(); + }; + ; + Viewport.prototype.onTouchStart = function (ev) { + this.lastTouchY = ev.touches[0].pageY; + }; + ; + Viewport.prototype.onTouchMove = function (ev) { + var deltaY = this.lastTouchY - ev.touches[0].pageY; + this.lastTouchY = ev.touches[0].pageY; + if (deltaY === 0) { + return; + } + this.viewportElement.scrollTop += deltaY; + ev.preventDefault(); + }; + ; + return Viewport; +}()); +exports.Viewport = Viewport; + + + +},{}],16:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function prepareTextForTerminal(text, isMSWindows) { + if (isMSWindows) { + return text.replace(/\r?\n/g, '\r'); + } + return text; +} +exports.prepareTextForTerminal = prepareTextForTerminal; +function bracketTextForPaste(text, bracketedPasteMode) { + if (bracketedPasteMode) { + return '\x1b[200~' + text + '\x1b[201~'; + } + return text; +} +exports.bracketTextForPaste = bracketTextForPaste; +function copyHandler(ev, term, selectionManager) { + if (term.browser.isMSIE) { + window.clipboardData.setData('Text', selectionManager.selectionText); + } + else { + ev.clipboardData.setData('text/plain', selectionManager.selectionText); + } + ev.preventDefault(); +} +exports.copyHandler = copyHandler; +function pasteHandler(ev, term) { + ev.stopPropagation(); + var text; + var dispatchPaste = function (text) { + text = prepareTextForTerminal(text, term.browser.isMSWindows); + text = bracketTextForPaste(text, term.bracketedPasteMode); + term.handler(text); + term.textarea.value = ''; + term.emit('paste', text); + term.cancel(ev); + }; + if (term.browser.isMSIE) { + if (window.clipboardData) { + text = window.clipboardData.getData('Text'); + dispatchPaste(text); + } + } + else { + if (ev.clipboardData) { + text = ev.clipboardData.getData('text/plain'); + dispatchPaste(text); + } + } +} +exports.pasteHandler = pasteHandler; +function moveTextAreaUnderMouseCursor(ev, textarea) { + textarea.style.position = 'fixed'; + textarea.style.width = '20px'; + textarea.style.height = '20px'; + textarea.style.left = (ev.clientX - 10) + 'px'; + textarea.style.top = (ev.clientY - 10) + 'px'; + textarea.style.zIndex = '1000'; + textarea.focus(); + setTimeout(function () { + textarea.style.position = null; + textarea.style.width = null; + textarea.style.height = null; + textarea.style.left = null; + textarea.style.top = null; + textarea.style.zIndex = null; + }, 4); +} +exports.moveTextAreaUnderMouseCursor = moveTextAreaUnderMouseCursor; +function rightClickHandler(ev, textarea, selectionManager) { + moveTextAreaUnderMouseCursor(ev, textarea); + textarea.value = selectionManager.selectionText; + textarea.select(); +} +exports.rightClickHandler = rightClickHandler; + + + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var HOVER_DURATION = 500; +var MouseZoneManager = (function () { + function MouseZoneManager(_terminal) { + var _this = this; + this._terminal = _terminal; + this._zones = []; + this._areZonesActive = false; + this._tooltipTimeout = null; + this._currentZone = null; + this._lastHoverCoords = [null, null]; + this._terminal.element.addEventListener('mousedown', function (e) { return _this._onMouseDown(e); }); + this._mouseMoveListener = function (e) { return _this._onMouseMove(e); }; + this._clickListener = function (e) { return _this._onClick(e); }; + } + MouseZoneManager.prototype.add = function (zone) { + this._zones.push(zone); + if (this._zones.length === 1) { + this._activate(); + } + }; + MouseZoneManager.prototype.clearAll = function (start, end) { + if (this._zones.length === 0) { + return; + } + if (!end) { + start = 0; + end = this._terminal.rows - 1; + } + for (var i = 0; i < this._zones.length; i++) { + var zone = this._zones[i]; + if (zone.y > start && zone.y <= end + 1) { + if (this._currentZone && this._currentZone === zone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + } + this._zones.splice(i--, 1); + } + } + if (this._zones.length === 0) { + this._deactivate(); + } + }; + MouseZoneManager.prototype._activate = function () { + if (!this._areZonesActive) { + this._areZonesActive = true; + this._terminal.element.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.addEventListener('click', this._clickListener); + } + }; + MouseZoneManager.prototype._deactivate = function () { + if (this._areZonesActive) { + this._areZonesActive = false; + this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.removeEventListener('click', this._clickListener); + } + }; + MouseZoneManager.prototype._onMouseMove = function (e) { + if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) { + this._onHover(e); + this._lastHoverCoords = [e.pageX, e.pageY]; + } + }; + MouseZoneManager.prototype._onHover = function (e) { + var _this = this; + var zone = this._findZoneEventAt(e); + if (zone === this._currentZone) { + return; + } + if (this._currentZone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + if (this._tooltipTimeout) { + clearTimeout(this._tooltipTimeout); + } + } + if (!zone) { + return; + } + this._currentZone = zone; + if (zone.hoverCallback) { + zone.hoverCallback(e); + } + this._tooltipTimeout = setTimeout(function () { return _this._onTooltip(e); }, HOVER_DURATION); + }; + MouseZoneManager.prototype._onTooltip = function (e) { + this._tooltipTimeout = null; + var zone = this._findZoneEventAt(e); + if (zone && zone.tooltipCallback) { + zone.tooltipCallback(e); + } + }; + MouseZoneManager.prototype._onMouseDown = function (e) { + if (!this._areZonesActive) { + return; + } + var zone = this._findZoneEventAt(e); + if (zone) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + }; + MouseZoneManager.prototype._onClick = function (e) { + var zone = this._findZoneEventAt(e); + if (zone) { + zone.clickCallback(e); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }; + MouseZoneManager.prototype._findZoneEventAt = function (e) { + var coords = this._terminal.mouseHelper.getCoords(e, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows); + if (!coords) { + return null; + } + for (var i = 0; i < this._zones.length; i++) { + var zone = this._zones[i]; + if (zone.y === coords[1] && zone.x1 <= coords[0] && zone.x2 > coords[0]) { + return zone; + } + } + ; + return null; + }; + return MouseZoneManager; +}()); +exports.MouseZoneManager = MouseZoneManager; +var MouseZone = (function () { + function MouseZone(x1, x2, y, clickCallback, hoverCallback, tooltipCallback, leaveCallback) { + this.x1 = x1; + this.x2 = x2; + this.y = y; + this.clickCallback = clickCallback; + this.hoverCallback = hoverCallback; + this.tooltipCallback = tooltipCallback; + this.leaveCallback = leaveCallback; + } + return MouseZone; +}()); +exports.MouseZone = MouseZone; + + + +},{}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var CharAtlas_1 = require("./CharAtlas"); +var Buffer_1 = require("../Buffer"); +exports.INVERTED_DEFAULT_COLOR = -1; +var DIM_OPACITY = 0.5; +var BaseRenderLayer = (function () { + function BaseRenderLayer(container, id, zIndex, _alpha, _colors) { + this._alpha = _alpha; + this._colors = _colors; + this._scaledCharWidth = 0; + this._scaledCharHeight = 0; + this._scaledCellWidth = 0; + this._scaledCellHeight = 0; + this._scaledCharLeft = 0; + this._scaledCharTop = 0; + this._canvas = document.createElement('canvas'); + this._canvas.id = "xterm-" + id + "-layer"; + this._canvas.style.zIndex = zIndex.toString(); + this._ctx = this._canvas.getContext('2d', { alpha: _alpha }); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + if (!_alpha) { + this.clearAll(); + } + container.appendChild(this._canvas); + } + BaseRenderLayer.prototype.onOptionsChanged = function (terminal) { }; + BaseRenderLayer.prototype.onBlur = function (terminal) { }; + BaseRenderLayer.prototype.onFocus = function (terminal) { }; + BaseRenderLayer.prototype.onCursorMove = function (terminal) { }; + BaseRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { }; + BaseRenderLayer.prototype.onSelectionChanged = function (terminal, start, end) { }; + BaseRenderLayer.prototype.onThemeChanged = function (terminal, colorSet) { + this._refreshCharAtlas(terminal, colorSet); + }; + BaseRenderLayer.prototype._refreshCharAtlas = function (terminal, colorSet) { + var _this = this; + if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) { + return; + } + this._charAtlas = null; + var result = CharAtlas_1.acquireCharAtlas(terminal, this._colors, this._scaledCharWidth, this._scaledCharHeight); + if (result instanceof HTMLCanvasElement) { + this._charAtlas = result; + } + else { + result.then(function (bitmap) { return _this._charAtlas = bitmap; }); + } + }; + BaseRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + this._scaledCellWidth = dim.scaledCellWidth; + this._scaledCellHeight = dim.scaledCellHeight; + this._scaledCharWidth = dim.scaledCharWidth; + this._scaledCharHeight = dim.scaledCharHeight; + this._scaledCharLeft = dim.scaledCharLeft; + this._scaledCharTop = dim.scaledCharTop; + this._canvas.width = dim.scaledCanvasWidth; + this._canvas.height = dim.scaledCanvasHeight; + this._canvas.style.width = dim.canvasWidth + "px"; + this._canvas.style.height = dim.canvasHeight + "px"; + if (!this._alpha) { + this.clearAll(); + } + if (charSizeChanged) { + this._refreshCharAtlas(terminal, this._colors); + } + }; + BaseRenderLayer.prototype.fillCells = function (x, y, width, height) { + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + }; + BaseRenderLayer.prototype.fillBottomLineAtCells = function (x, y, width) { + if (width === void 0) { width = 1; } + this._ctx.fillRect(x * this._scaledCellWidth, (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1, width * this._scaledCellWidth, window.devicePixelRatio); + }; + BaseRenderLayer.prototype.fillLeftLineAtCell = function (x, y) { + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, window.devicePixelRatio, this._scaledCellHeight); + }; + BaseRenderLayer.prototype.strokeRectAtCell = function (x, y, width, height) { + this._ctx.lineWidth = window.devicePixelRatio; + this._ctx.strokeRect(x * this._scaledCellWidth + window.devicePixelRatio / 2, y * this._scaledCellHeight + (window.devicePixelRatio / 2), width * this._scaledCellWidth - window.devicePixelRatio, (height * this._scaledCellHeight) - window.devicePixelRatio); + }; + BaseRenderLayer.prototype.clearAll = function () { + if (this._alpha) { + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + } + else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + } + }; + BaseRenderLayer.prototype.clearCells = function (x, y, width, height) { + if (this._alpha) { + this._ctx.clearRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + } + else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + } + }; + BaseRenderLayer.prototype.fillCharTrueColor = function (terminal, charData, x, y) { + this._ctx.font = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + this._ctx.textBaseline = 'top'; + this._clipRow(terminal, y); + this._ctx.fillText(charData[Buffer_1.CHAR_DATA_CHAR_INDEX], x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop); + }; + BaseRenderLayer.prototype.drawChar = function (terminal, char, code, width, x, y, fg, bg, bold, dim) { + var colorIndex = 0; + if (fg < 256) { + colorIndex = fg + 2; + } + else { + if (bold && terminal.options.enableBold) { + colorIndex = 1; + } + } + var isAscii = code < 256; + var isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold); + var isDefaultColor = fg >= 256; + var isDefaultBackground = bg >= 256; + if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground) { + var charAtlasCellWidth = this._scaledCharWidth + CharAtlas_1.CHAR_ATLAS_CELL_SPACING; + var charAtlasCellHeight = this._scaledCharHeight + CharAtlas_1.CHAR_ATLAS_CELL_SPACING; + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + if (bold && !terminal.options.enableBold) { + if (colorIndex > 1) { + colorIndex -= 8; + } + } + this._ctx.drawImage(this._charAtlas, code * charAtlasCellWidth, colorIndex * charAtlasCellHeight, charAtlasCellWidth, this._scaledCharHeight, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop, charAtlasCellWidth, this._scaledCharHeight); + } + else { + this._drawUncachedChar(terminal, char, width, fg, x, y, bold, dim); + } + }; + BaseRenderLayer.prototype._drawUncachedChar = function (terminal, char, width, fg, x, y, bold, dim) { + this._ctx.save(); + this._ctx.font = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + if (bold && terminal.options.enableBold) { + this._ctx.font = "bold " + this._ctx.font; + } + this._ctx.textBaseline = 'top'; + if (fg === exports.INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } + else if (fg < 256) { + this._ctx.fillStyle = this._colors.ansi[fg]; + } + else { + this._ctx.fillStyle = this._colors.foreground; + } + this._clipRow(terminal, y); + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + this._ctx.fillText(char, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop); + this._ctx.restore(); + }; + BaseRenderLayer.prototype._clipRow = function (terminal, y) { + this._ctx.beginPath(); + this._ctx.rect(0, y * this._scaledCellHeight, terminal.cols * this._scaledCellWidth, this._scaledCellHeight); + this._ctx.clip(); + }; + return BaseRenderLayer; +}()); +exports.BaseRenderLayer = BaseRenderLayer; + + + +},{"../Buffer":1,"./CharAtlas":19}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Browser_1 = require("../utils/Browser"); +exports.CHAR_ATLAS_CELL_SPACING = 1; +var charAtlasCache = []; +function acquireCharAtlas(terminal, colors, scaledCharWidth, scaledCharHeight) { + var newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors); + for (var i = 0; i < charAtlasCache.length; i++) { + var entry = charAtlasCache[i]; + var ownedByIndex = entry.ownedBy.indexOf(terminal); + if (ownedByIndex >= 0) { + if (configEquals(entry.config, newConfig)) { + return entry.bitmap; + } + else { + if (entry.ownedBy.length === 1) { + charAtlasCache.splice(i, 1); + } + else { + entry.ownedBy.splice(ownedByIndex, 1); + } + break; + } + } + } + for (var i = 0; i < charAtlasCache.length; i++) { + var entry = charAtlasCache[i]; + if (configEquals(entry.config, newConfig)) { + entry.ownedBy.push(terminal); + return entry.bitmap; + } + } + var newEntry = { + bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, colors.background, colors.foreground, colors.ansi), + config: newConfig, + ownedBy: [terminal] + }; + charAtlasCache.push(newEntry); + return newEntry.bitmap; +} +exports.acquireCharAtlas = acquireCharAtlas; +function generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors) { + var clonedColors = { + foreground: colors.foreground, + background: colors.background, + cursor: null, + cursorAccent: null, + selection: null, + ansi: colors.ansi.slice(0, 16) + }; + return { + scaledCharWidth: scaledCharWidth, + scaledCharHeight: scaledCharHeight, + fontFamily: terminal.options.fontFamily, + fontSize: terminal.options.fontSize, + colors: clonedColors + }; +} +function configEquals(a, b) { + for (var i = 0; i < a.colors.ansi.length; i++) { + if (a.colors.ansi[i] !== b.colors.ansi[i]) { + return false; + } + } + return a.fontFamily === b.fontFamily && + a.fontSize === b.fontSize && + a.scaledCharWidth === b.scaledCharWidth && + a.scaledCharHeight === b.scaledCharHeight && + a.colors.foreground === b.colors.foreground && + a.colors.background === b.colors.background; +} +var generator; +function initialize(document, alpha) { + if (!generator) { + generator = new CharAtlasGenerator(document, alpha); + } +} +exports.initialize = initialize; +var CharAtlasGenerator = (function () { + function CharAtlasGenerator(_document, alpha) { + this._document = _document; + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d', { alpha: alpha }); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + } + CharAtlasGenerator.prototype.generate = function (scaledCharWidth, scaledCharHeight, fontSize, fontFamily, background, foreground, ansiColors) { + var cellWidth = scaledCharWidth + exports.CHAR_ATLAS_CELL_SPACING; + var cellHeight = scaledCharHeight + exports.CHAR_ATLAS_CELL_SPACING; + this._canvas.width = 255 * cellWidth; + this._canvas.height = (2 + 16) * cellHeight; + this._ctx.fillStyle = background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + this._ctx.save(); + this._ctx.fillStyle = foreground; + this._ctx.font = fontSize * window.devicePixelRatio + "px " + fontFamily; + this._ctx.textBaseline = 'top'; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, 0, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, 0); + this._ctx.restore(); + } + this._ctx.save(); + this._ctx.font = "bold " + this._ctx.font; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight); + this._ctx.restore(); + } + this._ctx.restore(); + this._ctx.font = fontSize * window.devicePixelRatio + "px " + fontFamily; + for (var colorIndex = 0; colorIndex < 16; colorIndex++) { + if (colorIndex === 8) { + this._ctx.font = "bold " + this._ctx.font; + } + var y = (colorIndex + 2) * cellHeight; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, y, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillStyle = ansiColors[colorIndex]; + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, y); + this._ctx.restore(); + } + } + this._ctx.restore(); + if (!('createImageBitmap' in window) || Browser_1.isFirefox) { + var result = this._canvas; + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d'); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + return result; + } + var charAtlasImageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height); + var r = parseInt(background.substr(1, 2), 16); + var g = parseInt(background.substr(3, 2), 16); + var b = parseInt(background.substr(5, 2), 16); + this._clearColor(charAtlasImageData, r, g, b); + var promise = window.createImageBitmap(charAtlasImageData); + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + return promise; + }; + CharAtlasGenerator.prototype._clearColor = function (imageData, r, g, b) { + for (var offset = 0; offset < imageData.data.length; offset += 4) { + if (imageData.data[offset] === r && + imageData.data[offset + 1] === g && + imageData.data[offset + 2] === b) { + imageData.data[offset + 3] = 0; + } + } + }; + return CharAtlasGenerator; +}()); + + + +},{"../utils/Browser":28}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var DEFAULT_FOREGROUND = '#ffffff'; +var DEFAULT_BACKGROUND = '#000000'; +var DEFAULT_CURSOR = '#ffffff'; +var DEFAULT_CURSOR_ACCENT = '#000000'; +var DEFAULT_SELECTION = 'rgba(255, 255, 255, 0.3)'; +exports.DEFAULT_ANSI_COLORS = [ + '#2e3436', + '#cc0000', + '#4e9a06', + '#c4a000', + '#3465a4', + '#75507b', + '#06989a', + '#d3d7cf', + '#555753', + '#ef2929', + '#8ae234', + '#fce94f', + '#729fcf', + '#ad7fa8', + '#34e2e2', + '#eeeeec' +]; +function generate256Colors(first16Colors) { + var colors = first16Colors.slice(); + var v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (var i = 0; i < 216; i++) { + var r = toPaddedHex(v[(i / 36) % 6 | 0]); + var g = toPaddedHex(v[(i / 6) % 6 | 0]); + var b = toPaddedHex(v[i % 6]); + colors.push("#" + r + g + b); + } + for (var i = 0; i < 24; i++) { + var c = toPaddedHex(8 + i * 10); + colors.push("#" + c + c + c); + } + return colors; +} +function toPaddedHex(c) { + var s = c.toString(16); + return s.length < 2 ? '0' + s : s; +} +var ColorManager = (function () { + function ColorManager() { + this.colors = { + foreground: DEFAULT_FOREGROUND, + background: DEFAULT_BACKGROUND, + cursor: DEFAULT_CURSOR, + cursorAccent: DEFAULT_CURSOR_ACCENT, + selection: DEFAULT_SELECTION, + ansi: generate256Colors(exports.DEFAULT_ANSI_COLORS) + }; + } + ColorManager.prototype.setTheme = function (theme) { + this.colors.foreground = theme.foreground || DEFAULT_FOREGROUND; + this.colors.background = theme.background || DEFAULT_BACKGROUND; + this.colors.cursor = theme.cursor || DEFAULT_CURSOR; + this.colors.cursorAccent = theme.cursorAccent || DEFAULT_CURSOR_ACCENT; + this.colors.selection = theme.selection || DEFAULT_SELECTION; + this.colors.ansi[0] = theme.black || exports.DEFAULT_ANSI_COLORS[0]; + this.colors.ansi[1] = theme.red || exports.DEFAULT_ANSI_COLORS[1]; + this.colors.ansi[2] = theme.green || exports.DEFAULT_ANSI_COLORS[2]; + this.colors.ansi[3] = theme.yellow || exports.DEFAULT_ANSI_COLORS[3]; + this.colors.ansi[4] = theme.blue || exports.DEFAULT_ANSI_COLORS[4]; + this.colors.ansi[5] = theme.magenta || exports.DEFAULT_ANSI_COLORS[5]; + this.colors.ansi[6] = theme.cyan || exports.DEFAULT_ANSI_COLORS[6]; + this.colors.ansi[7] = theme.white || exports.DEFAULT_ANSI_COLORS[7]; + this.colors.ansi[8] = theme.brightBlack || exports.DEFAULT_ANSI_COLORS[8]; + this.colors.ansi[9] = theme.brightRed || exports.DEFAULT_ANSI_COLORS[9]; + this.colors.ansi[10] = theme.brightGreen || exports.DEFAULT_ANSI_COLORS[10]; + this.colors.ansi[11] = theme.brightYellow || exports.DEFAULT_ANSI_COLORS[11]; + this.colors.ansi[12] = theme.brightBlue || exports.DEFAULT_ANSI_COLORS[12]; + this.colors.ansi[13] = theme.brightMagenta || exports.DEFAULT_ANSI_COLORS[13]; + this.colors.ansi[14] = theme.brightCyan || exports.DEFAULT_ANSI_COLORS[14]; + this.colors.ansi[15] = theme.brightWhite || exports.DEFAULT_ANSI_COLORS[15]; + }; + return ColorManager; +}()); +exports.ColorManager = ColorManager; + + + +},{}],21:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("../Buffer"); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var BLINK_INTERVAL = 600; +var CursorRenderLayer = (function (_super) { + __extends(CursorRenderLayer, _super); + function CursorRenderLayer(container, zIndex, colors) { + var _this = _super.call(this, container, 'cursor', zIndex, true, colors) || this; + _this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + _this._cursorRenderers = { + 'bar': _this._renderBarCursor.bind(_this), + 'block': _this._renderBlockCursor.bind(_this), + 'underline': _this._renderUnderlineCursor.bind(_this) + }; + return _this; + } + CursorRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + }; + CursorRenderLayer.prototype.reset = function (terminal) { + this._clearCursor(); + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + this.onOptionsChanged(terminal); + } + }; + CursorRenderLayer.prototype.onBlur = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.pause(); + } + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + }; + CursorRenderLayer.prototype.onFocus = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.resume(terminal); + } + else { + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + }; + CursorRenderLayer.prototype.onOptionsChanged = function (terminal) { + var _this = this; + if (terminal.options.cursorBlink) { + if (!this._cursorBlinkStateManager) { + this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, function () { + _this._render(terminal, true); + }); + } + } + else { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + } + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + }; + CursorRenderLayer.prototype.onCursorMove = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.restartBlinkAnimation(terminal); + } + }; + CursorRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { + if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) { + this._render(terminal, false); + } + }; + CursorRenderLayer.prototype._render = function (terminal, triggeredByAnimationFrame) { + if (!terminal.cursorState || terminal.cursorHidden) { + this._clearCursor(); + return; + } + var cursorY = terminal.buffer.ybase + terminal.buffer.y; + var viewportRelativeCursorY = cursorY - terminal.buffer.ydisp; + if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) { + this._clearCursor(); + return; + } + var charData = terminal.buffer.lines.get(cursorY)[terminal.buffer.x]; + if (!charData) { + return; + } + if (!terminal.isFocused) { + this._clearCursor(); + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + return; + } + if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) { + this._clearCursor(); + return; + } + if (this._state) { + if (this._state.x === terminal.buffer.x && + this._state.y === viewportRelativeCursorY && + this._state.isFocused === terminal.isFocused && + this._state.style === terminal.options.cursorStyle && + this._state.width === charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]) { + return; + } + this._clearCursor(); + } + this._ctx.save(); + this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + }; + CursorRenderLayer.prototype._clearCursor = function () { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.width, 1); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + } + }; + CursorRenderLayer.prototype._renderBarCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillLeftLineAtCell(x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderBlockCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillCells(x, y, charData[Buffer_1.CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.fillStyle = this._colors.cursorAccent; + this.fillCharTrueColor(terminal, charData, x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderUnderlineCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillBottomLineAtCells(x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderBlurCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.strokeStyle = this._colors.cursor; + this.strokeRectAtCell(x, y, charData[Buffer_1.CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.restore(); + }; + return CursorRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.CursorRenderLayer = CursorRenderLayer; +var CursorBlinkStateManager = (function () { + function CursorBlinkStateManager(terminal, renderCallback) { + this.renderCallback = renderCallback; + this.isCursorVisible = true; + if (terminal.isFocused) { + this._restartInterval(); + } + } + Object.defineProperty(CursorBlinkStateManager.prototype, "isPaused", { + get: function () { return !(this._blinkStartTimeout || this._blinkInterval); }, + enumerable: true, + configurable: true + }); + CursorBlinkStateManager.prototype.dispose = function () { + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + }; + CursorBlinkStateManager.prototype.restartBlinkAnimation = function (terminal) { + var _this = this; + if (this.isPaused) { + return; + } + this._animationTimeRestarted = Date.now(); + this.isCursorVisible = true; + if (!this._animationFrame) { + this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + } + }; + CursorBlinkStateManager.prototype._restartInterval = function (timeToStart) { + var _this = this; + if (timeToStart === void 0) { timeToStart = BLINK_INTERVAL; } + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + } + this._blinkStartTimeout = setTimeout(function () { + if (_this._animationTimeRestarted) { + var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted); + _this._animationTimeRestarted = null; + if (time > 0) { + _this._restartInterval(time); + return; + } + } + _this.isCursorVisible = false; + _this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + _this._blinkInterval = setInterval(function () { + if (_this._animationTimeRestarted) { + var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted); + _this._animationTimeRestarted = null; + _this._restartInterval(time); + return; + } + _this.isCursorVisible = !_this.isCursorVisible; + _this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + }, BLINK_INTERVAL); + }, timeToStart); + }; + CursorBlinkStateManager.prototype.pause = function () { + this.isCursorVisible = true; + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + }; + CursorBlinkStateManager.prototype.resume = function (terminal) { + this._animationTimeRestarted = null; + this._restartInterval(); + this.restartBlinkAnimation(terminal); + }; + return CursorBlinkStateManager; +}()); + + + +},{"../Buffer":1,"./BaseRenderLayer":18}],22:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var GridCache = (function () { + function GridCache() { + this.cache = []; + } + GridCache.prototype.resize = function (width, height) { + for (var x = 0; x < width; x++) { + if (this.cache.length <= x) { + this.cache.push([]); + } + for (var y = this.cache[x].length; y < height; y++) { + this.cache[x].push(null); + } + this.cache[x].length = height; + } + this.cache.length = width; + }; + GridCache.prototype.clear = function () { + for (var x = 0; x < this.cache.length; x++) { + for (var y = 0; y < this.cache[x].length; y++) { + this.cache[x][y] = null; + } + } + }; + return GridCache; +}()); +exports.GridCache = GridCache; + + + +},{}],23:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var Types_1 = require("../Types"); +var LinkRenderLayer = (function (_super) { + __extends(LinkRenderLayer, _super); + function LinkRenderLayer(container, zIndex, colors, terminal) { + var _this = _super.call(this, container, 'link', zIndex, true, colors) || this; + _this._state = null; + terminal.linkifier.on(Types_1.LinkHoverEventTypes.HOVER, function (e) { return _this._onLinkHover(e); }); + terminal.linkifier.on(Types_1.LinkHoverEventTypes.LEAVE, function (e) { return _this._onLinkLeave(e); }); + return _this; + } + LinkRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = null; + }; + LinkRenderLayer.prototype.reset = function (terminal) { + this._clearCurrentLink(); + }; + LinkRenderLayer.prototype._clearCurrentLink = function () { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.length, 1); + this._state = null; + } + }; + LinkRenderLayer.prototype._onLinkHover = function (e) { + this._ctx.fillStyle = this._colors.foreground; + this.fillBottomLineAtCells(e.x, e.y, e.length); + this._state = e; + }; + LinkRenderLayer.prototype._onLinkLeave = function (e) { + this._clearCurrentLink(); + }; + return LinkRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.LinkRenderLayer = LinkRenderLayer; + + + +},{"../Types":14,"./BaseRenderLayer":18}],24:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var TextRenderLayer_1 = require("./TextRenderLayer"); +var SelectionRenderLayer_1 = require("./SelectionRenderLayer"); +var CursorRenderLayer_1 = require("./CursorRenderLayer"); +var ColorManager_1 = require("./ColorManager"); +var LinkRenderLayer_1 = require("./LinkRenderLayer"); +var EventEmitter_1 = require("../EventEmitter"); +var ScreenDprMonitor_1 = require("../utils/ScreenDprMonitor"); +var Renderer = (function (_super) { + __extends(Renderer, _super); + function Renderer(_terminal, theme) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._refreshRowsQueue = []; + _this._refreshAnimationFrame = null; + _this._isPaused = false; + _this._needsFullRefresh = false; + _this.colorManager = new ColorManager_1.ColorManager(); + if (theme) { + _this.colorManager.setTheme(theme); + } + _this._renderLayers = [ + new TextRenderLayer_1.TextRenderLayer(_this._terminal.element, 0, _this.colorManager.colors, _this._terminal.options.allowTransparency), + new SelectionRenderLayer_1.SelectionRenderLayer(_this._terminal.element, 1, _this.colorManager.colors), + new LinkRenderLayer_1.LinkRenderLayer(_this._terminal.element, 2, _this.colorManager.colors, _this._terminal), + new CursorRenderLayer_1.CursorRenderLayer(_this._terminal.element, 3, _this.colorManager.colors) + ]; + _this.dimensions = { + scaledCharWidth: null, + scaledCharHeight: null, + scaledCellWidth: null, + scaledCellHeight: null, + scaledCharLeft: null, + scaledCharTop: null, + scaledCanvasWidth: null, + scaledCanvasHeight: null, + canvasWidth: null, + canvasHeight: null, + actualCellWidth: null, + actualCellHeight: null + }; + _this._devicePixelRatio = window.devicePixelRatio; + _this._updateDimensions(); + _this._screenDprMonitor = new ScreenDprMonitor_1.ScreenDprMonitor(); + _this._screenDprMonitor.setListener(function () { return _this.onWindowResize(window.devicePixelRatio); }); + if ('IntersectionObserver' in window) { + var observer = new IntersectionObserver(function (e) { return _this.onIntersectionChange(e[0]); }, { threshold: 0 }); + observer.observe(_this._terminal.element); + } + return _this; + } + Renderer.prototype.onIntersectionChange = function (entry) { + this._isPaused = entry.intersectionRatio === 0; + if (!this._isPaused && this._needsFullRefresh) { + this._terminal.refresh(0, this._terminal.rows - 1); + } + }; + Renderer.prototype.onWindowResize = function (devicePixelRatio) { + if (this._devicePixelRatio !== devicePixelRatio) { + this._devicePixelRatio = devicePixelRatio; + this.onResize(this._terminal.cols, this._terminal.rows, true); + } + }; + Renderer.prototype.setTheme = function (theme) { + var _this = this; + this.colorManager.setTheme(theme); + this._renderLayers.forEach(function (l) { + l.onThemeChanged(_this._terminal, _this.colorManager.colors); + l.reset(_this._terminal); + }); + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + return this.colorManager.colors; + }; + Renderer.prototype.onResize = function (cols, rows, didCharSizeChange) { + var _this = this; + this._updateDimensions(); + this._renderLayers.forEach(function (l) { return l.resize(_this._terminal, _this.dimensions, didCharSizeChange); }); + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + this.emit('resize', { + width: this.dimensions.canvasWidth, + height: this.dimensions.canvasHeight + }); + }; + Renderer.prototype.onCharSizeChanged = function () { + this.onResize(this._terminal.cols, this._terminal.rows, true); + }; + Renderer.prototype.onBlur = function () { + var _this = this; + this._runOperation(function (l) { return l.onBlur(_this._terminal); }); + }; + Renderer.prototype.onFocus = function () { + var _this = this; + this._runOperation(function (l) { return l.onFocus(_this._terminal); }); + }; + Renderer.prototype.onSelectionChanged = function (start, end) { + var _this = this; + this._runOperation(function (l) { return l.onSelectionChanged(_this._terminal, start, end); }); + }; + Renderer.prototype.onCursorMove = function () { + var _this = this; + this._runOperation(function (l) { return l.onCursorMove(_this._terminal); }); + }; + Renderer.prototype.onOptionsChanged = function () { + var _this = this; + this._runOperation(function (l) { return l.onOptionsChanged(_this._terminal); }); + }; + Renderer.prototype.clear = function () { + var _this = this; + this._runOperation(function (l) { return l.reset(_this._terminal); }); + }; + Renderer.prototype._runOperation = function (operation) { + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._renderLayers.forEach(function (l) { return operation(l); }); + } + }; + Renderer.prototype.queueRefresh = function (start, end) { + if (this._isPaused) { + this._needsFullRefresh = true; + return; + } + this._refreshRowsQueue.push({ start: start, end: end }); + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + } + }; + Renderer.prototype._refreshLoop = function () { + var _this = this; + var start; + var end; + if (this._refreshRowsQueue.length > 4) { + start = 0; + end = this._terminal.rows - 1; + } + else { + start = this._refreshRowsQueue[0].start; + end = this._refreshRowsQueue[0].end; + for (var i = 1; i < this._refreshRowsQueue.length; i++) { + if (this._refreshRowsQueue[i].start < start) { + start = this._refreshRowsQueue[i].start; + } + if (this._refreshRowsQueue[i].end > end) { + end = this._refreshRowsQueue[i].end; + } + } + } + this._refreshRowsQueue = []; + this._refreshAnimationFrame = null; + start = Math.max(start, 0); + end = Math.min(end, this._terminal.rows - 1); + this._renderLayers.forEach(function (l) { return l.onGridChanged(_this._terminal, start, end); }); + this._terminal.emit('refresh', { start: start, end: end }); + }; + Renderer.prototype._updateDimensions = function () { + if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) { + return; + } + this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio); + this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio); + this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight); + this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2); + this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing); + this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2); + this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight; + this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth; + this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio); + this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio); + this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows; + this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols; + }; + return Renderer; +}(EventEmitter_1.EventEmitter)); +exports.Renderer = Renderer; + + + +},{"../EventEmitter":7,"../utils/ScreenDprMonitor":33,"./ColorManager":20,"./CursorRenderLayer":21,"./LinkRenderLayer":23,"./SelectionRenderLayer":25,"./TextRenderLayer":26}],25:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var SelectionRenderLayer = (function (_super) { + __extends(SelectionRenderLayer, _super); + function SelectionRenderLayer(container, zIndex, colors) { + var _this = _super.call(this, container, 'selection', zIndex, true, colors) || this; + _this._state = { + start: null, + end: null + }; + return _this; + } + SelectionRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = { + start: null, + end: null + }; + }; + SelectionRenderLayer.prototype.reset = function (terminal) { + if (this._state.start && this._state.end) { + this._state = { + start: null, + end: null + }; + this.clearAll(); + } + }; + SelectionRenderLayer.prototype.onSelectionChanged = function (terminal, start, end) { + if (this._state.start === start || this._state.end === end) { + return; + } + this.clearAll(); + if (!start || !end) { + return; + } + var viewportStartRow = start[1] - terminal.buffer.ydisp; + var viewportEndRow = end[1] - terminal.buffer.ydisp; + var viewportCappedStartRow = Math.max(viewportStartRow, 0); + var viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1); + if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) { + return; + } + var startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0; + var startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols; + this._ctx.fillStyle = this._colors.selection; + this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); + var middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0); + this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); + if (viewportCappedStartRow !== viewportCappedEndRow) { + var endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols; + this.fillCells(0, viewportCappedEndRow, endCol, 1); + } + this._state.start = [start[0], start[1]]; + this._state.end = [end[0], end[1]]; + }; + return SelectionRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.SelectionRenderLayer = SelectionRenderLayer; + + + +},{"./BaseRenderLayer":18}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("../Buffer"); +var Types_1 = require("./Types"); +var GridCache_1 = require("./GridCache"); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var OVERLAP_OWNED_CHAR_DATA = [null, '', 0, -1]; +var TextRenderLayer = (function (_super) { + __extends(TextRenderLayer, _super); + function TextRenderLayer(container, zIndex, colors, alpha) { + var _this = _super.call(this, container, 'text', zIndex, alpha, colors) || this; + _this._characterOverlapCache = {}; + _this._state = new GridCache_1.GridCache(); + return _this; + } + TextRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + var terminalFont = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { + this._characterWidth = dim.scaledCharWidth; + this._characterFont = terminalFont; + this._characterOverlapCache = {}; + } + this._state.clear(); + this._state.resize(terminal.cols, terminal.rows); + }; + TextRenderLayer.prototype.reset = function (terminal) { + this._state.clear(); + this.clearAll(); + }; + TextRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { + if (this._state.cache.length === 0) { + return; + } + for (var y = startRow; y <= endRow; y++) { + var row = y + terminal.buffer.ydisp; + var line = terminal.buffer.lines.get(row); + this.clearCells(0, y, terminal.cols, 1); + for (var x = 0; x < terminal.cols; x++) { + var charData = line[x]; + var code = charData[Buffer_1.CHAR_DATA_CODE_INDEX]; + var char = charData[Buffer_1.CHAR_DATA_CHAR_INDEX]; + var attr = charData[Buffer_1.CHAR_DATA_ATTR_INDEX]; + var width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + if (width === 0) { + continue; + } + if (code === 32) { + if (x > 0) { + var previousChar = line[x - 1]; + if (this._isOverlapping(previousChar)) { + continue; + } + } + } + var flags = attr >> 18; + var bg = attr & 0x1ff; + var isDefaultBackground = bg >= 256; + var isInvisible = flags & Types_1.FLAGS.INVISIBLE; + var isInverted = flags & Types_1.FLAGS.INVERSE; + if (!code || (code === 32 && isDefaultBackground && !isInverted) || isInvisible) { + continue; + } + if (width !== 0 && this._isOverlapping(charData)) { + if (x < line.length - 1 && line[x + 1][Buffer_1.CHAR_DATA_CODE_INDEX] === 32) { + width = 2; + } + } + var fg = (attr >> 9) & 0x1ff; + if (isInverted) { + var temp = bg; + bg = fg; + fg = temp; + if (fg === 256) { + fg = BaseRenderLayer_1.INVERTED_DEFAULT_COLOR; + } + if (bg === 257) { + bg = BaseRenderLayer_1.INVERTED_DEFAULT_COLOR; + } + } + if (width === 2) { + } + if (bg < 256) { + this._ctx.save(); + this._ctx.fillStyle = (bg === BaseRenderLayer_1.INVERTED_DEFAULT_COLOR ? this._colors.foreground : this._colors.ansi[bg]); + this.fillCells(x, y, width, 1); + this._ctx.restore(); + } + this._ctx.save(); + if (flags & Types_1.FLAGS.BOLD) { + this._ctx.font = "bold " + this._ctx.font; + if (fg < 8) { + fg += 8; + } + } + if (flags & Types_1.FLAGS.UNDERLINE) { + if (fg === BaseRenderLayer_1.INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } + else if (fg < 256) { + this._ctx.fillStyle = this._colors.ansi[fg]; + } + else { + this._ctx.fillStyle = this._colors.foreground; + } + this.fillBottomLineAtCells(x, y); + } + this.drawChar(terminal, char, code, width, x, y, fg, bg, !!(flags & Types_1.FLAGS.BOLD), !!(flags & Types_1.FLAGS.DIM)); + this._ctx.restore(); + } + } + }; + TextRenderLayer.prototype._isOverlapping = function (charData) { + if (charData[Buffer_1.CHAR_DATA_WIDTH_INDEX] !== 1) { + return false; + } + var code = charData[Buffer_1.CHAR_DATA_CODE_INDEX]; + if (code < 256) { + return false; + } + var char = charData[Buffer_1.CHAR_DATA_CHAR_INDEX]; + if (this._characterOverlapCache.hasOwnProperty(char)) { + return this._characterOverlapCache[char]; + } + this._ctx.save(); + this._ctx.font = this._characterFont; + var overlaps = Math.floor(this._ctx.measureText(char).width) > this._characterWidth; + this._ctx.restore(); + this._characterOverlapCache[char] = overlaps; + return overlaps; + }; + TextRenderLayer.prototype._clearChar = function (x, y) { + var colsToClear = 1; + var state = this._state.cache[x][y]; + if (state && state[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + colsToClear = 2; + } + this.clearCells(x, y, colsToClear, 1); + }; + return TextRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.TextRenderLayer = TextRenderLayer; + + + +},{"../Buffer":1,"./BaseRenderLayer":18,"./GridCache":22,"./Types":27}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["BOLD"] = 1] = "BOLD"; + FLAGS[FLAGS["UNDERLINE"] = 2] = "UNDERLINE"; + FLAGS[FLAGS["BLINK"] = 4] = "BLINK"; + FLAGS[FLAGS["INVERSE"] = 8] = "INVERSE"; + FLAGS[FLAGS["INVISIBLE"] = 16] = "INVISIBLE"; + FLAGS[FLAGS["DIM"] = 32] = "DIM"; +})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); +; + + + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Generic_1 = require("./Generic"); +var isNode = (typeof navigator === 'undefined') ? true : false; +var userAgent = (isNode) ? 'node' : navigator.userAgent; +var platform = (isNode) ? 'node' : navigator.platform; +exports.isFirefox = !!~userAgent.indexOf('Firefox'); +exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); +exports.isMac = Generic_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); +exports.isIpad = platform === 'iPad'; +exports.isIphone = platform === 'iPhone'; +exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); +exports.isLinux = platform.indexOf('Linux') >= 0; + + + +},{"./Generic":31}],29:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter_1 = require("../EventEmitter"); +var CharMeasure = (function (_super) { + __extends(CharMeasure, _super); + function CharMeasure(document, parentElement) { + var _this = _super.call(this) || this; + _this._document = document; + _this._parentElement = parentElement; + _this._measureElement = _this._document.createElement('span'); + _this._measureElement.style.position = 'absolute'; + _this._measureElement.style.top = '0'; + _this._measureElement.style.left = '-9999em'; + _this._measureElement.style.lineHeight = 'normal'; + _this._measureElement.textContent = 'W'; + _this._measureElement.setAttribute('aria-hidden', 'true'); + _this._parentElement.appendChild(_this._measureElement); + return _this; + } + Object.defineProperty(CharMeasure.prototype, "width", { + get: function () { + return this._width; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CharMeasure.prototype, "height", { + get: function () { + return this._height; + }, + enumerable: true, + configurable: true + }); + CharMeasure.prototype.measure = function (options) { + this._measureElement.style.fontFamily = options.fontFamily; + this._measureElement.style.fontSize = options.fontSize + "px"; + var geometry = this._measureElement.getBoundingClientRect(); + if (geometry.width === 0 || geometry.height === 0) { + return; + } + if (this._width !== geometry.width || this._height !== geometry.height) { + this._width = geometry.width; + this._height = Math.ceil(geometry.height); + this.emit('charsizechanged'); + } + }; + return CharMeasure; +}(EventEmitter_1.EventEmitter)); +exports.CharMeasure = CharMeasure; + + + +},{"../EventEmitter":7}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter_1 = require("../EventEmitter"); +var CircularList = (function (_super) { + __extends(CircularList, _super); + function CircularList(_maxLength) { + var _this = _super.call(this) || this; + _this._maxLength = _maxLength; + _this._array = new Array(_this._maxLength); + _this._startIndex = 0; + _this._length = 0; + return _this; + } + Object.defineProperty(CircularList.prototype, "maxLength", { + get: function () { + return this._maxLength; + }, + set: function (newMaxLength) { + if (this._maxLength === newMaxLength) { + return; + } + var newArray = new Array(newMaxLength); + for (var i = 0; i < Math.min(newMaxLength, this.length); i++) { + newArray[i] = this._array[this._getCyclicIndex(i)]; + } + this._array = newArray; + this._maxLength = newMaxLength; + this._startIndex = 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "length", { + get: function () { + return this._length; + }, + set: function (newLength) { + if (newLength > this._length) { + for (var i = this._length; i < newLength; i++) { + this._array[i] = undefined; + } + } + this._length = newLength; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "forEach", { + get: function () { + var _this = this; + return function (callbackfn) { + var i = 0; + var length = _this.length; + for (var i_1 = 0; i_1 < length; i_1++) { + callbackfn(_this.get(i_1), i_1); + } + }; + }, + enumerable: true, + configurable: true + }); + CircularList.prototype.get = function (index) { + return this._array[this._getCyclicIndex(index)]; + }; + CircularList.prototype.set = function (index, value) { + this._array[this._getCyclicIndex(index)] = value; + }; + CircularList.prototype.push = function (value) { + this._array[this._getCyclicIndex(this._length)] = value; + if (this._length === this._maxLength) { + this._startIndex++; + if (this._startIndex === this._maxLength) { + this._startIndex = 0; + } + this.emit('trim', 1); + } + else { + this._length++; + } + }; + CircularList.prototype.pop = function () { + return this._array[this._getCyclicIndex(this._length-- - 1)]; + }; + CircularList.prototype.splice = function (start, deleteCount) { + var items = []; + for (var _i = 2; _i < arguments.length; _i++) { + items[_i - 2] = arguments[_i]; + } + if (deleteCount) { + for (var i = start; i < this._length - deleteCount; i++) { + this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)]; + } + this._length -= deleteCount; + } + if (items && items.length) { + for (var i = this._length - 1; i >= start; i--) { + this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)]; + } + for (var i = 0; i < items.length; i++) { + this._array[this._getCyclicIndex(start + i)] = items[i]; + } + if (this._length + items.length > this.maxLength) { + var countToTrim = (this._length + items.length) - this.maxLength; + this._startIndex += countToTrim; + this._length = this.maxLength; + this.emit('trim', countToTrim); + } + else { + this._length += items.length; + } + } + }; + CircularList.prototype.trimStart = function (count) { + if (count > this._length) { + count = this._length; + } + this._startIndex += count; + this._length -= count; + this.emit('trim', count); + }; + CircularList.prototype.shiftElements = function (start, count, offset) { + if (count <= 0) { + return; + } + if (start < 0 || start >= this._length) { + throw new Error('start argument out of range'); + } + if (start + offset < 0) { + throw new Error('Cannot shift elements in list beyond index 0'); + } + if (offset > 0) { + for (var i = count - 1; i >= 0; i--) { + this.set(start + i + offset, this.get(start + i)); + } + var expandListBy = (start + count + offset) - this._length; + if (expandListBy > 0) { + this._length += expandListBy; + while (this._length > this.maxLength) { + this._length--; + this._startIndex++; + this.emit('trim', 1); + } + } + } + else { + for (var i = 0; i < count; i++) { + this.set(start + i + offset, this.get(start + i)); + } + } + }; + CircularList.prototype._getCyclicIndex = function (index) { + return (this._startIndex + index) % this.maxLength; + }; + return CircularList; +}(EventEmitter_1.EventEmitter)); +exports.CircularList = CircularList; + + + +},{"../EventEmitter":7}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function contains(arr, el) { + return arr.indexOf(el) >= 0; +} +exports.contains = contains; +; + + + +},{}],32:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var MouseHelper = (function () { + function MouseHelper(_renderer) { + this._renderer = _renderer; + } + MouseHelper.getCoordsRelativeToElement = function (event, element) { + if (event.pageX == null) { + return null; + } + var originalElement = element; + var x = event.pageX; + var y = event.pageY; + while (element) { + x -= element.offsetLeft; + y -= element.offsetTop; + element = 'offsetParent' in element ? element.offsetParent : element.parentElement; + } + element = originalElement; + while (element && element !== element.ownerDocument.body) { + x += element.scrollLeft; + y += element.scrollTop; + element = element.parentElement; + } + return [x, y]; + }; + MouseHelper.prototype.getCoords = function (event, element, charMeasure, lineHeight, colCount, rowCount, isSelection) { + if (!charMeasure.width || !charMeasure.height) { + return null; + } + var coords = MouseHelper.getCoordsRelativeToElement(event, element); + if (!coords) { + return null; + } + coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth); + coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight); + coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0)); + coords[1] = Math.min(Math.max(coords[1], 1), rowCount); + return coords; + }; + MouseHelper.prototype.getRawByteCoords = function (event, element, charMeasure, lineHeight, colCount, rowCount) { + var coords = this.getCoords(event, element, charMeasure, lineHeight, colCount, rowCount); + var x = coords[0]; + var y = coords[1]; + x += 32; + y += 32; + return { x: x, y: y }; + }; + return MouseHelper; +}()); +exports.MouseHelper = MouseHelper; + + + +},{}],33:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ScreenDprMonitor = (function () { + function ScreenDprMonitor() { + } + ScreenDprMonitor.prototype.setListener = function (listener) { + var _this = this; + if (this._listener) { + this.clearListener(); + } + this._listener = listener; + this._outerListener = function () { + _this._listener(window.devicePixelRatio, _this._currentDevicePixelRatio); + _this._updateDpr(); + }; + this._updateDpr(); + }; + ScreenDprMonitor.prototype._updateDpr = function () { + if (this._resolutionMediaMatchList) { + this._resolutionMediaMatchList.removeListener(this._outerListener); + } + this._currentDevicePixelRatio = window.devicePixelRatio; + this._resolutionMediaMatchList = window.matchMedia("screen and (resolution: " + window.devicePixelRatio + "dppx)"); + this._resolutionMediaMatchList.addListener(this._outerListener); + }; + ScreenDprMonitor.prototype.clearListener = function () { + if (!this._listener) { + return; + } + this._resolutionMediaMatchList.removeListener(this._outerListener); + this._listener = null; + this._outerListener = null; + }; + return ScreenDprMonitor; +}()); +exports.ScreenDprMonitor = ScreenDprMonitor; + + + +},{}],34:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg=='; + + + +},{}],35:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Terminal_1 = require("./Terminal"); +module.exports = Terminal_1.Terminal; + + + +},{"./Terminal":13}]},{},[35])(35) +}); +//# sourceMappingURL=xterm.js.map + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function attach(term, socket, bidirectional, buffered) { + bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; + term.socket = socket; + term._flushBuffer = function () { + term.write(term._attachSocketBuffer); + term._attachSocketBuffer = null; + }; + term._pushToBuffer = function (data) { + if (term._attachSocketBuffer) { + term._attachSocketBuffer += data; + } + else { + term._attachSocketBuffer = data; + setTimeout(term._flushBuffer, 10); + } + }; + var myTextDecoder; + term._getMessage = function (ev) { + var str; + if (typeof ev.data === "object") { + if (ev.data instanceof ArrayBuffer) { + if (!myTextDecoder) { + myTextDecoder = new TextDecoder(); + } + str = myTextDecoder.decode(ev.data); + } + else { + throw "TODO: handle Blob?"; + } + } + if (buffered) { + term._pushToBuffer(str || ev.data); + } + else { + term.write(str || ev.data); + } + }; + term._sendData = function (data) { + if (socket.readyState !== 1) { + return; + } + socket.send(data); + }; + socket.addEventListener('message', term._getMessage); + if (bidirectional) { + term.on('data', term._sendData); + } + socket.addEventListener('close', term.detach.bind(term, socket)); + socket.addEventListener('error', term.detach.bind(term, socket)); +} +exports.attach = attach; +; +function detach(term, socket) { + term.off('data', term._sendData); + socket = (typeof socket == 'undefined') ? term.socket : socket; + if (socket) { + socket.removeEventListener('message', term._getMessage); + } + delete term.socket; +} +exports.detach = detach; +; +function apply(terminalConstructor) { + terminalConstructor.prototype.attach = function (socket, bidirectional, buffered) { + return attach(this, socket, bidirectional, buffered); + }; + terminalConstructor.prototype.detach = function (socket) { + return detach(this, socket); + }; +} +exports.apply = apply; + +//# sourceMappingURL=attach.js.map + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function proposeGeometry(term) { + if (!term.element.parentElement) { + return null; + } + var parentElementStyle = window.getComputedStyle(term.element.parentElement); + var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')); + var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17); + var elementStyle = window.getComputedStyle(term.element); + var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')); + var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')); + var availableHeight = parentElementHeight - elementPaddingVer; + var availableWidth = parentElementWidth - elementPaddingHor; + var geometry = { + cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth), + rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight) + }; + return geometry; +} +exports.proposeGeometry = proposeGeometry; +; +function fit(term) { + var geometry = proposeGeometry(term); + if (geometry) { + if (term.rows !== geometry.rows || term.cols !== geometry.cols) { + term.renderer.clear(); + term.resize(geometry.cols, geometry.rows); + } + } +} +exports.fit = fit; +; +function apply(terminalConstructor) { + terminalConstructor.prototype.proposeGeometry = function () { + return proposeGeometry(this); + }; + terminalConstructor.prototype.fit = function () { + return fit(this); + }; +} +exports.apply = apply; + +//# sourceMappingURL=fit.js.map + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function winptyCompatInit(terminal) { + var isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0; + if (!isWindows) { + return; + } + terminal.on('linefeed', function () { + var line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1); + var lastChar = line[terminal.cols - 1]; + if (lastChar[3] !== 32) { + var nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y); + nextLine.isWrapped = true; + } + }); +} +exports.winptyCompatInit = winptyCompatInit; +function apply(terminalConstructor) { + terminalConstructor.prototype.winptyCompatInit = function () { + winptyCompatInit(this); + }; +} +exports.apply = apply; + +//# sourceMappingURL=winptyCompat.js.map + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/FluentTerminal.Client/dist/index.html b/FluentTerminal.Client/dist/index.html new file mode 100644 index 0000000..196ede2 --- /dev/null +++ b/FluentTerminal.Client/dist/index.html @@ -0,0 +1,12 @@ + + + + + + + + +

+ + + \ No newline at end of file diff --git a/FluentTerminal.Client/dist/style.css b/FluentTerminal.Client/dist/style.css new file mode 100644 index 0000000..41f437c --- /dev/null +++ b/FluentTerminal.Client/dist/style.css @@ -0,0 +1,24 @@ +* { + margin: 0; +} + +html { + -ms-overflow-style: none; + background: transparent; + height: 100%; + } + +body { + background: transparent; + height: 100%; +} + +#terminal-container { + width: 100%; + height: 100%; + margin: 0; +} + +.terminal { + background: transparent !important; +} diff --git a/FluentTerminal.Client/dist/xterm.css b/FluentTerminal.Client/dist/xterm.css new file mode 100644 index 0000000..b3ee50f --- /dev/null +++ b/FluentTerminal.Client/dist/xterm.css @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/term.js + * @license MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + */ + +/** + * Default styles for xterm.js + */ + +.xterm { + font-family: courier-new, courier, monospace; + font-feature-settings: "liga" 0; + position: relative; + user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.xterm.focus, +.xterm:focus { + outline: none; +} + +.xterm .xterm-helpers { + position: absolute; + top: 0; + /** + * The z-index of the helpers must be higher than the canvases in order for + * IMEs to appear on top. + */ + z-index: 10; +} + +.xterm .xterm-helper-textarea { + /* + * HACK: to fix IE's blinking cursor + * Move textarea out of the screen to the far left, so that the cursor is not visible. + */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -10; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.xterm .composition-view { + /* TODO: Composition position got messed up somewhere */ + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.xterm .composition-view.active { + display: block; +} + +.xterm .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; + cursor: default; +} + +.xterm canvas { + position: absolute; + left: 0; + top: 0; +} + +.xterm .xterm-scroll-area { + visibility: hidden; +} + +.xterm .xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + left: -9999em; +} + +.xterm.enable-mouse-events { + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ + cursor: default; +} + +.xterm:not(.enable-mouse-events) { + cursor: text; +} diff --git a/FluentTerminal.Client/package-lock.json b/FluentTerminal.Client/package-lock.json new file mode 100644 index 0000000..12a4258 --- /dev/null +++ b/FluentTerminal.Client/package-lock.json @@ -0,0 +1,3104 @@ +{ + "name": "fluent-terminal-client", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.6" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.6", + "randomfill": "1.0.3" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.38" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + } + }, + "errno": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "dev": true, + "requires": { + "prr": "1.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.38", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.38.tgz", + "integrity": "sha512-jCMyePo7AXbUESwbl8Qi01VSH2piY9s/a3rSU/5w/MlTIx8HPL1xn2InGN8ejt/xulcJgnTO7vqNtOAxzYd2Kg==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.38" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.6", + "readable-stream": "2.3.3" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.8.0", + "string_decoder": "1.0.3", + "timers-browserify": "2.0.4", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.1" + } + }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz", + "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "requires": { + "async": "2.6.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + } + }, + "webpack": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", + "dev": true, + "requires": { + "acorn": "5.3.0", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + } + } +} diff --git a/FluentTerminal.Client/package.json b/FluentTerminal.Client/package.json new file mode 100644 index 0000000..e76ebca --- /dev/null +++ b/FluentTerminal.Client/package.json @@ -0,0 +1,16 @@ +{ + "name": "fluent-terminal-client", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "xcopy /y /s ..\\xterm.js\\build\\xterm.css dist\\ && npx webpack --config webpack.config.js" + }, + "author": "FS Apps", + "license": "GPL-3.0", + "dependencies": {}, + "devDependencies": { + "webpack": "^3.10.0" + } +} diff --git a/FluentTerminal.Client/src/index.js b/FluentTerminal.Client/src/index.js new file mode 100644 index 0000000..ecbd614 --- /dev/null +++ b/FluentTerminal.Client/src/index.js @@ -0,0 +1,58 @@ +import * as Terminal from '../../xterm.js/build/xterm'; +import * as attach from '../../xterm.js/build/addons/attach/attach'; +import * as fit from '../../xterm.js/build/addons/fit/fit'; +import * as winptyCompat from '../../xterm.js/build/addons/winptyCompat/winptyCompat'; + +Terminal.applyAddon(attach); +Terminal.applyAddon(fit); +Terminal.applyAddon(winptyCompat); + +var term, protocol, socketURL, socket; +var terminalContainer = document.getElementById('terminal-container'); + +createTerminal(); + +function createTerminal() { + while (terminalContainer.children.length) { + terminalContainer.removeChild(terminalContainer.children[0]); + } + term = new Terminal({ + cursorBlink: true, + fontFamily: 'consolas', + fontSize: 13, + allowTransparency: true, + theme: { + background: "transparent" + } + }); + window.term = term; // Expose `term` to window for debugging purposes + term.on('resize', function (size) { + if (!socketURL) { + return; + } + var cols = size.cols, + rows = size.rows, + url = 'http://localhost:9000/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; + fetch(url, {method: 'POST'}); + }); + protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; + + term.open(terminalContainer); + term.winptyCompatInit(); + term.fit(); + term.focus(); + + fetch('http://localhost:9000/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { + console.log("got response"); + res.text().then(function (url) { + socketURL = JSON.parse(url); + socket = new WebSocket(socketURL); + socket.onopen = runRealTerminal; + }); + }); +} + +function runRealTerminal() { + term.attach(socket); + term._initialized = true; +} diff --git a/FluentTerminal.Client/webpack.config.js b/FluentTerminal.Client/webpack.config.js new file mode 100644 index 0000000..8e4c3ab --- /dev/null +++ b/FluentTerminal.Client/webpack.config.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + } +}; \ No newline at end of file diff --git a/FluentTerminal.SystemTray/App.config b/FluentTerminal.SystemTray/App.config new file mode 100644 index 0000000..b4e0aaa --- /dev/null +++ b/FluentTerminal.SystemTray/App.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-agent.exe b/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-agent.exe new file mode 100644 index 0000000000000000000000000000000000000000..f273e3a346ccbb6215060a7b401711b1c0b1c283 GIT binary patch literal 726528 zcmeF42Y6IP_y0E}K&TrK6ciz7L^O(#2!cV$k_7I;h9V+}(gXr1ASIzlCx9%MML-cy z6i`7F3pSbpNhqO72&gm**tj7U6opVE|IhdCCIoD}@9%wozvurv$ph!k%sF#r=FFTk zXUe^s*m)UT=_@E(= z^%>G*KzPp{0|!2q9R6_c@F6J!!}|>kk8jgHe86M9de^H^p=?Be_0aEr8gb_n6Cw-# zr(QECGMaemHA5m>+s~nqckwKLVB*b9?dRm1ueYC*Zmz}i*oc;q_wc;)iSd!kdA@jH z(#?@PmmC-y+0c%s-mK@n{d)FQ83iqBo8WNtno`#BrDt5Hg0$m~>m21uRCGAPLmiIF zl8VD&h6BPBa>ND+DqOi@-l!B;65K&Jk6*Xu`$e zdda;VluB!y`Am}Rd4B=ViFV^8`RwVkr65Of3oO&gK9XX4=L5`fT zEu|ef*WVxF$eEp7(vh?Ibr6F-Bh+mhq1G8-yW9v^aI%CWXL%h$>whEEL1~@?&^89{MxoJ<;WTSHF@8>p3sErpj&jF9D64L)|RHAGLI3m4uL)KDPYQb)i z4l5Gu*h!Lkqi>nOX+AXkp^({hG77}XnKG>T-CE8nvYF|UwZ3S(6 zM`?>U0hXztxh9}_4~TEir@gO>RjZk#{kWBECHI23?+D=Nl@wX;DiCF|;1U)`HGaCC zXyED6< zasb4yJqi0Ga{y1jMcOrcsr`Bp|9(B7`zVO#Dq2>c%QB*?w?MM@1HjsPWOI#x>4-`o zN=v5O%afM=1<^t3^Ot@gboB;8?P3U3TLMYXNq}kUid!v051j>T_xTH(2+f~Ki$0zO z`|Cd;dVV66{Pq#5R`&%$-P(~h`wOzoQjs6lC$#Tva%8LrG3Itct0$2+xGBUHRp<01 z5NR6YZ92oH&dY?d=YU=DJfWlClJb~niD<*a zAZ97;4z=jHQlxd(Xun%SZ|f!)oY)LlJCEq;l3-`5e_u+ZjM=}@%I9w-@6M-4`yhkR zwA~Q9Z-Ld}k02ShjOgs|2(5b+l2DUqIjP$0H(+)9{nUA01)|q40-WhbS`R69-6?SH zqfU87wR%)Dv+O7J@3Y55lY&{}CG&%#n zecd6xSN+>>9HH*-LL4IrZ668Ns|szE*z=XQj!EeG{iMY{MUGY)?avGZe7+mRre`VR zsl{Y_W*E^1m7x1|7ud&crpWF6$??Fwq>We($R7^zYp;NqzZYT zE>BwN`9xn^O6YkFu1&{?F4UO3c`i(!SC^#?rv{mCQ-kl`B{W~wv93B`VLG7VN)WZj zKo`~<#6}0%>R$(|peUk7M~ck)k!&YZ2`!E!?T)X>Hnc7zUDculRnoDK&^0pQ_udWg zsxEnZ2)!huH8z_Zc00nJChf87DdSit<^7b>t&8fz)WYT)vL+BfcE_E2hFXjT) z$&k%E1M#7BYB23-NOBGm+WH!K-%|I?zKv-1ZA6zzV0*6xlzJR6csC5Degk5!@;-Bj zs4EzLtKT4cbRggtG1x5WzLyDh98O8jv|JD_b#3{^n@Xrt`G+B=EP`jKqaRCxYVq&3VV+p8*fs>=p3 zcuk<4%+j(CC~|ofqAw`Toq-VF`ySBkJUOoJ0!j7PKHivM!*GT9jP^2Agoya+=m7RHrg@C8fkOW%REYMQFR)mNOji`W=uQ z5;z$~H1S44t6za+Z#{_5r@_T_07U4OAWU&t`Vol9&4@;+LSJeU{_!`W6PkmlQI^mt z4XJzf5}L2M@#E@*uHQzZD=q@@hHTD$r3Kd{?=v-tb|_2U@bO@yvncYJW`K6zfSvax zAZrHE`W0ZcWCz*W_Jz2oM0ZaFq3S~r-KJ^eT_`;|rpacBY@(wcX>GhjpG^kLmjSIi z6fRG+0ns&?a*tF8G_wsjo`K7}Ow#tLKL)-;-rFC5-=rT1J=qj&*}X)M zd`GmugmX3;;-%#Yjl32_{9H&<=fLWo4%7!HF*?G-yzz155(F1po{vD=-Hj{ zd*N0>gAY+;@+X8^{G|4NNRG`vlQ&JZ8a{#0lwZkq`$0h8&*5@ZGsM_cAcEvue3k{c zsx+XUrqubTAsO))p;fI2m9Sv?>SXeUZleP>4k3EKq|t621ud!oNv-pM?KhHkyV|xa zh-f)^hi~So++l={t9}n&L!E0*f#i3Mzt{T$+KBkrgQWGAVkfHyf08jj^9$Hd-Xe6% za$&uT$qAiGy87lWY(drdo z^s%=v4)+EslC&!HA5Rbec#0vFR>J>yQYP`G=LulFK zgm#GO7g{{lmi`VJ1^8eKX%D|bw%_}cE#gf=xf;~X5}-@`0+R6(@xIlh?NN?O+u-N8 zf~a#oVB(Kp2c!VL*F-fclcs*!53o+w=bQ}V*FDKG`wBw7@__wa0at}X+;A3P@m%P_ zwiD{6!VkL1n_ZT|Lza=P&0T=)!63G&S;;=~M$6pnQh$v65D+^OM7gT8WA-Z$Z|(&) zR7T;{9Yh~*4ZlRy^!PJ`+Q_qfSQdDI`s2QrAStKmz5Y2s&>qs7{6^Z|S0OpMf>68T zgbqumo2o_UwHzrUul}Kxq_tPA-pnNWb`KB>t`*%ja*SO|w6WZyPD?4b+ydyDeMI56 z3Ol+E*s~9TT`z?gqtO|11n_PxNWPl{$q(%bMT{cb@TWk$cpqGDP?3EH((xx2gMA?z z?3_44`=wwfq|Oyr0aEUV!8e-En+~FCKmJT8yCemDzlP90MeBVGNa+aJTAsXdCty0` z5kQZ#FnDMn44iQkc~UNWw!rEUq1 zzg!P?UoOLc`Zg$$^aIu zgf3Wf{5ww|h<*aS?t#mW`$0UujM4_bNi<5fbCpEbS{7-Jr14N+vb`luKBH+n@q5zF zO@YD2n+d&{3id!ru;0r*ce@5~P}@68t^sFkMto1X@B zc?W*6vNYHH3WHrw0TxS$d1=t4CIRlL1Nc_5-(QbVdr4^8O6aPeBh+aup~#m2oi)4% z%%O~5cS3j7Zm>Tl0+!4qT3*>Q`$4x>^Zxwlq(#X;eQpO}t&eC)9}HgCeA&uJt-jJ8 z!08l1d8I%sj3V!gYr)o@PulC!tsS=Svw+YNv0r^HbfbDgS3>psM8j;wQbHR>5&A_% z-n5I*ep#Ae%@9iuz^{^4Hh26=HCo8XJRS?HF`}FL3*aj4>y_$7+U9$RmfsHDoiemt zJF5&CeWMBBL^sl2P@R91@pxGZ(MEp6SMPxBt*wZ|9&#KN-B*nPZ;z$l#>@SkTNkD? z%ExFUys5Ep%`91iSMHc~58s zG`k_8k(wqt$ul~%gwR-Na+zs>PU?j|>ghc)WI-|%A)i3fr#Wf&Z-Qj9T!`@>fyiG5 zV!P^6eG=H68coYhuvf}(d$lX{@hr(ef^99%Rpt5i)lB^0QNXiWpI4Q8zPcKS4KI*Z zHjA_h;uj(nZ~7qEA2m(n|9Yjaj zdFvDMK1y1ejN6G-L?4l^CN2W(*BU!hPTTgk$(x|{jHP-1tOn*TE%lEaBh;%AbUpI{ z*U5(6q`Y<4lB3%ILO(7=&acY5N!Idp$Fr37m2{!^jYL1xO7rX2!9M&Ph$B16*5qA) z(?QzAv*dlF9*x;5m2CeVpk@SMiPi=oGU3-~m}R(#&fiREkz{rDWwKS2uG(vj8hM0z zJ`462d8O+%knQ+4l=hfBg@>OZ+G8pt(`AgVk$p~5-Ue5LaLDUhF2Sz92khD@7;_0b;am6~0SNE+uf z!!8%+n^n_vS&P@Zf(V{ZJ8EjyozRiA6`6$g-2iC)8_{jr7yYIQTn@NiNbX`%f~G>FZOK=c=JxjO+ByMwLJnzVUiAvvVg?38&dI)rGrN`e+&$Uq=&%ACjgIq3i0;GU|&fZ)k)U2o3`oe_W)$C z0de>yvc1&;P-h+_OO$t+z`N?pdwn2s^PvgP0?`F?}WAgHT#jUp-T1 zD;27%g-Ogf5KCnzZ}^r_l*ZpU7Jw+*C5KhNVMfWgl0WM8HT2l zNAChW{0JliRPpHz;rHkQuq%H8al1xX-$|t9is`Oy}L z+*lgWdKPs_%!K6QR|$<0_8slcj8rJR3u&*&G{2zr$E{mP3%wHJ7L6#Q^CsvzXf5ve z9neCK;deSJOOPl1a#y0Ir$Ag*p5QvoGf#IRZHJaYkEf94(puv_t({*|T{1KX=a(UR zTvJ={NYZAs1>D|}Xt*YpEIBrnwO_JWbN8~Ql-8ycX=~+EkDP;?_b(mW6!Keh?sMiP`lYt+pL49s7p;`%KTPs-| z_<*$C?E%rV$<|zX(|ePnubS0H_WsIDz&b7LR-^*Dy-T$DOK`bC)5+9w0U!i)pu(EI!l?_ttHgG5#Z~-Fqo#D zm?d%o7vz!StQ>+}n!6J<4x(h5?cUGiRy0-1D@xTvxs?rM5c1y6suYgNU z?Y?b(7)0M6NIR>+b<9C1JA=@IPXMj@lQ$y>@O%rRlkSB5*GYt4ln%~W2JxiQU^6=q z{Z#9U-Wo%%4zq73PJpoArEfBhQAgyB?xHMF6{jibHuMa@-)Ks!1NlkA$OsK6i zK3GP-tZc;l?No+rm{VLTPe2eiX}W7GIlm=$bts^aVHK9{FggYpH+ceBZ{0h^!99U&&6u+8Bjz*uuB~BB;)h9t5kQ1}$ zW^%+R`i{)-4KEV?W)sAF?*-Hu4M{ugBh6e*)Rcp9vs&4E6U0-cZ>3)%^y77a4hGm> z$0@g#liGJy^WV@Iid8j6WkWnWozR%^gyv~ocBg!rUE|4CMpoeE5rB950g{qv%;|HG zY|5v!$n${hH$j&m`)tplxu>A}E)7JbV-z$!3`A}kImRv^ZB{85^its;$g8TH4tPN9 zXDY`I^~cTU$yU`Q8ZK8n@=fZpvNd3EeOUF41`*u}E*0+}bZuWq!X%O#KO}EOO()gm zGdR8gJ1&gq)l%JlDkH2k*@k`(;;SIQd^K?VRuJQ4RENnbCnywR@5ww*Xr;zb_Hw`? z4XF?0ia)!Ex*WNm=+n7y*`a~{-6}$rG#{nOgvZD`%-BV_=^crVa8b~s{lU(bPOnkd zhRe#2I|9itZEXy2ljET~0DDz~7nhQ)!%Pt6HSc$Pi6XD-3-OX5qSG_U`_xkCcD+F8 zqX!5je+Bl*8PI+DBzaGF0<4gk8}&Y+EyJPfCstE4h+gpl1-Pt4C;H z54cp<+1(;dZO&(j-oF9t^Y_6ZekCLw<^QdH59}M-?s#2w8TA1<&ZtGtS0prE^JSa< z5LbSWyuZId+6vJvuTQqCd%^TK8P#x2srgE~YoE$kN9Y!i}={-H_8)ZkxwoM?rosX-HMdUlinT{#`>Z=%vsllu$5LJ%D?|RwJAAckIQ5IY#9VYaYN-Oam(KR9Dz2hOka2@HkRIlFtGN5~J zuwPdu?Tapy=F`&mvj|w_?gOz_Hhayjr1ckrR_d84eMYkE|oQZZe?L%a9zEqxqtg?xSI38#J0C^MgU$EC!z|+h+#gs5sXd1Idzc5P!HD z278mJ+W7|no1Z0mpGNUhQm|?A1-d*Bag^A%(lPn{+RyHNKUhy~u&u&HCm9UTe(Yfx znG>>;Gs+M>@(6i5eM>=+I%V8aiyXg&LGr6?@dgd9m8x2fbf(t>0H-8WQ@a1T7C&2c zBOvZW(#Fc8_`M!nrpr0G%>k<^K0<@FCW%sAhDu4k2nF1#`t_B&|8-YDS1p!*KLEeO z?cwsSbgTYt(47`|{Y?-}2SBn*-c9v+0EdSBQSBbpluL5p9=Lp_#aZ+OK&e>3M~lFQ ziNSCUpJ&xQ+cdI!>EvwHc|t?FlXk6$zY(i(t%=sDKn=QRtE7KFNHX67+g!u!XWcb8 z*A0>rvb$$G0VdBNTBRJJ_R|Or)8Eg~8v)+v z0wSU{bWJ}c+ECNyHZAPllap|0DBzhFNvrxcp!`SBJ*9$b<`Eh!FKF3mz+*~#SYXUD zK_m~72 z(E;$mLed^l;WufQq`X!(3o`&^HQT%AlGjlN#BI8x)KVQ<`yinEm4Fu7COy-hQ1&&@ z&Fl<#?q#CCq*JR|_YqnqNt!bVP5XkhZ0ThaRs8HsI{CHnL}y8vUaw2&3RP{QeEu@? zU==E1Z|n@+$sY;5dK^$!)9g6aZ|!jCMy`eFIhn{W9YmLEOKOZP&AIOYUy5$XbEMra z`#gO&#E)(xt)`+Q=M&m3KfBeZfFI?g&e6Quzd6xd*@$EI{GloJb?wfqDoc(jdC)!o z0MX>yh~y7i8f3eF5k49}&&hs(iLe zoAoN8Mz@2l&xzk7%K@jofMrtvPkl&^D<7m9+4i`X?1K{^t}mwR zWPz(F+r}S=9-IOwQ-ZV_@>!S532dlY?e3vOqnd!o)gI%ScZmk6sVn5Q#Au)Y%^%4- z`9Z+EFw$xbC)+eR1aCATx^)`aoNWQmJ`2;y+8dd!^~W`_gvuU;WPr)rV5MSJ?SKPOt_S3+}V z6M9(ZJ=L{h4%2A*x+MjDF^{xu;(S;e8dqflUh7Eofj8k2B?hLpshY2+jB7Ulc0LNf z+ZvGfX4&i|I@bN9F3-MHLzPb($;bdHs_|^&{fgaWU$sL+aIHh-jPIi zo`Tgi1Bhm5aQP(D@*4ctuLnCY6fOfK;*V|JlIXUKBggM`;rH@jun$UCS0+NzK;!D^ z5rl3Nzs^a}&6*B&L^P~=?xGs!tAYJ(6^L``AbNgHw4t2JZBLS;dlRCW8lrn9f~~G= zB=5;=ZdCK@tp?n!O`X144E)psMCG%PBtAh}BZ1UM0ChB^M#>mPc)&iT$@NVQno4a5 zy<8rWCw34zIEEst9;V2;?crBTgLRjVJ{D^?U_>hreYEHrB1CO*Y1;tdl+!9TN$u@@ z3c4_jh(lWZ4AjV3w})t5tccei|8TQ;)$Add#fGQRI6xBMMK27($gReO{q63?cT|xjgjup8%f%8jR3Qy z?A677!57q^g+@t|M0{Ge1gdo+dW9-fQJs81qt2nR`=y5W`sR?Nt3@MZfj@YH!nbRo z_=6m|Z=_6-67jRTMD&Ba`bl2WUJ|0K_PHkfL|U@I^-}?l?}h2+8swPt2GI=~b=y}G zb!lO;+D#en-bZxp0kH13053~)(a%9QP>#sAnjA*RE6tR-Ii`Ek?S3O|MGRo5+FM_3 zoA4I==DiB`>?DZ4(s4~Ctu?|D0Yl{vJz^1>FK_*2ZDT~fMX0s*j7EM5Vv&~3%fEz6 zMlfkhQo-KQl8!ndC8-w=xcvvxVz+^9Qxfp-QgUSL*lGHB=-yfaX!r_sS$6{BsM=tM zEAP^NASP>0j%W$-TT#aZub-d#PLi^+-eD^*%{O4Bbg!+skZJ_+C36qE>tM^9@ zqJE$1Ok_zNSS3pbUs?k8UJ0UtMDqQ|@ar}X5_`Oq)R4OG9@1Wtp*=Q_Y;VjXG+lNh zRfciB+^AU{;Jiuxc(e+dt?li_CY&c}P4}EccfKu%9@2&QDP(J}ye&1TtG@&2I~L&7 zYW7%LKz0Yf$J*I3*Oqrp_X^kGj5sYm(>9+ zegV9A7odl_r%HW5u#8dJ8%XQ$ETQR|b!$Zsogo|By9G_yxtY+RWt4X8Ta}RoSn&*W zJ9KC}P;PR%CY$fI6r3x&R$1FDOTtNeUHc$0n%`Px!k~fFVD$t-ebhZOHbIg;nY6yG zC}Zw2(pJu;$n+|JMN0t-wFJFdy8-Y21aaOWh&L*2i%iDnGXM7pJTVpG>vUxQTODM- z^#P(+iSsbcJ+owyy1SuklTF@+-w_)8JRofhOvg!K$G%AIZ%_jduO;m#9r$jS&DpFC z@v!Rwhde~TcoGH;-Y0Ke+2Rd{z#Y7FvMJo5GT$gv=B6{sea!eP=(CUzkZ3-e?i@gt*0_-{dUU9j> zMYOz^N}4C3o1)R)PIOHsP|1Dc0kh?9-Eb0;1rq@;h0~5{$6-G}VyYp(c&LkPw(t0W zHfGYaDmo>j)m*1MpG(<8UjUrauHO*t+`WB*s`c#yXmbw?YA&RpCFTS_IEf2Ys zRv1a25`7~9y509ecZk==a*j2GuEU*x*Q=4O)l1NwRGn|oIPI^aqif{S-Ft*+B`={~ zDzc5dw4@b;=4iOTq1WvRg%y=ExDi5ih1^OqB-&e`@aNnbWIAXI0k-| zB#4MwM5DDYzdZ-K_cv2UHL*V`{hgvp9?^bD^5aBL%?Hs^$8r6{e#Ax)d$mCAs#^zT zN&#LEg)U2n=%wV>%~A~vZKy5m1>KKY$KS1O8&4xbUuQ#7O7?1&i?sc+FV6P}-K^>9 zCLI{Pr`hF8P4r(y!R7Z^fRAM&zt)nwp}f-59zx4rA#Z*iz{-k5M=l~Xz72VA)VQCf zYzJN@wBRNXw_Qa$)@uW&%U47j$&|an0p&D&?yXIZAT2Y(j{y!z;`Mc!JNaWm{YR75N|!TU zTTI>q(SW`)L7dgF=sX3^-*%vZJNLnA;Z@KrWfR7JldBjMOQ2W+#S$o%K(PdhB~UDZ zVhI#WpjZOM5-65Hu>^`GP%MFB2^349SOUcoD3(C61d1h4EP-MP6ic930>u(2mO!xt ziX~7ifno_1OQ2W+#S$o%K(PdhB~UDZVhI#WpjZOM5-65Hu>^`GP%MFB2^349SOUco zD3-u~NdmF$jnwaBJ?6p8_=qU|0+?YQNHljFX3H?Q*_Qut)r`n=BWCxo8{K9s;S3`t zeaJNl(c27igy-{@Xl{(&<2JWjx2?+0&#mlE-Ikvao#r-4+hINQbbh{(8CT6|v))ZG z%wNimEx`^ebTe3UqmjBP_Q8#p)k3?zQLgcg9BwnsV{TU^{0tAIl%&|)itf~{`R@F* zX5)F!Hsz#Y?sl8otdr~ht{M|I6;vbYpQ_>U#z#~$y!SB+G`-fF9d=-A%UfN+TMG89&bFWov z3-$1pGQ7=04YQQtE8ofRwhlAQJi~k_qPt<<7tsmU9t37?wZ2&ku`eXXrcT`y)vfD4 z)&0)|?4cFme{7WNKG*#&HO)}dqWn!uqiKneTNBNn-Pz}zlM?xT%i<}uq*-RSb%c_Pz{;Ed>Po|p{78MoCPv(w{@JL2*7iU@a`9~m=Dch=tCmYnWFW=7NZ+ zDzi{HnQQX%Tl$*B2s6*F&C?Mxi%?`)OQ1l)F&2UNg`x(AtDCE<>!E+IFaNB6|0&JzJ`};| z932sssG)n%Fi)dZ9y8mZmJvxa-KjYx5@WKHt0y>Dm2f#%1tqz>CETeQC6W@nK_F7T zaGQG>k?xp7$=5q;IgHd}CFr;0tDp@f3*-)WYFddTZ&{L44!g~b9y8M&b2j+~XRUa; zEY*TO&880{3-qCW`Y@7H4tpXGY4C@-v(L8lg>*AaYI=E=;?G;|w;vv}WwnIpJ@M#q zI0nz1dOCDSNy99g8_Ym9%w}O8Ux>?2C82V3n#X&EddlN%&sf>PBg}ev{bkt<+e%20 zVx>rpq(~BZcf*?;(bq5;@du($5{@#ww;SHUbj9E>X&kzR3f&uKq-F#q*Dh)}cH4&I z!!2mffONFSI`)cc(y^M6dd6;rQ?1A{%oenwyvt4{p=os5RBR=}H_R(&gf(Kur43Si=nVDB_Mu8y;==M$6>n8QJ+pOslYz3Vg|0_1a;rTckn}2bvK{ z9_Om^Bk1GYT9?qxvFYNVOG^$;@WF~y+?~DZzd|81umF)3(8HW+Q$?zsP-R5zR`IQGt?oB+p#TDvE zh|c$TM~3mg8vn!Ny(8-yzLLZFn6ZI@_m!Muhg?xE=gPE*psB7#3hcHNY#i@(H!)Jv zW3A3UOiQA7Y+wEl;{S+5@A~o7g@>#c51A+)vRLTX`b9hwrmp9s6iVfrN_wdFZr=>e zE=H!Sntp3lRWnjYRgAquXQjw#JbYU%TfwcyR5L~N}r+*B;7~)J3&g%d(BQ)kNTS?`Hn3_ zAMm5?xyhH9X>E#eIOv@YKe^2r;$>yMj!-;iEFC+7j-^kj#%{!uX-!5vpb|>EQ}aTH zgyHNMW{00Z{bUV6sRLY8vgQ42E=~WM%Pny6SGswCnd)gZ`D`TW*%R{+~_@ab4q-u$s7W+L#F0ebH;d;cI7j$vnQx2QFXV(ML9C#?#SoQ@WnMU zGGlF@)Z-mtOE}Dy@D_(-YO7B1Qy+a`OI&A1Zm`?@(lE~&-Y##gu{-75Q{?t0Y%o(^ zQQ5b;O}k^@zBa~?AM=X8$&)G8V;)w?Dt2H&lhrG3Z%9NU^LJ>1CUMu6_=qY&idPc| z7pSYmD2Iz_#csYE^ZwWEcTM#~bV``oKjHyplMoWkqi*vv+W3lJ2&brXK~<2zm%@0w zz5gJAM6>yb0tu9UwNL`X1|fk##^jU9_-(ta=CcYVu*)*hxS0}8dE8;d`HGc9)7`#j zWbNF(VMueARSiS7=A=5Z>dC2Pk=*_@d7!OsMe223qOWyS;^dQw&iE`%wc!b7^Csd+ zZ>&LMaUR{~3(LqBFsv%Hmf>qd|3y-qPDwT0<5z`f`dnt*YbfDcwjNRSjpbRoD z&iPAz^Z#{zcKeOgys#nBhFQj73cFiB z2R|hIWO}WXIKy=1`MuG|t%jWQyMZ?jzgz0Nf!UyNM*%5?73?X<&Md8~%pNMfqD%jYe7=Mp<>J3;upJ4X5iEPPo6Vs`e0cwTl?bD^f2QOMf%EiuK$HXMD@(vEM4vRgLs3_ZgFW1n zyr|DY&0`ur*V*HzqDry{(BNr=3a7AoOYO3|jSy+g*hWJ`lgrvJ^y&%Jpl~889Ux#2R{9ZU7{?h?g;`l!C5#d_=Iag}us*E)fjhji~js7^T2KGmiBf`}2 z;Tkom>D8^YfSgD zHja`&8fkd{Yir}2T@x>oUcq>87iRb#2vcQi6)8MB&x*y*xXiggeUUTpV*cXTNqflQ zhOedHR%V;Zr4&<5&{2ZRM-%_eEgS2mkw%sd?$I? zp}nkrQC;=-CtKC`U!>EC=5Z-0J8P*~P9rt{{4h55&g3?b%jGt=8reC<>gBKb|BO>d zjqGFWbPl`H$jr32gXq}Ebaozxhq!%B*cNLOgqcnWi9VUz%9wE4c2RCKe6AbuPKKAX zCQi^;U@x9YhLu@LDeHa={7%C+=td*;yTb@3FZT*-i?CG7CTO4;Ah(K|-Q9zZ57Kb& zD`|{iy}}wqE{!%Luh2fuUZs^w)Usfgl`>C!7!7ipTFGZJ%LUw~Mz~GMrL6soeohi> z=V?eOYnvVQyHG<*S!?Ymj?}PH)|-CHt=6DPFfBNsDL9=es6(*ouuy*{_kyA`-edx{KxUYR$k$FDD7UOPUdf%JLa^1VBG%q1EaE=?RcF%Hwvfw ziWjE)6&Ret*?yZ=0EJxqy}??*hkznv;lvbC zgfu%^s0eS{QNJQA@l$TK`bd}k=V@UaH89>e0P@z9qH2#iN`w55{z2hD{5J#tBwvsD z3&YnciPew^;lK-#uxK-{utl=f`uqi3B)E#BIIlXRoqDEZ4y)n{536=q53=P!n}#87 z{D6?LJZT%Q}%?vlEbsUMsWDISCFXjHg)-N>76PeCo52s}! zh{+hzP{)D6yEzez-bOb2oNvE7I3qFUpicR)!aTA$tVP&$bE-Z`g9&WJf8PBD{__MD zEtetV0)K}Ypp1rx%buVLhljnqq}~4IWt0(EUfyaiFWG0_YIPs?r~Z&NhRJWIHQa`S zZTP6*Km7&fSGMNdG1-YG?K|LcHrtaBeJC|6KM}R5nPBcnprTD&Iycl|oPEUQtTjna zfP-T+M^fXUl!~~WoV%s*|5#A&Hj-Rxw7VbgY?hU~!HC&Aw1VF!3FNm~xtw!1+U#8B z#>*VK>R)MdX&f|L{1eXD3Vowrp|=ma)jEYjBPldBxsH*Vh8`bAkBvM(J@)`U6#;s@ zKDWHp{c(vc79VVHC{#(^MZ5IM5W-aIG?cBhK)y78+tuEh}QeF zCCvQf-tN?~I0o#-HuSp)H!%C>UJokeTO)A(6E=k24~m`IDECfH+rf_9+pwCNcEXI{ zR$*>mm3kg?i*>73BAViv(rs5GFwKWF!gG}G?LVHwW$S-oVHWP{DqT!|4P9(1*%4`@ zh$S^3(oB&Gt8Wr8ZLO*eY0^QC?ClVt5rq>qBtM-2mgR4>p+PF0uwG0ab_X{_Ndzl&6D zb}PY_pfxvA80T1&p+wI0c7=;`oJf}FVTnTN?Cp0Kbvr0CeQiA z+qSd|6r80>}w6eDy{EEW89_N%*1^w6xyT;nZIq6UOk&pUctTn@J>ztq5)0X~_ z8`Xg~r~`kpw+R9sFnUu?9mp>5jwEkzZUdfL9q*c$22 zIDT)$s>Y24>CX^F$|>^S{8Rri-q>H#bP(u7|9o<~urKZTq(Fb{xdeY}d&+HYUq~aP zu`A3u(XT)Lp>8kE%4`V<;)EIzStk)k&V}h^d4U$)sHsU)%)Q#o!f5p{{8NnaXHyJ1 zL={I~m|~c9?I|XbGL*Y~OJ9|STraV9dHv%5)9FQ%s2Ww<&q*vwY#XCef#HA>z1jP*+cer8GVz)uL)ZD3;qi|a6$h6H2%Ls zSeidBjDIY5dB%S$#{Z|1WYM*T-7WoU5HT7xus5+Uo>lD4bGciE`e5PSs0X@A zA8bQuyIhyfESgm`y%f$Y{)wEEUuKo2Xu~jT;}pN3|6)e@Yh|dgSmXaOzcM%!*%62w zT0|uIx&J~}*kD=noO zN}T;XmFt#Ff@zA{a@xC>rm|?M9R0`ao3OwI*)xEF$^A$P%hIc_kD4QIHS#tBc z1$Q%VV~TdJ{KcbvST5H*&IskOlk0En0o1V_(&OYmsxye_LtIVzGRfN|ix&gdju&TN zVwP1#V;BS%8ncYlF-Jq$cS^`g@>YxY$s4X(iC-7831iu!O=?^#rDVLhF}ISN_X@ZV zou8J}EVW4sN6K%Suf?xAWNU9N;J$ds#N> z{khNu>RwRuKfmT@`YB7>CoSGC+~e({`+sj)w^A23yQx#MJLhaf1VMpY(Oa!@s07q06$`t&{3w6rZ!B7Q zwaaPcQL=q3mUx@4FZr~9<@%D{e-k#PAs$^{`ai$Ar2QrLguK9AlZ;v^EH;|iyO$A0 z!5)@V2TP6J>4!ru zssj6t{wmyDPzCnXr~*|htirZOsKRMBMR!^!Z1{r>kJ|8v;N|`Or|Q#K_33Aq-qVI% zY}nC;?F29H@1pvQlYAQSHie_`HV{2@IpTS(AJsX?nA>T6Y{OkP+-k!N!OQ%+s6I_q zpC)XaPiFZ3%XPX^b!u+cAl8O=+3*e<))TypKiNma{GMtJ!VIo|v%n1cmno;MDd^~= zH0PvT*-7l>B30DaVJqi_9`Ab*a&E0UEXbUz5u^|H9%SX>3=4HuO5AE1Vcx|3&Q-BhxJ&+7l5^;R&?Lh-b{m)9 zjr5!_Bi)Khib)@L71yr&&@`9t{+@Uro7BqcPx%ER8NhjUk~eX+D&S36Yh5`gKR>?F z@X%!4*M1Y~wf+3^nWmgy(wcXIwzMe2)SqR!2HG{VC6Y=$guFVbacD|K0&9~R8zoXg z-VMqvQU8!uAX!%B0C_+{*7C>byF=U>>IQ2jp1yiG6LwS00V?cWbS!@A@G>6L-;q+2&Wh3R*d{^vu&U>6wW__$nOd$CIrDjS^FDvEY-nMJAW` zQb}R`!VQy`C~y^H&NwG7woBwH0B@_M4X zfQu4+6~3EI%ir#Cd8Xt~yXfNfCvvP45CK15N_hn$xUN71{(VDxUES{D>Ljv+U~8o4 zTPPddk$7q4+p_JzX=QSGE|IV-c3U^$r~S>!>XJqVsgXOo|9g!r+P>5F?VIgZ40=fa z)KAR|O0LEf>#J~*5p<#Va_;J*vBcg@R*}RzweGw$u`RCMpUSl$(Y`Nezx!q1I8${x z>G-I-Rw8}vy`~)84C|EvypV%Y-(@|o(0+v;>x}-J8+Eeqk@Ydgz(7ChTJw1YXQqZa z$CoII&V<_*yi`F@Z&iqFIR@8bQ}NztUHi1yH=a(l)?spSnMJesA+3Bldk#K+j`j7qPF5^Tk!HaX2X z2jM8%q%hjf@Xgt67o25vmS0X>Ws9n%Ki(z7&kzn7$%SLD5pu63rhWUF0XVc*)V%tS=QfYz=0H z(tdh8w^O_c_?gGi)6j(IZ(QcNTweC7skA)eOq#DT9GEoU;xYN8 zrpDGvz>IzRpck9toXp0UayfnaV{^~Z*jUOG+)}i+^sF(HNX^ofTq_uPC zwUfm0mSHC`bP~tsSAFh&O;mOZOpOiRy~!GXBxtI+NRiz?xyBz2il1t4g9P3Ru}fuH zY9B`^lFahKUMwoohe&QUzmj&h;-J$qQkXmKJn^U?YTaG^)aim+cPhy7G0ShMHMZkE z?t}Uz>e}Kl%;Z(8nK~e<1%44c z^iH$JXtX@Vj%g>H;}T}_O3xzbmKD&gE~Hy#mAgQ<47$}GbMjQ`P;^zOK|jd)N;}P& zHd1RfN_!X>BR3t(9!& zN$Bg((7U_JK_@0}C5KHNC`bKh_vmREkGMm2R zO2QkPH%`$75w>-kut`R*_??}L=ZF7vOcQD~|J%J>58%WsQ7^FTTuZkEc;(zVu^%SO z%_T8+OnM-~bs!Gg3>`pq=VY0?8K{Tt=_zIu_i%ym3qepx|aE2V&)NZz4VAd%ex=_X5k|1;$Q|%1N^+b#RvRz8z!_ zl-rzzXGi{fTbsGC;j3~JzEfQzILkVX>*0?1BE_XLIIeE$j`_*$jN4a`wOlTnn3pip z0Y+0JI9o?Pu(95UM{d1KFOd|MD{{VLQ01Ni`cN%a{BG&cBK6x65=BdOYU=kz+e(PK zxF4>O-bDv_?WUGy!PpVUh)BF5&OoG=BCDAigsH5^az*|x|LpzrD5k~CX8!lCyv-Op z2b1)XgKa2twk9To%fw`jW1?5HxeWN1Th;da{<;ru-;=Cs`#ZeipJub+JVJZLoEd3Z z!%$+J#YY(NzF4-M?~5?3@9b^yzbnCrnKhGqyettjOZ)4|*ASRWz&WWqo3%v76GPaI4i8bH*h<+->{E8tny}<_EM^^)7>n)m+2dH0^LS!zU1St~_qVF~5%g zU=dUf=StfhOXkXvJwfUyAu@VTe$|m}?A2PWKze@Fwj>ytsVkI=zb&b9 z9oAS|ygMv+Z+qJ@xkA9tO9^?0MYO8bib>BMX5GSY(s;L*TNln%KX~vzFqSTrkAHlO zAE~QR2XWL3)}tvEtrz>M8iCHTT0UGP_SYlYUJnc^d;>*WHtIdYEcw-ffG=#%?W~*d z+UW^ltE-;w09#a64y{j@co%T^RU^p;%H z>dwCKPOGyG@3UcR!9W}QrM^hF+NH+Yr6vYSt$Xps-7D>Ug*Vts+tJ9adI^vl?0GbO zr|Q8C_V4X5wRy9HB=5l^VhXNmkJErqwJ~z>@c-+M`8P4PzS~!$CwxDiKDel7S1W-P zjXA+a6+H#}csxD1r;}>F!+MdWLCz|?1$O8PcI{lNLzUb2w7rLi4vB^JSRy%i>)$zX zD&$7$hc-5JsJ2AjhUMBwO;ElHpO1xoeHny6#{2G7IKYg%x|~(}IX38W5yF{zn-~X> zHBj@Mnk4w0LROm|dG7vU^=TVf>BIW>15r@Sn!9sb;Y6H&1!GbPhhpe zuY@?Rl(c(cHgb*@=4l|xK|e<6_(w5nIGbcQIB`0xf|slU>x{wtu+1UYRjm zUx#1N0m}}f1FzA&S`6w7QB-@4U&FPVMlr2b46BMu?#M6qXLjjL+aaZ_1$MNs7+;ZM zCKMDCM=>*V%P~v~HX?I8zia#~h_J`{giYg-?|9cnWqkmvVs^(nv3o^t#Qw{# zU$G?HUq(RSng?^y4$^7~1#?YW!%p<{-ZT|CVUZ3fAvRK19A#}U>tF=caP zpQ>8dZ|3}G6cgEZDzp$x$^Wb8z#j86jqdL5%(ygls@wZunA`hkHMic(HA@b7s?h1e zaN=|gjs>&TxpH7=EZ;zB#2dn>0-p!EkJkA&&oKQMcK)|b0^BE?3#TmWMmBb4>eE@V z1#*7K@9{hYo>!@hezd50e4(IsSkKsgWI)jI5iKu~v@^gH8J8174(>lul{PWO+EYm< z`90TimgMn06w%#nKFE8HkA}O=p>^Hn*Z-bY{Ix9^KeCJ?ke% zU`b4QuFMhJO$+T$x}=`f&THaAkJ$$0>hP8oO&`hq2)9i^hlNn)Tf^+d!G4O~r$*Rr zUP@N{)RYYgzUCpw@7ocw5{VnEr{Xk<UX4H@>6cLdgJ*}#Z#&x7U-uf313oV!oH%V zY`D0TJ{OnL>Ecq{MM}B5pcFpNsZwk~P)gR8gbga?s-mUjUtCJi#ijhh*2K=hvV=v! z*LKw3mVI^@hiJaPl&b=5ac)V-N5CCwu~&X)7(GVFoH3JzS_3d#80dv;1SMAq+}u(3 zOQ(Ix$G_<< zH^8Fb^`@h)<(W^8*Ra%nx9;4@{mD5&CtsrPmqrWyo7f^NGyA|xCF;|Dvg-JAUcN}< zb%lFfbvavTJ`81Jw?6DG7xwnM`07 zKRc=OOUkyd;kbHMI(mSlqx{?I_P1X6#0wkq*0t;dMeEB%QQ9HLM~z|+t5w}0oS?*2 zEAnZgR=jKSPq#R2f4Ulx8>t)ppFgQcuiHlgJFG?iQ>(!DPXb;u z7kvFrGS~J96db$fgy8gCIsz_^U%KB_SPAnNYXcoD3H(_#s{dm(tS3-cK6t2aPYjZr zupb|ESGU{OjOjD2oHcGQog*)<;l(i~tvoT)zLPy`nI+du3(QuNA`aW-WNUD=wJNa^ zv&TtW>pN{M_$n+MiXS?__N9H(BgR8)9Rj08`wAjXpGti$ z9q}*blX&_`Rpit53~5gHR|J#w3=2H#q})w@G%Y)N2#Y-HS0B;^gL$$ub2huI%h1Rahh_mWU_C0t`t;VeJMy%W9O}xD>=Z1ECBxEZ$ zv7+Lg8@Mc^V7PO`w)kKUU*h>vp>u;fBse=hCSy!gV$6=@nuf1cXcFVsooBW?=kdAD zdE14UmAvgj6IohYE^iQ<7*$+eS4eJ0=LS#2l}wxGkUv! z%e%rsq(ek-x+6mXGl0_R3if zlE$mhz8&Y|gVSupx!~P&l-rqj+GU2Ejq`@= zb(!&JL*l&gdqX_tK6lLd(JKKd*UJ8-Tm|w(UV!SvIX{)}e#F^7f+Cu!%65A^eB(9d z;249lB1$v55Jk8br8vOTT`E3! zw{wGwHf~Lb$sSXk&6VUTW?3`XTf$q;Y!+g+3Sqo@<3bpwu>x&N0a}#`)&PzR3EoPk zPKhxalWS;%o56f$+vP3iGNC1_%d7EjXSP9mq^rDzS+Di*z3yr*vz&4UD`T9Bba^Q@ zE<_Rvz1S}Pp<#cKV7J#kPtvF?e4p_bov(7wfK680l>ThY=VJzW>OSn9ZXeX(z308w zLKd|scBm0^VrYHC*Z!PyLkYyyQsCaQ2n$h$BD#c_?V~FrxX~4i)LfMIm~sr+kF_K)V%Eotu5bbX?n64R5B<2K2$k{N`B@>X)0t`M^wa%>lZrNV!N zDr?AVo|sREbxQQLJg52uCBPq(RfNA-*Ht0-9=V~3z6Z|fd+Jx3SJ1OwdguzeheEvV z;T*&lASgd4)E)E7kQH!F=|dULN&97-RV8=Key+8V)uF6mcGk8bcHUTqA>ZvdBrB)N zsTqkeyhL;c-@>IlG=ogELj|fKD$*5_a{vMrOi?MkKb(vB_Nw8PHGoQZ$;p@%?Y$a6 zvaeLbIq5~R{Z&J=NVMPw9pLA2(tOd`LT#GZJf2n z)4@!?AzcFY+OrX3+9_WKdgD3S>y4#?vw3^d7B4vdk8Y+xSKy zd}WnytM+GW>$5g;#xPOJ5GZKOdd*0%p%6)-6Qj7%zqzKrWIU;HFs5-iG)`a3P?`SK zb!uL?bH*&%q$?{k^f3hwz9jVz*M1Z4f!F77(WA?v@;m0UFq6fOzsO62T5a`TKB}+>mE8ZHw>$;--fw8uoA+P+DL|gD8ijjveM9r zW{J^!)M>N-eytUEmsDO}EyDx6T_lklX&o)NtItQo{@Wh=0>Ts$hSvjP*mwajcJh?HjXF zo~)H}i5~28aC^FW35;;$7f$^?iF1`F_pjr07_t?e`jmJ?v4xlHzofc zduIY3RdqK0$v!~B4N5dFNUX6&;}QvKFrYIq19v15P*Gf16pd)LBFsRnEWt@M)9bW+ zR;z8bQkSZ=R%$DopOO$r!X8{vs(?$qaX>*U1gy;e_nv!aG6_Mz)_(rK=gX5b_uPBW zJ?nek^PYD*=Zbo7MQ8}B8?poL+MKov|Ful8w`JR1U@m1}!452I*pD(W(b!ptx{mnt zMO-OXG`HVOZ;gaKmNlE0`8u3066ZWdVpMZ-qdAM@11LPwAIXc5ya;E#Dv8bW1Oo1a z>67!*c>3Co>2J5vKPKrHS?R$@D#C(g59~veVh#O0G4m_LI5M!;k``6QXwH^XJG9d$&pE$I(q>!rW_ioGB$oWo z9h0ALC0{Mcx1OWAg+<|C9M<@#$Kb!005NE|kMg(0y2ZL@9?3c)tgA!ta~{i3yhcS& z{(C`phxH_uKT144KzuDP=o2-)NcT!SUF`c#=^yEs{%8B8x5}Fqf4-kTK*hIK2XF~0 ztF-+Adi&9ltnP49CaY7V(4O&dzE6R5#?NZye1y|^j2`A~BV{<{%pc1^V11N-v^T9ju?MN}c@$N|~q!jH2~%hk<=< zhk?Aq%?GcioM(Fstlyh*C@urt7t<#}%VpprV}Z7d;dREwHUHG6|DsP!`PvL{kS4h>&A?o)eWXlL}<@ex! zs($f0#q3ip4r5Gx?+|Tfr=5v?>hIZbuQBJT-(RcW`_=Ey7&M z!}&X;lZ>=1f1FpnNIenN3G+0U`B+RK)lfFpEN%%LqE(H;K42tZrN zOQuf==VXc8$rzT&rGRxX&jT5+j5o4Ay#X*f{cJUXs`KYcO+{lern^|#Q4)9++EEE2 z*Wv1xCEwCr9H?$BF=dgJvf2FnbZN7dwTLS9&>xjPC`YeU(k6=ougV;yq`Ve?zGJZ; zAX`c(_H}g|FLs5xwTfMArEE6uq*$cP^tF-!9HC?Ys!OGd&p=B_hpDed45og)Oe|Eq z)Rmk1iY^L!o8z6_6^C)rh+gHB=uOE+uxJV*tF zEga|naww6$`vYC}GU3eo^c2je*`KikXiE#^pqP#rDQB)KQSy0SGz0(};pvxcOy}3L zQPdZv#p?9W5rIn7ElbFPTzB^u5uBwO>jGvwWP_yt{bC_JXS z#HTa%Ky!7rs`YzPK+Q5%f#W>V`4~NAnb(p{g=8aRAxVMy>?xPRa#6WbME^9~?eI~35`fm(Thk5J~4o9_RB>vVobn=wRPB?25aWjuq4WYHt zI}nRHV_g(o;lS~9`7fl)-7Ls9;~{n&MFTLNKaK>yCV_x`{x$5WJ&fiU){8u|XBVIR z3*FVRyeNe@ZS*VJR+AJ$_HvA@ zjH6g+arotA5MTS*m#${;qXUn~TJ>5rv};X0J3gXm&~;0^g5|LXRx}<<8VWku#+$gk ziMCWQnmvtX{6DZw*QyP2fG?6SE4z%lU_&ftny0#jhzH?tvub*OIpz}gFK_~(jZ23l zo^!bs4pZ!$OE&lL(lX%=c8~C3hjfcoIuusn4nTH$$WQb~hB%$kMtA8h?XF@$an`nH zlCZTVOQ&0uwfM#PcG8xE4~)PQ9WPu~IwG(AEKK->USkVxl;(W$1nAO#bMTW?|A^ox zS^oa$wfbRNoHPGY+-9itO%M0^f*Z?=WcZx7)C)$1Vd%5u@(f4h7LqSce3~y$QM)_m zH;GSwHkzj{o(6d8tzPNJcTk@_fSG%d`<2J|vT&Klcy~ja$1ptxHq>l}+y;JYq9WF&u7Vjk|QYR@S`x9a68Fvq!ziSj4jLh;&nDXkva;Co-DuBBMcs^!dzg za9BOYMvw7196mkRgczlH%3XT!>!@;1@qobTL`7Rus-HmIoGAMPV@QDzM|n~S<~!3JR#Vo+r4tZ8YEfT&fmHo)5iYDdNaNeiIB&lx3u^|6}K8 zxJEO;q7QpZ{tm`DTN>ZweMr&EM%uWF7@h1u{d|W~bdTn=9gWrf#%PYo)nn8_i7K+{ zM8UtBYATeOdEYjhen$DC`VPq#`dKG_s~sOh{8~FMG`0}J=1BvrW&AERY7E#&Xxk^u z73`Ipyz>NhBpa8*f2@_A{|G^@n6=;+K%Pu+1p2_6+zz^ljpR<^=D83_DkX~V^V)$0 z6Pc_#WTdYE5D`v zH7-r4@r6?3YMZtmvww}7uHgNXKd@`;j@7tohpMrFNul;@eK7;-?51b*`eH`ZMF%&Ir*P&KaoYNY)@p*g!%ax#bb< zIg$3*T|dc8m9F0fxA7Y*_ji_zSmizu>gB9&sNC^80Zuo@t&qWtj0*>^`6tq_wj-vOE$-z=cW95-PaVwL zGi0bs`(gnY%bJWaJbH0g*BP&cX~1Vg`HVFsgXmPE_7);8yHxsmvaFA5-F(7fk<uKt1K`MBhHDtWTXEF~^11@gXLRtxD1VPUAY+s!WBIQ8h(qZB_QYa!`n zk;ytiA_5&NB)3h+D>NY=vs?JFd|ndkwIzHhf3TaEVdR`~f$$>2sfi3;`-r1$gF3J& z-c`48HpM!1Yq2SoSt*;%>RhR`(th^?F@WVHi?#nBCo}hh>jOPd{AKL7WPfjYQ-HZ_ zQ>XLC+SG~=1j=4f#F$0J+adh(^d`4D;9C#fl-=Y9Q>XU9$Zwkq@pCS!c9SFP)w}g>?e)3({2C z<`1>E`O}0Y^nr(p&bUy1!wrN4kr6f-If{fNd|2cp=Ax=0i36Xk60^cZV4 zraDj6qpBq0qDcS{!)Ow!^fl-k;r6Od4lbYYpJnwjRG1^?a>;gJx*fbD&msP!?vEM>#8^TGx);Y=r}{>rc*Qw3mbf)-KoiA&&bqY>`1}YO z*KO3fgIiGcFjKi`3sSRdlUPK#xRW?KDOvbIAT2R|fm7OqDGYxHE2qpr{buFj<4KC; zZpB<<*=y$0S|HOMtqZoMx`S;QGq&;ToY_zLFDMK587x&PWYH{s8yqOSQ_t>{5T}710F3#&el!hFj~EOt|P!E8M9`f-#-q zW41F@0WGmt_W4G2eida3Hw#^S571H;^5r(V^T2=DN;SC@mcIz2!yKP0HuP* zFB3K#zUI#Drd-tseV9V>$k_-ACeK+lj~tC#<#~HHLVu7*}MJw3`oFdST z!V(Lu09al*=njuq>_3YbD1`=!WP?xw#1eQwZ%+vweSqkG z`WzkoEKIWXIUW)=3OsSDHh~dxwx93#wMc==;8q*MoxZ}AzWC6IM&WLJhkmYXMvQgX z*WmAKr?_GLA&Ijkv6ZC5==!YD9oRh@9Ue|yfYk3ET@FrZk2`hiR9=DIfBDo)rGJ%& z@dHQ_@kO@2G!A+!I!05uagmc@v4K#uNdZEgV?&lu4ZlEq8!{J;cYdK6KP4iMPboC%I3r-~T_2^9%L+8c@5&Tr0l^|7#ZwsGTLd?1eiF48C@{(Qv`p=hU;^;W>_iXmn5%wG8cU zL5bQzpj7y_%=24hYv_k^RIt)IFC9Aq`LdT|YUN@Fm|F-am$vX4^pmuOm@~l>bcYw? z0-F6M)|)s-fHdk};pwq*ag-fj#YuY>JHYf6J@$wriIL>TcPgREK<(>g=c30q*&Qm- zS1JIgg|n^_61{W%CTNG$D+lg3*QK&lQg~XwQE>!U0!tfRT;Xfce<)M3n5hj0t3^Hr z&Dz3d=`O|VF2J=U4Dx8sPcz^Uftq-FP5znk{&dzNZK1W^a$96N)qYLH-XNpWGZb{{ z;|~iPxh@swCYQM_7m0JW)iQoUNR-$d-&;n;TQS*f?DT32x5&aT`zURprSbuJ^_9Es zvlQj&R9o0m;@hYP#c1VXaF0)tj!lO?;2@qZQ2%*KH$rWi+NWX zyQ)EJiNdSApFCYJCef4E=erPVd87+<>CBO`DRY_AkhaZjr$&_DgsfiW_!&4gI3@=A&O!roA4@_}YZ^z|qIP0D=YPN#)7D!nmuJeAJ*4Vb!9!)>xO!XXMVb! zm*?`bRhYfS+qH%7QVaj_F9}_Y_{IJ**^0+3h%C(btJd zthQK5z5w*37AGv)otVVx4l79uNn~d{S!Up3(ejwHT&7T5KsRpeVNJ&aBbM*!8%thv znR1VW%xG&&Hi!cc8-tuyW@8ZV(d84jVk})I8wU=tfJEswP78)XXEK26|Ka!yX|*v;%*!0U&{XME+Y`Eb^>vhbk0eHo%c1%C*hkGx(A{l=x@;MR0G_KM0P7dl4xe74DNZE*7WW6*U|D=@r4|>`2~Xaat+7bQJN-KIsUu~clpihA>Dt%hW z;wrsmcd|A$`&~8gR zXP5xoZCT}9@y?x^&ksC|sy&#OXbb9rH8fU{cuW5uAy5-sUedtfEf+GxReNS@9>us< zufLG3hP*z6+N@c_Dxc)7uB*&YcsX(|?2@|tEd!BtED;cnoU9(~7`TN8%yvhlx6nJJ zX>%_IXdDA~xHZoP&MddQD65EQP!sXblDnGMxx>v?5{#?-x`9<%O#=@o)(2Z-LA~{8 zzV&ES3XkkmkH}}QEDNrR2De=3)?R52Zq2CQn%<+Ccs-9|@nx|%WGqA{tZ>bt4c%ZY zYe*pUj2>P5i6~z2+mdIy136-bWD@&#gw8S}ac@BQBN<4+D%fhLJo?0>El+Cs*^0~)| zd@btlp+BUjY}8A~mrUUt;Rcq~@Q4EQI=Cg|JXvxUz;%h;VTl+Uz7*RZ%0`_1ZHN7y z|1@D5O!mO55L4L^&S=h$c6XCAVT6p*-C)F7%tDo!80DQRdFzsGJhOH_hh#x+C1%lA z`#@d@xOKzo6{g3?Z)xvvfMJL~w)rtZ+4{DlHA5K8+^vd;U^+F-pDg_ZLvb0?#?~H1%bZBsf+Q6ve;1B+%1W_#R!H6v?2X zqUR-hMj)8N_p4W8$9&7U;i4)kkQkI9zXN-j;`9LTmiy8Ssjqe;cP+@Z;-(&$ns9s2tS8HY*Iw1k8x z%8AF2Jh$p^xA9qgeoN15VKLOesYiY){U6S((q2gk`%LN-&eYv(6;nltTj}{oL9ZUG z3R=OqXf^8W7F9v5x{O@Zp&#CU+p9{?2=pcgRBS$z+B>OztL#_EL2RxIJjO1wR^_Bs zYdrTEpIPH6_1OnhP>EsT{tG0J@H8s3VraPkWL1$(>TM6xXH{ekdo6#8d-r=4?&!J- zFPS@4)nGzkOrjLftDh#$CRS>d%`=u6sg<>dlQ!)Gn~6ZXhIBqaN(P{d|3K^#NI)k`;i3qzm>JC*Z5FZ1-!~$`p3lRr#N!S&LL%&<_Z5$N7-?MbrWN1G> z+JbL)kO{Fxfs#_MQgzg-#W_#cQ2w3;<)10Yi9z{p^D&j5R{gcWmWAuI@D2;Sx`J@3 zvewGNywR%4fgt=@l387+Rf}5Weh^MpciCATZ`Wcv_X6QFZ9W@182M(=4aej2b$Vf&9_P{PyFZgOqE-%HT5+~vDGg6lFkcH}E2dyxE}4Wgmm=`1 zMXYCdYO}@NDO%*X-EY^-@0h{8Dg#UNJX6cgK!7PGZAf)HefO=VdyIc5O`ep2Xcd7MU@Wm z3zEu3svZrkd#E=2C>*`2{q0)wmCyDG{{Q(Fc@g`xn{YO&*QzF#!@3YcO4z(Yqq^XC zp}c6;lOby2u}_Zklw6-*pCf~r42p@D_<>{)NGn{iUw<4xA)g&`5t!Im<8E& z7{U&p+RKUx*`DF9YCA44247(_E-edRA(H*>?(>`dL(ON`J@h;g^R9@nhaM*??4iwYPHpzk@A^|@EvQV`L$i6W*hABZ2pCS4Z%Y`;szDRw zksqxH0g$uKT>rla}Ed{rSZAeeCxY>eZhcy-zs`cLy8c zQ|tt$J;pw9lG94mtU^?}SR@!C-S`=mG;&@+Y7&=jAlPUzGLr^m9nVuG*f^4i`JO2- znnBbOY^3)C$hP+u!NzAJ=;CnJHZJBf+XNi{M%3X4BaYq;H}5I)hBWa^5m%?M1Q;8O z$>F#E*rzytyUkzhVCsy07AXMQEh%bjK45$zZpE2lu8rOd$Ng@hBr4p6cZ>J-ifEm- zv?aPKG`dM!>U}=sUGFW9dO|Z7QfL!y;@6AGY57V_Nf&ws4A8X^_1Z!{PO&}?c|VX0 zKesa!MGKW-b97~>d_5WdIpl4!avQy#+?q<8$qiXtIk}xrZmZ;T^;t?1hc!`%RfsMVSnbF@{b*kN=NIR3gNaNB# zR=gy6WK9^lX1bH4tl8~z3F-olME)2?YZ@5kPfS6X?fRWIb18&Sv6YNR!$ zo*`&hs}`429wY6i)fv5$2INE#A*hM-J`wZDk7VM!Nz|G+YtN+T|Jq9? z&MP8o2xq+{$tJhT#Ceve!+$mt=L6tux7o_du;0X4UqlW!?2JvEtG2`Mft`*ER`W?& ze;Om{%mc5Ym>3rJJZk>^XJLOUy6*e(5%#Sz1^ZSl7BF)7kE~j(G`a%as}`H; zNfLbQ1{{QG_jkoERs1yj{5FmBU7Zi`*bzcvckLBe=@%o|THL-6LLZPGHRBe^&q(u~ z9a|7F)DzKG@g_@%qge%x&8Qu_TZxnk6bPn>%rG<-b#HOdKT}g8rQL{>jEhrQ9M>DK zDNR9GEFPKj^-6)Vdvuv-Mefa*u|2rgIrAK)DpC@5e}*)+1>;8bQ-$fy7qOBulX5nk zrsP|@%{N%&w1t<$H)ImcWR=39#tSGUG@BnH*yatIIIGR;trzY^Ogj1exAHk@9^`9g z)X{p%=u@z-KTFaEc~*6S!+%ulz^0t4SYeYSx!4&{)*Gy1BEi~iHZY-On`D%qCt{4@ zP<5h*tVY3_i~mVQI(ves{a(A0Ow6ts2M7xQ1@Q``Sgm7uMH(H*cb)$if&9R6 zuJfOjNf9{0bN*jsQUtoW&VNZs)IA)UM+uQrW%P1PxfuA1T%~K?dKlb@&8>}y=3U7a zy^NAGfURjy0 zsBVNO^-8dmu4JIMqSqGAwbU1&S^L*xPtKtL5+owCt z>ZxbMW;Ft9WFR~BQ29LE_G2;VMz%$Kfq(@S4h&ohTFi^H*>&+j-(FZ6^sq&FRvfvY8_XadplC-<) z6$vvHdvrO&^!IXCx=(Bf&{2Jpxi{Y&@lU|?7&)`_L_Ng8Kyq48Fsd-ue2y*Uu!=g} zn29FZF8^5_UN)wtjBEd5X0!E)bxJ7d)py8oTF|zkA}4gHNJfbG~5W%xuBBrrc zMz^Rs?nNS~v?yj}Pwm^=-6jHVZs*wZz` z!=ss&Dk+h0R?|t;A^dk)Kn*Y2X(+VWhXKv+sLxghDW0Iu_Gfh)*Jpc7-CFu=zqC>| zn`1ywdidf36wct<)p2~dId`M*-bCHwD*#Ln&MI;E`&P}$a|G}fk#&hw#zAFt<6=fW zDVp6lG%qQdv+V6|j?mo}EmgilR`%P0!-SQ+3fM}}r#cX3|GrSH|GVoU{2@zS)H)4M zG+p%{#+Sm#vvKS!(VIMwrFM{7+i-ro_Kp&p*&h)h+H^Bj?zRiwlbxmHC6I3i<+^m7zB zA|q7fY)53MiWEB{gH(ik`V%>ud?SVG36UQVDV8V45a}=>1GfX-ectM|{uFPIuX*J3V^_64)xG#Qa;YF) z9`n&H4sX_&MQ_6=UwrlcFOHTMh|ETT0=JbJaFx9H5pUMRfo)~luy*+_W7$*e(EPp0 zRAo-K?(oPY^9^RZ9&AkZMH|aYzYM(TeuauUA}4q`Dg0vhVrhS;$~?{&^0vsmxOD%w zHS#t*;_OZz{g}rh=yb)(w^|nbDk;#-8`fu8gRU(s-`4sUGIirw-hZdJv@tMHddq)q zv0x{@iPhZ`9&wy`44D$Sx>H%n*5j)pKzi^~lWXsb%*%;>g}PNB!@{l;5s(O78=`9LsuN{IH4*cq#|PLt4~Z z`}pmm*>QknP$djmhsdil%TPN@tjQtT8@22fklZ1=MAQrt?Tx~1ikwJr7n|J4U2L-K z?o-(vT_iR`mb=(jxMDX{EW5?SvKxxor*+}KH`#oYNg_;3$Z5$Pd*$GP^qyjUK>rqW zw6}rYlfMgN{#zelf*!zsYoB+dS0Kx}^xqlQeC+?H@SouBppUqE* z9VLt&E?dtff?4G}4)cD*g}QOMb5R~oL_l}G68wrpumn+PNhrA~T_r|S#3j9PupPOF zFLN&yk3YE3@J-yP_PTq(u1ZGx`#vzZM@iw~tQUxzQK6L)AM1s~oOp3a9*{9hWVs6@ z-6dAKpGvy7NQd7zG+HK=Zsg!&RPoqN`p}vcLh%Whur+lq?fypC4goPm;HfAD-VAVY zeraQH2c`s~h9rE2aagp#kw2k5*$|S6tE9vf!h;!8hWwBt$XNo}qo@{KBQ={~)ojP{ z)NGK{?5r~5MrYU?#k+lYh*(wl?@cC-0l|!)C6~TCbF3cjF9ZXa`c1rQ%1XN96D8rT z`GTi~5nnj7zdrGe;_VzRQ1hzxv-f$b_;nSY0W;<#Yc*?lP!SwBCr_)XCn}curORe) zZC%XGZ0WL1RA$MY@(TarQn4r4pqEX&Q1!%ZPTg30aX4QH8b`UY+?=9H58OdVqVOk{ zRfTKCf^j4sEt7rW-lvzojh@v=#3^;u$>A<+qB&Bxm9vhj7~sDvIdB2BxhpSlo~lXx zj8BY);j}>|Y|&LKX611{0g2}%2YRWh2fEwU{v?w2vOrb)2-NSgR^>cKi{llf>kYcT zbv;At z1BMQ3FiI7pcNuE7)?%nw$H~~mD>?ZLa|AY*F!qLEKDpj}X1&7B_%9}5VTLM$EoWg1 z`(&j>+hh)URV88m+V2ZD>h&Ka>q+DJNX(>|a|gp3hdyp`{wPicV@QqO&KB>Eg>*W6 zHTnU>Q`#^yQ+CIK<^F^WlU-sAW#|S+;(aWS(7dz{_Yp`t6a=@d(|H*j94CGn-YE}{ zjJg|>abvb{HC_~yJ+V9Pkl`Jo?)pgFqS#Z|?8Ya9x3)X9@TLGJp`2<`?+ZD~u`b0i zuTfuyLe2irvwuGwzJG*c!C>E=e}u!Y&lHf=cUK=-pAXw#!tUc@Rr;Uzm+)=s-}n1d z|G0hr)T8W8J&TNN=#_mw5)EaQUlG^;W$ipnd;EXV2EPn>kT7avN;sa+xetD88+;xA z;Fj^)Bsl!R5FvC&uMCPflap+2m~krHkmmlJhlrF@VMcg?G2Z z*xT>b;!W6ro%!NEIFBwzdw&f!?k#mqaB@V=NsZ#d2j>JmUcfH_@~z)|x-WW>aet}K z>#Fl@x7|I3d1)~%la*5-68fm#3rT~GYL(OOmXq2zuPs}j^VM9+pYn)sY{i5oA!`>| zi~2_Kt4g$JGQ{ys4qbV*!tS-sD-s!Nsu*BquTioJ^1-GV6901NAyaQy3 z0tRKF@-AeFPL(F-cSk7}?QSzfZR|sm!#Tm&)2Te|AS0AM8OOsHPF3AA1F3u@HK9>I z;(<_0lJ5D}Wl@vZBWvX;x^Uc5_4ik#gI-B8Cc zV`d)8=7ar9G^b*@l0yCxytelE-H<(Mo{e&>*V<@Ks#VfiQqmNw zq?nRl%*Ep|QtZ93?X6-xQY=LAMe?|M^FFZy5{{XJGfi;wyP3y=gKXcbKun7&=yBRA z8u-5zaU5TWkm9cY;zs(dQVGw9OqPs5WfL%M-X+O@OwY;;jmZbxMk91FZZBpc92od> zZD9u1*{Bgsr%SYj!@8rERL8Yv$h({ihRyKRl^gx?Iy3J}>B$}LMTiHP6gl&I3&5A< zPcR>3!^4ATc@UhP%EPpW<(=kjiBI%wndlXB6Q{a-IhHTu8QvDpa43(pg;yY3mPCJ6 z^wP$7x)G8Nv3s7C3c6~w8Me}3kIIW8wi7nvUiqtAZN6T|L{l>S-nXx zK=NrF9#XWczOPo3D&S~YziYvrK%E?1h3&g`*L!k`Z@;ir{R{ z)~FWUS&5;+t#Pam`-s9+=i8z%dDeAls8N7JoHJj(czdMufUvm1+rBp9Qu$l zdOm6xiz36xCOdF-ydS5+k-F1A~RQ78_kiu8a^c@(SeM@JD4lYPKe0c8cRvIlGwZ$;&zycH$zsQGJ@BG#DqtKXlg-&*y1m-?Ndey6G5$?ErJ z^?SYg9jAUptzxd*cwJ$v)>lB>Mp&@6NWJc4aAc(tT;G0d!<{a5bc4kP{?ECI>T+%R zzlZzxKnHyi^u$DAdcFW1HvBP-5;31=p+2!kjDS2^xNM>FCQG??DdhEasoKK9>8vIX z^5JI!jfl%X_SDXN%Nypfp>U3#CRn8WEwc>mM~LpD)XhJHW{N3dUHzeYbGhQbzQY^0 zG0kc0>-VbL*bFWD*dO+>zI38LJ(5lJt1sl4efatisL!{|)g(MH_4(*4$5VMvc-A%{ zLq#_=UcyTs2!MMZEq>Klw?75yE`4ieKU6F&owlrhJOe^wT}~uLofavYsL}>0%4`9F zH+i3@EDG~J8dqyuh+5mDsI~1zt?hYGVg?!kbmcLbc2_1zhbi?To_^KCej1^g;Hcdo z$qbMrClJuLW0K=AD~re(UNYlX@`LsxaJmhv6+Z()m~@7;>PZ|~s$<~usL zaN{?V_ivduOIbqRtBm60eef&Sl;72W6mMEaZ&&xxXm{p_EkaL>eXs%zk{`q~9TxjMgOu7rQAK&noG%oU@rH^|V!@Mb)LZ7| z(1SkM!nV(j_hj%;wp6HW&T_$U|EH3%|7!5BKT-0zF3!u{t4{KT|6=-CS8!*f4DYd% zQb!^?&FE_kkZ^9teX|*o;%6VIkUdh!7>mYQ@!vAy8_l#Xi<^6h#VLOS_~c;AmFn1q zOGmD-qMHe?y6Zjx!M=@uMiSs4m*bIL4s;be`^UvCF3Itc+u1*^w|Zq@z3tx7@{fy` zRhx&7Sc}aOrHOM?;kNSt#(RV1+ZBhXDWCI$Uqf+ma2Ug;*89URfS7;s9F|EEqzw9VUp~4lDVqiwKR8z7S*QfVIe70os$>I z8t2x$E2#XghGc&V?ta8XhpV%~-9u^#HB)ESP*Zn!Xp-A_kB!Q#pW4zP)zW0GT4byi ze(l`m(`CmlRYVjq!K&v*RnH)GTXLCI&quSVr~hN>$pQ6^DW#rp04*cxIwUDxL0(za zBa%?R@TJL8LFvs6>9IO~N*%SI-44q{EbQ~7?8!2jKyhRL2XxB62^_Jvy#i-_0)Nyq z0sh4D;O!Xbt<%~;Zwhg97d43YO-7X4ZSFDY?$OIc7e$W?J#){V=cfq#`qHXqAEz{i(S$m zr6e2tntM{xBha_5>MuRvY1WWpCUJ$Ts1z9=-P#dJu3e3>0d7nfU}Locz|{EQ?h*j3 z6#yI~^`v3|U=@{8@>;t-c&M;iK2Yj&mDTbRsZSR5sc6bLyA&7$#027Mhb1dc1i5vp zRLTLM&aTvLOlT&BA@DY3k z9n}`R!;88INP9!|CJ^>U#uI#v{H%jNa|>U;(-pqn6j6Nn!zfS=z@zNjWroX%2N6A)pAE9!$ZC<|-h~vylb_F`l;72Y zb3ljeT`V~G)UsC`kT(lWi&UUMc@y?wtdE0Fab7LnGTZ$K>xP~yhfxmbp(fi-b{@j2O$KmBa5S!z~{7;wrc>Z_*3=g`=shsy&`#Ig{U0N1KdnIMH53W}te-=Gw_af=< zhFoMX!oZw@4Bk@T`x8v;vM|dCoE%)SPX$QsEP#{qopW#wAaBowWzZ%FUQAiy%fxx? z2bLUdLEdoUW**xH&}UO)`Ycv`Cedp1CA!+io7w(c>t%k08BqG#FM@4Z{u6?AzYMmeO+UfCsE|6kwa4qG9)TPopBqQS zDY5Rv3OT?Wk}VI%V>*YK<5SiA;R2bTOnl+(Jt~tGZO+4?G_9t5gZ^8JnGN_Irv96f zbt0pN^(3I;616EEdBhW&(j9sT4?{b3<4PKE6BsHYv?zdnj;Y~PHuYZy@E<{PpD~oYB~w&67#Aww z3k_w0T%0Xxj#u+OPhVoI!}Jwh80#eX=@;o8&$!8hyBjEFB*g>oR8GfH@`owsD9-LV z!r5K)=Y7%g(5!4iE+LQZFOV&3gZbKzew);9z50Dge*fKnYWxy(huFX^s#hWi zL)iGzYFxJ`DJFL`o9;B`b@ezrywYr#uQuny$C!)lnCpck^UjStMMX2$2T?Ia6JD5s za^`CDo=uXxX-KZfNMye#o1Hszol~5;kx~(IM)>JLuM~arhOtwJsI8;rw8>T)6!}`7 z#p*=2)AmyMVh^rx8#`lB2Lg_^6JJ5Yu;jSM)ozxoBZJKf zJP%)g)Y2zmdKxQ5SqtjIQoRyqJX1$8QGGAPz^x389??;3OOYg{%ch)HR=B~3t9e`u z7UL`5auL7Lm$Iz9^qmB~D>+X9;A$QHyqe?%;vIg_yXm+#5lQA@{z-ki)KBHWrC3GlN9QS z^Ls}L9xD>w28aTEvwaNyu)IJ|OR^Lmk!{X{)2MQx`b(`E%-<2YRZw0Hk;U({T% zL4aYt`u&6YeM0^IR(=oR@84LTUC&aVAF9&x)bFwCx3~K3DZhvC7xQoG>VT#u%d%Gq zB^2{x%6hm<_N|<|*za*1WSE|ksZOm%JQ8-)-*NTZB~&+n?8z_k8T-`!u@D?(9cky6 zoiqsRGSP+2Y%>S^X`i?r!aWy&dZ~aF+w|4Zk=d>VN!T2A_`0-h$}(ek0V=yEM|1x8 z7+ybDa9dhGgEQ;|Cq_r&2Uh#MR!`Ona4l}*GKuNAeu8>Ual={P8nVRJ8FW5 z22HZGg{jb_nw6Yuyv$&lQgyvh8o`n=^^9ON8aNiN(N5_1CBp=8!dYJvH;-UJjHI%< zUm$1TTtw!P{?bldI}3RZXR1JyNe1u&Pglw#%Da-s2rG}plE*qIpQ<~Z4y}5bn6g3; zf!rXdx)Jv6*F^biH1OE4utY^|9c1Y5w zbaOlF4BW@IQ#d7WtBM<|%*T<`Slk`xk4omU>pODedI*r&b&}Aij_k-rw=*e`YE=BUMjk^T8-Qm)21w-ETUNHZ*?ff94-!IjD8=PzQ3zEa$l>Gd^r zl}8Pdgi|#X#~V`zID|3~W^&^_;vfn6OYA|{^*+$kgV77thQ!QZu9tObZ_)=@eif^< z==Pvh-|%bH_kwRxUz@&%w3L1IfF#I=VC4>$4q;U;cDR^v?2~kJfOHNAI6;3M1+IM& z-Tv@MH$BxLTK-SB$Xj8rvWaY;t9)4?s$TUFsA^sjC`JK{kP-!U-ddI1lRa!4*{17KAlsYZJm#K@ukgC2Uy zm2Ge@KIbq;fB)nzWtb#e_F^Wtm?v1>+*6-Z zxkC_^R`XZY(_^fj9%-&$(4nV?C&haDN@C^(EEVlN4UU8?J)B;?PUU`Ry?m}pd!Sw( zsj2~iNR#v(`j0l?;?|d>r;KdVL)^37fO+Wh|DZxDNyvw10TP$n0$KjxUL=Pua)zd4 z3T7UcxJc~Zjo_>*^_3x+ZbM`v2VSb&Whc7w>2%T1J{^K#}6FH)-1x&2ny%Zo8NG$S& z2f_<^)sm6nV+H3Lvdhv3+>tx=6!93kT%Zb~4DwZW^!t+VsH;wJ#hHDItM+tfWEigl znBU*Q>pOC@Wy7E3sx65O)s2S66h{OawSj~^A}4e@`qibq@`j#*(p{r@JuC+GmSr@1 zN*YFTmdc(8qkM8L9k@1-DI>wv@ya$P}l@ zNZayZysZpvN(8vuFLIb%9>j;mwm{Ia1#=iH-iH(|qW zjLgK?V0Jcn?kX*Zc-(CbM6EDdG+wIVeRvGV; zjE0(5XZ1srlI<=z+utLK>$!R?Vm}87J;ao3%8j6=J}jF7Sf|FCVXj#Y7>H%c&G6Ov z`e;2&g7b@}^uU!mkn#>+vl(r`dXO~**F&=~q`4wj5BFY$aLAJ1a6r9=3g0DdwH^)6 z{VR0?RgJ+;OfqMGs2gitwf@p<^Gm3AfNOJZK6X9*0Qa%y1@`;cHQ&CEU1QG= zbdBW`D=$`$Sp8$|i?uh_50}~H9PE0Hoi28rWZz$JUnkpFzkQw2=~`>wSKHV7J6#{P z?_<{|?EBdDkM@1+`d9n@zwPT9`}(?l-C|!qw6EJbUEA#Yf7;j7FD!VAU3=U2vFq{n zee9ZV-*>*AZa?pDUkBP(k9{q(ub0`^YwYXw_H~kdy~Vyxwy%EsT4`Tr*w-riT5Vrz z?d!evb*_EA-@ZQ7=^A_fu>JfA`}#-wI^Vwj)xIt|$TgNOc8z@>yT7``t%R9`FyRrxbA*=(YYFcXwiCW4WPuy|5Y8YBB9s%x5^g2TB!me8 z+F3(*fbb;YMZyZg8-$MtUlP)2OAg^=!Z`#lVKm_eLV!?1c!2OE;YGp`Nbnfj=Ch4?WLE+V%C+jZO2@B)z#OG9XEc$wbxC& z{)UPhC*5@Ok8Y`{x%J1lO}>4~)Q-s$@BD#j(<^Ig?x?BxNzI*!FKTLL%$zm5YR+B3 z>MmE{|9kkqsRugIw@T^3eL1X{tmM{o3{lxyij1&$lgH@OW~Q@i+2flC(ff(07k7i$ z_lB-?Y6TnIjcg-ocFnrO6CR#a(QXg!v&iJk0wI!5L8=0stGP?clC%9s*xpxm!s$8M z6B_S~j3_rQTgINqXAI6pPrA(L-7KfrZARIK-Cu@VwtxOiO3psQjbgQNmD3%qMr@{q1d^A%ngIuifB5p3sw$o?SD_A|us;fCdEs1;}X z${)_e?dgssVF*|Dqqh+^?|%t8Iy|}ve;e8Kce?PqjG<15_sE&3^HKS=G8!&({?kHm zx2XK-UE*uY(XuqRJSfjeA>=nqwp&E)Bz_e6A-2&Te}8_q5_;3E?7Y!;6PI|$q5p_- zWQKUWER;&HI8u>dBuPB^DLq6*_aj!M0S?swmoxzGz(E}|*+YOm_!XFxO}1q?1r|$S zOfClCdFVB*ecfgWROe5SB+CD|Fb;u8c4qLB2j^O1^sCsB{>0k)C(G8qsWw;GD13xn z^C-o6E-|;jrJfr%3~rIF?n~7+TVP}dwm?Zow!myeFbO=9$?7)F7Pwa3T5N&QR?24c z=$|QFvvfC1ilJX18-!U{P*sB81B^Z+y+qrN{snpmR}I9sHDXs)pRzx(55FFtl1s5& zJ!YDZSPQXk(=KGAv+EOP89ej}=2kXvRWtG@*x4Pa#GsOALWZzNCP)+aAP9)`VkFb! zwx$yeDrXE$CHE~V!(iLE=~-TmWeJt8&=Kb$Yai>6>6nu4Mw`0sPS^Dj?iCI32@ym9Np zv`qNYO5W&_Ni49%6^M+>8}Is62YF-fV4G`yY2&a94^Pxs{3>Hw5pt&zKneAsULk-v zgbrS46q96BUZ;8PYCr70vrnfofE6TP@j|;d$@7Df*S(|zJKZ}Pu3O= zPp+t0S$Vv+a7b!}yR>e`5fuZ5r_adb5S2R4JEgq;^RxtS^+&p2I_K z984Kmmwe)EKWoPJJf7KXq;?;Wwz}2nm~}ekFC${!dY5<}UqCb(INH3GF{@2`k~`i% zChsr2n<+EsKB5kP?{eW~DIX4I1N^(z-_a0So?21Zqas?bEnR6e{%ZFg_kRoiaF;Ik zXd||0OQ$AlOD|0?{e1ScIRB;a&FC_1VUG&YM-b7)b*la-Ph5{i>T-AK>lIqrvWjSP zMM|SMv8xcbrR&Y>!KQ9)>9FKNjt72zx>KLHj;?_blUl2$6ZX^Q=~PQw>d&u;Hd>|5 z`UQG0jFP8xhyPevNw@otoa=)VQ{g!gr)Fw3T`}cTSq&!1YA{(=15pA{uIt6k=J#mc z#U`$-Kj>S{*(M56ApF0rizECho_MsSZmc8ra_!|cnze=QbhxYlBA*ojS6*Wo2m0_h zl{KM&7xcBDu_-x;&H z1cB~@zhq-Jsgy7;pF_1wn3qa+VIB7Ut$J6gC!47I2ii|MvGs$)X}^H@1mA)Cph4bl zbZ0x7+`Z`x#Jcsl<_gf4XbKNOTEKC^p&>;Cgf}9!&HJXBsRJw$l~na;2b79DMx6m| zX@G{)GF3IiS7|QFsqeAmA$&NXx6(DVFX4N>_+zIpT$ZJsEGHJ}15_&4d+;pheJo9m zl{H1a+|`ie@43X~5M`M4<~1zM3^PkEU&%y2I0$}Ic|{${OWwb{ZS(%E<<$YI?d`h{ z80*x&8HZoq!Sq>d{oSJk9dxOW6Sl-e2h-mTg#N$N-`yko1zR6v=AXe5XUeQT%s=3{ z;9KkOz8sWZS7P&1_Y<3&kIGwHfA`ecRLwj|{id*3t}(wx1@#c>YT=7rZe6fM;0LIp z`~j$r+4`OE5zRgh3LD*oNfv5A5NgM|%srkTtI*p@1+bsw*B80~WV`M|@>|VBL9g8s zVk&K3QBgUr>W*xOzo#*(x3Nl35$!VY5UwHGZ@Mh6^Ftf|p%h|-9ujO%t<0aJ- zNbnCa+ivaIsxL!-u`=kCt!h>@r$?oDm7&>s=r5|F5IH4Q?{@CHf5*L8yo5(V1#r$$ zuzpPIbD*Ted`n05_KPv}Wgh?)at0hwu?V4T>x)pdooI9Uj{WZCVpw1kJWZ~L+IPH@ z@*sdVt%wsqwPfc7Nm-lT;9_a6LzR{;rLhP|X%|tNIgHZWyBbpzgtqZyNs{&Uba{I! zZ;@CE&BQ`e;BfSE$%2C;9^8bjgo(3+SRE@$H0QGE(!Hi>P%k-3N13jYc!DUrOAcei zE3;lPpl=`z(PX5jz2~eLJmC0YvWewXD+mMgN;X4tg;3Guev;|`rQF94bSx9s3oX?C z7FuGif^ugatIn^ILK0OMCUx9~w>?hpGh@Xn2EEu;bsMKx-ch#}#j?&y*=)|8#q4ad zvbHz{*W_2CH!+E3s@*JBB{vG~tkfG~n!2-5T0sG#R^^gXXV>CNZ}FOVq7ZkD*q|X45J42!3s;5&u?3DAO9DpKhTC?qNb!1TO?(*xPFy6px1~Ap2|C zVXiZs42T~3lfZx{G)3)XwqYVP1$V=DQ$UJ`jPSjIBxvEljD^L{r~>B z;zuc(2*?y5r7euq+W=|tN_Th^2deD!3y8*54e#2Vj;i71z>fT!gyv!}2Z!?K-T zV+%8weYVF4%+?cUvD9}-i+mf-s(z2U&tZ*o8-ELaV9nzqdB4GWf4#iFmiKd3I~-0I zLi`8Kqb$}HK9yKCj|T~zB_C|GJ}8zCiueErVhP{*OWi;4mQU$8m|c^3X>TOpX?s;ScL8_nDA7ylgi=wGK0#JK{+ILZ|KP!_uN zEzVuNwFxibX9d!{#)?RmxEF_MFm%A_G4xR0WR^alu)}B!B+EZG$K2NmHvsd38|Fz9 z{=~ciH{i=W;dq~qJEDcHk9I%{ud3VlbZk(!)^uEGrEE6u_z6AJC3^vfx{euFF_2#OZe;;c(MsS zDu}@wx)F3+{&RByuIL!6;#Xm=xXco^324}sg$jM45!lqJBqzznJKpj7qOrtqtZpZ9mV>D;pWL!{g3Y<0QXk5Da3kH28z9p-L#Y!WlN+b4K zjaZ1WrTJHOiLEKTG%sX)Wi5GM-tGq~V7)*$pYdg+r&yw3P6_Ipu25g2T1^0#Oq$4I zVuQ=6b31^G1uNG`k$25FIIO$~<)5&G{9fJ02kSv~YYmoRrEE6KEBA*LJZEiI7Kz!6 z2nN>z$xY@LY#!`R7pRlr`7P50_$_}_h{6tZQhA0T?dt`J&si=gq}}5X$Dwq>JO6jv zbq}cZLTF)2ej$WEj7`f?jhbA~0vItjF@4_#NRDTW^a0~1LFtasjlsFPHkcbhE->a1 z9mpwWa)%7z2n;q^Xv%xMgx@Y57efrX_=NX~IKeUY^%lT!s^%eoq$9`7(d z<1JEX_FIgPZ2HBlR}pJ6MomMqnH(I9rw(F6!B>>>d(I|Ra5i3on}$u2*HbXj9yX>C z3}aQt=7(_CIBX0L4}liwRCRS5-~Yw;lUD&mOZrh-`k~KkKCpnC;@D z;aKDpwjL&fWp4SAax$!BVGxwE2juDIS{b@VYJE_rS_v(|Kaa9lV7qC&ZG7q~xjox| zEjuLHG%}rhPSHdjBmTRr{c1Glv>z#7%*U{Qyt$iW(1$D12X?vg$238>)J4{I)p9rvt$X^yIJX+CAU>MB zVnG_?RRl8n)wON|baBTp;7*rT?Icde7BD1vK#9^@kLIM)1<w`@>k4A#Wg?U_hPY%BvlKs(8Sr$e|VP!E&TZJc_zQr%kAL%Ef*+0-TrO`zB= z&nt=jYV)V}Lg!;3+wKgZn|UNujbTQTjn8=ewA2}Tp_}>7pYwPJk9P;ZPSUC$y-+ZUw) z^3l2SQK{69WK)l9!d+OBLxx6dT3D#YHT0`XxM{E8L1I#DuF`VJbFRw0_;8kX+RhV5XH&b5dw-Ow!PRHT<~SOyy&qYl-(Sv&EQFZCKUD!2DPmUEj?GOu{|LFk=eXv8J3KN7Ljp3XQdz83h zkx&WW#h%2XuY~KuM8lX4NmQ}ba?gJnyR@`hUZiXsuIK?5?d(*-$?Zut(&Bd)@PoY%{{0MQGr>3E_ z83<(r4k ze?;zfe?$d0(My=4ho(}97^yd~kIk7j(Qtc;KS()bt?;v+(Bq73vqZxohoIdFIb<4=#0MAP4W*sFE*CnB!KSJk%y%3 zv=hdlz^tY3)Jwo1wkc8EXqF=UE8GXgl;B?heWzYs=sRT}p1xBDfAhvRfEZIjZ(WS) zWJv)Lq%HVkjKjL4+}KlY>`=!smp5}hPm68@Cg`DFuqewyH{lQ|sXTNlCxvD=xpM{V zJ)xV9_tf5$XQYSRKOhCiDc)41H@QpXB_bY|S$`vxU^z2plKf1TpGvnaL6Ah=&>!=~ z_^O;9a>A9G?}Hcr~#s`s>o=@&W~le3erzon2yu@`NC9v0k491L0=SmJ)1%#n;%=*L~~9Y z%R%E_KEFKKXs&NXo5=e@MQQgktsD_n`TUB~bX_Z7hgwp$wlIluL@O!e{cA;ZRYhnt zC&E|_xr|a1Dv|NyebMlx8B$QK5RT!|8-0*>PIE&IcSei6c#KurCwR_hTqv_?F#F3A z^B>ns0?gH5VVqQE3@cz=$N3blMMt2o0UA>ybX#s&=r%z6wgT%EOXlI-RnoBKF;{~_ zAlZe8R6~!MU^|!W`^Y3qkk@t-#Ci_Hi~XcpJ1%va=1ge}`@Gfd{=m}AOj;~#SX?V% zP5+JOyvFiJ0WgdoJNhjhLp(?=56gv$vf zvuQ%qk7_Fb({P>ijRi0?Y8ZRO5xKEX@3%h965q;cELyzt(DxI$hOn=k1`of16G;1C#pr(N}w&P%VBp2JJ0B0UIH0A*S?XZ8U7!A zov-?O0&rq3zf)S2;4ltx)M^WI>i?eB?gVB_M<+0qECc_#yPp_*p>NO?{1#Ys>jb}L z0LCGL+yV7RGGhJ~(z@`sP<^d*NwZMcUHe;@C<$zT3)`;|y5eK?+XR+cW7f;>q5bVY zAEG&JS9EivU4uv^*mlJ9o{M`q&@FtteroDpk|N3dHo=8-Iut3F%`R(6*rFV7!5+f= zGl)@?DvEb8!HUe~Y6H_Oyb9DYmXRx%vhpNu3&0Kd9UfxcU5hc1rdX`uoS=FQyC7M<4m z3inBM)g1TWRZ1uaq+|}gf0%>_2Ni)?bw?g++zx%B@O71Hg0X^5cvhC_aMq2)%|C+b z!>Prk8)wcEGPJ0$K{+DRjW0Oh>J_C{@bZ(V=G@r#f`&g;FfoQPlSdTkDeIs#b*-!( z79CGk=(}4vCRVTCi~qW1dcAp}_zS*inObDEg>MQ)TE8_-PZ=@EOczo#3TG2Th3Cb5 zh3_d?I?E+prCS8(p*6TuDuItgebv*SuqhEs!$5Jsf_tsAnJa;TB~QS=q${pjPFMU6 z)U3FTKtO@{bA`EvJHuCiIv6gYv&_5aKw2*e4>2(CnpB^s9? zsKJ2DKn7-DqM?c+ZnSEO+arZUpaKR1n(;C%)!O=4ZGE0D+Sb-x7OfLcXoen#kLlzz^K+98I= z?z|a`kw27dtQ=3iI&0~|!u?d;I(UB*XC{*I-6t4~9$!^LCilv4-{9K`Sl*DbZ5_nX>J zqC)E>R===iI`e7&fysW^{*C#4(ER?w{QgwGo%@GAPg$L>4-C@T+cX`>`Gb*h+nL&e zU}U0=8Ozpi^k+sT1HQn}Lh{nbKP|$;F|DZFux- z3N^GqIn;+5?EK0=(aV)(DBvr);F*B+E zTWH-PY4_ugIAgK43p)Kxm1XQKNWpH@!b>Jv{VGdbLG;yMG7ZI6I;~{B9Pli$rQm+H zQN4Z{{dm-|v2YrlRTg>LxNmS9B{E_)0V*!YgId;bv`9QkA4QM$=@Vhj%AFB9+x}=Z z>g~IWK4(LfM4mVK=kAz(9IUpAWx5iRjeS$lz`nT-&3(Ghz~@4NI(2)NJYR6P$s@;@ zp7R^5!qU&ssbB61f2b;pc0s1A6aMHeG3r+*s9*B-?MvJ0UtUlBhfu#$vvL_uv8l17 zbf+i$m0MWc<>pI8nqFdr9L4mg$;j7_hY}B*`A%T&4$qJ8R|QsU*!q+$TBecCC^%EO zGQWVxzY$5Y^!|sT8d0;)#%=(@24sGZFpGcUAoV+60C--m6_3)O?5p?| zjLs{lP;GZ!3{ey_2-{kdgs;j2I}Rz?n{YYE_7c83t6A3pR@II zu71u-;O@U*a6-Qb{h2`GLfh~!3=aQJB~JzRmKzw_)tB`NTkGd;_S9)#z~On2Kj>~; zUQiXz+-QQ1hB-#5tBSu4{K|z+BW{D^^0Z-|1>u}8D+dL?toHNVBd2muPW4$PHH*}& z>H_mjaxka*aM%`{F!g!0OS4dx$eYp7+M{-9W^32lr5UXmv8A=2=T!}i;ds84&kg+l ze){wuWACK1Mf0w+rEI!$w$$l;_Hr%MRm)I3-2Cr`jE?J97`x!?2HpQbg2OUgqbLxX z<}Jscxpq)bOi^;UYByMEkrdySs!{O96))~jMtmm6Xf!`)O`jC9Y}}JiER$H^<6!BQ zDmX*U_Os_R1>&cbZmIsLafD%G45$x#mIN~V)@$L&h{9lG1U!rphKJF3M-815zKz_W zZW3rdPoxj@kKw}UmIR~R5JCPcTLy8#?|7&kriyvi0c$Pju-3xX7-RuQhOC!DMa{v6 z-P!mr#j97*Cfw|Cb9voda(o7&VCgs8n`k_U<*)Jgiq9I4BhV^Z$Mr7{&Q=Khi-uj) zf-lF=B8`cEFe4hosw6R&6XMC+*@Rbf19=(xu)IhPuCv7yTW15rp-j{U%S)Srp5aZf z%lLzMe2x8MD8%_j-C0$2HEkdwELxlBp#9DalLaxc`@LwR1`$lZid&r6;``$Yb~tsN zN;LE(X8p#Gz2SdN03WUR&jh~1YaYo@u^j*}OIk)GE|M{_@0#AKWcIc8-J*a3jv zb^s<*pI9}uW|#gVtXh~N?@PqC^# zT*?=2?FPy(;ugCGcW&Xe_VZA$o&|x|DvJWIcovk)?y8c2-`Rd^bt~3N4gAGW%@c;l zRQ{4G6eT&c$qF#4C%gd~=q1!nW2B5-Udi@`SGJN4L~eUFXS|sY`+4`PSaWviWR^bgwmU2< zu+fZfEi}i9BD!9U`!NW-b&P5a1EGubJo7cJ44oLe!a&A(o+V3T^@Hvd@|e}%v%ows zKr?mm-kTDB88rrg3B^4bTkly=UEhkwT0I5cG?O&hOwx^3`5R$yLPHBkNSC)fY)&Cw zi|S!h8Y;82X=d+W!~6NXh#X~VnEx{BZY8O7<*e_}K8r;LW?0`uoo1TJ)u`w@{6eP} zi3z+5@(E~O8o9H^puw(*9kcUUc1($LQD4Thox^62^BdPQh5wfctviKTI+w}i|H#nJ z+T^#=o=h*t=-7XPU2!wh(l|VasobCBt;6%}A~z}r*GqpH9J9(IKZn3>Hbd*!+d7oireyS#-xhL~%{|Afcw|=c$qM~EX)_VIpXrUP@x@aR&(Rh69DoE%ik<-De z*Sonn3_MHD&+sgmF`u6i7$R%)vGcc zN>}1+tqvy_c(&+g@}r!3dwzA#%0V-3N(o^S}?6YsZniw;L9ZFUOu&x|Lr{h*B* z|K;)=Zsfdxyspr}D|wQlVO{CJ{NEr@O<6y1$A3y=Z$HZ>eJ;mjJbr`axVhvW_qc(o zg!UzD>9Z}mriQJzt;uZg79;OwoCPDmu`>#WiPc#QQ)sZGm|{=73N*A)PSei_;EGU6 zKzC%}WP2>!jNBuiW?eT_$W{TSg6ooCl|Aiy+;%Rs0)0w1R)uGX)DDty@dwT}J?1G2 zeUIxC8H$!guIPhTz4QQqY#PA~jjSwKoCR#mY_jGGSV|kX;6}_NC9*e?6y~zJmcLwQ zcXHDW`=dWDgq(n&396GhrA?k_IfT76w}xDF-ZMv`e>lZvotV;&(}F*9by6d(Kb(0p zwRq-sR}E&IPpHcuT_9{Sa}sgDCngBGf0mILC+G%jE~np(0Ylb>BLRrHD zD`f+Cs6>6%%tEJl$g{*~3snR&%Zr1hYhWJijx||pipq;MR?f+?f)Sciq7t42 zbhFqG?9*l=o4UN<+@Q5e43QFh%qaD9thsp))Xf`_md}3pdTAtm;FTsFWV3KfC@V;n_ zwRoV_(bZrVtIVl>s>q^-%k_3#Tiu7(&V*Vb7Q!m~2e6k01^O7sp92J!>B6l*@!=VT z0ycs7@tT{EGdDvXXKrqX*nyx|`71^DFczO)PQ98rGoZ{Av;4)ZYh(E8t>MhKZ~;=B zR(+UYB1D*kK=+UAmE1cqyAb2yym01jFy4n8$7KX|fK>B2i?%&f`lTnjOklG`6Ipac zF?e+~f=>?2VNkkOpu+Rm6(GRoVDy-};KDeAHn=h6K* zx@TjS6`V4l-o3}Szr9B*(mT4q+jkq5yW0=T=~`LctbDpB8PTE4(o54e4(HrnVWds67W|&hSICeqh73Nz{{(hG2%=0LK1aq#T^5qY)b#`Ea4&pR8l3~kP#;Vg34ZUIJ#96JN{fBGW)p==zsZX3oM;|;#~>YE-AD8$LNwC^_D*h zydc2Ix2FvQYEc6op5gJ?ICLi;iWQg^yZo46Jch80b&}>tqzWi@#?d}Q@f3Ug)L90XeB(LjL<@A z(Z8W$%ZPEa!Z2=jPhtc8k)!(MaP-vvp&|+Qu(Ef;kktn>m!ckCx>TH-Q0c0$XLw5( zj(!bQE1Ek@oE{SdhP#4@KOFqhTh#WnU=fi~IW(H=rDO6jd_oD)9>>95 zqRST*NQ1$CfW-NzpCWmL*CT#YMlf@`^cN7p?Qh#^t6?1YGqwzY=F@Em`HI>#Dqd3ua?af8?+bAnA{!lUV(B z$Xd@_he|hBo#?`Iu=f2dR;}uA?v7SBwA{o3j%1Kj{Z2?)FPz(7R2>tf+Hh%ulZ{%X z;Fd*rMhL2R!bPaUN}H(Riwt6Y{aTl%PRGk_KjxA#191hGG>$>A?S z^kQ!>yy&E~v}Fq~F~8%@?-k~EjQOoFze53yWmdzo`LAzEPut4>@ACgP{{Mvkck%yM z{GUaY#_wo$*AD)5X+OmMzB~6pO@I{HkF1#vxrq9aCZXpa*nc;34_h(3Smq`j`pGf; zNQwHnyJioao4|3txGCG19LMs;%yCNnPdq~Xo_PHhnoXs@y*0o%*;4u=A=1oGlR2wCgkv)jiQ!oVF^Zw>6ALNl27GiX#H8Zeed7b+!Jk&-X;f z7HSmtlB0A_wU^%B@!KwGPGD($IMxiG71Jbpj9j-(+j@%E%^3AwL@DL}fCiqti6?FN zD_gqqx?lY9KmF01M@F^CsL5|am!{fla0?eYVXfzW!(uHO&5D3C5*ypu=OD7Q#^D1+ zYiN5HYm5ij-tPI=fjllGx@UWeLQiknUhEY-;%80$SPPu}HH|C0|2eEdfZL22M^%>1 zy)2{Z@XEP2bg9ZU-T((>R%bmfT`|~?3%awX=hUOZvp8)R<=}&R?ro?%acQh!aT;7I z1O=YCw*z|m;$NIbr~~x3mXch3P3i7g6JS?Fds(P*D3$MT7=4bV)gy~`$6Ft7TEE`3 zJ`AC3M!a>J_1s$z$0$>(A1fQ)>K2G}nca|9@X(i3nAsFLw6&K%a%f{0ol>obm>xt9 zjdXG5vLor?zD~`r4>ekkJflw^=Sw>DsIUC$x5_0Q{ak$M+Ake;)*b)Fg7}>Uxr=9e zs8Kq`VM?=YovX-IRFqx%G}Mo|`mG+5eX7%+7z9dt^ERXUy0wYTP_%^Im9 z(m_@!N|-|{CtUiL=brl3F8ccm7P0CWRBy@lw{Q{ghZSq6cI%h+!@wqbidh^$c-M)Q zmE78^x}4u})qVLb*6FLW?;bVyanLz^^%*0CsCN*lts+bY@<2v=jmgn=l$8;#h`2=+ zsQ=zt5{}$vV%<0)Sc1_heah-e!qzQ0;i9vH)_*|Go*ojp-moX5tjVzJxh(bbQi5Shwzg@rhoN)ik7rj8l5lIeKR;&AiRttsrev zPHM2b)Vwvcpl^@*nw2$ma|)D`e6#tpklmSPEJDf5CY@52od(-?NQ_IE=Z;x?v>F=h z9tEBrTit?sH`NX8QR7sndZ<+^x9`wT6eG=JYib(9cYQrozXpY3}`*AB3$(jS7?2Z5}YeMPo`IYfiyKl!aA| z{xEFnzGg~~thv=8@&sn5{u(g5YebyLQ*b0qLWcrc@W$Y**^iyWHgRBs)i4!+X;t)@ zUs3b|in3b9$W%)TKOgm2OmA zg$$IGXTE43btYnFnFztgFc-I4^p+(Lk%!X%#aI2WkJP?FN#R4IYAgDC$@DfV(;&i- zwbuU4S;BK{r3(k$nuonXbR>)&Z^47?CPPBM1LMIgD4a372FU}&&ClxVhQn!bPE9b1 zAg0PiOrJc!%8nzSPSXU*{8uqu&Gq`=NalU(iwKcRX&g&dEMPIv(Up5-FwQK%<<8n$ zq~Gz%1o~4eI>nCh8@H0kq&wKy_rR2YG`f_cv=g zAA!P!$IyuwlCJ#DLh)ylCWIr#Z+H;vcG>qr>m5kVe&6%`y1Cl>(fQ~ZLbbH$rQkY3 zY_4M;7Hxu?F;3i!mWLRU(Zi9Uc~E*d7odmJ5Gq2S#;DX*B)B=Z#ko0-8cxwwjPniD zFdQ|UmqP1yOHW5yIQ5~-25I4-&Yhx#)8A)i1$_rHqGhvg7t92*m!q`vioMkN>L}pQ zI8uqs&ELBEO?}hp1yOqr56OG>EAZ2_LI`1tuoi~-qIEa~gO znD@n#OhdhB=v+0_hlb#$(;c)smv+g(7t@0${%6MUoLkca-j2d zB^0RhrR-^Q|1tbFL`2L#dn!#w0bME4Pf%oc$s$rYI?D=tWzk?d`AYhb60OMOQ5PEa zp&9zwbX~3zrHLUIDzE)q$I>~>!M}L2dqQe2GN;&yr!pIqnIID@cxELld|)_tRpn3K zoch5=@ouQm9IkHSUQ4#$garJ3I_Y5GFK}W4{uZm}_nmIwufT=Bf>ij+lf1BV@MrL^ zbqG$sj3P?R`{@a$C1Ky1U%1%!6k4Ocy|Hh5`^gI97D?t&VB*}0d%L9ZSje%lm}#r$ zne`f>MKZouW8QaCMGB$YiRUfW*m1<^>dU4=kej%l z=3h4PVxu<}EJ}FH4a6jsl6ba>u7Jt@@EVO6kXp-e0%K3B$ zt7{5e$yLrcCo2EQ?$1qICkY^Ds3n{EKHv?YC;0&ohLZy zLoMjK!Z)A~^++=~)t)?6^l-nC<_rD}n(c@AKq)a+E7d-qxA0jINzy-l=60#sDbmwa zHpQvT&9h8-DE5exg$qNoJtif`@7x@BI62_+H``~V7Tm zF#p0r&2ZGan#}gOwwej=* zVDsDf7NC=S+I*Upn`Biy=L}v^cO9-lY@g+u_$A%=vb$Q~MG0?e(7k*$ev#p2G#F z1UccjAE7c5KaE`)>r{3Moj4GUMgJl1G7MroM2K$OfO>v?E+!P6Bb_jjc|qB>R2B`x zLCq^}(kMe7$%kIhr6_)Tw3!BxQP(kvwnrVU-A@3Fc54>2mbKK`ZV~7d)K`Z;EiS9(s&5z?^`vz1@0t4QWEhLuI?b4<8fyI2Eeg)lF&Up3W|ip}w2u7LFcU z#UBY6aMMC`kzd1J%hvA+3%Ql zjntsR!!xR}nyqJ0yF8L(^cYEMkKxsawZ8FWI_9TzBPUSWFyqIq$1f6#)voHx+*wVq zVnE#4bj!Xk2-Ejr*qjK=U$QHU%(Oh9_uAc=)gwbPOp1EDku{~im#V+xGpe!lUqM&8g+_*E~%Anxo}4w%@Iwk3fE!Q^Pd{lc?ev0!S&$p{WDa6HM;P z=qr0OQJxEqo#s}MrwYc!E2uCP_)G;oLe?9tJ>&WqDfe#}fO`y z`P#(+Tf;lvOwId7?U)H9Y_%7YAT=8jd?eJ{e;{GL6aJlB-%z9x4paH)kO>K&S+2Bc zP8tCx%A(jeLo|FUgr&1+jeR8NHZ?*Uc=WVUrnT8Tm03+3G=c{UVnlb z#F)i6jte`^x#K?hOLjEK2lt!9#d%6Z23TWWi<;PyIa9jW_2$)a%=omEv&p_ikkS~~ zC~A&nT)QGr&;CT#Er)b&D_c_?jZaH$<+{{X#wWFMe!P`Drlli<7WIyZaHJz&6iJ?jMgeV=+#18B5-Z0C>d;lq9#3pE{ODow9z| zdWxm+pm|Nq*pHK1xjo)WnbS&%JC@=V0jU}ShQ<^2Va5}-ff9k)dm`I9fKe5gmQnyX z6J$T@7HGdKaJ7A($?v+_7M#}DbtZSaO-R;-$ypyF>qGVxPS%C)es%V{fvgv}#EXFR z**k}P6?0v!Ms?1JkX#8huXqYNq1vJs-dbF4U0p&HLs3s(_uAj?RQ!Lh|EFd^=Y+9m z_2HTUC$-ilFi>&O8ihXG+K^QN_ZumRlor?C(l2EBcwVXvbF`FVf$n@M8 ze5#l?$7Dw#3}TP`Z+YDO8B>zHcUqpgV?B;er_XSX%}#ah z7e?|R*`pL(hap|-V-AcS=J4ui_lMOpKfWK>;s_T-;N(ok30J24)h<)?F_cu8mt;&sg#~cO}#W|}qhc~c8W8QmAs^j`zaOx(X>LeqE1S)Fx%L*{~ z!r%u%v5AiWVoNabV&1hqb#F3(bO8RPJ>2aPnFsWagB-&z_o1XUA-?_r-I@ zl=F0Q5~0MMlfmkj5$hb>yu^{4;rGqn_K>P!-*LfqczrV91Bd)|yo*B|*CdA7_wj%a z;NJs;>?|yMY~#CCpsfUnWzry@%V#eBD(@K+9xXFZ0ShH-$1O zR*l8>F++tT`RJgh8|4ZK4Hxa-i7ELjl)u8>2H~Lm6XW?OD1Sv5eT_QCky2!m)9FPj zqFHp@_lW!$Whn6n3e3=FFV~cOeK|vXe%t>w@?sN_tah7EeRi+m;`!6(X+(NQz%n4F zQ<486)g&Yki^jo*QHjk~#k`LS_wnhG^s1wn>tpZa4t~i=V9Mb<*^e+feMR23uEl8N z1b4m_YFweiGvx6x>?Zqy6Ey=HRX1J)af@MOFt|VRM=xgI(MFIq987yeHy2iORr{m; zG~IClnr4ujmRT!HS$Onf4vs}&j>%}>o$_#-CYEY z9v!A>I+f+Je4p&0_S1R5ckRbM*jYGQZTT?gaA0a={MOrSPW0qGw@)!VgArH^G`KI& zAIwP5;h|vz=oz_7()XQfaj)yS;|kHMY;j*GI;Wlp_9${-H^+-E(I^NrQga zXG%U^h3)J!Q@?UvVsn~ zYj%wv%krY-RlU$57>wi|l??x=Xs_?vWt>!@(l_O3VtAiWwAaw`()U81;Tuwm$KM>> z>Ut0DHD*+_#{_hShT2~tdTBi)WLA`$<=O3!u?qB5#?jGUvsB2g5V<9cEic5v+DqFWdF&+xUO(pSTt;aKkdwxEW(jJeGkdj+ft;}mmW z20F(>B84*FRERJIxofubNC1FR4RpS6wkMJT>4GeEjdRd-HpV&PCya-f8Xe90j%%26 zwquxcPHTUsW_yvOoBK7$c@`SSHOMJ3x@c&k?T5?$?Jc`|K4alx;=d3lZd0oLO$^1E zbyY`Trk4R5E!|(25sEDh)H(JyATXU_Skxr!Z(=XW{H7Oq@vM^JuM-EUuA8yH0r0u0 zgt68+CKzkNcb>_XM^1lTj+vk#jKEFHYY$K@Ex|n|5T_gZzDN zk=654cc4TFcLJI=_a{8t^MEho5*I=p9a^n0=&p8G7U(E*U0gj>$M7dm8pJc|lf_X| z><~Zj_HL&V>iUi9nw>|EX!g{(O7iBHK`d~bl<0^pu@?a)2fc9Z$Ae`DT5<8gyh}sz z!7Sz3UV=7dM}tXs2gClOXBx~&8cd8ZN4Sb@8_YAN=ee(`uBRbk8O$H&n893#>y4zr zY=bg7=)q8+{djcbr!LT8Nn`quw(V9!hal{0w?H|QPc#c8TGScS7$ct=4(?4^p{-^F zx#=3zmP5^;{#I)SHEUSPpn4ztpbk8qVYD7!qvJH5qdPsG+4M&M*KRy{&UpH(GLJK! zY-c=wK|e5Qkw!w89ONRg;EQl*CACP*#P%-C_vr`teyQ`_DNO!Q^1C}<(d+?Am10Ty zj-}~U-4<&V?d~TrU$iA5oUB*E1XeZHLAb1w?P+M9osq z9cu+u5H-aRHBt@r%=w*C7N!t23za0Ircgvpu{O-y9aXo1M<8AHq*tHikPFx`Wx^mI z7;GIa;$~|H#7*lc`mH>pTM>I0@?l0nN!zUt|BOL2;YWC@`=K(5H4ToM zo1DLh%0SW@%{}I9faV$4j-n$xdU-@I-`YP%UJ3RsN*9)@&Zg-?i9jyXdPj3-ux$2t z(Yg59tWlD8_jwM`x|f~1S;KvIC%)e{+4DIvu~EbLoQMgMPOmgu!F#3vBbs}-8v3}K zY3RM%OhfbChFpAn@_rj~yU^BNKJ5)oPipVax-dk&pO{hP{)RvHY^S}cPJ8*O?JXkz zz6a)h5qu(jZ1acihfqTKltH((*iSx}5uWRrTB5^n^}~qHUOlK6LfxgzMc4 zwe;4EqKtEQwwHOC+>EOJ^yC$%Cl{(G{hgllQ%^WZC-Av>Fx}w_sYo0bX-h%Vq(=- zjlskk%*75bZJ2sw(0I#t^T!!9r*>&2{sUUB4d!~^Y`3J*e!SMhb#H-gVlS_;`@jcq zw`v7o{0%hu+U9(JPx!dWbJWY_Dv^2g52%Nx@FC0P7dJ{=&ol!UQgT&~Q`nB7BD^mlP={&A`oPGhQYs|o3G~duqfi0&j*0MS@Q2C0< z$#DB&^Yx%r{$2VzZvUrFQl&QiZZ>^L7H8;_;fr%E*7^jdDs3`U?7g?L{ZAJ}Msrv4 zY_HJG#X3|QJ+nC|2L)35g@=%|&s+K<9@rmn@C~%Q=|^4C5)+xK&!5=6K^>tL!c*f+ zA7N;IJYcf~r*P4Y6fhVeJOtNwa|cd0jF7rM@qJVyIWqv&noA@X$k2wG!QF^~BzXte zN<5Lz*)cW5BPT;M8J5)y?n?&d-0=B`cXB*eH%HE4M!VXcymJpTz^2j~FmTpQAtAM= z5~Df5;5+zi;Mu^BiL?_Bnh6-Cg9Hf4MG#2a-;>E_E(#I&`xmAm;uosRXL-oO#WKgl zt9hHNJUvE%F4!=)e%cX3lyUEfHFw6OQUwfS3k)+YE><34UK0X_bIhwFU?_5OHrXG1wa4MP z8@2RB0%z|4$%7QKDTl`G z&je-?2NLmlNE&+6laI&jyl-_moC&1pjZ;Pii*^MuRG&PO-+og^in-1ilgs!dQZU2Q zuncR8L+I!gSp&?9f+-ZGpw`62I$U&$oojx(n%{K&e!YLJ=j?42;{CN9{tpyPP=b|x zv+k6V$jvG6IVm$QCq;U%cd^hh?_d6vlO|p-(5ml_3P^6Oo<%mynh_D_B{DO9t2uw_Dq?;C$)!p=PS;-kV zf*=ljuH?9|X-1Ts+LiePu|>-tw!i-`vv~qr9Hoq#HmnFVrq!Hh^oU+;J=85TtY$DC zPmuZ2CE}Eyrb4)reHc3JP&!CrSNl<*OmdPvQ%R7Vr2IYm3DTVBhwWwq{sD-O#NID| zFLm>e(*eiv>FSh(%xhxvpKD&7&40R+v&r86xi&{2=5~MQiokocF7@fQR=TFP@(D|y z)XG21Yoe7`&8yQ&lasT_zKd2EuT;~H)9^Ij=b<|_-rS_|Hjw6wx6$4#bZzZ-yc1J< za%pN$MkV#+ym(L24t~5DsjYl^oQ9tm?>pwz8Sh5(%%-}3H{-Rg-4Kq>M9M*QdcxIf zM#G-rpO?>lryBZZPm4TU5G`$i5d_TOC0zRM)TyDOe-S(-9IbvB4fZ7}!4tRYi~XJ# zP;G-%yV{;27zeol=IGonH{9DM`_H73;t3b+48>Lxs3;trn%>Io1~{|Io$BBgW9tW6 zq(AhlH81`Y#C@TYD;6U@bfa1SiZ)a`Xh)z?ie8_ggT&$wlQkl0OYfT3qO}V1fuh$2 z^GdJ}l%txRoNFFVt{CQ2?{=qJ(M&D@xzSya!YBSc4=Xo@dn-5PYY ziew4>|1^u@D0#nsJD^vBHA7w)3p=YS>&*Jr@6`->(s@Cf{GyomjSmc_)d>~NT{9Wn zJf5|HkAZ8I+&@X)q1&u{@A%G)wPyMjq~pS1P0h#Yb-CA5kFRdXHT=<tZ_44p z(yu7@B#xDbHQFb9uqW19PkFqIN3ahSW`+8|ToR&VMJ6~vcNIf?FbO|8kx4jQh~(@1 z)A;D1%RiaG8QHDWJtL)=Vkx{FU*R?79`eI3X(CGGNx=~&i)a_|ZLFnY-llCj@;B1o zSoMj-H{^B5dwj00s(lI0Pi_+qy95R+HI5uQ2WhvA z^K)3qK%JjZDP>Mqpl}Lx;e^=Rpe{h!(Jlr1QP4d6yj2feNws;OJVMCN#D06aphkIX zmrwXMXb;V|x$m{V^vD&8+-OefAxeZBupvdP?8gSVQ#+?%0-x;HK)|w7x(8w?=Kc76 z7u18n=<@}Skb$fB1lBf7{Wq5lNtIEBX3Pu&$>6+#hsfsMO{4*A|2Zw?(sZbE8|fOn zZ$(+wgfyI2T*W1d^Ax%-=Jl{b%u*SVxbl$z_=1^D!G)tQy`$u{7jGJ<0A57zB4Tu? z;lrWf%uj*~)9wqcnTQ|HF#h%y-u7Pc(z?=j$A)%(NIrm5j^f=YUukcBmK`qIPID8~ zT)cxnGp{nrevk!Pe7Wh#Jd+gph{`4uPAfWCkD4zF*Oz}k&%g6S>yw7Bx>ze3 z?7o@XW8Pz^z}iKe0sdaM+6D^Cias`cF0Duj^HeM_F`VmwOvP}l>D}-jA|+@LY-10A zSEl)30^1Tlz$40hfzrz?hR9c~lYrm`3fYhVA)P33r22+Y}B<|%tA)t_0do#8q(dkcqV(X6{O>&uFo{8j^H2}Dy& zJ!!ZzBc##hDkxZTpT-0!wY&%gL^0_?>psV*JQRBgm4kf59^uHCeH-Mo8-#j0puRjh zioPzT)^r>e#ycbrYi@^dxKytUPKV@QZ9{nx{?njE4z78FzXxoVZ#QctcE*bwg{P&# z_4Xq;EyFMZ&xU?%CT6_PZ{E!Q3x!QE)My1({6%!4UXZ=sCR^=R4bH0!fXdQxr0tRMg+es=P~;>26p#f+Min0vH^uPJeRMe5qkvAwdz`Rua5~dr*9XMA zUYzK<;`1G_^T8-#Zu7DV!jP!qc6jo_NVhcveA{_?Y9#Xfn$K`}9fh|ig`8C6iT4y{;Az;H0KT{-J|qqu1yv8S06(H z;+jmy?O+$PZZC^oknXCEj_wol?)-<2Ec|}ejn131vf3N-2B=V1uG}}&_+si{rs1`z z_ngubG#lT_5#z{H;_=pdpa{}uz$-EDP4tM7i3qq1hS0n3Bp5>NCYkcHx6K!dv$Bf^ zP{?5))R>e_;^m$@px%0E=O$T{oonz%OW(kpl?HE=N%zgg7dsQ^qNoXf>&ducGx^)$ z3I|{`LjaBel^`@fr_SIIP$v8VE0BXxC#TQTQ%})e6=58Aa(;__7*q{>31j8R=SlX} zNIc9GJMN@}lQ&6#=>5c1tvVlWdS;Z{NoN`}CsnAvGR8)J1G3EoEwEil zq?x}4&03O7e68os=Tax~=|BT2#P*jfnadzTSr z7e(jCwzyb%RwX?u*tUoG1n#o80a6VP0||MK>Jm3DYXkm!-gL0LDp?crUav~v)#Xm7 z5{`fSjn)q9F}E-oOD8zNUuX2#UpUg<30Pn}t|Jf&jC_!F?P)IZ5k?SSTHq`<}ue*6o@VUO^4(!;y z-C}R&d42~inSR2bdK}!v0qV9px!kpdaNC^h+S&cl)R^E_{?fcA+MAbXuZvydDQ!8U&E?lYT(m!3`|hH)1xJW!RJilaO4`2n z4Sk^lA|ZCaHP1l{?B}=`y+m+;!zUCo{{lZz0N_izWhw;Ej;pcRHTJ1Gf!aXBJf{fn zJt3txISQ19$3hgC%X$77;1Ly zZX@WG1@jiizTk=tm60nNS*+-VKEvMc$NCaQ2&4nYyLRRlqEQYH;KZSi2wDgz5l;Cr z?}RtNOcxat1RLJgbv-}W9g?d2C-(iEy-vu6uAaPLo~LJdZ%>{tpGXb;Ak%};>OITP ziFuDyag}JaM;f`##>KkYNtb^GH5h+7+dU25vk;QRAa9!Of$g&WT8F$9z+H-bm-NCK zCvcAPHL~6O=Jvst_as8Q8R0S;e&)`!suP@6)a+H1j|-udQE6Ah?23yy=6xhF2P}MJ zanTdr4?JgOd(RFDL-1*f`Q%!bA|9ZI(@ihglArRpQ($M0CM&gjbC{u~SK2C%rUSzM&REPFX@d_&~PK{#wgKIg>7 z#Kth#=&N@+Fb=|HB4iSRIh|{}<#!kA1gb@z^|HfOMr$Ugvm(pjG#9c(Ukmk=UxumY zfL9i^>=DcC%1t?G;j6dLt-q~TuyLe0*W_cjtZrz_hpc-@;xkZ%eGhtOoG! z+jorZ!OV`MU(VF91+j(k${PFo8?`g$Zmy~jf}9X6T9y!&Et3@EMZg!VI2?J&GUO%C zn%5$js$WQ6^00ZW{X+7RUphHAY6p(rqFvM&xAH?SenTNbiegtl@vU4%JA|+HiOKN( zx)eUdylQX(~(hcFkLv!v?-$bK*}#|?ZH`z+aKqHL!+0Z+h@MM zuU6hRn6neDsD5+x;zpD({WJc%*s=DhZ_)rKf=_HxMN9hZ`Yup%)7Vb@SL$q9(+ULK z0mq`X+kbn{|Giy%5B_`G3%74C@QvFu_N9QAm2M8WU@Sj{ALp8Ne$($=VZyY$n$xBS z7T*`>hYh+;Yvj5O)uCrHsC}jDKQYi`q%vHc^=~4dW+eAZ~++ z@}DYWQu)zN`6|inAiNyW8&g_dRFU$kq+ z8qJPvH;}L2<;S50_6Gy)x}5TwfREpByLHwl$)4aj^h|^d!M*$7s3po5sS{>>lgi)P z`SSOS@1T6?0m~=wFGO+n&TCc2ZZ?;cKDA4(U1tDng+4^O?pT&ym22ES>*Rg&QwPbGYpSeWM zeWUX_T#zGuai8SMOfe)CWF(|y1^4`SSyGyt;C~{clJ6I#L4$7c5UTGY-U{=Pw2OOv z4KKwi%HRBa{@TBL%NcL&0cALe`-G9%B=no{M`&a=s0;9rzetO3&-$BcH5TF(B3Q5l z$nN2y{>T&v7JQk@)kp*z=LjZ2ktxM!9hMBhgW7zRpQPJ<Q6?Tz$$L$}qy2&YXdrT}TQ@b=%Uz)j^ zsy_M{uP^`W*Ow!`Qqw=i8n2JAy$9bv6f#Rf(HhN?%tB8NMJsX~{!ZhtT_ob0W!RU} ztB6d-1@w1mYZUj1rs}u2STLU96Zp%RYE=P`bf>nS$8glrWG|LZhcl(Q*~&l>%b9n# z*Y|8yj<3=2pjGQsgwNEgxL_Kzz@_Zl6qzM($-m>FlkhKOWzTvg75*;;{tFzW3#>D# z9l(ENN(t#c_CZklpq_cQCu(;_p2`sdj67xNi^x-boHx-R?e~H2r8u0?MjXz*!9Lj4 z60h&u*#~J~#Onj_;{E$t`@jLx7uLt?WA5Vh`MwT#vaf>dE6uw0Re$X(qdt+4zjtnb zO>+0wLsaDMFN40U;q&Z{T~^8xno zT6n6qVGpk*TX7&d;wT34lkY-RDCc>w2uYLf!*lVpQ%HmLq|X&H`Qag62}!?N=CEAt zWWMTJllwJeAT;)I^K#8cQiE>_TA-jVVUE(;22NKTKDzLzq>fM5@{R2d*TsblG&%~s zipO4L&L9v_2kZeeqk=BmxpYXZGA7Huibm%<*LLY-J-*a1OJR(z(B#p}+^C9N4t_+J zFl=@4N5>!rC2KU1^_TIipD1g8L+F%09*lV47cUG(6wHJ}sC>JmLv((t@C{_ z^tujL?BhDT7iMzsk%@m%At@iuGE|4_kxA#(G`kP;Iv)n*Bnj6h83~W0PaD02cqQbB zdH=e^bWbe4`@?i==Mq$c`^LPh=yvU{AF1CgpU>PKSG#4ht|&iTCTL>Q_A+J>-y+a;C_c$ZC=nPos6lb=PP<4>cEl^tp!R z5V$!Qb<|nxg+^>Ur=Uhz31}F(GUrJwkTiMHkC-o!E{pO%;PYkg^CkPh=L=ivw~RD? z*UCSPVc34K_<_%uM0>@O>2Kn6$~PBC;FNjgRFDpm5772Qn#8;_|7uX;cVphCUO?M= zJCwU%lcw{~XIw{6L(F@QQ#?E0137`b-{bzJy7&ur^r z{p4$%ip|-DL**_(5a(+S;_OCkW^Inwf%K4}JfvXHy}2UfdPNIGW}$&;yrP9H6f;7u zSG4o+ie?ONj90W-aj$5v$;RgwV6OQx{DED%I_ABM6=k1*hF3n1Iz7TPJU~vscm+Yp z4H&TeAJnoKu#YSHf8l(GSLX9Whx}q6+%Bc35Lzfg^`~ zpkTY+t!(chEJNHd5?baX`G8(u)Ad6iE@gxf4 z_V_YgN)gv}zqZZw&N5A*lpR@Nmg(1;|6>-3x}Ax+*=>^jascU^S|frELo`uzer+Ak z+|6_~=51b-gI3n|xHbhPH$Vx`Z1gYmX(&zOY5gs<d(rw z1FWYxxb_CDC!qnP#o{QqqyW~$_d5+(L!7Lg0j$H6)dj5CZ^r>^!LuoV^;2^x`dQnp(asY4a4C17HUe-hAz_O>0v5PzmOt|gXoYiP_L(Nl3hYcq8Cy*DtBsmMV5i&2 zM`~mX@UkH}t7=|impEBd`=k1~-1ioTpge{P1V1cD0bK9o3Sy=kJKu|gMzekPd(K72 zD(|a%aE&fOvzKeK|EI6Q3HguXA6+Cc#8l;=bLAU-jqKxBVpHEBpXj5ici_{8#Ul7< z=~LQ09qD&WG#9#MlKOQ{zXSP-QY^`2$7Kx2@*D%QKKr2W+jr3E%u)=JjM?S)z*z)x;zZg*0t7325>$sF(#i@Z`eB+^0Mkuo@G412caZY(V9=A9q@qwy+rP>3o8em zu1)u1t5-vIzg86P-q_q`yCv|ZUGfuPLsN*2kq%P6x&EEX}>kuPl(=< zAMObTA;m+G1f3$+h{B;O6Pyi&x}G``RDNGdep*t?0}Vw4gDH&vXYf{&xlBD!@Q}s` zAMbyFG;;KZJag}Td{0cv3CAT;Y}VIVTmw&&SiGn9Bo=Q1SPj$O)6%S$bW1#K=O#=Y z{TQ|euw`g(uj#^fd-JO}Y;U2Aw$@5^!)eJjMl10+p+z}OhhMR-Kt357;oAR!Yoc9!$iey2L`ZR7v4ZTt+^jGuWh6HuAFpE|Lh zztK2<`C95Y@8Qh;`s4Jurrwh2wDJ4ku^C~FmHqq|?y%<+>;ftsr@^xI;<|~gr6E*w z`;S9?7-D1`$Oc-aGBBuEo@7=y8_<#Oy7*?e;!}xBuATPa8tpVzm~AxAF!yZ2|E3w0 z@HqwbH0!8^&nu7+%25rUQ?Qk1%U6sqA>9G@xhL1^{A_esagNWIs)A{(-b68@U_$xS zhl%zJ(7WpUG_eUM25X-$sG(MwpYST9l8y$5mv@EFTG86e!7#Enbnt1)`2Gq@y50Ex z)=X0341}&yA0GPSp4gM;I?rzkDFv-LE-t`>g7HmaIrEcHxiztYm@(b*k&Cg&;JWj6Z(MnoD2}Q*9W}eWzFpV^a&ICQ~Aco zO|IO|HkOT(&k#SZIB4~kKez7Xne}oRd;%AHg7oy^8BD<`W*2W(69$DkW zpod|?P#NhlO@y&AUc719%zbvV}tTTAt4S?PFy7KUJD*5cw7lq_J+?~BtLgP zfMdsCLdvbjlgN3b#Bq#r0d&Roua@kIfe4EeDKYP|M+^sFfiUY}b3`jZV7b2+!{bDa ztT8arSnD+gCQx=-fCh4dtFWhnjo_I)dAca84?vQ9(aCOKnf&2Z=fhxq2)G~e zRpL25B#?n^E~w4+OwJNQ6PGFX`#Krp^+(CghY|X)jt@_oI;JZ1*(*j_&9yD*RTx93 zSM{&mji{!)qN=ao;pa!a3#i;ak(!NMx59pm@~vlrx$fpe>v3_@A@9xV1VvkW@@>5P z;$PTBlPY~Z+SIr+Ove#*klFhKH=DhTR3@?XpCUlVPSS+u+gI$;#df1xa3$1dGJ2%0 z8-Hui++1O8<7meXBseJ*+nfQ0Ou}&a<~4zBdYV_~h{$$wHrb7THvMUaH`>;pRXdaW zGidMryz!e(_2<_h@}&OEH?N8Q%r>u1f2y6FP4+qThmKUhADF0fnWt#(SaEK@fOeg4 zW_J6dTJfl$SmRUAT!?&{2?5xKG5V?OO$^ONE>Djx(6s6dM6boBh#p+kFH=SY& zRBY8>OtF8c*aW9oKQnNORhnXUyqHJn(cBsp`?*uB7fJTXD&~l{@WCr~Kla_R^>ANx zF`dm!5x@DrB3_9}L-xW@5$MyKRYWM&P7>_E1f z<@e0Yoo>#Hv1^#QHTD;r>#cC^vacOP4Rc2_k)2mHplBoS0dL_Y!)2pyWBs{O_l`4Jgh2&njEMTWs*U~E(50SuQ zk-)=f3-N#8F?v>boEEg%ANw08VQ&mDA7g^64y~Q}@WASv*(HC?`sk~wfYXQH#ryD- z!6Wf`p?H)1)UWs1aw|wn^>SsvnTxR^pl5%WI6lmb>qU@!A4S5mo0{F^ES%&mtHQKre#mnuGo#J@kt(qa4PAc3p$DkFU> z2Vvn*b+~R~#jZPOxQ*jn9wPTds4DdG8?@#u+&trgO^a72X*T$NqI!mpR{nIt1aH5{ z){I}29O1!Xv-=HewcPp`$Gu@=f-36n(y%p#uzsJn@lKZ!18edylLU4ERV2YXLLhQ6>T>)2iM_2Z&}z{E%40btZRt@f(qzZPRy;_rK2SAz)oTxt?=B@g;$B` zeWRm;bIRpzW2NwOl4p)xo;zhi8XR-)p(Oo#t4aL=1)oXM#>l_idPAIM)*^4+l z+FAG0$Ev&wqFHA{`4Tq^B_i%GZG>*3P7^n4y5e2<3^T_tgwZSr#~H$Yg)hjxVm&Ci z@V`YwL~~2@vJP5AFGYG;u9yEK|Ddvitc`+pLcck*v;Bjo8LQr*o%2OI$Gr0%OpwiE z2E@tcn|ZRg8KQ-ZTm%~I{MubzCij`z6&<9)^vNEp0mA%e^#He8S!PbmV$WQX_Jzl?uZ|N8CSzi?asdM5gJhWhs?bhMa&`N4*k{My}J zJohA~>p+vkckOp5rnvv0RDYTNxWCMj;3831{3HCtx~VheICG#*F!t_IFdo=URlQv3 zCMq18?Ij*0n6@fPTsqx91-`PsXZkJnmI6nTA$O7d`{4a{ndR?y&Nq4 z9KA}YAM{A_V%~Rw`bEXnLLl9hC7SyHm9?U;k-J{Cehk&L2*i+PpZ}-5sx~dP>&t1B zYI%-Q@opIXy^i9yjB~^_jt8G;d9gjgOefT(K!mH!lmf1rp{d@x|Q z3KM^Vv@+R3N5n-_!N_%-HH!EM`ZprS1{_2=qQ)?C8;`iEE<<$~3}d^BGh@Dvp1%hp zuvc!*k$n`WrpSSJ8H8C~xv;B6aQO8+<0SY&wakpe50a|5wjmZ+{+zHiEH7w%mopbX zpWFR0UygmFX?Y(^qBj0e&>}#F913i%y4tXYYFEds6*w#zo>RL^p`$DY)*QxQIh!cPToJ&_9PlFS*RSDO|NUrsINp z#|PQyJg8go?QnT3JLJlUCGDpPyvPB6mHHBTGMk(pa_)aH|c1( zLKI`M9{}gCLYv{1wO%#TrKDr zF=5e9Ze?#NKKjY6n>qs}#vc@_l4WseFJZdXb6A$yHE$&j5m(l$VHeSKZt0{4%J&&F}Bc z?<3~-kLLGL^ZOU``?&f2?!Bt#OY{4o`Q2)MUopSSlhPkC&-a_(dFFSP`JH5b?>4{B z^XuXU_KbyUer|&Xz+Q}An8TipU`jhGM@F{xdCzFgvp1RVpxk}o3mpO|Q$({HO-?30 zn*Cez2;xmrhG^GrXkYEFFxP_YOSJ-VMf8p|FHE~^Nz-AGnVK=Cc)B}lP(P6|ZJ}NH-aqNPGrFWn zY&WLteU0gMb2Z4WHsANNb{&oH@l!QX`y8Kh>&QMTx#|u^+7{!~g|kadwH?6OYflow9k26BXMOk`@fT`?o40P z_tn=~PK8e-SJ=@$>IeoNJ!QWzaH3Q7#mQB7rmtg7wH?5~E66Gsd?2~P&h|BJ|9ze6 zRQ)jaVsPq2O#xG0j%wsLMAv$bMM-eJB+lg>N$L zV}`OKGK;1iqGf-|f$i|ei-r4u^I=AakbSS2f`f$fNv6_$!ufkfVvv1qa@8HLM>P8+ zQ&qaI8ZEUya}QU>otuKW>3>d2@1B%?Z&LcF z_q6qAW>Wg*r1Wc((w8NrmnWtFDUmK7ivxer>>}le`@ms1_8hXM-U$9_qpcYS*5CgE5t{Gr-=Bip^uAk7?0xe%aEiH0>AbLy`%h*o z>V5A;=dP4*4`E3X6}08+exJ#Ab5lH@cdvZbI^DMN?PtZ+iF%J&5zqQQE0U;E_bN2i z-Mn??5b@R|^1iU|yzl9XOZ??T-n;jmx0^GpU5UJvd*zLHA#4sC?`Mti?v|!xP3`X< z$=vWCk;r^#N@mvN?+8H<@fU{K--NyQ*2itR?B`}`TQ0K9U)@>DEq@8B;lvuSA7>Lg>IYm? z(8v+x;>oP6dpiBD=%vac6bFgi;kW}Fp}i}EBo==<2oLmIYw6$euZfbGp1K-1b*Itd2dFwH0Et^lD->H+C|(@C86nn zknumnCb~}0c1^JMq|4=%L>49&-)kC_my#G0?tN!<*R(}G#$YY2-8vM_qxEZo13nL~ zZw?N4Js25s8u@~eV^7x~WQs7f?U#f*v_hhh69OEEK|f%n>^$-7p?*ZN-;?x&?XbMH z`y#Qs?4IJ6IFDTttdn*#|MgyBvmMD$Kt)zlaKO^qw}uASH@V=#w>_)&@hxm+zh%BP z_^q{OB5L0rTJ#cyLn$mt@-6C2J{TaDN~>w@UuNxzcbRMNb7pCBU*$!-R$Nysn#Cj~ zZDlj?1U{kQG*fUg1#3^#^iMSJ*Q+AokCwH!rGjm8*}*37+2pmdd#U5m+>=SNytnE@ zeIz^fa@Vv-=Cwg9>!fikjen8U5yDp1S}XeeP=?ge zUpd`P9E@#^dGj=SEBAP%Yr<*ZpELL0j~CxD{aC@$I$dnH{|Cf~X+CJkYO+;>-HyFB z-lOHDwDm}+-U)S9r3$0D_wpyU9<8c->str#eudt>R|$fw+!|g$EY@rI%~VP>_dHUp zjWO@pyw2S$LAirc6WcXq{yP7XgimX?5kRU}L0ET~a>cp22-T3HwdI~+>#q%4$DAa& zLwV`?Pp0&)^v`}fZF_n2mucH$7<*-!ohN@qPl#tg1`_C5Si z@;9V|r!KY&?2dy^xN^B<7889Ifj=n6{cO^R>Mj_Pdt zWfp(HD^H}`PYcMFwH{B#5l+S&GEQg7U#`Kl6$=>qIK~YE0jPbQ;msU0FmzDBto17T z=z_tfBq%e)78|SO=Z_fJXyXmohnQ*DWxr?$myPxc^G=xIdV-M|TmcYY)w0teM3dSz z?VTYaO|S**xG)XaJAC0g^%7V{#f9 z#3b{WA`(CoDtn#R&~b*RbOx|sM$RI$@vmKQl;eBS`rFY`M>rW*6qBr$cR^a1#97&DYr<0;yG-en6f9!pGd{b4nf6^v2l$H}7 zfg-2@iWcjmQXee^Odx?1Oth#~d{U=^sG}mB06r+KX@&F{<<97+^K)j@@s7?o;~>{T zL`TyWX$wdz=umu7)R7&dQqU-Dos&mP!N=UW_x>^P>B&C(?C08Ruf5jVYp;zE zQG+J)1Ux0O1>hXA(R-0X!CTut05Q_qMKeTOGhR@CPu9_R^Culwg$(zh4;Hkl6C_)-cPSQj1ZW2s}Ar6N<;529`)Xv#^ zMxv){F`1L?OYOt4!gLZe2S*XDdS~>pz8%NQ^v*c+&YXh!#Av-UG}zgCXX1nXD zv?;m?U|W3xz_y%Z?0*75dI6W{16v(9Ane6#C;Dl+z0!?_YJ1b<*d`paWm7zWJV6fJ zkc%toFxh9z=o;)an`!D5u-_VQZaKZ=(RM3}g*~uB#a%-OEWhJ^NeA3i0zb7@Ji^)j zi&{}g>mN0x98z7(R!d*dj^boH=2JV$lkI>r3%Gmh*^bMRE!Gr>rQP!ax8%B`l@h(- zqMBa_6OQyDXF*1Kn7@6OELGv0gbVdtmZ82-7G_^K2f7E2=m*o;DqqOd;wx!ZPI9WA zESME89N@&}etNxJ(zdW4?laAc?uH|P#vbBXqLswzr%wnsuJc_5Zw+0E0%M>755@0ES8Y{4&sR>h@XKQ1W-pOKFCm<;CLY#H?%O^DN8S8 zZvYMSe~Ihkh@#-C^8<;NXaO!~rdCdd_>~_r&eKOj$mAWW zwAS^d+0ja8c$H~xWF6{GaLLk&-=TbQIZ8x7^5M(jRP^O(qP*7=!n_3m z5bGfSWLc|=dFIVor_DTPj{h?Fh?HJ(!ln7F967xWL7w=yD;ZZ&56$(!7j2F@Gs}w; z!I|n*Ono?UUI;?bkQdzrM1w03LiM46yK)W7D3pnb*AKsGJP*IG3z97wUexUre*k_J zZo|k7z}1l%@(SCRSZ4sCUOHMWebwX)EMJDYorfo=OD7m6x(0I|H)yfQR?Mj*hTZj`^wH#nU%E6YD+6)G|o#8T~ z7ctuSy1v6F`V@mv_E z({UVv*1zQVCC)TZx2TtZ1Kd^47yp1D!*4O$FMnz=bh&b`F|Nx*BIzYCC6c=y?V&uq zR>Cb?Xm!@+%Xb+I7Zb`4|_~yz?atQ%R%$cAydt zAg;fedhLe&sT&sO3f`bDIGe(cYT=O2uD#1>vFf%Xn^mswu*-!A7rL!-VZHpab~*y( zkHt%2yt0x;%xDP6=DAcS=&_6gO?bVIUO{($7<$lH#btdC8yq~M6y|XZW#0<_Vu0=M z&~gntfcKS%i_E`S1K4WVH8(&}M1PQo%kYhHf@#8)P>9I^i%E#PIFOd43shQRxY!(C zn_-A^RLFl~XFNalHTTBDq$^C=!T??;-UjWI96I;*&tSX{-A)PZS%4C@ia*~2&B6{j z&Ai*K$}Z_ z&!w6VyaR=I^;b^6GT%L5r@GxWU}yFI8FO#*7q+O~t^wP4V5O&m?oOB5;tKk@)#l)} zUkA$$yRi&jA_uZ(p~{#u&}9>uG1|Yi;Id4HuHyD-?)w>N+CrvJ?+yM3)h2yIaU!l;zWh7-C zXvile-S^}cws6y^MZRt{DtN7s)_>feOH4za5y<0|*6$v==(Z;F<1cEkYBK);rJqrYyeQ1rM!r(WjY_c0irHt)?Ki2Pe**RekR#A+X)<4d0J#k4atnLVJPU8i zkU+D&$vg!?VrPQpNeB_f6oD%60lFVNqmCjWKPrOeMd#<37Y}11;vdf~HT#a=(mG)~ z>qb`UmTZcD?omf<+|O-qUAKVRc#n4b;&+`!L`{A}juCVp<==T?5U@pBtL-{$Av z_}R|Sclr4~KR@JW2R}dJ=O_I9l%Im1pYii^etyZ%PJZs^=hyt~;%7HMzv1U$ejeec zVJ<;3jh`ld_T#68pPBs3;^#nqTKPGcpF{aMjGsCDJb|C1_<0gP?fe|W&s=_tSV@4D*KCZOSk?eHOOTJbB{%rF1MRUsPjLXH}QMs@Rbh z90VLv(=kLk6*3z{WwV&I7|R$=h`^QIaZKrY^)wDM+Wcp;@H=DJ(CEvKz6)Y5)E@57N_dD?I^0Jp1YdZbM^T4R!JL>9C%H;jNMWPK8MQd)!ZjQfIVu&3#S?(+3JJm z33aEBihGBACbXk)uX;Z_6~JbUtiG80EHd~o{sZ~cXd8{r2n?fm7dt$1#YI^#4uSH< zr*5dbKerueSAxHmQN%ig*~KAWE36Je@z8)`u(uOGZWrfZkta{-asS*7{RUmV}f(DkmZ8>$IRc*Au4tM?z<1cjh+`%0i->n&&BY=BWcD zS8H$p<;de4{?X8JA=#$D!L%iC&v<8n!9P&c-}G%PxYVIG1xuo7w1)ivBu$LX0&px# z?cSgxC)F*g{28pH_Eyqad9q903I=$uh(Vcva57o{pFpV1L;<1_8Pv`IE;+ydL`Y^O zi%e2zC<4_N5FDl23asmJ9&VCqa{x(oMq<)SD>4w_Exxfps>OZL2JxHusJgh^F4f$E zJYp4IWp$}ttl+@KMH}5sMz6X6H%tF7K(d69So+z=E+H@Vfr?&4FV2h7OpQNI=^0(PE? zi%fF*Mpy9-Mw2p9WG18JiffD}aS(8l(;MkdfDPIeceajti2NTe;CWp0dKz#k2HWzD zL)|4)?s+cqEF!$B|B5)Y&c(Y1t$c)1dLpej0THg^iY)2AivTwl+#y3&-JxB;jbXwB z;fWG*Z^p1_^W`p5N%}UcWjnx-1cnp1Lkq0V;>DfPgHb~3lEq(35AG&tT!5DQDo*jH zcR1DQhl6f1OL(B3zBsO-akv-;x?z)CF)K?>Z-Df)OXS7l5vOKZgTB_6CC`bRClW!aPKlbJZI)`+pp$C)ILLG-Pacg~F5UYCVgPBo zGEn3Jf^r3Jt4*)h1{JNhbxq4PDV3l~9tbr%ujek^PLWbA9TMiOgTxm>f?JzhF%7xf zDEHeW1Qmgu1$te8X$aT!`ZN?jhuuM)?{=s`sN*=`O(YTH$akMpe+mLnhro&B4IqPO zVBr>b%;niqq&OpwY3IJjgJH^5^XVt|ZP*ouC@X_a0Kf?78Qq4%v z3UP4-5$!+bb}%~pQFCh2|`BlWcwu?L@lZ$6t6-V_H-^J59l%nb>mrTPi zP^Bi9G;BH^(YBWhn+Q1a4@?Hd`6+O*Vm4E@+TR0{0?V=tQq4;=1;7N*!cKa%awbu3 zokY3SH{?)_&Mbg`053x;dmFeborfqP9ai865;MUb-b`s z`u?mH)<0QT6#y&Ml738lMV&did0i%p!#_{F!(W-iY5rehEjSW1n|w`_8sj~xxY#6z zOsfde>CN$RAW*>;VaC@q3J#vyq)ROT&jjL-7?KHHAbJ`<7K3)VX=qS;VZh$|9B3cu zEt%JX2VuIU!iiZnxdWqaSlHX_cow%6HV^?RH;ASc|?(MR;rjvBb zPIhM?2eU&Bab09Z8W!rnT_(dl!@LzU!LD3_O_Hqs-U?Hu4~$5S!M=CMKe4V3t&}0K?JbR5)ejZ61lUOS3D<2k;EyN5@xl7^kBoQT@GD= z$}Y+iyE8y_fWv?Mq-28?SMOY;a1^enJJYSf#_C6s2*^ z*AKUvr%vm51AVI2XU(x<;PV3Z`PHsXAs8X3OHFP_*8_bOF>wmi#GcU5j3~|z?%?Tl z7f3LD9wahJg^WFfifKSKAU`+*N70>DspbkKDZbm{w-lF1p_zD52h_GK%|t=~69*kT zYg+CsbawT#Drdl6_D!-cfL3BO35s>|NGn04Ih!orp;|`z=IE883X`y_-lF7qR9_xx z7c%L)Sq=`2PT~zHlxI|Cc+@g{-3Frxd_BikF&#RBt-=KH(;287YLRN6qjjlxid6Fy z1=N8aT$Cy90NSIb2ulXTP?J-=E(c8-C|A5Erp&^}P!_v1Yemief_M|gP$egNDy|#K zrQ}m7Y8%)(s&f_Cw5UTgW1@MAm*wd#LZO4i=cNodPsMa#js`gD(Qs#7zg$yS`^c69 zJ7FAikaoV{`gowIK^dz=B|SCK5v(xXApvwCvQnUt71l>Ga{muM$etyI7B2uL;w!3P zLFpR(Dlhil(eUx*#Y;1-kS|_ExIQ1E92PS1JG{xN!!EFcsqGAnN2d z6D1URiy;dOeBdbvp* z7_;pyrK^qrI-2%*UXWe%TdR-!n?NH2qa-j+Vm+$FJoHbfp2B*y)8Gcv6uzfehF+Ag~&^)1aTSy-r#(6iC|nIkHVF9WY9+*z%;x06b|7#4T=7R zc*lA%%#m~8aZpzzj%P*U*i=O#u74wSizF@qUm9~1@J0*sdOZ|qDeYvwn$2Q}CfXC4 zuW}i(R*_HL?WDs`-_W$jhGgV1jJB+fAmwAfs=KTP|Cs6$;+mxz2fkF75a%q_5Wni^ z+USsKh+nNP;qj@52OX3D6?Iy2e4d9JH8j^IeoNRDSZX&Y|4%%^m^Rxko`ao=7aBDU z{VyyMFGAK_C5Il$tpa9&*v4#YE&>yeX`@Bp3J)Sx`I>)!bce1ga7gRFJehvQVlSca zg&5{LvRIl=@1&0BiE9%dAj(g&5*%t{m2-s~@#HJDqMtXt6W$s@_t=w+L!6?a)Y;;* z%NfqT+E0`rK4^%*@I!8ee6U%Zas#Rh*?z)p_2w3dWmp(vtyDUA3lmozeS~D_Lm-Ed z-vH%wNS(%z%1wpTa1BycaVIKdNJ%xfB8Rw1YXA>){1!z>D2ve6yD?2ZX3}`g{~BrB zvd)hFqk3L@HJvSE6Hagu8oj4nqj!2NclyNCPQw_J(4)VoVRm#jNW!I~028-! zqztlou~qy;dx2bkagHdXm*8xBG*b@Dv;thX&sjJS8Iub{5q<+p3k=Kpi!&%#USMG0 zX

Lb}7^2JA*0x3fyUpvD;9o#t5_*BTzi((>>yi%LwsgyFPDk5ijZyJb|wf{~7;& zr=9eyO0M{MGKO?A%3x8Qj2T0^*i*#qdJJz9RD!_*&tMf-B9;i9Y!|D6zQPmFr)@sW z5=D9h*F9B?kAF|pJv>mMi53_;f1`c(;tG&R$K*mV@03Gjl z0$NYNbdc;PSVkXQUBohbrfyGRi=H5^Koe+yD=osSH4!`mkv}n+zF@q?IiM_kR0ut@ z3!NbSvK%a>4q1Ax>;-NWW||-cxV-hC7yt%`*F&iJpBwM0~uKDKz#!-C}_KY z|IU)b(gR;0Krs(|h(Jjt^u+HV;H@|y8ffdL;vx$Kt4?*2ktl?CJ|#{QVn&Hyro?Gd z%u0$$O7qv@8nR?#JbsM-yp%lgaxO`U)5>uq%W2SQujZ}-*bCqLE9q<3(`Nxz6^I24^#%L(%3gkHZ9C_)!dkiJED+Noo;$|o>cP?l`+R8)l?&{_;J2F zMygft66mli7a+5LqED^uMlx;RK%9W(Fwl)HkOfFoG6Sf6BLXgLj;gIl0>znV#*~N@ zAQn_=EHw(abWxEra1gnOb#RqjjBMv2L_Axx1$mH@=2YHw$Vs!Pcutnzsb-9QgZ0!4 z?ZtEK$`Dbz2;)_8v7LdzdTQd^pqCg%NlO}}d)Fgx*9@qqYltP)xy9Q7lk|l*6<=;& zjFo75LGf%0sO+UK8vKjEBHRQ?O^`?zm21CHaP#8hysal=%V!UGE7D0lfzq(%V<5pN zy}@h>rVTzkiVt9VnN_CA9D65<8!i$VC?)04QzDPX;cTs|;X0t|$2vwtApP$+T&QlK zbsbzq{B~q=TCT0@q_=A1DZWLNV+!{{)BZ0+fv)y_zFxhiu+33F_q#Vv%5)VmrM337XsIjcyb?!T}bRjN>3nc^`?jA&~&ReKP;`aOqJFS zHRNydXW%FZOqRX?V{R%8M~hdd)wm6cxhun>>wj&Kfnl)dqc zZ)4Nc`>SVcOEY-VTVlIcA@FDX{RjSjgTMFi*MYxI{28{V86L%N0e&6$3nN^L-yHmv zfWwAQD8YN|jl-Dc=c6U-dM@oYRc=KTh((I{^WJoo{ zSxMuao!*k{S@&lc77vd!ASO9}_|_qf_i%oUbEZ|Uu4gnE@2o=nDqKC7`2>AfjXM{S z_z6U=rpPcwwjm~rm^O;(pqNhopQuPrpkuj|S0Bxax62a{Fms_snUql}_a91woLo1x z9X0s(BB!KedqO4)ic169$@p^u7aIXShe66md-KuWoSIBJ6iww*y@__`quu$v+ntYg z=l5tgvO6eyKH8t(qy4{ zj&9O{kL>Dad6}*D%|TyBG)r}N&^qR-$MGhZsVD!F`Yi@^(5pKfE)nWPj0fH-t7mwU$rtz6@~9bb7QSy`!uR|=<8a&v^`Dr z)|bpTRhmoYTPic47r}lDRtnlx!&xBOSd$)Z)Eo^ElYlL@L?8PKP zEbs8B5}$?TBRi&v7^#YB*1{HVI(DaB>V;V@)e6Qz8SV*{X2}(4o{|P-0PQk240V>Y zEc^nGMUUegZ!Uly^i+6PT4gm0zUARooLtwdyd7Fj-P81PKhkcm4}Lmsv1nJxK{-(1 zr@0HDDua@~h5M^7 zr1pnQ4@@t)rpQ#8K|hvCi&K4z*rpFLaR%awZ8>DB@`OgM@T7l;lV)8?B^)L}6vIgS zEZ{6iyCrKlgXP_wNPj?2bp{Yh^FfG=AW3WR@ z{K*R+7DOh9L383wt*-2P7viV|Qi~)@JJ7N~L z6Z^uO9~+m%f8ZNC2cz48OZj5R&%}1#Jb4EIhrU>JS70{G$x=Hp7dDF~2hRn44zj5R z&xHjv7ZzA5`{8gxJ6KPMto@w0e?4k)sWKd%#SKg!pt+RnISU2fA8(TFW`apX0^%dC zI08Mx;n#yAkD3>p4P-f4jH0l5X%XA4dUKb;1rC%y3$V*m1kMvguXH{Tii#}2AB0qF z(8;PKxh&jGva;FRuWJhmrog8%n z4LKMnZ$_KsHYn`cMLAcm*+RQLXbQA3Xj^PMTJJ!$hNuC^?m+GH=NvIeU`q zN2@mwG=3yU&|}CFFNBjC&!m$8AURw*F#Xym#!e!{ywrjjUM`05%jHEh-9>+Xxez1) zSAsREIGnLnPA@GlB%c;Yfo|aslt9;imWt1rhVW{q8U1|sWREOHC1~mK+qk?WrHu>u zMQ`I=e)$1ylz(^|6M)>3f=5=gpF1EHJek#4J>CzXd2!u&mi zbL+>o{~E$P+<-Lj&21#dfAt3}*~IKa*yCsygFDQ>OoP8OGSL zX2kiw)J7!Te==P;Bx&EXwD10XGS0b<3xa^-+dS!QuA;$S$pz1_;N3TTALk0xRtN=9R$`5moq^pr0P~g{_^8u~ zQ)1xSq$^sS+jpbtw0V+(X}=@v99!?lJ#h`xo#|Hs}crRZ;fhpjz0>Kj*$ue zgChoTF!UMh8YwyxJ}GdPt-oNFgnW$lU^$?tE>4_XrTKteKgLId!OJDTC3qJq>k(pK z`X~!)DwfQIJt2z)Rq&~dqhgT36--VeS@OB$Kr6feG*wM1GWZWbt6&tDyJ<0lQ`@jI z$_taD&=p{jn?()F5sl7`(=A3%uph2pg(_kMYLDW`BIL-ljZ=wRAQqA3bx1%C>fraY zht&E+4Fr!1(?ay@uUL6EPD8}ey#riT+ha?5y3&Q5vYmX&wui_A8`J& zud|@>GokU{_z6!w8=7)Xw9b{Q*~Ef$Py?~}{Pis}4z=T=qtyt&8s`Q4MDD?o6-O(i zp*S{HMY1QgWKU7DvXo?0*6%4D;-I}TKc=PoC8ax~SGr$OIwXdXJfO&{FkLsl|*r^TD-KnL!7eA4|^h#Gt>F5MH(%qq@yNl9=dZk-N>FCTm z(%qz`TS)2V_DbicbQUe$^;)`{Dc$7Mbdb-E+S^O$B4j>|C*#af&3|$^<2*KUav4+4 z$BAB_^unuOudd1j^0WgRv4O1kqqq6g7r*XCwT0Vo{1HZoXh6(1cs$`OO&9;@nC*sB z$ZN?J{vja9oGfPBm&Xa{n9(j0sRqix0ndsWE?xlUX~%p;*S03%`Lk!VDD$Z@)!<61fJhKZV8>%oAaze5(mgA@;} zG82|IoaYhBqnf)H0u(3+`l9Cb4)g)g$bYMD6Del_kx=%I!I0+)+h(qKh@lrf1DP6; zDf+_8l-#L?6F$Om-#jPop1DE;wT2520~6W|qP6i8BMBP#V{qWd=ILv`@w!v^1+ME3 zdqd}bI_TS2r$>6>k4I>fVYLF50lb_nx!#B_@~AH!(MA}8TzrII92Xy9nqB?IrVcKW z#cV&<63`C%2Q;KsD$}##ey#y(f>GM2@@sN_eKCfLg^rh(tHkk%e{O60_;cqI)@ywO z>nu-6n`Ywf4W03}75X@x;ynG2IPRxXoPWfzJ^_;_fL=+8vww6dOhA}$eoRY16zBa^ zio@l{DUMcIg5tb~Vkqs19u!9}fD8z-*zO9n>19d@!2L^cPvZy3ixp8>@B}g2?=ko~ zl|5qD`aG1WEan_@QaFZEi!_)SJ^89QJ|7c5HHUjx5irqD-Nf57Sbs(!gk|{z{J=Ba z$KR0EHFHHd#11VxmuMfEv_b7iP~Q%7i3yms{~S&ovyD#8DIhiR@s@ZKA3z9Ad=Nj( zC5Xw%R$_OtS?oB6RO{5r|Hei#p2u~FL>sAko%tB0wdh3rh}8!ZAcI8GEM}rHWE$NQ zQW&das9cW)i-Oeg+T0um#$OQvFxKOTSsYQ2tp7Bse^VjV@6DZ0P7df?9)X2?h2r=v zw8gy#(Q&jozu@~Zvp~4sFmh3=bcU)xYiKck#QohpVRQ<&kzj-y3myTQYv^=rAoZvV zMjWB+gH5OkIy&N^{*EwU@+E%6Xs)W8h#>ZSn#C&#HT^rE|w8s2*1fcClbD{__ zM=D;%Ax|>xLOXE4saaf#cDP_thr?ss6fIy|b5a}#Si*~Vmyzh!G3G*&hS{FHS-XB9 z;j+@LHs?1(Jv>_lE3zHuZnJ-Z5H6R2&5k^>MLzIWV0VAq9PABR(Fyd2-c|-KdB47StHY~+K>CePRP=a>3P4lGM4(5Xv%T!DOSsoUZ6iNX) z=cXQ!(_^aZkjY!pE#3PEq{9n3*DVEpg_poRhj8k*=4V{5)yZ~Po^+g< zd`B3^l3ISc!;3+_?2r|{0bHsN_DgTG!X00rgLaV{;+IBQ3}W+HFgM;9IhXnQ$X`&h zM_mlOs+2wXUq^m{cTlJF7S**`>)E{&Q3qMZ=KCIk?t)=v$^lbH~dT@!T(YSXq+ehF%Elw z4~@a&4$MK_-|S%V(wVx)-lqznz39thFL0OgS2;;c2=_7>HwFw@ePoxBbhT;X%yL%tL-^Jk91(Vu17*Rs)tkc5UJr*-9udO z6#wm^GkOXI^`TYik*2cmG?@2gKmjHn2+vA{Q}k1*x+>Cz6{hrIFXjrN#8LXKUOKMS zGJ3S@Q_@Zytr6;xrlIdN5cU{<6;L_bLO zEyTV`n@9RH4qVsQ8G(=;y$$U`NeS^ekH#uwJ9HFUBeWd1FFh*NIy1gEVNCyk_akvLh+-43ZE z00T$SIqA>94-q2DjX`ZpK zf$cUjxyLWgcC|`*c!#2OxhYr7#P~zH_ew7;g8?#@#^_+2LnBu>>XDf3-QgBczynwu zMJAa9L93X?zZ?IjNDOp|zKZYECECUxBaIw1PpQ$5x%1c&&R+n_2zohc{>5z0p%&Z( zMbc-=y4eGN(~!9j9Or}fx7hfged_!;YA&VB#UADUfeg%#o;yUhNJ*N#;wNx3a1%5g zebYQ*1_lA0$^*3UH!EgwB^Q`5x<-E!^{Ls#D2+IWLKZ>A3aHoA>|8_w`3koQqoz>- zj}$TwJ~W6K z60y_TXx zsZ^eteIJ#9A~TjT;&bwO;%@2h_Yx)PT3aVni1JKzJDJTt@=9Sd5Q7 zfuB+l@fh@%{FhQ+_2=Xf+*cU(ks;9yxv(q68X^kzn8=4VebX04ZGWHIhW#a6LPl+~ zdYbCVWF%_Q%AU6>nYae+N@Pw}-7BPx12&aHw*Oep@(tUD!b81wapMY{3;>)5#mv9N z=U5}|Ls+;Sj!rVf2d8`+V?XqL5)8Sbo=x>a=84FMU^BEt4_Xt>O0;^_6J7WkJrSg6 z2o=9suN)UaE<)N^_Bh01x!=Xpr*}okI{sFfsG~4h2W{l>CLsE(>j)Emlljv(8=V$| zv#zuHdP~ee!XtJGwZkSP4pdEq97Cs0fQVjIa@O^COx&tCL(canl`OG()*JUj^oHKw3GNQH9OE7l|qb#}XE0 z)LCj;l#yTp@Qn&Tg;ojdy`@J-;h7d4R&}?<;I|@djAo*-#;6I;G<~B_SEK$YIu=I* zoDTtraQH&!zgEICsV0jugmw~ybnw({Q*`-@?C6Tb8_bgQSWV-l9tCd@dOikCyAU$q z8M>StH z2J{eXhKVpBp(Q`|@ap)TGDOh&qb&2?B`r#gjohmLF9FB>ag-0=#c9_ORsAPccg`~tZ6N-)3D;VRA~YaL}2ROvXJA^asKqqZ6DGM5o!V;2>8J4)4qtz(52)1^B^S zB2=}yg4xA*m4mj^@Ds(kBlBnk;F^34N1MO86Kn~Y=9z62fgsj7Jq!>1*_-j*wbFbT zKl&Py0{xyr^x;1n%?1FyN7uGcTSDe{@rmNms{VCTEvKhVGA>RBns|dSP)fjoN(^{% zNJ=`WXMo)ez=CAFVUO>e!R7 zCrBVy<8JWmtxIv$z?-M(Z1F!qTW^Aa+%btuFSsymWm>52j8E&}*#s4Lg3_LghKX~~ zusEeXr{Oy&E$C1tuSB%sfExV>s3d4B=xAXJC}|H03$jWo0G+H7p-@I0yVF`(@$RWR zfqcC40@^u5d;k_(r=5D6S=u@lagMhOmx*`xUos|898-q5N{q_~c`Cx#r>MutH6vEU zwCK?F#N0*A>&bG1T3E(ADaWPxq${=R_a~IAzUFlheqy8D?PI|*n(tejVR+qOMPY%t zVS2O~g1%;qiB$6@s;DZuKyy`ES8A;K#^IkL2h1~(B@KQ=JH!wRdKt0}egz{3z8Uwx zh!3GrBX?>cUl@kaXtO&k?ty$K<@v(VvZ`-#{g=}%DM8QhhDcbj;KLd?0C^Ha#7hzC{&GbVhJe0vD;FMH2dTP}-7x*Jc^cTvo zG|l0Ezj}8XIvQxfof+sFdPQxhTGpJ-GT<)i-LmF1Wn}H-hmpq*T4!EBnZXfd%#)V; z+M?L^x6RdRYZGrV=`~+V??A#wcMU zH6v)wr<{R3-NKtl7Bmmkic>Cispd=yhkOvF+QeLvov>b#4TaiVXT@SR&biu7=sB^? zFS%A4!GXlWE`X*xnznLKofQNGw<3L5X8eVN6s$va*?`E6iTRa?aMr1nncev#w2SD}9tt z=@*{#{nO)O0WsBZ-1M;1Lx*=R$DYYVgMWbZ+9ehtAxm^P>81QQrb_3ijZrLogT)=J zZ|tLQgg-Q%+7$%amWrbe=fifoikz0^R{{HBK7#U2CJqyPQ~@#k1u1-{Xc>k|&*lX` zd*>av`y^Cq6>pPJgSB=bR>B%kDaXpC;1JLj%(2blqZ72Q0m+JhVc)gkrXzW;wN3*7 zHFf!oSog5TmCMCvL(8%qYg_a(@EhPZGNsqrME8-yvFJ3dh3CgxI6-eA$r=-gjviCi z(As<^xA{jbecbv!+YYwn;PPuAaHH*IMJFh;cCv&wiFxbW^<_3aqfEc1z+9!!Id3U!Xy5E(*Y$vx{;P zu86;t)gdVAPwUKvfDE=8(+< zaziyXv2a!CVCJ%b;-U+<9Qi66em-JH=*ubE1~8Va0`V@sv7O&mZK>%eex8ZcZ*b~w zDfK{{l6Mmm)GzX9#Jbc2&gxGMRWPEjnFU)WwxVouR(BY3VB+^GT7mnhy2;AP6?EUe zp13ln^ib0{LpknNaxZbJO?cga8v_j6%TOq zOm#=~M-*56jRBVtOEtR@Ux=GxHX;I7ElUrX@&uZ zI0j?~5O^zc;H|EDT)T(PN;R}SEshL_-!?mVlxHx(MJq2o#OtlldA${4Re$33+$+F9 zxuDPm@Nu&IcGdk7U8X42kUtsfBRVYAK93je%De(`g&FQ#30iCJrt$zY_X@Ed@T9_+ z*i$r0MfB;Y1LxflO`6}6=nZ_|EzCUaAZGE3sv@T{QDc=$g$IqsJ@In7RI>o%TeZ|; zq&7(p%)^_s)?op@AT*$zP$fe9m|(2H)=GaNa%{c^1&a*q!$vcC@Wn@Y-^N~{!Kpow zzWL=fr!$Pi>-d0nLF`Kb$a3(=S|4m_FQC9gFCtj5lD(L%vC<#oNS)TLP5hbgY$F&? zHG3ayJ=FTQ1Wi)7?t`U`T3;_r+UtH8E7We5YCprTHa=nkH-=Zrl-BGcmYE^yTd~Hj zf%7tb$Oy`gWcxO9QvV9|+S^^~txF;v!b^2-EBqKid?<^##(p%qY}e?ry`#(iEC+oD z@V5hhxZ(lW5%j?e{aoA{A=Qx9mpl>AB`gK5O{V+D{Aa@bAJ3xe(y2vI1Muq_Bem&( zkmIrRx+6M-3dl_qfL{8C#S1twHR+ysYzD{PlUq>O!VQj^q`YO%pctvV~7^O0>rE{AM;yG|^ z+9oI3+7vAwUG^Z4s|E+g(gJZG5>+j0O;=6;Di#?lhe&Io0&`Y>La65&fNS06wyN1# zXhM9Dl_GdH;Tfo$NuwfOBMDp^Bbt#cT>)<5#D2;8G3TPV^p?=(K_q9iSB4SFS6X|c zIuk>z_P9&jVNj+VFxSn;@Bpv<6Bvh9h%d3TKopM3OV;-%OjUhG(){~1UZVrzlnxE3 zo{PIJXq)*9@90}sxQcIGuFPSX?-}tFa0)Za_&hByBrrZA{=~XC5Ro2rczV_`5w8c# zpWUdnPst>3J0ib@iKCR~UlE<6EkPgQJF|TsfEV!M>^N4TL2|%u*yw=DxSVye(R8$n z`-HlOumD*QSoRW-ARoib_(7MhB=Cc96%@&K`JZ_1J|ey)F)&ny12R1t{HUo18lMil zrLpNo!*%Q?x_~VDhxvV{Z;q$el0{D^#J@Jt8bbVw(VF%@>aDpQtx1dwnze`P5Se|K zesfQ#eu6m?#Wt?(F)oe<^D^QeLbln6KnpN^wDKl%G!qj_^&B$t;Ca4199x5f#J&}@ z9=tvl(Ior#fJ`ON#KZ(2uLIyiG%*E>W+N5W!|G+X)A~ot9^L&?Ja-8#dG6XSIGA%v z?k0@rXadQ=1W0HR2YZjnh-w|eigHx*hPk{LJW?-)5P?*NiVF`NM%&u7MA0;K{1kCM z;rc})a zR9i37xJsK3?)|Kc^TtC72;)#GuO^zyXJ0v3{OZ7 zt+pD+vAfQgKzp0@4>Z}g5*H-?A)&sfv4cp%cNpW0OJB?Mf^E;x6w?!KK|%)B)wGRC zqR&=wE(%?E|O(qiH8`vPPW=OJ)iZ9@1GgFuw7W-!oz)%0S~;u3L{s0M3Zt>&x&*| zO{)l;wCxsT*YNlGfxurIjhR&+v!%3*eF~hQITY_EO(A#f7d>YXv3)(Ntw6Opv#7C$ zdb^oD^bhNcX;jWab0(3DKomSmB55D%Qf-WoM#(K88l$lmkBAbDssIJYo1Tjr>UtipR^_J_1epvCG7Z3N4Ki!OI#fmz zRK_$+azIWqvQ4DRY+SH2F@^Ihml4DBW1gZvYmw}AnYDDyoX=p zsQHFx6=$k_50@S$GEk@Fc&B#IwC$r)cQ7FVPH?9RTQpqd(txRn;$EiKBrr9-zP3r3 zSeyOj9B|uI&A#91uv>79YBGCN1L?-P=nUj*iRUXiM!s!_b+iDrI*)GL>I9sz(F?bx z4yTm2s1uL7J5n8+;zAyljQ{=kHw69-f&a@8P|eR@ty9oIhi+SSQO#pG9oD%-q-q|BxN$`Jn53xYBUjNo z40iavm+qGIp|t-@hxm6YgW~&;P><8@X!K@s_;)=C51MSW5oHBpM&%?3NIBxwERbic zl?5(x;Kf?ou`tSvj#-b|4dPe&=RtMgtZf%Q4Qd;-!W$|3;p?rugS8GR?|z7CH-RRq z`2@79UJU91hkhIf&OHg6?EP25oH88PU0!vtoUftcGO#Cz_<8}xJek(K5pm-T_5>W) z;ysz5Cmc&PlNGiqdJU_7+_VT9TWF}D!~^*^Ux@;U(X82v_o||+z-l1?0GkTCqJyCR zf#!8!HwhT#GdU@kv6qm-CB0^F21Ehx>gLI6cK2+OONbX@Zq)ac43F$ zHd12RIhnos26%6WEW&IzjIG7_;HgkcGnJDM{X@60au~{e0`Gz1{!qrF@B;A}?IBT! z8g}F#oaJH4Qqtrf7PlzU?7A>|=DYBT%(|qS;ZR0Iv-LwRo5l1`DXT)Rq}Y&3msvE7hGG{P3=9Za`vE_g#gt zQOc22i7Re5i^)J|K0-s%g&kPz{|&G>7G}u>s&;cN)kKA==3gLKFEEdx{tlU4lu&ZF zC3H}BFazmPpEhI{A#F55;gBtpQU=W>h*Hh7dKB`^<60qLeL3kOdJmedNF-h%*@k!Q zj^}#+dqFda%e2Xl`-U%fUZHs!T>$tzbvfCdpsxM!GU_VAox0>aLDY-GFrZYsosvv9 ze@t3)HTcjrVT1)VIrvE3xp#j;{E!=+^{rlWEnw$fEyfW(h00b($Qgh2+;xPX2c}y{ zwDJa*tyUC3X3In9F7gNy3CBNCn_^G}Vq*+64sAkHl*?GM>=1MILW4jJ=p+roGO`3` z>wz|1queH@e8p{mwC!ut+R!GR{F>W9ajV6NNKmzGow4#!Z}AjmuHF_XiLCudjocQU z#43tTaWa>V%W>djRkKZK6CL|gN+;a}27Ve!N3YxXjk-!X#9BQiLqU%Xi{C+qAg#Z( zc>r|RVUo@JMQRyceVyLoiOL0Q^2D>eC)2aqn-bO9p8hq%N~=w5H<0A4*BzDCTrF-w z_IPvk-3PShxsMX<4r@>e3l)Gs!@@YeDsF}9oK8(F@G$pk$7MTtxNHXpGuSEr|3R*m zX@EmDTP|Y~0MmH>r z-4m3-f$nqta;OyNN;ZoLpoY;hCZS^b9-?Thxv`5+Izev70A1gCl!kzczYO#>DkU~~ z>|)w(f~oB{zl^7tKvJz0G=->wHjRIn-5^bDp10V^(&lO@og1ZfJiGIf3`3o9rMsvm zEY(EPLH5WX2OX@Q+fMT=uo)W`Vf3~M2{*b6(Bq4i%#~_L`4i}#Cf$202i%LXGR#;! zG0^QAx_we@DL$evf9AdbhhmU+A|WmEXNUw{3)yNZ(1CzL0q87k6%^PS z=)PF0IUk9o`z&0^rP6)fpa6kxkm`>)Fh{EW0s(352yIBlpph!Fn#2D+y&x&=gGW}rJ)8660}inUByafIiNEf-btq`QWiNQL69Q#`7vj~}3~tUm4# zw*k*VF(PkLH)1W?$OW^XnMKqcef$(sbmWg*fbHGK(2-{Y-LiBqSyK~q#u9XZEk0=l zZ33XTf2TwN1hya$Swg!(A=_#S-=c-9C_D#Yh6o)c33OkgEDdyDs@xdpE>kXt(-*}Z z2%{q7lC#k!3|EfUoKCS7=!D5UPlmA*{652gC@j@xqj|uljL2|pEY?#E-_jMZA=@t~ zyiW_?Md80|;p-^8QwvX}@S6y~fH>Us_54%GI*$LUdz z*1w`s26w0Uvg4@!`Ol1;tmR$&h(4-BpJyOD1(S8vW;^h3BHMXa)k0Yo&CE3f@A~I-?WJPGR^0 z4a#$OYP38s#h{$dn;RWs5O@jVebMzq>TSe}g~~b^b>6@Wk>W@>ff-r-@Q-g)u)ShC zC*JZ`4<3$nHKuW7emqh_ccM0mCQv^83%%E?kQOKLHh`+ZJSh%(QA|suJxMSv;X z-_RzcBD4^bm_r1kPUc+1f&E+Q&?FSb8l-+w+fw15qb9wRuPoIAoPpkk319ZTJkNM$NtnAL3hd+RkC%<0HyX0*BI+ z%L0c?%JjgYeo9f`kVQEya41U|6*x3d8Hkd|AEK>b1&|gl5N+pE0Hz$aQz(#+KsE(n zR%846J_KMqVf%^#Rs`OqKn4OW2=IWWx=fTojQq@ z6_xP8u>b}fOK~X30e&-n#d&D{?_r6t3a~2dg5gCoEH2iue>wAs-VB4jWqbhlpJR03 zpMI}nrT=wD5zGp*pdYO&%EiX=a{uXW6`sW0uVV(@jv2U1yaX;uF81$IvO$7&(SjRU zhV)z<@&6ZM!&dzg<-v)Ee;3LOORrhh4MQu`gLtclA$z`aVzX27g-4g|$?qOrwgbDs zt*Y&52&7H_gm24A3E>6zkA{_3Y%E zkumZGh^1D})v4v|690j6RNHCD>|EzWvoU~1yl7(80S}3Cx&G67qCiZ%2p$dK#@etG z?2u~v3<(qY>+$k34L8hSrPqou&dvD;BV&nNtLCTi5h$i)$T9Py2nS*(ODmq`iv5IM ztsws5ED&D|$6lZu0cS4_%U-dW^T zK&E(l8W1hZGA&Cd2-4B@RHS6VwzQ+G3HL-13q-p1Y~2WHbEF16cNLwf+=kWUd0IU} zzL@Z1H!R+2ef`=i2D89!{=Ll0G1o{vYIPOmDH%e7Ryq`4Yyr~Y^|$wFb{-076($In&((7)=&dkjGX1!c$W7_ zN29|vk!5L07FW@&e7MZE3|TNfI$E`}OsJKLB=zKd#CBbeB!AJwM#i|-*U6Cp1BFPJ zulP*m4rgtp#XsFwe3s&5E+;1PvCU5Ix`3vMwtW6^92tFkHDa|_T+EPj@5RA=o&!;b z^MEGQ<0?d5l5UO0OMM5dB2q?&P*oa36%%2O+!3#asub0z3b3F_&?*$X^k23EeS2Lo zLulTSjVaL@$)&Aqt2-7Mi9oS`xwc>JDLzlRjl0O5D)khfty~z#mA&Fxtuh*0y~3Cn zs`ZQUL+e*eEYUO=)LO`bw1kK+AUa2j;zh;8U=)QiqVH1`!;{bqC#Nb=?h)huK8@O zHpATpgmX{u!uHYR^CEPqKv*D5XQS<;gIE#8JYbz)X#i=b{8ML75;{)1euk-3HGkqno8Z@eeMk19)1>vC*#KBa;WnHN!Uu6O zHFW(MuOUo~V+S*iLrJz)%?}`Q%?0rHvPr6qf_`c%(o)10Sz%fQLw2iwER`nC+fIEj zUyD!hYs~ukSqRhdpncJ2!K~0A`TMUiijVgJmZNE(C1^eqN#OS32D0@Z$XhSaS{lVO zpgG_u+Th-_U6G{qpY~q_%VV}IB+FyFLETy(kpjDoRm<9qL0?W~e~`wu$W#)XRr5|q zhM~*wx>WN74Kp>)MM~JfvJQwZj1`mLK@x-Frd$}T4r&|G@wScTSLloA{(yV)AYLd9 zedR5f>@bXg zYg_bI$-uql{e%8?m|0Y@VRAp`fKI&gS8cz6_xfx1Nwt|;XFtDyfvgOn=4EI`yqAE7 zdmHh!*`ML5oQm_kW1Y2dRRv8)2ijNGp<^qI*-A0UR2&R?e*a2UI03UIH>MQ&veI;)Cixk8s4{eyhz z4RYw*tpPYk44NNA5-0IueydZ3sN5=sl7@{;9z)KyN&T0chUC&~^#O4fQeThMas`xB zU1aIxYm3BH+mYvy0Tx#O<%s6PU%-nY=j)TCC0=Bd>pwCDgj23)meV&;)wo?DXwK29 zbxz#uZ*$fe5Rb@oik#T!x4BWoII6_P!X#1QEjnn-S@tL@)rs7=M6w zO?%Tp8wWQ+meDp2lE)6s?;$Sa4&x{-mGB&LXgHq17n_m8U-fGEXj_y6#W)n?AOGt{ zUeiqwVTXESbf$sFhQd|lUw?JtY zm2`IuhWIWXuPMFVQ1n>Bw7TiG^_^lLIBabhN@nRBpFm`nqY1zyml}4~3(0w)&51o$ zh~n!zvKD6WUMcp2yCAzxq=clX)>V$uYoM16IQTspALwS>7GO&ta+z{>AYxQ*rN9pv_uZ3c!ChI zQokMIC)6h)TO$QXQ}{drj0*ioOd`smQw_rJI8_9J1G1ddO0{Z~PQ2Q#m5p^I1Dcr_ z<`)zWwrM5kb_m#OHi$hWjW7kF4Rvsc+O{c_b^kh~!YC*3O5D1Y8jz~-O64iQu$Uj3 zNW-}^b)Z=N^%MrD&M>J!y8k~Ansj#M8IuYt?UT+?&Yg6wBAtHTB;yh?fPNWl4muyQ zJxc+C>mw8(xZZ~VL+yDm+o6N7l^ z4h_&`tnY54Wji`ZTL3hgEpCLa>%WUuC-L4Jq)Qt0y%_ja6xu|sC?oTdSz zWvy)F-V}6y!dyBPg&ZgMc&u3W(u$O!h-?8 z0N#Y!;*+U^)G}F~bT~UP&q93EzUDfeIRGD$qmLLeor913fwtuJ40g(p1-n_QL>zbn z%~*e{7)WI^Q}#444qqdOd9gOPECwP4)1v1CGE(hF6sfQ8@xHoNo~L&ey`G|Xl?!iq zA8IP&xzC@E8lA`wLqRpIs^}ErgUt)Hf?|I(@5gNFZ*mn2^I;17rwr9DP?sLg))JYW-@k9`rEETXE|hdb(^L>k@e zK?kWt>xW21^c`|S8;=MigqIbZkGX*jRmwV8{=qPG!mYq)w-Apa2L`#5am%jZ))#N5 zA|Y!TI>hy0vI!e_MW&^gSLM5Tb5&cNfAp%{Q(xUfS52n|Nqh%1sFT@uo=b}4k8p-{ zZ0J(5fEX^mg{B3r2|=3TyD)3FVSYXd^W8clh$2>IEaFP0#-`khXb^$3nLNnpTb+R~ z&m$Kp!R(Vzv@>vIyg#pKgkq;O+ULpmmPX$~(+|@+Kggx-$BnFii&i6bx=Wg|-&L|- zdD5jW+so>1=wM8_uCd?9!E5)p)h}JaWqUD$+&i3szo$txxlCakQjNA-VOx18Q{>^| zVr+kbRFM8BLnpHt;`6t7mIuzE^~*OL@F#xiC zwZo~dJvZKg_3mMYxx9uuqjHtWY*LdUw!nPnsB-Vu%cTO> zuuaWyu~&x=Lq{`7EJQ1r3Y`hI0XLEo6_QrYw&*9dH)jYLl)QFN^6#Oiu{kg4WEltd-4sUk2AB}G^zq?L4) zR?^=Pb^MZiU{!HJyL$(l8c9~)sh|Q9O!lxvK$J?jzoboOO*^ScI57EH1V5~IJN~Vh z{2|Ne_fDI-@BAM?&7NF%s?Pzsz#9g4rU~IF+`(f*cQ%gh!&H$KP3$%1Sf}7|_}?f! z96r*VYiC>FI(P`+bzVP-5bG8&gFFHptN7l2tz`91D?2Mq zwDGZcA@Ed;HM$ZFPkdVz|E5*&U53EwEcgjVTeInIW+)d_r=`xM`xr>{2?EPOvJk{c zLNN(bZcRCb9ke7}$@7L!8QL|X?1JG|4omk4tvNNmVBZ5hLP91xzTs+;XVL%~x(mI7 zsI;e>&UFoz)&I}lmB2?)Wc|r8A>ryE1R{zC4Tl6Y62yc=nNB9qArlRvh~j~w5d;-w zMnD7uovfL(1GMo)ZK!t>82=}D|x~r(W+QaAyxE~~<%=drQ$Mj?-$s`P? z@h6k&>guXjuikt0-m6ztSdZTzFCqy?(3K2B&@hx2QlI7tx)gvARfn748g z1?Ti67*~k#b)t4DCkY2J#0pV(!A7w;BsW35(07~zG1Yd#X+cpq>e`h}exEMfsx@%> zD1lp(@xB^Dnt$8k>4URZcDu64zcYld+JiIaD_5heHL6l6dl{>XAGXc$S-BdDHvn1u zFdQC%Ym2IJ_G!~QWc>9sC9XjCg!lR~1%eYwD;?p4ok!StUQi3C18Jk&Dx82+-Me6y z;Otd_Vj?117jA~`z?FP}C;{4g{wkitx{J64Uq({m;<>kpbs5~kt$5;A<#B7f)l~NsO-Yx+1`sC{g=)~GyCMv z6m7yE1%C#c5(*I3hEEQv3lu=A{Gjrt5>r($*Bjzeq2vqR4T@jZ*=z3wH0E36S!jj= z53><(4+WcBK*$yAuICo~6OUpY;tk1+=2mrZO?yFz`VzqZ1D}fZS8@xZsA#>Fb1kBx z^%!&t>#*MhUdt2fK@l7ADAo_1dy!b5&Ml;y#}ta_tWd;=R|%6?y;cb#1`d4paMITp z-E?+WlR}n4ZDyiP*s!D2moyNfjExh$BB>6NaB3ZEDEM#XUAs8J;Fv6lJ(z zdyRU|O?wnG+`=!O#h_5lDz# z4bCcOm34|iW#sQ#fk(Q0pG*vi#*oYQaYW3uYJ#zNZzO7+5gg zSnv@PWZ~`mHiW2O;S*wP6_!+!DY7JK@x~!im{Q}D1E5Ogh z#UASM9yvj&Yma*a8w=xz&V0##M9rAVe7s*l>*iWeY8NFawPZdjIh4E0M2uJBz=QiK zpk1sV%PlBiymc+Npp4~Q$1S*s<$xdWM~+UT=k-;D@*@+dT%DC$aG02`Zp2)KR*m8o z{K%g2xl#-JiUGVwtc(T;u6@xT;D;eTJv}LCq@NH~Q@)Kb3Wro>A1wDRLcigEdKYO% zp1V;DcR4VR)w9T?B|vvE?r&GAe5=yLZ4H`8MiZ#!E_{L7_hF&cae;hs1!a7b6(3NoQohl1^VS2ddP?Q77j>>5FlPWM^H@C}> zz6X9%=0foCV+N41@&(jqkRu~O64<6&G9Ja%N$MG@9orD%+!Ft06=cx|? z39UkJLB+_drA%O{lJYhoPx&wcAG$3xNxBl|DBtaoC&QBQL)yEm8PYyUVn|zeGlDE@ zAdfLJEN(;bkQeM@&RC`1*HIMX0kD# z5`g0U?RYOo;!9&}`uDWlPcBg!bMoNJ&wWTl_@Mt5!IRT59+c)G@n@f_&^&EB#9X%l z!$Vdd4iOvY7^(z*jH4oSz$FFMym}jOdXVV7QW@Q4MNH7|k-w(QCy`m4ezT)T@l34m zcEMS+*E>4Edc%o<=6KXooPHguVeuppc$5ch0*+^~8D=?L*%X|-&!MoVR= zn5jWVMWW9KiWcDMPTwTq8!U7uWfIav|nL_g{g2CE#(NJQ@-*FXJ40Pa)%6dmLd2Jd4FF=26@y|9d66 zk2i>2W;M$@C_|}IZigm3SNo!ze)yag1e9_Yf-R_Cy{4zsn$D(NMcBbmWY|@{n1uq+ zL-v7ZV9QaY3AB6|@z_~Qi^bwc7P_!E?0n-}AKt+XN8|diey7xQcIs*>2ISteX+XdR z(B%FNJStQ=9=Y7AR6L0PrL7V9c*Yt9_b@}XI8lZ(eGKxn&B|J={9>xXmC)^0vnkJ& zFUxgn;dC`$z}iR{J2r4{-%b>O;W$=0a%iV_?fFM2LZ1Qz>LMIzsA$JTb-lR;31v&h z%lP8Z&hro9JW^Leg`T|t*`5^;QOcxnF@^v1B{dwuZSw7GDBvj~`9%R0Y{$H|@0$ii zP?wl3VcI$2(>S#8FtK zV4Q1GE!MPBLEgFWjv#0Q7g6x#2jN@mL+ipe=fyZw6tiXNCYXR2>4(u8izxdL&(`!y z7US9835kVBa3#H=_1iKowci4?W?>2e-xbSI%ufk=1{NVlfIc8mezt-rTR~?#OUXg| zAhwS;R1Y#iwb-0Uc_9o6UUqOcIL2xzb-?rz#{TBMT}AR1L0VCt0sFNl#~q zo?OW%=%(n#vezvv2a%D}DW^WxK9w0w&&hG`!0eg;sF#qpr5}R?N<1A97F9)HG54WG z{syKiJAP_uKiE*{ghC?OWOFO~#sNG!p}dseQHv+JXQ5@#dpdcf5a*B%cqxh?l^IpG zPf&Q z3F&?4Saa5zSQ|+fX;3Taj+=qXC5g;7;Y#gLD%dzw$`?Qg3hXcd|B?6(N{p|QY!5L& zkVnt}QQz6Pk$V!yS1r^LHaxF;@}fDaS$!3?!@`RGUVJ zsOe>V12c^)-3~G2PGd?ITvrobS1ALn?UFmOsv7!|H@>T)!2KT>ru-5M#%wGD%$7Vs zzK{9o5^lVKu|>T61Cy)`>AZ~U@PX4Q2H(>O4I^nNCddLzLQkgP?R2C&!(WoeOxT&G zpm7%HFR+J~7^}3V&xmyoqTmq8yb^U-vC}1iA|@yMkCW#*HidziVG_fq_8CNrCzrJ) zp9ysXT^m21dIH|inA##2z=9kzO&nDeoUwL#8Bb3mDQ2NUg`lFw*oa*e|QaYa@i+jemwo0JZUao_YkD(S*e>FmSTrR=^$ZLgwRLDD&@svBy7^?*xbz8 zT<*%+T#N*$X+6R(Z7JLN^62)s{={3A2g|{+KTjC}|9OPz;E)5m72Y1iR@xHo=O7W- zNH`PjL^{jjcu0G`o}O>UrcsO&lL5|zk;sB7^89Oxr=OOoA4eMEa}ZTTm*`zY-fG;+ zf;BXAqMGUOkRVN9ih=UxNauE>Nk@6k5xlkP0+`v2Ox*DU9TPOXLB5yVXv`dF`AH)i zH>PaE4c}Jo%JnL$w&fDRRsmJDyY(~1Y-!(ZI$tWhFOKf9mxQi;z4QG%a5xd z^Li2QI?d@Q0(9IB*OjNeqQkuR4-IHvsJY)jDD_iM+UIWw$feZJ^KJAG%xa;3w8GOT&Nj*Np*t8>eL;7SG}3t@Lr*7EP? z-To{K;>C$vf^*JdYxyB|FjqfJ2>0L%SpI93rP0ZFl7;8BsWx}9`#I=2#hJ-A>9FJc z;@J_&j$YiV{77f@J12x2wdLcQucV!SudgQtD*?5MGh)kq^6pw}L}a8E$ltYpX8s4hK%Bh4D|z87sEhoGSumg8B8=hua=99_{2}uPC}6U{D|DrhaoK7-*hlco5t2at?7_-K zkeH>QuTnNvmpz3-B(S&0Z(u%?Hh6d9@F;k~fbgxVo3h}0L@BVawuCn^N6A02Dz14I zd5cvoW3l`QbZkuWi_!Ts6ry*eX)KlxGTS0odGaL9yL~mYpIp~epbWy~=2XaIm-?`d zk^HIy(Oz{P;vnD#n2Y$9P9GtQH0gNsW3lXIQ$?=|Dwi>5v3+Q6$&ZfqbR^qmdG;IB zziSp#x(?i#3+t2vQ0)mQoCfh!0X#_Ohbgye>>)~#%$Lg=|6K~UTMbe~ZYQBV+2>~pQP>C3 zDH9J?>1XlqC~o0C6c7)O;9M6YfgtV@TCztpEY@}-kg}#6Qesq*u=hZuYgevx7xHN| zYMuryvj;j<*h_w8S3!k*5D82AoM*X(bQS_qtGR_l@%-|M1dHpMTB0xc5;E&)LEMSz z%5!VWa@S@Ja&#=uU00S{Ta&x)LfliDTYDkOuSNNX<)N@}mflXE>SSvJiNHq(vIRY= z=TKJ>gXN&g;tUIRo1wqh8-4{bbSG;Zk>+Ok2ej-?qE1k~CiDVjejZ6ArkrrUfk2aX zpdHU^^g%Lu~Kr~5Nxu)8lR@IJ|Td!96n<0%l~^>|MC`m$=*Lk&I zJ+Hl=X?Xu0-UB}s>=4r{g8QWJ4NV8yX+U*q|0jYSOC@YJgE*h(a-zd%V8_zroTbBZQ;E; zb=h_a7DncMOE0lxQfDKbZUa@SoQAoT4JngRi{&F|4>-TdJ^{ax_UrK*Vb4dmaa2fW zWhLh@D!|vT%G()ikUs!arLu?RdtPE#d>BO1oeHXi_66jg`*Xm7{HKub`4EYFDefa&f*rt7{)j7%kNuBM#Z=?hmu5|X#FBy>9GHI>e5 zk}Tz)LB+WSnP|1_nXRaXL_v+sRZ3~R%fLJNUeI(od+Uj{meAN*+_Fx?@R~(b zk$~y~*BWQtT-GTWxh2@<@`MVOMeYc<55BDb|r9#mJDIjF<-s6{GZxNavQ|qDe^knbFia6V4B1Q4^E# zsOYFtDZ`r6d&OVp2KZDZohg?87O$6$dN#4Rl983+&k~9?aKBBRqB@O;Y{)Q8G zUX^BB=ZO<{nP|s85;8IQVO}+`wfkMPjr+7|AIh%$8H9wQa|bi7RU6H)b`B(_MS+6Y znNqZNc)cTuMJYmK*0x0=01w2{5ygPJ2prK%9-SDH?XHCHMrjkqKKUt#IX3Wyb1KuH zgQ)F`f*(>ra0WH6Z_4wd9B=TIAh~o4@8!jWpxA<^N1U$j%@%9I)g%Pj) zX77vIN7*mJZ$7u+L8Y~Vx$$_ua_*V<9nF;%Ay@hOF?{XLhm=+x=i`y;Nk#l?Z-9g2 zpDq%futim(p(4DKMa*xAJ&1STh$>dn)nM*JfND8i1?J8}9*ZQ5VTnuT-XYfWTxlKp zId8q`QIw#rtfaC9Db;R@FhoAM-Te-dqC1Bxc?k(VWdm38CoM6bz3Rl3zOACGdRk6znsO2h?*<|XlUfRa3+}nviubQ)NdZ7I!`hsQ|@t57R;)UUI9}0oFly53uaB(J}i}`k6pKW9Y|9KSSsznSQ$QnYgoR zExtwrGl7`@DamO_x|QT4B)?RW6Oi12>W_pt%Gh29vG+l3eCGL6hxm4|jkZS~A0oB|;nFv_F2v>s(AqAbHA zc6O?WtWTUXMq0Cy4pHoY-O1QHl4$QC*2UU8igoe!_~k?*o-~HpC}5Uh{yc{HM27i} z_>FPwLV@<4_V|s(PS=%t<8WiS_)-6+!=z8?iC_06a7SQHus{oYGF{T9p6}3$oFT4+ zXGm*yn)m(|W0D_-b5A?0Y8n%WjjV?fVzl~q%YVi)kRrD=w*z~J2^5okf|aS|yGi`Y zlVPPQGvOilpGirEt7RLcG3mD(oS|zUztv-c!T|wE~u$K*E+4(z_%ZP{!k`O*2ND| z<2{td|L`m8mm+V0nE@kc{@Egrf!YAr?x5GKJaG|LitRJmq_Yu@0k*ITZ0(XaW4TY6 zsC-Kd3!n6X!B$lP#Q`?QA>T8Ky1rVyap)SJ3wurYyy)_8J~Nsf6u^2558SKKTL$?oOI^Rdsxi zyyppktDF%7$0i-HNzVHdd1Z1FHaR90BAhpN={C7d>h!@cF{a$|txPZ84>=ZrZRpC0 z^XKGY9Rs((W4!}qY|c)P;g39R0W1xgvp{k?F^Q84#@hSFulVAO;f_MKfZk7zXX;O< z3HSi0(l&OC#v>>xcPDmdmOM{{#7?&zhHMnUmbinv&f0$HbMG4Y9?YC>x>(cZx+H2i z0zjm7IEb2Gj!TV9IK-GXpV+x!@d%6ph`7c&s@mb{5?(rG~L(A^j6(cNWlkzM!?Buy4L!*Jc*WpC4ieWY$l_M`Ih&me6i z`pGjG=U?^+N-5s3zdWOO!>EU3Gj@Tnkk>$cc0Yp#SuWzP0IK{JGL`6}9`Yw7RcQAo zcB87~_Pu=XpBZ<24+2lb2lS2@^?UgXn1v{f7uZ;sk5V3ME^w5LQ6a~Jcsneg-ZygK zWyDKXp>rSC#i;vd&r(*X-$e$#?jdg@_nUH<&rVYC6F>kD<0U!G5FvKWPI()T_KhB#qtg9jlwu>R>a%UkLy< zZ>Xz1%05BtBJ1i~F6$2Y4gspI%V8xeaBWfIJ63CO80*va2cD(w4>VM}nhDURtJPwK z{nn(!S&0xv?m3qzy9MusmlzThYcU(-DZVlVdxeB>nBI{_Uv#?S#MVLTem@I5{>BPf9sXeGgo+wHR)dauqbiqjnQg zuyj-Dx59OReM$6|9>H$n#_|kqNk6D&Z^U-E&XWYZKpLzoH2!UzVh{f4Nm(QN;`YCV_9F=ljyQ(XTrXpsqroH-o^9{7BKMD zC&=?`0)!QRq)fPNbibqV@TZn83;PIDO{sccNH|-n;Oqs=G=#GY7}z?_&Z9@M&tUw~ zaMlB9AT>!t8PbG40r*R5fVrLJ8s<9FoWd}-^?(m^8!7GVwTWfvm|I4Vz}yl{JsReo zLLS51oX3tS=2Y3|AFBX=@NNVJvolNF@@NPTn*>jt4P*k39Xt`3wmv1CW9Vb$zhae{ z)He$Vo#YCpX^P}5rh9ki}?c~$NxA+xrC8(9n4VCQHz0dBT;<;50cRypj@ydYc*U-a|g& zZm17;69{(}4R-~gJcdxh9jlaRCvBZKVLp8-mBte6&QhgjtJ0!j)77Y8Si-Sx7>B$K%9+j<_7b-VSrT3_1Xx@1cEmI@4rwn4Ma`;Lb*>F00uUp85A$a z#A@(!D0WU@yh$ogy8$5Y_hOQf|NXF10WU~TunKTy7Br3x-h`Llr)5W)G$05tdSsT9 z1YqpXn4j#pam4=oO@en1CXIVH0M-pcS}#F^b%TJDqLv5kHCqA(3Ev#39enBc%?X4<^k;RJv6ga_3X($ZH-MrM$Z@ zR_u^00Ffs`pl}rtMd(r2qRdDKP7lSYh`978kK%a#gI8QdP#vW}I5n96lIvyn=I{+zFc0 zydUrjp$d=@y!B);>wq8RNh;*%=*$p1p!SCK<5a+PYheT#ScoRFPjZ?F8O~FHE<)~$ zLexjihpnZJHdzsxuxpbQC)fNDGJmzn3ge{B<~n8%GH0A-hPIdgjHUHQ$wq#o80QDV zGVLH=TMExG)(aXtSgX;xMrn1$lxTHzXl-3b7OHT~pRd)m8tPxG;99EHwMvI;dTZ+{ z(&{>6t_D}X*4EWitE))I{TE_0eMCGv)MddbB-&g8R3ae>LHf89G6@^ZV&$H8rkVS% zx{^)O#5ZYwX!$pX9WDRn2lBT-U-wfnn}O|yX)XWeUUJDcY)8V~*l5c}_`)4ug0m1N zvkk5YUD+Da;AG8lqJ0?n&YS@s|4FWNL9CCS*OOD>BXT_M;tu` z@rc)vDBF};9cgklQdVcG=YrD8S^aCGSgBs}K;*79orfkp9prP_0~2(QVf_FEuR597 zF#!*fOBGwZf#_7eNsp;f!w5ai^at{fLT1uB%+>6IZ;VTB+P{s1V#~NKc^X&pGef)I z$m~HDM&<|nVI#AZ6~V|**cFY;XgLd>R2muFYGoXmlH_6((FbRyGC1eKiATu1S2p7_ zHaHYcB_D!k(wXj_M`;hzN`-#o6THH07$R6$x6M9c9HZAz1uAz8k^hPmjnM#%(FG`o z8+(s9ddUwXTOXtc*aI7+A25BWgH%XPz;WaRoS=*kqET<~n^Hp`h-ON%al+~W8yf>nxKsKSu;>Ko&B(kG?IxpDE^>5kEa{&&ci~SBbIo- zoTvoMXTce$j{c=z%2HDvupeq9$~j$GdT*dpFvlCjK7Va9}E3Nxk6UGa3b;9U|s2$LC zQ-tv=#>hw*)A6+*N!XmA5{)iyI~uz9_+FJRZuikeegnEtf|XRdxBzr9fas!+XExEr zy+jvhf-Yjf(tU9Xi%LNDd-0q+LZgf*(7MgZD8rf#5!VD^bOz_pS_n}D)juh`1)vMMiX?g z5&8n7i&7t591EGT1+?Cb%+Ltqb8rsH45ElrQfBz;8Grn{MjgTRj4?BH()bv5aZu9m z=^1YUIY!b*#@9zBGn&vd?z&l}jZCtxj+LJA9?5}bWQL|^tfmE7Y-c+4^^6DKG*U%S znKA5soiN^n;oJ;iECOnbgwX+CAC1gtf-VkEQ|aPm5Ti;L$3kX2O@bgaJ>wN{&MBp5 zDEl8^yi-t47TFV*l4XJGu~dtj+1{$cpY}6_70ilKjo~EuTsx75Y7C#j9+;g~LPj)< zVHm!R1w26sVmc0UB;X{0&>*P#p8`RVGm|X6B>9=?1_&Ny4-A4x6#_WlEd)k$=C>fO zh=mb>lkk^Qv?q*;d5qb&$v&G9c~k}wD*|U#Ln4Fb(Yn5Wyjqe#=#UP8GbFcg2v-#B zIf63_BByim7jSK@HBtOJZvGfAL>&Y&G8iz9PQtt+1jUT#B@wvZGV^VExc_I`CcdSJ zBoMos3kSWp2rl_&3a4>CLupGzgy4LSiX+VA3*=kM)rAO2KU_s@I-)jEOI2t^T=5{P zjj&1E9Nh(xPeL?mUJ@?%%6{oUkWVGO7~th=H6p^px61qB#H zIIguyJT|m;%cZLYt>t;V5VaLIZn?T`%joIowl)%0uE|<9D%$GIj(;bjyxNm#rT7~q znnmV8Zn$scJNYSJ3mwsd2Qi`@EqPMO`bW`lxn+tR!46Y@Ir8pZIu82IVR*J{^wnZHGR!DP>M?+f zx~}rI@DcdTAIsdbqY@*^9>n0Z)p(yPr|Nwk42VEmVe0c-XzQ%cH~CuFI{QTQc~Qf0 z-Z(|?^W}gDeZF5C=T^uOzmYyylb(}&ZF~-sHoPOw5rc#lk`6S0v~<&`aD9@x%&EAcmgdP|2_xI!;9|F`y8Y6Ic)Rr_o$DJ zbgHk77hu+gx7SU|4V}IN`u!Ie0;+D%88Bh2!`APGTEEkMZM=bim2mf4mk(eTKfysZ zqGDl?ZW6Y40X&tUwvv}*E$8d3Wsz>SJYh6rF1cMt^Q&M2p!q&+T57TSk#1B!9so@- z;@WYW-a;-~@JDiaY*`p>m=OA#>w~5OR(1IL8wERo_4nI}dVjA$3t{Z9PBZ01O=Y?= z+gN@8J^1WeD_7BoKAP+U|Ie`CfuJzyW|Ki_3_)vd)e$rVE%+mdt2nA@rD=V%u|B8z zAbJ5NZut8AU#Q-!&zo=2`)olA$G^`3dRdkaqQ8T5(dV$~qYKeP*6Upp^j?ob8{zGB zlkZx$7#l5$=BL{LWSQO)KHb50D!^xoVr(h}ih? zCcVoy!>SJ-3k?RHGGdZ^E&K+y@<*yL@#w@xpxg+d&-FLzeVzh{!q?{tXx^;Pi+wG` zosd2Uu#edX(G1ww;bfn2ny`HS1|6?m(MDKDIt1Dd=yMkzJR*#vaP~P`>+@UV^**1A zHp1FxT`mX{gUgGf%x?mx@Q^b1IeEhU+~*%&ulM&NSnt5;^j7Pg8AiP`5(LV4XS}b4 zP2eYgj7mo%E?U#yP1ouD9S&&1*I!9ftETu`_!q3$F=)up~R4#9d2YoB#F zA^C|3pRIb7`AzVRO_dV??(xUR>NstO{sN~Vn9@?LIZf$>{5gn+VKmLx!pq<# ze~b!8B`9F$x2Dg}U!(WAD($_b@bT0iK~xOWp3!;>H=>2GV%q30JUU#r26tV2JriL)hYxpK zpjb29{i9IFU2n8->f$bd$3MMN@7YLr1;WYW{edZly?cFadUIXd$c^ zYMp*G&!+eJXPC|5>+^6;Cp_2J!eeOR`1d)07hL&zpS>__!^sPK&_g!T7x>zE8f}EN z*CEh$K%bu+rT4i*nEU*Q*5^xnZM+HtI;?#Tm+Wk;o&cP7RZHe29pK{mI(NXL>c~7D zqboq`prYBKdR-86=x#g1H;czF(pB{ZOvn_sMAE81-G} ze*^DmfsDuEU4UHi`Mw(U)BI@FF>y0^0@x1OPlK>@f61a*@AN_*3=(E^CizWrdq(h+XfIfHe!6U*H4riaEwLZVa>wP{KZG^SYx{NqRewq+)8eq44Xwmz7 z5sd%v@lGTNlu^-mUkjVSPhrJqkohPC8M$t_-sem}6uv$`tZ83&_*&Qv!}j?1Ie>RQ zyUmHKcSPg5R zkGs6+p|*%PMT$$q91-abkQh>yj@92l?=9h;fDKpLyhAVKtsozU(+hkpJdGCoaf-mS zqHylF3aQVFGxa{lg|*MuXj;`Jz7}4EDSZ6<9Kby<4%7Rb0Ek+|Jv5%dH4HY=2T>mz z>EXUM-iApW)?Nph8-k5>K)?T%q4&ENUNCm*E)G%fG?}cSX3nu&A_Fy((v8usj$4T2|7GcwuEk{Cv8z z0-H2nTytM+as2>$6ps4VuBg$sWVWJwkysblLR^v9SQ8u3MvK2GuAj!bsr^OuN(LY| zri8Ag&Z&t+#(i!d)%qgr!Ja83p?vCI# z~`0b8Z!8NbJ zzIh>Pje!(%B^>B=h9JecU6*S27Wne!2FbfUNZwdIPdP)&#g7AZ3sM=u!P9p5byi%< z!dYttaXICg9PQYCeouScH=u6lx4C#Pu5m4JW(&NOonBh`kU1CkMhx}V;n1-8cW+vetTJeV@oVd+PvbFqxAnm8KD`O;~ zTa~-x!793ETZ$3HnXx8&7eVUIbE`JXBQC&cm~~!z7jKjlMTrjHwVA)oF?(vn4)~Z| zaju`rhzkh>1pFn1c;htS2CEReV&(F2c=AY@A?? z{WzK0Z4!S+*X3q$eJtB%aWs$zyXoHb4uUfu#F!7n=YtUQG2r<5B z%Lg$^bU`uxD8z`~i<1~x(lsv595&$Nkid;?Q8v`(l<09$l>VTBM_sSR3hN4>cnbp=UR7m9dIt|35n2uuiR) zmts;ZBXy*KzJb?LB&pp}m3STnuHio&590H*97H;{AU@ARI&@{#SHI*W)ki+i4;>a? zq_nAlN)u4FrUhl6YC+k%TTnK;1!cRppzPkhq2pmy3(Een1!ap`PC!U zj)!F}C|llwvNyG$?BEuZjcGyI&yz#P!{1v_c76-Wj%`8N0WBzdR!?zRI-KGVSNftPK zO*!%;HZeYuT!}`dU9!}hQ2i2nq$^1a)hkKU)hkH_X{V)pv-~wA72QtyhypCG8Z7Ij z+zv(E!Hsf>xP=m~8*hh?MRS?@N2p2{xZ1f32a+_gcOmo+l{R zOWtA8@m$Dq40!&rOCX+~L%&*&=hZYy49_=5Qaw7J&riZ*^LU;GNvPnN0Si1Qovq-R zx)WwRi%}{*gW>I>;f>?%Jq$`i`kVwfTaUN@kb1}PcF;>ooQ^loIU(VVhm`fln+%T- z-ClMK@HV4UFubXJedsbBZvlKghq$l-U#FgRG8 zUoU}TOL#j5d_BBl6L?#l)i~aAI|t&ej=WN>mWN3Y9}3=5>izIGo5;9%ylsQn^vByw zc%qIG-r9jVG`Y70?4hNrwX`4qs&sfyX5;w$KMX`eI(&^hX|2ZRe-3DLSo~iPG5Rd-&><{nLF~X;WDUjjN#mACbKzlt7etuS^xMz=8*)NKgr%t(N?>zD6|bmOJ}T;yPSs=`3TO=`!+6!+W8Q>FYq`l2%MYux#|hr5@(65qJWw8i zWC&X zdMVnJb^Qzu7p$$x=9bxF_lRF}p2)Oyyeqmksuo$%aaD43gIbht2OPz>b6;$tU1~M9 zVXI1;%bNPG8F(K!if=c+&^mZy&?dI;T|c8UR}ngbmAc2l+Pk zZl)tz5Uas$?aI4CUMegXflF*U;FI#GvaaP@%fUp|;5zVDqlTbCoWdrQEZwR%YMVnF z{R`Q__P){~D&VK(+F#mdO3%&xJ;}c>9i7S~Iq;ojO@iW=X~ zEn34Xn_Y9$wwG+@N?!&xODeh2XYjXtMD#mf4IEQa&Aa%wc!0_Hh8ap zF+Y@VzX6{4Yf^UDv+yqs|MD_-*o8c4y(gzYs`7kMAXR%lv*8E3a^)C%E!9w+i=S1V zr3KO&&&oV$g9o8O8$4aby)pLAsG&WNAG7D3JZYURv&u8XI&6*Of?>6eK30Ts6!PWR zG}BogeekfCI#s@_d~7sjSdcNS+7p8v^5$XK)?2A?nq*H-C%;RG0cHjs3}>>9&Q4W2 zbN}3c&UPW=l%caCv4KD|+UK)g+&zYuSisMU^Bt0nn{j|~!zojwr9RVX5^eUa!d;~Kn%kR!nT zq};D0tsvz{+L4s|fu5U|a_dm!WR-G5Ny?=_%JoyE99O}_+z0>D$d9W~9vMJCH0!?Wu|i1^5OG5tJ>zo&Jd%#n%r#R$%k ziJmCS;2*`yO^(>y(u4LWt8*wRM1rOKV?mmVNJ*v>-F#C6BV1!(!(S!TzLhX8fV4W< zVcd%u{bYx6#3=yd3y=sWJ06ehKi)86D@~HRLd+N&Jk2j}Ps|O@mM#Qi`zL9Xv1olEF*R0%r-Joi>ae{uAuO;Oc)F$VRqZok z@Z^K9_el=lyq`{P{C$np86Ov)eB;X>7x=JV27a5G9Ivu2oPo|saF*fx0LK|}_q~U; zn_SDVIOvI!pZVc1ogo;D;7<2SOx=Pw8&N2qc}3>Se_!$OmyqK~+=6ArK{>8ylQ^*u z{|1`eSJ4OFoJ4VUe-rn}b$BYz;iWMH2PUar^c)^u^!}O`-4(q)s#dDvmUX@ zA1KzxawS*ev(j~3Nj*dhPCnyGc4~4{q(1w?qYoeS2~E=mNv+LM+e*= zlUTyT%|GH{IUb5<^8=t+xW+)lY>=bBL-zAjM$Ab<{9;ZLZXH6K!WQh%@LViTOgFjz zpnVmCuZDPVGL^5WGk-|wx><2zeroig-FSd78;hQ1CE5FDoo_!UE5+U|YmmKtR;nWh zWnw*-QAy9G_>DmA`Kd{s6#Pbd`iK*U0CTDMmu0HSv6!5*(`$0BHhDS{loJuNfMtzq z0be3~u=zY$q|Y4jdKDB8G}&Xs*#p}-`uYz}>0Kxy<@8tGMzlkbh3m){$ogPEedw@P zTI>0zK|4CJN!88*ohrdY{8(Ni*t8%0NOt1)dM`eOrwk;!*X<+Oboh;hj46rsoghz} z>#~>1qfK6smI)>HE7nDECGjXE)={AB`)sw4D>=f5N2CQpn``Xc!3-Mqe`gnLhb9i{@ZRrZt zOPd(gBd24ALi9A$DUhX9)qVI{${8rufe*$aja{N8XXCFZgAa~?B3YtRN!TC2ll^Y` z=}$l1#X9i8MJP^HK1DPxqa;1_`xOsg;DPu68TL+s^qIVPD{_fd!IOdP zX~i@^)??kWKh`asDt!z1gy@^ed7^J7=PAMDJP3LcQT6o==({(yixEBWFO_)dVb0fh z2$b`GuS53pph=_fKI!EAAxy#`-h4meeO@Kr2C{ulBeK2V8+~wBL+?ImWV??h)u2%9 zgh)F`;h!0AlN#bkl>dmaQ*V=x2I!=C{Da0gF}>FMry+DD4cvCddBh|V!OxDdS@!ZOyAj^Aj{ zVEjgS2I4o#(-*&yo+QCJJ=Ib+-2z?1IUO=|x++7b18k7tct0|HNhQOK=>t`5Bc%aF z&Iq7L2v3WuaxD8wAKU(z;y{)=HEDHX|2CvcP2V781GM?NN}C72)Zw25b)9Ha(J&^1 zHWdvcd;Te*Vf+l~A7%}sFWh#zhT$Yp8=zsV{|LEE!?=ID(tc|-jE7YX=|pK5!_mJc zHH@VmRzTG-KK!RnI2XYnIW05{AI~WIg}8#a1R`%Yr1-`!^bTJROc19iDg|v~__~1@ z_o)<%=AJ|mvG!7Fp}s}%N)j2MqfrTAsHKB7}$VVxW*g??PlG#H9A z6K(KGDu!YMrQ$Ll@c)3>OXS#%nTA1>iaJcE zIVT(bj3PdzhQ*$7Tt!Z{(YjOA3xjpXTpI79BGN9}QA?y}-QiBZ~4#x*C-RO}%iFZcQ4-r}(RUsHhkp8%r}4 zgLD3kVA5P0?q~2sz2q}%?5Sei`Sw0yU5dS@SU1SdiFK)5>3pSltmi@c2=`@?#xczr zH$ByJC(}4?3!-rp;wF@wZ1_5`MTMPu;X8>5rm1ocM#i*Q`?-SjCz3KeS5Yg!0y5Oj zIC7Ysv-^9ZygB`sAd=I5J83QK4wL-sBJ{e{N{WjzcADmLaRbezyPxJl;Wan}$YRsH z&-~5R^1;t^9+(7U2|Tdv#Of`fw661r;rOeo`D>I_xdsYOg0F)QL;oW_DP(-2D>#F0 znMF)-NACbPN-_%iyHU=dPoeJDu} z9F!UNw|HQzgdD}6GXH&KZ$!2{e~SXZZ&Y=FKjkgt!k>}{e@ZU=DStIq#2hN`$@hJr zRPceJ0^Ol9Er>&9oWi3Y+2K4o-`<;e6#k$=_731tM-aD)HEv>Rvu>3?GPjU@SVQI- zr!f~H<2&eh;J^g;7vx&`Xot=*L*bNZMDYQmjZ+qG`5XBgnqRsNh3t=88J)kHnS)k< zN>sx(1?D;NRy)R9LFOP25hL?h&Ug6DL9Y<~>2uKAc=EAC6LSz|py+giv*mSsNYu|} zAfkRY15x4yqA(Et6#BWT0rk(P)-lG{6J={NkO#^|uojCdlkF`oDp#K(Bz zk}vOzHo5N6)UvmTD0P;g$Z(A%Qa<*dBvMtMyH6{-*s#z<%Uh(C#Zo(@m3fF2D8YCF zx>!)HjC@eU6VI&yx%W~Z>OmOpcsw-F%2q%RW%0{KJxkZh{)GlfD5%A88+Sa-4dndbqfm)YZ{q1O*Xk5V@q!4{jik`t?&{a+1JyPDR`##S43v;OOKf_e&a z>9p3(nwf`stRF7^Jo~*r@+)hXS2kOPHoXY(yUAwY_qkaea1Wrhp=Pg-*@k#g}saSK4+g(8)i%!W6+A)ix_1!}}cWoppnau0J@FTeV(wy31CC zHQ?d{hdB;*pWgkNuIoBj-l4iBGb<7h=9yy(RY#d&UA8z8jELg zL@$Z(+(JNakW=4cK=UmFdLf*@I?zkWVtq@#&LP3t%wHE?e#9~@Hl3#CyV+0y`FQ(VE5vDe5EkXkh7Ly zqrYP1dn15!oV(@&=m8klAq_0B)UvU?O&QyzP)Xr6wyGe2AcMiag~7f~hh6hB&|MNr z+H3N>Az%5Sj>#$*&7lIWj<6A@x4#x93 z_I5nDCc^H|wP$NAJ0Fy!dnjWV`V@j|nn{})!|Rokbr`pr?6$^N?)*VYGA`YDKu@gz zs{s$T0w4Fau3>aCFB?Y#C@m@x^O`TLE90#g-fQXa>CcM-xT`lk5PRiGWs2XdOOe&t zUV9QF0yP)CYw!teGfKskOtrONr(m5une6!hC_B3*o9Ln3&oifSdN!PL;wZq9barlIJb8Ynpi9PcRc0K>DrbypYyS#KP(%~gFHKOov}2+DHchF} zZ$a~)!HuRs2J{#|@uP$Z3*Jg>OrlLOIJBpmT=R~u?WDu?j3aC?@ii?i{3oBV!#xjr zX7g}&_Q73@WxbOC?sY3efqU#y9pAN>lUfcpZYIDw9#P3QE4PdfAd~FUju!i*CUlNu zrgNMVpmSKubd|#kg3HDZHlmeLpp|TeR-SrWhrOc__Wn(4Cq8;Pfv|tMM2Ec)^RkZj zQvvq#e6TNqS=@5iX{IAbT&RD=ymT+!N5-e(1}-O`g^Sp9KVI9rmgA*(7C!){3C_86 zjZSx`{|$%Giac#&_>dfM6-M06NkO>>x!m! zjux(_N1L@5XQ!LyM2q?9-o|CQKTJa*`$L1t|2qd3azp#B(Y}mZgucWn+Fw}ul8yNw zG?Ts^Jq5bAFLTOvGbp>-Og z^~PfK>o&zK30uDw{j~+K(fmQ{2O}J39*l_PN+)2wYb`&p9a|^;sK5KRzaREyUE%1* zUgjt->1aWD&l|e*zY5dz;7WHtycK6~5-Bf(83_g6}~Bc-<~X#z*x&(0?nr%!cs#XO4g zSpUKi#(biiTER2!{xPv&ZKTbVevAr8^vxtkyz&j8WZ!sZq7at5O`dy@z}9Ayrw9q^ zoaaVC8l6}knU&_~QT#x}U zh@YRt8suJFGrb*Zh(j?ZK|-D-eRF+FQ_YR-gReI-w$XT@`s?mr-Zr*br{LJ`f=~&{ zxBVeS)v$JeZfz?I}r@3614!ylGx$xMNIxR%O`fj6z)0`Hbe6(>|D1}#0RR<3t zG^33cPIFoq+=RX`>v5eHJn*Hr(ZZ=t3(DP%QmqhO{RwHg9E)6TCwqOz+=s-v$vDxi?r!^dvF;vwx>z^OewJ7_osKkd z*sl`nW;$+n6+Yo9kc;2MQHj^A<GN;dN)Ywhj0mF{-V z{M40X0U&(Y6EFAv3qDT7#)bHmr1j^fRmz13a`Twwt$(KYBu6_CbuPMHJlkU8O4E^& z#-yfI7U6p1!ZdH0HTf!O4fcvr^%qhqhBZ`!w}U)A`I4RXc9c%>be7g^lj&V7J>zm> zZ+SjlvGm$k4vxNK0Ga`}Cn|SvrHfzv+E>bzCyrv?-L zR)wSZ^0fzd^{m7-$hSoIC_@pHkfskwnO>N3=-`@;js%-4zrR(g5nL>acxjS+!E7wQ z(5=j_DgAA(cUbr#x`GRwH__$Ig?Z9utF%@g`bX@U%4e91BA^qi+>w0A7DqhFp}wW5 zC@25xfy21Lk;1^Ae+Z!vb4;cO&ysSma}Gt<+O?wS>SlQBBv2$XI$U&PJ};ESs;+k-Ds;ObNPVm!D( z-6G)VWX)iwsBk6Orw_Lro)Hqa#4ZehTmFH%6mEG3j_@YAr36J!VQx`e5hsFYZY$S# z=0I7ic;+FZ@z%~IDNhCP%*78fo*9b~KmF#Cf7wIgj=fR{-0>LdQn=&Fl4iK02t`j} z?l=*A@dl=IWiGh`9-mgsB`Y5}3clDrGk`A!10c*Le+I{#etdE1Vrk4S)v-LV z#1+1H3z}+^vqmL~w(*5n*8DV`TypPG@XQOC z{2SQo$uN(=Gv^};^YoibJP84X&(u2e5BJ7_o{KsAGF(bx7+HP`#L$e#&ab#$jtnhE1@V)u`Y*Baf5%0 z4ya;t426)2bz|%|;ndwG+*@y9WK?#+eBTOoaX62HUG^0Ru*)xZF?Kl&MpD^js&25; zo#D*A1Ytk>mpQk+k@o(D$3k!k1NXD z6vX|7JInzOD`j+nb@z9H@#UY&gCY8x;3@KLkq<1s0Z*N&`oOv<TpfvdogryU12GbfII^Z4=JpU45omRoZ$Hm%^j&x?+N_x=r? zs)6}7gv>#+d?DPvzf*m*eria(w--xt&GX)ys7&F#yMXJad9N5{jl7o)A@FviL;mB#zN7Wz+vJmf>91=&4n;Qy8_C#e0 zM;1WuX__PdJIS9Tm&`v6IWi=D^s<+aA77Tha#!ZWk+-ypFDd?|)qHtppi6VTqL20; zuk+>aO&|Tw?ICgCXOLXY&xucIq^aa?P)hB(wPqIaEc-Bry+5C z=L{6qIY$pE-Hw}}ak%fH&+(w21ETqO0?&0AqMT9Txdz7t+{&gBdvd@T74cHe5Z@Kk z&Ky+S_^Cq%_*~FZTLhos+gfN$E&8_6zP&UWeR~B

96~U*DXdtro#Y@%h@oy$4a% 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 z z_eaRf0^h=ZNt3}I9^qSTdGb*D(v`LjMW#Qfw(*``%v`m)EFt<9E_r>sFC z42J0X(91Sq1}EPT!a$`{8D_&#kC^(WH{k_JCd^fJ zpUK~Vn*9_hItF+~1Jydyna}hCt$LWg*C8)=Mp@ zQh9{HB4I*muS8jjUBvmkZMt{Q-2TYJ4qxHXuJDIq1eCR50PAI&NY>l&7~-Owp*$*; zhdaBA0%{JqQ}if_3lhh7lyQd0JEP#nPx28{;?hEShv7H{i>cZ4-IHnF(^$~xd8zs8 zQ)%Q@_PWS}xkP^u57>|+yE(k@fc5X@63g{~W!-n;1Y=}NedJH#a`f!OWHWT&Ui^o(vxeF7YlbZ8hqyM34L|C*By&x@a;z1Zf5Crbn^Ml$^nH~qH|in6+W6qDM;>Fb`%{ZO zW{T_WI#CK|iT8EmgsQtDh&WoX~x+OVZ{h(Uhi2pmA;207l zXITcHagWs->%&8pB?A0LDK;;ePd~Ue?8Ir?PJ&vPPs$Bt+aNYM&6&T z$8JEFMZZ3kb4;dlj>*hm^cuRhU`3;dS2@cBq582LWdd>xwvSag%p(y-9OzJJnc||W zuJ#!-2bvck&D6;pkUW+6hmgFN^D}Plc7BHbWl`D>^9YSb@sC(XXjG~rG-@fM+1c}8 zl9F1f-+_+MxIkPfY)X`Bn?Ji<`Xc1@aV`dsG{9P&8};Gqty44PZ@D8d>NT(-`0_c( zTJ}0Z4^F5`mHY}AynU(_C`69On36pnV%h(1>ab5;? z6*M=XxdF{%*QgVv|J#(c%8RT`$a3QPg7?>|-YQtrkTIqj)Dx6VF?uHVdS83UCBTk_O$;}dh|Rr8nVtop2t5Oq@QQatr5&3Bo`#K!Jp{#6)f!dKjN zgG8oru;8RraF+76RARiEe_}#lyw}U#QH1LIWSS~@_oAz5Bu5ihQ@A;YGHn(Z9h8^?-M;!1uM8EWbC~Ylq-IGc9!{z25!4WeW$0N>DhOZkgfy*6X(C^II6;@KI^XTcTNtFIg$;Ih8)dWjZF^ex2dY?F@FF(Hg(einroG9U^D( zsUF#q?U7%g*ri)jY_;Zd?Gf82s_Ys$$b0`zDW+4XeYal8ZAb4NlW7YMf^^SpK+#FJ z#V5;Z|HVCH$MPds);gao0j>`pZC)UCkQG2Uya89MGC<2OZxVOZHs2zG;A)HFa6AXZ z3~$vt(bMBWZ=CaVj!IWPxm=4)+^5>%ZJPT>-$MDuSSe96BFoAzPt3Gj&Ijch#WUpu z2F$71Q>Z2Bnw{8d&8nmMRBpeT-6kI@v-S`*n|H{XS@oh;*a{ZCM&{J&9_;7Crq{bH zf*i0`Z0^p`>$yYLD&3EYUYVNJO96IIc3{`;U$XgG#7oU+QP@n

2jw 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-debugserver.exe b/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty-debugserver.exe new file mode 100644 index 0000000000000000000000000000000000000000..8afa0dd53d91e803abfc8a8d7c419e051d33bfb9 GIT binary patch literal 581120 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
GC!+<&q{tdMORSAl5S%R-T7$92Ki7 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty.dll b/FluentTerminal.SystemTray/BinaryDependencies/x64/winpty.dll new file mode 100644 index 0000000000000000000000000000000000000000..c16544f9ef99f9e4a9437c875adfadf677a6cb5f GIT binary patch literal 640000 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%0DWi6Nt2{FrX+T5=c z0xe9Pp+J&60SN+ezU*NP4QVkcM58!Amg~{idRRfkPbJJbYIau;3L>5+rjzcpD7z;M zPguAstb*}whJ{<Y>>0oiQ%`I1{BsD}Zb=S(d&Mn> zqF;#iIEY4G^w|${|D0o|94`8FK@+6FDZ58A zLnb>%rSwixGkNZPrfA^eRl?y#RWeH2gVD}-Ba`)ZQty)Xqb3@gr+1Y4l(ajWC~qqD zEorxOF!StwO>qArV#)dtsS!FX3T_$cn%fP=R0}x9j9}l#FgR;9QYCuQWG$+GRAdxh6B9FZyc|VB=>`E-Y|`G5P|N-%&D~ zG~99q`lXbl{(oU^v#d*b6}^W3KYab=B3I@Ay=bTG1s%dhnd2)RDm9Nk==N=4Yn-He zJn|Rf7A}bJ2bDH2?%*C|2Y^kFB$LUOa}$p!bI+y%IL=*_FhWv1p|f;oIHscpRLV{} zJjcH)>y{z@_r1K1e;2)XzVBZ&)xPuG=YW(iJX~UK7;m_*M5)e2n=nmtF(oN}WBdwx z2Gg7Qj*9}L+>VydfUVUqa3tAiNnP!hbTfH)yVRAz?XIFvG@EaHiyc}(MszXSMDq~4 z_GwDnt64+Fo~a`)hj+hb!@E=_G0G=^IjRvc8Op;bXC_?XMhj}9KEc=xtQMA!H_ujN zl(4*&_hZYivWFUre{{6z7jx=0G+5wN>!qc8{0W?v#-N59Jg0?2 zd(PdQx)<(0PnwO@mgG5CtGGWRTUcBsTqqo_74m&qFp}q>QI!2*AbYY7?nTVv8YYJv zVGTsM&s~Piw88NB&cJ3i!KpSL1-t)-tfR#;%QH$DP_kcllN63}jUr{2QeM4RlBYXm z@VbUMN(e9{YiXB%`%vRNBVy)5lPZ>6w`$?=iqgyF3a+s z-=85Ix%McCI7mQ8uIsV}_u$C&N5&;^~Dgb`P^6FtWncqmmLF*{vzHSJPe+q&H*kNLOW*<⪻{@8PVw9y8l!e>Y@v2I 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%0AMPdBF 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

bg!FTppO77x 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-agent.exe b/FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-agent.exe new file mode 100644 index 0000000000000000000000000000000000000000..925a3333f88de628e488cf2edd351b08fd9f564a GIT binary patch literal 580608 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 z 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

  • >BZUgSA0o;=a_g=!iVK{E$5w*|n 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-debugserver.exe b/FluentTerminal.SystemTray/BinaryDependencies/x86/winpty-debugserver.exe new file mode 100644 index 0000000000000000000000000000000000000000..96a4a2a325ef8079856fbd1796529f2f12be887b GIT binary patch literal 463872 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
    lH4Aryb8sQRS{at3`E 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%0Da!u=H_c6=A61lQi7s zC|@xzWbKu&SsikpBbgUGTjMg3#%7C9@Z6=Y8+q-G7?@x%%p#w(nD((DF36e(3(zHAN1lxyhWDX z_WXI)j73>Yhhi_BmR(ft$TQuV)eQx$FYJ(yG`mrg&sfv=l{K?Vil9A{7XtGFYwnd8 zGq%U4FuZFqX3V$n`?qmlB99+a|0zv4EyHZb{W~*Lg!JnH{cK+*?mR=Te%vROH4ETH*M?^VS>=9A@^3(@R~ud#wx4}5g&o`)5) z?(X&2-#XwZ__DJlMYsnxF8UX|{>=d04$RQ`%r3xtWn2!-0q3BMw1T9$FU`<4_Mn2H z_Fo2)p5|$5F@`(9UuA41jSP*d)Ot+p3u$IdpxGiU!Kxw?zl)%+3H5KOJRc3zNcVXG z+5zeRAesiN6`8Q2PU)mFccm6>T8*UEyA-Uxyz=hmF-uT`)s z&&ux%S?QCvwupnv^H?k9q)zmTJA2K8Wo1dPB3Q~{6Cn+@EDWh^SD0+18mF6*A{amt z1L8oq;h(u|CHdMkCPjF0Yzm`bC*H689PcLcXJzfxT}lRPw@fS@U0RX$_*E&w)=N`_ zsw)CG=l)BY@NYj&5uTIvS&K{WEG=7KYAW22U%1wDO4nZXs|g;^BHUNK@EE=2s;7y*ziC)d*Q0W4J%k9n#!&#^3i5s61!}M zX%TEh;GU~?|3LMP98`QmF0xSa)Y(=F-4j7#skO8JOFmt2FhbBXXACNru z!nLrsf+x2^dY9Qum*13hH=~G*sgNi6g#~DYcWgv<+?t8fI7{;ELHrMuW$$vsHn+B< za086GawP;_P~PBvp2JbNW~~ERvi5JvTLm!&Hs_&(^~{$EcSc?wQ97+0mhKYx3zUQ+ zD0F=|{Qa@-`Y0%bKwCot-TKvq@I$b(no%K*8>D#|$X}s+ZDD?qtqA1`w5#&MUpUnz zMt51+xEu=}~cNfTbhIHZhiY&^8v^ER4F z3)h32rK=o%v+on{r3r2LqksA3YnsE@9lvPsV~Y5fF+s1`?bVm32)mGn?vn0#1dq%2 zV_x?Z{#x;OZ5YSjQ&*?p<=VSxn7fn<)1dn%ecCjvFKBg9h&$3<{(tPf3qVvw`#*jV zP*7Czu34^%iVDhQS(eMPi(EoQMMcG1u)qqd%d+k+2&RQ)No9sfW~GH@MrCDXg=L1< z(7d3Tn))ggm6es5m6qxM^PD-edv?Lgd-?vpm%pRWe&(5Z=9y>a%*>fHGv|;k&Rr?q zgni>+iMR%aH_~In+}8}f`3@~%@QK^?E{fcrS>=&Q#pulA40(9gWfMC@ieWgCK~E7@ zG!Mt5gU3xU<8sMUNNFbFD1;#$Ly-;l8I}vxKh-JPBqLmB)}jeW-C}Iqf#W5hPp) z60{Oj4XOdvfewR?ff_((LFYghKo>!mL4tR(;05vlbpmw*^#mzE0iZxo5GVws1gSx> zARQJfb5_W&^%BXXd$Q^v>3Dkv=+1hv>9{^ z)Cjr^QnW;VpnT9`&<4;+&}C3SE7S*Q9%vRiu}BYbAr2Ub!S`PH?*`2S z^+$qv@C-uSU{EkzkUDlYZJGS*vjmyN+_Cr#?b$pItZud4;UP0<#fk zAWbHlQOZ)ta#kMeO>PaKN&M95ZW7R2pf}@)X6{W@IN9MQf4z#A)q9f~ZF-fUyXkdu zyADlLW#yLQVHVwtrr+#lXjRZLOx~7wJf`KC>&m*4Tnc$R8r%)Dbjb3?bmJ6F>+NPL z#C068iwAGqh7-s5sOZy2fy*N((lHJx5*?doybmje(NL2hKK(mmF~wK#kr`=aGVwI; zloCtHQj8cDtU39m&8Qa?3F6}fo_)q-&qUu|oP zDBh5=t|2mH$Phs~8Ys}ZnNv=*#?4a1b7RE?759?J;!(c*!rUeT^9Lw|`LJC9>#~Yb zQ8X4BO70?X|O{qyjwyqeqH|#T}da51G#E>g;h%3rA8FLsj)t+Buo;4jU z1?P}U&^*kFJ_)RO3j-B+-ofG$0B1N0@i;CBcmgL@pu@i8DKcY>r1duV>AEvSi^J+D zf?!{6bhLD?Et4g63nMAaAq*yy(PA^&Xd(d@M2&>dEdtM-*1|cgALUqZuBgBw1Sy!E zBrn0hI7s-S{8n&Xw zXpxmnrTPg~Wr{O0@`r~p{~ThN7kaRAtq_C>qeqS&Gifxb5S+CJ9n?G!rYJ6SR9u#n zhr*C!E0Q{3k(rh_sZMDM0}mWqVP>(#%pzgVt`KA z*NcVKAZ&$BC%n^FC;ZWeg>`xw>%lQPAp~o^m-?|V3&PexPoF5AU_v;#y$IW;#Gag5 zC;Z->g(k84@xntraR- z;e%hnCo4Y-P7q2gC2&5i5ZX%c@$o?vr0GAUZsJ;&l|59ppbQy$K2-M5{bilJy^-UC z4?gHE2q7V5X=UYtj}SOOoi?cq8jxvPS~=w!SXN$!R06Wi&(HVqX;m`EGRI=MVSa(s ze=x5O#FIIl#5GCh$6E+q!kOQbMEkr@1@->PqJNq=I~N3sZOO>_><^@OinC;6M%e@S<2z>rVcfpNaU zz%;}oXPdYt!cStl?vv5}OF!(8+JqqZXa$9xX?KR15XMgG^+RpB>u=7s-YjeEyk0+V zE=S_1^gP_0#Q~X}ZKX4ZdejZyA;LNb##0jDJAphV6>D-7PBloD^6(_bo`|Rxrvd5w zDXkT;(^&jmD&@~zGP9tXO9hZ4}=O%F*K`A#u@?Z;Z93S3~eL zgvDY5d+$fqVsZ;}is-3BT=XHO*cHLru8n8g1ZjtzcC@KPO;6MEvrYMsngc01O-bh? z6=L}c#q*j}cNo)9hqNC~SR}RtI&n!M`X*PWHF9F7yGfTpY!TFUsCCkwJ7M!}nNCg9 z2~BFr)TW*1ez~Rc+^${fCeBSFm@l|iJ;4aQ8HCQoXc)Fqh z6Bk7`_QS;2sd6!5xVk`$hP(w(AEcdSb~b@dDJamw`CDqvGShmY1^t40w!CD)kRO3_ ze(6BkPo>kZ3ULLJ_AkwlW$#DiN@JC)B~ES##v#6JP5nzG{Ir&OTP$yQw2h{a-FP7z z+vJKofD=zwbNmku5BZ+cfju@`IpQ5kHL@ofasRU{Ey506*52m2(Cl^ z37LPH%)haPQ|29+U&^Lg@Ixr_5j;V@Aor0o30IK43DH}uvulkXNa}DYUDf(nbBqk-_l`?$9$kb7z$E1xNH$HvB#7P;Gr%atT{qD>xeKytrXXND@ zXU;MemwhM^X&xt%Gq<+>7g#IVA1!3MM zwrQGWQ9GypMo8_Pkj4UvqrS@HNH3)&Y!4#+{vZmw4b(v*3hxb~@CXp`@e)rZBt8v9 zX~uy_ZoGta;)wK9yQ92KAc`*lDL@ubPmmQvwo*Arz6?Y*FOcwlAjLlbqWFa%(u1)= z92K9F_|-tNXDx{GdkI8x?}5m^{UC}z3ZnRKs1&N7|CGzR9s3a=+Kck)iFI~R70CY% z>n+4xnC9X%ucexh=M>U3BPrxY`O!R*O2X!nG&`bM1?^nA?mdPzlf#X4 z(>#LSS)p@{+*+z@cWZB~hfZVi86?-#d=1}77u#*6QIG3s&Y~M%rxIAi=7;P`@OE@_ zWuyF^ZJTDAY))&1Rm?*6{@(R%q)XC#d1$E3bKebzOUP^KFG{h+jWC^G&V;DBfzIN4!FQ7$Xlffp*(EWqU+>D>@FC9VTuwfpLz3yTIJ0Qsd@!L-F zAwGe9Jt7UqNwC8qolEyXJkJv{iCB-sBPKTgC7bA8CW}vEk1ZMF=~z!P4(H&3(k5jg z&LL#7R7bL-1j9<%YwOO`%qUD=R}6`%k$tO!nKv4bL0p@g zeI&~^1Y|Wsa~X1Ob?sWoqx7~}OiY|-@p_iqGTer95yspmM#yDS6GrJRvX)8nJgzG> zVR&MCp=)xNv|?+e(m@Kc?lx0OyTQe5(PH^^9)%}mw7y}5CGppZV>Lqav~h*bQyr9m zg-yUlBj4T<)rj*uUJe`(VQ*!l0p!fO3;WG_thKUBLUT5nuaRSoAz3=z8WOHz!T6Q~ zR&dNSgwgS%1+(5v7&sn30}&5C(1suKQ~2=FiR2Z-@gBG6Hw+F5q0x4Hky#jpgS+WC z$1(}~|LOTfLbBB;jMw80y&`k29xHQ*7ZEZx(Svl5HFFMWtULl~MG>SgvP!}uU|+H! zTNtIc3h@>zuv8dn4Vp-fUfeiE(V(SDx)J0)252kz^{`gUt!-GbR8k(Csv{clU z3m2pq1*afSDV(SyB_+C`AlfF5C*#F?nHY?xMOq1CE*;^#b4`LT*AbqN80M12*$MNH z#~npn_y@~$(u|Yk$MiaRrrRdYNtpz$g_sAe+PQ|)_Xp?>=o(6Ee>5|4>SXzoq%({x z8v!eLnUbMBo0*HU()UrAix<~Un4iMAO(SG=Lw>qmTI|g@aUI+Ak zOtBuit8BUA>LN+Xr3Ji`kb?Ew0{n}{wRhb5U9EJz514p0b44bp)! zK;@t+(0|HV2BEG%6`(2*xtVC=!RV!FQYLfJ+JmtQG+N?kp&td~D+l9T;?pr+aHl{! za{U*G-68hRHN1H)1#2eP`?nBl74H9BE&e#bgKt> z+_n8a&6K`_2k8%S#B>rm!Oued;paY*y2%1dV(#)cS6Zi(zu@#Up9k+&yg}T;|H2w* z+KzZ%ySdi)ALwmZQ{?|Vgq!=vdkf+HvVSeGmUuJ&czVTuVa?uB{hz3TvIX})u<*f$ z7L`Bz$fJuNTk?3t(kGTxKDqp<6;D6&?8;ToJzuqY%?oQ^T=!D-%dfn;{NwkBgW7{Oj`HSFQ^G?ncYCH&SkDqvgN7 z{QrrIDAV!ZUY>vVdfsT`?Ar0-#@T;+`DNGQ-}SQnXnJmArxCb5_i(mro`>fgIxoYY zerTckZ^(juO=(eThPkE67_X zmnU>j!*_Mq`UQRej=qUO=T5SrBM<26+|w6fe}KEDalF=>=1W&ZFC`>PDed*HzN^f& zdI`>yy6B=WMU+4{tst<|NY2*pE^8BaYvj-OwCiCNuL?cqv$IO9zFe=fs~q(nDhaJ| zm{CeX>IqKgE`L26U1givNNtLZOxGHLaOM^^I7c7aKcd|cc}cOBiTbf3+<Zc`4j= zv-=E<sccMfj%%#%IQwA^ETlHc=PYD3 z-Mgs|b6e;%EuBwbCls6Nq}-@Y(aCCgIzFGFJ!|=lhU#Sw%1t>_`7h-6`kxXO+*RFZ!K=^q0)iRkZS$Ks^ezO#w4*9e2 z^Su03PCM0-pX^DO{HgGlNPe=XQu33XwUVFgIVt%^!0#2wbWVX^A^FM9bjeRPR7(E4 z;NKwmsjl|Q{Ab`##)>lK<)>zTvOy{N$+j%XPx{N?PeiSg{ne76ylJ|;YG9(`W zKV2iTKLvg|8BF0O_(x-xh}N7iC7{J7O3oBtPjX zk@>;?k9AZpo>{#3*k?L1#}Io;HSDD3I7K8r@%_O4)ySll-lW8S-79p z86F6KI{s0+qie;>m5y-kFM*$zovtDGBgwzyx*}CPO2zkz#>o7Bem(qJ`K!GAe1g3^ zz5M+BeeUp~OnP~WfOTTD(^1Ld*-;bF6TBVh1)K-;1}+A+1XcoD0apSk^;)1Wa6ORD zMQjAp8IsLFKj02vTi{+`JK$kpd*DeRol9v1(piYJzz)C*z>dJnz)nCfoP+2L^aIk_ z*iJw?8{8Av9T))Y0Sp4(4pai^%xx?XXZD3e;GMu!U@u@gPyw6<>I*c1 z4*=SM{ebg;{ecUC1AvQx1A&#mLBN&3!N9e^AmDmnFmNMqC~z~7&UEYmMgsQ&>E*z~ zz$oBJAiZ_a2-E`40(HO(K;$AX-V;deH2_HWfgm8YStXGA zPb`qyVIq*)MkI{vbAg?Kc3>CaLSQ#wC9peiEwBf0Bk*?M4q#8@mVO-7@xWSO0VQGOW55{T1z;S|YXa&8*ao3 zfLTCapas|(SO)Y1RseedtAH`U&A?f}y+CXX3nzhIz_Y+sz{@~ipx;F30rmv?0fT@& zfU&?BU@Fi91Ku>C7tjQ31)K-;1uh1*2CfA90oMb205=0;fX9Fy7#Pn0eSsH&t${w1 zAP?*Y>;Vh}#sCw69vCRofxf_8U~8Zq*aNr_7z3;VdMMDYfWE+5U~6DK#RD5CJ^<~S z;(oDJCy^YjK`=B+$mD4MfE+!^lA|{@85W61 zYZT<@S(F^Df0LtUTXM8+!I1H^D?yI_wgx$R(}5w=NAEh2<139eVYb81|YUw3bLNA8VZC^wPS#L0S_kkk$m~S)Lr7 zq9;f1&649gICKV|+$>3cmZXo?Xvh^wdgN^%8``e5+| zQaG)_kfVB@CHkn$rIIvVS6U}^I%*%m(lY~vQacI8a|6wV$WeO9DE#!Qpzr#JT~p4SJp(_mPOp;C0zUWw=WsNIr%TpzVxDj$Ye z(a~BSok@(Bcxu;VKRxS`qxMbt@%p89PS=m;PwhPz*3q1moJowQzsbWKwSUTw+e7^z z7}7NNB}e^%%16)ZFEh$fm(*wJJRr^I z$x+`Wp7#yv!^HFasV~#DX|67)f6LoZwpezjZPf4Owo?C>^E3{)@^syu>1kY$^95o% zaK_VkA&;jW0y$6P2VEOpS2FJs|8dv1kl8rA;4Qz~|md9Em8)rx(YiYAl9;%&T z($%4zGx@coy%FlCysp`}G+Y=f<Wtq1W{%Zaykjh5b;j1fNP^W_f}{V*%j|9o zD~Gep+&2DBIkPR*(U+KQ;~lm#+frq=(DiiY&1}2NVLP{tUw<|Z50lwifH{V9q-Xgj zI@%Mk!Pb>p*{N zj`O68{%QnsEU!`0Ri-vW*ZJCcQBUSAm*ti2XiqFJ=a|aMmFTDkx$dUdnDzvnt(EB> zgI>n%raBuT%Cm9X@a9r4Vz1h+m+-z{K{(o+tu>G=r5&Kyv^@G*mx zjkiGFKSnt8vHWNyk=sw!(U%UGWA?HA3kuWTeUkYJ7+beMLv_i|A^O=Cv z5VZ|*w01?~EUmc(0hQUw;_RE&ILRe~KL$((9tY+E-vru$RltS7$AOi=1HiSw&wv|& zhk!ePF9Qz)Hvt=gJAfB}CxKo$Y|X9{a4+}(;733uuntITgad(z;GYF%0cQbC2=5J? z2R?^**y{mY44&pwD}nQY>w)h9?TBvytOHMdb1`@?;4$!Y&p!iP1gu23H}E2O8joo0 zwk6OfH(6K%>;_y43^{M!TTz&{B*2Bdk@S;+YV&w!^sz889e zffvD3&pr!26zG$W_kVy&lqVY44gCGU3rK$(kk+)dz(9mQ3{(ThQ#{g#0aL)20vCht z2h0GU2V4j~0GJPc2CxLU1h^UDgMsDX3xF$t4*+Q`oxaOb4gMh@t+mGhYrroAHX>aJ zunznx;4$DF;2B^M@FH*mkoGz{0DX+f!g63YU^*}m_!Q6!dO8Bt;2#5aLOv>B3ix}0 zeu(b`%m6=;;=y+Y=7XOEECH?nmID_9R{);}Rs*YnJt5x(SOY!-7y!O2uns)UjuVkz zEbtik2Z3jRF99zCi-A5f@eUPGiFDn8-M~);+QIh$27=E8s)1X8DZuT(4B!S}KClK@ z0{jG64*VDxi}XE!E5J_!(pubCz-sW@fIEO60vmwqfR}+!0~3+%c3`(z_?tJtK;U$W zM|e0;4Sp_=_B?dJ6!4D#1Hh|+8Q{x+w3iYE%m=>!n2Pj0fhFMY29^WOz;uM)0bBt- z6X=I@5x{Ej^MJIsqyW}{&jwC|{GGr$@L51F$SZ-zz&{7P0K5md5^@88{wBN&3{(IM zfgwOopbq#YFb!A%%mS_kT7Yi>%Yd%{D}c$sDxd{;%l*Hr0k#G}UvXiM&6)J#eStz4 zpDo@8oP4g>KAk+Bf@F@#8>Q7mo_?m-E}ZhSq}4heZxY*`Gu|YQe@>p}&CD_V&eJ!H zpY0a!JS)rM>1kS?-npv6;!9=arKf84#F^vvtjR*zFP)ZhYGLc4bS9JM!`A)yDlx^= z%-ebXi#_kqnPK`ah^sEPMo6AbI;&vw|$;`vHBe-6lT*w5mf zYxXbShTP z)8C+W<=x|5)6phj`OXi2?|P== zUdh&N>2x=9Y@KzMqyMqBOsD;Pt&xWiPiGr>{jqh~S&lKCt!dLQb8O9<@AS~#30+TT ze`M>@d`E}kX|0pzMm&v$^vfJuOO?m7{^pD)zQED`*t#?QGRO8L=;S=-DL-fXVQZ6o zhm7{hD1W&;>35C?Z0*=-58LD5J8EoCjr8;SVr!dxr%k}UkF7fL5rgx*$8(kG`p?pn`#WhVw zdoCK4|3YY)~9G3Wh1qdXFZGa zJU!#{9dWOQlDqK z_8%~Yo*#8Bo@}-C;fVn~U;1-rUO}DhWWj4cSUo7g*8RBy*5vHzw)W?K_Z-}3`T6v$ zUUA>A%A|)DJQka;Y~MH2Z}W_>UQt6lTO>{Cck$5di6gdcKi&$@I*$*j_DOi_m3cjS zFVXFP*f`ty4~(oa75>Z{W}_Dl5sEw9VwgX7+K z@2`Q6J)TuLNX(DKehG_S$Re+>O;Kw8ezvv;rS^4*9ffkS+{7Mh3mFn6cg)`j)gz2=o>z4Ov%2P+4D zuy5*&@xzY(&#pR?*V*jbdDYC*6f!M3FdV-M_pa=?UFzdSPFo9dP8-qcV<>PFO` zy>PC)?|nN9T4xk`eUz|$dho>*pWA-wIl1c3z;hS&Xa``0E_-u6zJFyozpiUWss9-UvHeX-}L z_x7E#tU9iV@ABU0J@vC!bZk6Y5v?2ZrS{cJg>y#r|K^R>)XMxrC%o!=D8p~vC;jyk z7d_B(=GF^~ii*!91|7JoD*icdpWSgS->*7Tci`IzwSRu`R-(tx8}3yE*!o!yF1S?F z__}xJR=Vt%xnriU-5(zR<(Ptk_Px)CPyBjf$F2RII{HK4!XK7@IwxlMov#P?x=W#c zZTZ3de?D?z->K0L)#guFJ>B@$!?7I#W+%<}$BEpY14eW;PkKH3>?;rV`S~Azt$DZc z=P$aR|8PclS^37uxS*PkmY!PQ-6!|L;n6d%MzotbF|X666S_SygG%zB4V(4(&NqJB zY|QPC@-$w^Ec@$?gA;zNR*ZP|;-sfuZGGi+k9*byjW9m>(VYW(?)dnXL!TWh{#bR; zZ^H3q6{|jeruvhS{kj#OYwKHH{fFJZSM=rEQoep|NzP>dZ$EkJjPYpyIBVm^hhC|e z+9xV}Wl^iSBbR=6SMZ!m=4Zauwdu0s;uC)U=Q7XVX4>9w*rS(ruUgv1_Qt%c-VX*R zY%mrL4h~v4X`TPiz3K(s+>gJ`t~oQa{FwjOEB4jxoba&!gm)*`AKvm;M(F)Dp52pD zJ)?Gy>b_ps+3U;N)Y8>uyJHRpzxmz8J_UC_^RW7!W8F*lTZ?yqKJv~xzqebiwk_Q@{D-|y4bFU0t8V}M+e;OlB1;aQ z9(Hi+sXlR?C!K!dk<71uoAcv=J|UweCEovF>LRZj|AQ>JPj*)rmS>hp1<&YYON zvvK*&?AlwvpD~(EXk`?Ej0`7He)dzpbi8f4y4LY2X`U zFGoG~L%+@;gHzkI^IRPhdnNGw%jI)25}vDB+o-W^JD)snMYjF%_Px8Gc>UcMhP>4& z?Ulz~jrx9=a`{s)pFZtz<uU?ylzscDc}6JN(xJ>t3Am zLfv_H~Tgxb%ue_4%|9 z9(=0Pu)llkO}_XK^*4tWwK8@+*rLakU*3s({nbs|3xD$IxrNl3{?)h)9cYrUw?F^R7<#+H$bY65<2xopM{=HcB7Pdv7)=zja%s%OkQL*J`V z?Hm?Zx1{v-fK%=0BIU+!eWv`gr-Kqc@9}NfnjxCsXK6}@-=FaEx1}S#`Mb|EmLm;6 zAK2r4bnRmwnuOf1-aa|{MYB)!>gSRkx7VdFxjbo?eedDzHN(s~pHJF5^___Cu5>i% z$L{EH;{7MzSvC5X)oI^eIyw8koK}OMA9`w4AIeYgfB3_@V<$$=`AYr5Cz>(O9a<3d z+#hT0A79%3)VDonsv9%cuYB~^R)3x?|7`u%DRKMvzVV<%+iTUQ1;J(GQ27EZF|GXi`A1$h?D2wU%?up=vlmi9#dNl?-ohIga z>*xPg4YWX)^u&DD%UAI5YAbkncMv>Ub`x5(yi;h=s-MupCs^?Gi4Z(};{;C}^Yv;y zPVj0oUGVZV3f_K2f_K~d1@Cqhf_MApg_iAK7h3vn5nA4MKxlPagV3tOd7)KDZx5f2 z-8_6c2YdK*N$~LPGTFnotHr~&Te(N;ZdD$wyKnMn-Q!b_*0=xU(dKsF7HxX=Yte>H zpRZHTbibf|kTaN}_+w$e>LCw7H>|x-wj8@NU;O4R?0JT^k3<)O-_XAF6;Q&l^chef zeF2n(OY?G)E%TQc>Hb+JZaN`?PA1SfiwW3G3Lr^0XDZAKrF>l7IodjdJEslzVm^+H zbN*h%e7zZ0)=ZcfbX9ci1&(51?Fp72(ElREJU)yg;>!?lp94#tPwSZYsW#*74!uHu z?j=r8Ne9#C{G~9bbC$;$CijITFplH7tBgN)AFEF%UfTcEu1*g}=rjuk=K3!4shzMe zVrJRyezk`pmY-}f^Ro7jr@P(z{HtAb5pT{pd4BHsk9^{Xd}NwCMXFDEp8uA=Oso-7 zf!aCw($P&1&Y1mXTOHGR^=ez)AF2eu72SV-@^2~U2CXOlHad&PFJ3bkdsmWhd_K}vu1LCh?fU3^yzm#XKb@3SOPr2f zwV&@}!v0d46}8N>LdWo&6wkP(zdW8_JCbOS(kPmWqvlv(8Dz??GJh@nwUS>95oPwA zA3huO3x#A2ThkUqTd<;={OiSSz05CqNGMKu(5LYC$nj^iJuK$u4&EN25o#y@aqP7!?P~maiLrxjM|{q%KmL3{tNm@k zFWD*|#Q!|`&aN+MPoy8v_V}<1;y-Rt5%-Grp-=1UCLO|G`_*j^4i9@x+bi+&izntH zebo`mZGjuK#c6K@KKd*8tY6OdTKT5-@PzSqY8zl*t>N$6JHM@cGHM=vb7sA#oolY@aK^JI(l?H7bEHOl zf9mMHUkfOYE}+lG@b|S5lk$|7UsOo{Qu@13exUt$baBAl?FMRuhVNSR|9-RflTU`+ zKk(oWvDo0;x^dVR?RTRd`?dYo_{+grGvD-n>?7?Iv z(_;(5s6N-nwcVo31GIpD`c21zqcm0)E zq2WT$kUzF*<8ykn{rI;KjgVH_-cq?;n``Y+s{Ib*QPsxr_JKRJ%8{FQ`tGOtxbkPf zo*mk;`QHpnPz=!sA-)}ovUh5OyT0=F+0#fb{NAI-`JLL1`ncfRf7XJp=(6UqUE2Dm zmtPL5{4o|g*QN}`$J%}Ay6kEN{sMDa&#O;v{8+m)d})4=2g+Bqf5sYZo%Z>@iyqp# zOQ8|YP4sKGw@!Py>cHxaU!lJ0zy102hj64HxAQ&W6Rqu)+*IQQZwAQMUK7FsEzH~$0|ElF) z?Ys{s?Cbmq)t~9`s-=6i*7e_1CcoQGBUE(M|8?6wZJXtGU%E8+C{%CsQB#%#8*@nXY@Lt6)L)Z|HB)t zkpGEZWltZ_<}W}0$9!8Kl*cz|YU_IKef`GwojMEkede#ovXpx5t`3_vEt`q%V?9|F|CZ)y%wO_O5zu*w&E8Mtq0zRv+5;`PF)D*{WZDZx?~~Ub1b=P~Ac8 zqwn__rig_-6~^vQ%{{1ndRlPr((`El8S6vlzH?A}@4~CuaR*QzHPM|Ij*H}jtymu=UCf|@f@qRd@jm!ESt`Fj%l8Z=csu3m?+P&VFKeh23|cX#&gVi zgYg_!WHO#(eS5}pEZcrWOwX};F5@}Yhccd{=Sw91R z?w2H)>jVgy$Ih-PfwWT)0HmpCAg~wk%p!L7@Eou=_}GWoSxzEPacD2HN!d2m_$5qd(t**Ae+Uu&;@nk0^^1v_FIUvv7KbMxLlH=>C z_hk@IdZ&Ptt6B=mr7bB);Bj<)sBKgrt^#q>DDq!)ooaEG@>zCG1pm8SwNL?Xxmz`G zs|Ie>!2gmOShxrGxh1am6dJ|?q_7|fNsc?ZKagJsa!*U)6KDgtb`=To!n;k zv|MI0Xn=lJxK}N}nr*nRp(M<4)eL-P3ZJ2G~*U zrk8BqEQQqpxy>ZooXzg(xo#b7@ml7zhr&sBHz_Ot$n7TC=5)KK=eipppXH{T(%Yr5 zc@mNwck=phPs?RCL%zmMFWJ0T3Ofemx=FSTAS4~3KNKq*WK(q~CwCLp(+WSg_yJw4Z>IEeo5rkiZvEQRd_ z%55k4=4^M@!SyFX-sdUT>q_?Zl)?feBsuQn?a@6gm&t;BmYZI(+b)GI1j_p=$v0=W zyAH0u0`j$P`YHWkDXam=>zrhpt8@4CTz3uRd#-Snm%=H1h!m!lkmR_N*NJ;tE^`?2 zb~n9bbGZ~&3FNv-wmF;K({tVDAYb2%?nWu>oJ=>#HmBP?J=g7b2>0@*on@tPvRfyG zr2@I#B-@;B_w-zM5ai37(Y;a%tCr~|+2(Y+r{}uUAm7-G?u$~G*E3GLNwzuN?&-Pi zTlk-=fn0wNVe)MrLW3GtV3>zssr3+QH+lG= zP(Ek{s2yz* znlo*j!DP_e4Abx@w8O)sh~Qj9c2OSwbak=8I>eHjEoFNYNJQ=cgImA1YT#B4+^T_F zHE@F((8=QOw(A5r?^UF8JWujDE1&mp?Bl(RKDjNNTf^q$$`@Scek4cpKO&mb6W;(? z?s!)gg9p2UG<7wN8m49U)G#x932JftV& z-6Vn1k^C_?c`i$FM4J&@|+7?A91koa$aG?VxV zD0ieIOJ?>!w_H z?Rp@+wVPNzbwIHlNPInz;t9DUKI=W_HO#$^Zc0P)6*BqCn~>*u@$|JQH`QUCRDSBy zJ8qzd(o*?b0+laazx*W2omf7Um-5R8(lxRGDbEsFJ#gI>|Dblj$ZK zxIKi#mq~R{E~|sO>*USTH>b;A(m`eGRDJEb;X0_S+}|8h8zV<~)#6$c)=Af#>apx5 z@}M;Jvc9|d25ETx`@ei``$^}951egR-ZyFxPUWwauudjN=_=l5=~e(KFDggMb@D>A z=qRnfl!o$Kc!M;go9-pYt|KSv+|2Ch1|+=-i6^9ZLTaOd5{3Y&?W-l!0p*U;R3MD< zCw)P$T)Q4A9m!|O$~El<@|1@1r?WRycU6$5a?*YTxwCt9B2V|wROp_*Pbbx~D3%-kT8XDfUVd&5U9+r@brdB!stG68KslBvkK~ApccmzvJ;a@A6UyZcnsNAXW zn?Uk%)BXWDxt>!hoft+xw0}WP9^W}qCx+3FI+*#ZqhrHi}n=AaXr+A0=nxcNOV^aL7u%567O|ECv*dGw_B38 z%knCRU*0xJmi7V2@w}*gt0g;mKF4JFjQ(3E=t1Ooe7!85!bb(i69^rEJtaT!T)x^( zzM?0S|N8cL;b#zcTwb34{QmL60uZ_8;>Y&DH|as-bmA}jS$9Xgql~<)JlX>uqWldw z3n|@0OW>!la-iH%7dHFvc5HEZJ;;vHayO$+B)VBQIbZx)1UqX)CMb}`>9XbjU z9nWW;TfJT0!t%LR{JS5y#vgV|Klu~a_#JNXd-piY@x08>^K;ktk(<6I@rPaWbB~{L zgZPS1ub=+68^rHAbp7;$rSy$bJ-FNV*`NgRdVC1nC;2JhTJ4 zPmXJPc|V|h?6 z@!danjhEjaNdK`fUE|&LhuxV-VvhQAk3Z1MHQv3wmIbnSetkB&wdXGVUE|&DTh_-_ zzkB|@dS5^Oso3ks+a|ikyZ4V}V_f6iuTP-GHQs%^++5%q?_R#5S+4Q!<(s&~HQqh{ z(I2_SyX#+5>l*KF-|?-k@$UKmvBNc9UOz_$B?;$2*J~di23JT(-9Jhk{f+JeUTWMnu6l3=DECt^#mk}v1?KE>zB#{#qPfr; zhqXXD_xx|13TsJ7M|1uElp|dm2eD@oDnC6V(Av=ToO?Z$39Va;-`bKTqOvK5FufEk zFRR=yOM=(EU7v~mU7qXSQ0LUE3&r~Z;n=qdbcS)ce+DbILeDOygJwS-Exdfzdg8hF z{?hwMv!cOidZ zP2-v#!q;ogteJXk{r9dGQ;hW%gt5o(KCTclkIy_F)>Qt}W2YJ};rllCa?6^C{1*rK zU(>OS71wnC#fJUQRXe3^LIC<`y{s>^0kn^7P;F*_dUL5L2-27mGedTtl2Gh^EGhxDw|&p(Z)~2 z(MOzyOe)DSSnS3^vrZ?ek;zOLUSKilv;pG{IYm~Zy>z(UP@tPI-k6)N&(py9Fu#(rfE=bIaUK|EzM{#@OpRV zEEY7m$Ye?=G~2C(rfU`WS|&GBerN4sPuJN#q-+0A+LMH{v!#V*!z45p!++Q~7}~6T z+5l>2Ce}C|m3$Ko&LOKyi=U7gpOA_s-L!q&uzpNgZCCzA* z=W8#u7&49K8HG|Sk;jSG$ZFM>;=?s_GFi>IW!J>Eo4IC*qxA*o3b`2m#P%W2lUkcB z%0<7$EmEG&;;z)~dWq5F?RtBWO|ITmzuxGQw`kn0pZ`%caPmS+;T)*NZ!Lv8L4lw+ z(A}W9pe3Mx*1e82?}K)Mj)1-g3BR`#I)R3OVnHK7Q$Ti5Ip`VC2GA~01L${<-yban z1xN`R21*BIgUq0NL6xAjpjyx=(0Ne1izovq4m1vw3wj8&0<;#i5mXO40}?K^6uN;z zKpCK1kQG!0dIYo*^a`jJR1Z1@x&ZR}v!&1j6ah9jFFW2Ra41 z0P^_@d4dLkhJi9bX3#^R<)Ag7cR_nV$3fqNE`xk7qy9icKq;VX&^*v$&~u;-pdFxk z&?(S=ms@<^nRgXk_j9!t+v=)yZBebI;$2UN21Y|;~xB}kRU$%IRs%vAZbf77aOgGW|{*|)LV`EY?C2g*d|F+rjzicw**t6 z&5)uu=fa>i-YAdEhEBvg)G{HOFc^dq?{v)bYbERe3@ z@LZvtER`AOh{cpB<338u>`pXValHzyrIQ42PlQf1SZ!!xNhOnn`@JWa^TkTebv(kL zFyeO)6R4K28LjtDH&_ddW_r43-2i_{&vUpBGO<(H4DLBV~g-OorXC! zwQ+NfA%Px!@PWmVp0bvnYP8u?&=7?@=t`t_Sn~{4u49W>CcEBhFS1Y*o+RW^2)hQX z8KC4Nlg5osO6BcZ=QU1mv>6!VLFX6lH2zZRbjzP>3U5Z2fo;5ptYqcKR)Q`=mY76ykiJ; zG!`Wk7N8lR#hTG=cDsd464p{kd_o#VN>4Nhi&zk0sOV>f??@ITqWvX{gC=tSgF>ip zIzpCVv?{RZt%mX9V=`oxd!{Cg(pwySI;9aim4P)W!H$-P8Z_pzP~kF3Ou(zuiG~?^ z^yt)t;W$8Z7p{6y0qbB)&<5>Kc!&*yYGhc^j2Y-?_fRn8g@j{%jhGoY#w^911=j%K;|CnCzKohe;*E8EIVQ zBTT+WG8(=(x(WrNKiP==C$c!H1lrB+VbDEa3>%G4qLNs=aGwi5NwD%7OQ5c#&oc-Q zQJsxR8b#%OTP$yyc+VL?;j;0c6^d$Zl{oS>7xg36jx54?&-m#YF_Un<7iq@Z9c_0f z<;yZlN9#p?YbZn-tf+kn!r!Eg3MdT*s60U}wzu)PX$yi%^p7*J)^|lnG{{Gee|08t zE8VRc_`g{LTkiH0R)NTUfxmtb>@NsOL-7sgf%xW}!BZrPJM*xoPzU-6^aE(ZBc8%{ zpz$4WF8@wJ=neG6$Bi41c4Dj`bjBz(0`UntoZUd!+qdIPKkzT4y$G6!_&Vfw1^%}{ z&AE>K1c6f#4rY8GB?v#$2bAHmHha2|e;+R)GR8~LgZ|KZ37vILOh!IFOTC2km0p79 zDlg&N=e-2YGhV{UJG_M_Vb?a;Wkz{#x#nx25y9U`QRF`>^Iw$tr6V)~$#{9N2=cd< z`SH0M(NTC8$^RYv--Esc{RN_fKEH!J5KkXgX$A5Dbp&++wF9*U(MyPTfXMX#-VP$Y z{iU$JzyMH3gwa_m`nETkx9F1aD}IO^I2trv3}xSso(jJbL}@tDMljhx&KuYgv=IJ9 zVu;f}8GJVxeTt^diA3oSH|Bw6fXJDEvp_Q?-U2KHnI*mmXb0IOz7$vjnj`T{%dOvA zHSn+1z%1FjdHD>xXAg-~uxTZA_ zt1T%oDX@u2i#wVDp+iCjC=9f^fd@j(fC=fz!Ri4D8~$=euHJ-G4VnR^2HOB_T-(;M zdYjEqkZmeeK!Mq&8Bk<3N857p4F!5zaDg$$T4*brVGqtJEQr?I3WgMi4p899-8jQw z<4Z{_H>gr5V(r!b||kmFikJVt&m$a@c-``z?w=TYG7S>O?auYZ)9*}WaK<`TJ(d_k43*3 z{d;uVnC&suu>qQ{ad*TGiVKZX#bw2n#Vw256t^udS{tvOs72y3%wqvFLW@Ill@lY5 zs~S~5snXO_)DK0ih}sbKVbnjOzKR+Yofthl`rYWA(LYCbj=3vlT+Er6Ut@lZeOI$n zb5!%IrhQy@=pPw3A#Q5idvUws_Q#!x`zg*#8>+oqYtX)nzX|vwr{b}<&nE0KZ~qV zCq!+EJ{0|B^!aF?n07IpVgh4^#3*A@Vn)ZL$K=P@VoGDai|G{GKQ=6OUhMkVld)|y zw`p$IjMR+POw~N9S*m$f^NHq&ra_YvcQ#I_V$TWvL)0OgL#Bq+gdbNnDt}ToM*I|^ ziyRTTO8t`hP4(5Nc_{VA(JeLj>yUV;X3sZ2g-i}z9{OVF7onF!JA@q%`#P+3xPN%h zaAmkI{P%DlWiMqvWwQ2=Fl}>fH z>P^*$s(RH?)mN%Bs@;)ys{5%!)bZ*G>S^kH^+W2%)K9CQQ=e0Ji3*I;MvaM@9+ewq zi7JX(6!m0ORn&`7Z$ur%^$CxThLv^Er*U=uj`oW2kLesUASNP47n2k-CT4cboR|YK zM`Ds=C&XG~?~kpBeJb{a*y`B#W9wo+jXf6oWo#GCP|Y8j<#8{fT^x#Qi2F9~*SL#u zt+m~>eYJtwFm1N>9<5M|Z)Kng5<}n ziTpY8QsmXh&gyT}t)kjR^@!>fRTi}b^|(4}UDVVVLrfvsPp-zSDbd`iU9NqR+G~R# zTmUQ$eJ%7z=r^H*!d8Wi4WANj4PS{?8ml~_{8|}{+`ftUEuyDNiF`^__o^1E9#K`O zmaA5()~Mc99abGz{if;=*+0@0`CR1Y$kUNt>VfLfYMXk6`a|`Xuq7yJeAE+B??;`E zx)jwex^J{PdQ^0F^qlC$(W`M)4@UdO#KW>T(YAZXPL5p~yF1oPw zV8mS!qavn9ltgSqE4~o%cZ83sy(&tjRVArLs>Z4&p+y^1CY4P!SG7P@j(S+3s#2|2 zy`y?xRjb;A+Gtc=PJs7iokJ=XfPRuVcqhs~4_SiDC`_-{$V?8uJnsyq6W)SLPi{@vvd;d5! zY9k}=nYef2w#L=ReIEBsTxaba7`J9=?b@-0&94Hp-65DN3W#qFjgmzghXQvR;`K zF+O5y#LNgwM6oy;lt(OysEl|fqAFrt#QKQ0B5ESGMC^#z6Hy;=B;sVmml0<$9$kp| zGeS_cRQahosA%K}Pz}OiNtG&AWmhdyy{LLyrAKReUcFXbtzNI*pl%s8GAb=9Jt`w= zT2ybehSi#_n!a%{DCMhh0v2&}C`bDcMM!#hUigFI%fjPvJ@1QHh(5D8q5`dXFtjUG zYUsZZ^?vlR=u^=@MGuL&JLX{;0~H?P-$ncX+Pm7Qs;YIpfUS~ZVv?d!Vqv19&X4su z*B2@(Di#(RCMGE+8Wk2M86_2_6(uGX85J2N86_2Ys4%fCv5SRfMM*_vsY!*3NlAL2 zweWP#IOpH}cgLtddl>A!*P8QvpRaea_Zd2xJGjy_N|kz6ea33^enx`)@8^z*NO4GRm4lTYN|@^|VPwYN4<8>UUx%CsH8xvzjIXS5J~GWz*yy;Ofze*x8a zME^y1jRa#dkb0F-h`W8m_}JKQd|~`)3=mObh)5LkMW(n(Jca&#Tl|ms6nr+wyxiPu z7FuiVsi?t2&LzO!F|Oj;Zh|`vOg-D3?=EsTxLdqhOb+rnJB$n_OGyWbU?ej=uelon*m00^K`?3ovUoe-V`xqpnpaX;J8>EA#ZGaVHPfoL z`q%_0@|Hc(x!ZZ%>E}+s4oK-iepY6acSs)~^dB^x)v#CjelE)eSj`wk!`gkUx9G>v zf&GjaLqQMDH0Fb!J~yJoDB+3}u|V7^o)?Ycs5mKNOm0pGU+*;~Yp6BCQZ3u>&^xS^ zR-v`t+F%{A3_HcX&B=F*+}-YXu9O`lRiXq&l50pVSwRZOW8^7PPF^D4lMAT~?wCuL z(|hP@x`u9}hv{+fa(5Qa64?SUMlpMx)v^A3D1QKzv4z+2<6!AO_!)F)cX^C50oOkY z*u7Wf+M`+tc;cisSWmzj#b6hUjcTLLXf~z*k;}y%alpRFNpfa7Sx$ko25S_D9lFNN zbXT~mUH_X<^Mia&3nu52%SZxQNq#0lvMV7RTCTpMMrbM8jnG9;X!TmV z)=TfJU!uq8BlWHNRB*{=W2l%Q-Vi&`yWfF7%FGeg6IP9N)Y^dWG7gfev6i9aax$5u zk_X5p(n3y?V)`203x-?BUSMytk614r$H()0{vdw`o%9*_?xZ{ySXHKMQR%vmcU)Hw5>5sIPe&3;TvX_O@(uY33io$XL~H3Mw1W;|i`go+i8Y}P zNAs2C9^a{o*UpDYltste*CT_7FSP9tD-4+m1aR zI^hcYYI~MF-@XkhVVP5kJKF42Ia{4?915Jd&dqQayV>p&-n!Ry;Y=FYLH3Xd=(0?# z`AHheGT2o-jW6Oq@zYT2qo8t^%PZxJl^DfQrYNaOPjD1h$D(RysSDL*YN7g^`T=%i z81`eFmaNUz4xnyB#HC`G=xgSic(2ATURlLjp|Q5|i{yNHym^To@UEjJ$j|->UC75N z_%{jmIcPWA2lXu!s@|oo&~G<>7sp*GK3Gb|uk;`?>ic%GnpBhBU0Xtr4M6A z_EL#mz{awfz|0M7H}LW|tXHtvC6WS^5 zG!*F`eWr1(aUHbs4d|Miv8NO`vlp!J1@`e<@q;)bJ~QvI?y~LyLOx(U3=O#6T3{c8 zj{DvI(++aFIp;aO(KUTo|-OWF2sVvyf5`*YTenf3EesSB~KfHaY3ikb`M7onO zasi1Xqp-%)$aFG;%p!Bh^<)8AL~bHWz)CmMU{riCe+)bMm^=cgF#@6FQgnl3Cc*hH zG*_Ez%o6iuvl*T;#hP#3jf(unI%IXXFSdu<)ShhT+ufW#&V|79`@xd+&L_@I?lM&6 zeeN&rDd?9FU%wDyqC5AKa`{d9sB%m>1wYZLp0AD8ENzlDLrd2dYY%7}v~uk|`2SG7 zH(2>reVHDxF0-at8?Eiu4_3g5f_BVuUUWWmOm`0IzQX;$ZE*LwO;C;p(E}mAetCtw zPPUPEfn!bNI5g845=IB0AI8$9^mX(zXLqv4*`MrUK8~N|Q{}nxoluI$N=GmEBQ)0tcSo=E-+pES`ZLtAhUADMpxMQ1NMIs1*$*mSQcj)*vZ)-ri!r0f)5L zZnl3y!lOC1bEWg7^Q_a$?dxMfh}4A3yozq6hv*n+&pq-h*lqo`(aHV0Rk+v zZnN&R)JIzPFFv-{-T}>^(?wMk8}dh8jzAZgz5<=bQ@X6{i~cQv(!qt8>ih z;fCRAhe4%LcaodrPIni&S-{9uZlSx@-Q-rn-|a%R>~#;pWgPSFt1d*UfY0awgzHO& zkvMSrB$5P-TS&5iY^z8iSqsfnNnV8uX&`&aA<{~YksdUR_NBvU9ME+VO`_B3LYhUF z&{eb$?qn0Kq_5Il$TRk0wOZ*hsKGGSmknca=;TQ(iA{&{%3@1^nT0^+O{|i=%672^ zILaaDG2Od>V?UmlCeTDrs zt1FR4Jg;t1Thybd*OO|vHb|QateK7Ox)YhrRydgt;AM`0kG$+j(S^PcZhIH z+M$$W!!R81)6GUX5~ph8O=M2Tjab2vRoEgGX~jD6w0KTbKsOx{gH5lZWFSR``3yYG z7PH#iXZEuCTNk0i##+n3?M-c;)<^HJU#`o#iS#a0zeQh% zeBuC-i5BCe(Gx3_D-Mbfvp3cy8A;PK=16Obb)U7_dc%6(s<8h+A~Oc}ycFqdushOy z$bHef$CePuqp@Km893R9)NvK9p@Z2~>=x9>6#fFAD8C_Z2RRV*9^gHx zt?RjS$sObgVBaU?6!KO|ucV9cD$hd49H76`e)t>fY3xSmpy${&u*pfrwOcft0Fk2c z5~JvRIuiUbLf)WEHEXROoi_N=SXT-U_*^_%`BaZEE;2?M!We7JGSZE^4Gun7ZymID z+s)2oxcC`RBXAwy;((Nm2SFx4D=dUE`v-KHr{yIm`Nxs>{Yp>adMKN~rm_@dDwQl8 zTy_b3+X~)Cj>0~uawhy*rSgWdNBIWHo=}e?d0edJAx+w%{efhyryc?RBM|p#dqBsVJDOlb-Ox3 zn~p^4Y5jdDluRQ6DfnV>zvyM%j*R&xd!;?sySLhtN&NcavKJd0B<^ zruDt`8@hCeJ=e|xFKn_eb~w;>sdL2n(@8{1lkfiOsY4uoNx~X*C*#QDz{MPv!@p3z zSAJIJA@{i-zIrp#&ySGp9mhWP*JFV*HTtvW!}c@Cf8Mh{wMRN_&<1C{^~?`Q1P?t( zA2O76s3&#P*omFmE=HOm);rd5YZSQkH#^K3g~a-lBNYYwK9TUw5wu3GRgNpm;Wq^O z@Ed(H&?z2wcenYc+1)C^UG;(g*=#R%PI&KC7VtH#P3}PAe3D**j<^>o^GopOq4HI7 znp`FKQU)O*x<_eOPs5XiYZt-COx0FsA8M^yvgZ-1x~}(EdaWF)zp4LZgdz2qDprWc z&Ew`0YbDr}J6}6bBE31{y=Ps(&)}knL1vTlp+T;v577;*19~|Q>2e-_mha+`z@AF^ zTcu6uqiX8aVv`tU4ztF4+MqGu`=2k74-QnL)hUK6CPBZh6c5@`OTgFhY2NR(1$-SJ zC*LbS2#r-IZ_qD+cEu?u|M_#21xl&%oU%uM7l~<*2o=4dv%5*Lc0oi0Dy`Fu|mh<1_-D1Dbj> zl8E=A>F1cAnukzX(~!m9jj2(8XNa@NS%HdHTo+y+D?_^Zdr?Q~$@xh92eQkV2B-Nb z|C0{@=cUNG$V!Tk-%U~GD~FU$WDw`8t?ISGCXjnY=>&R{mKI!n9zZV!(B8M(X-8@Z=~`)>n|v4?&W#RDVD(*1y${ z7|Eg=()Y*A7fj8Hw;r+z?Na+?D5Li=Nvc8?;AxFdodNDRD2v;W0zC>v(G0&NC3oEm zKC2PhVGhYA#pEh_9T0U95`kOboF^dh*(Xm^ep8{6kepQ-yTGd_jMK(J`wR3pZXzAu z1BZux$lUKyw`(V%jh?bLSvRAO{Mya#CY9pn8j$7ya;9E%Fcj?$?8Z3dI;4I7Oo_*- ziRu+b*)DT=|Os-ultb! zygn<#_uk>*HhYfrn2K}h2_!wpS=PI?P>d;#)_<-n?6wGpWJjhN6_$g$cDQ!E#?VyXG7nSrFVH}c5` zQ3tq~#;#rp&~P~dbG<0^BY|SF1b)`iwSR3$@H>&?7uSpYIx>4eJAqf!%!Kan09ERF$cRSopR9ScbTxK*>R0?`N zjie*N$|LzmSreg4lflKQERCfj^T~ul&1N|)7rH5*6|mLNszu0GOIRr@W96&@oL$AL zkq_4*arN%1!N0F2|IQBj_ttjq?j#=Ip*#$8(+D1k*=aPUOtC;ef+?!bElg4qkXtA5 zWK2_1ku|0B44%oekYwk;`Q#y)Ea0o5iHo3$OW=gccsVlvN?ygQF%7Tfb$ll@Tmx@J zQf;~MND~v?WH-f4b<>b=Wx@qyLs8~|y$aw3iriwi#4U5n;T|iYZ}4}`*uGleP%~*$ zJJ17?7C;w-0sSMiNG%GT5TnInszH!wmFQ*XCNI_Cw61+=&>JzGYJ!4p@%N}56Dr9F z7~W1vW&l}J80NGQW+c+kXfp=0>^PG^9qOiqxorZb+DWDqjlW;UbyPvM{PT6|_5Xb3 zR?LUn^^Sjg{ct1VTrI?$s|NX8JtUl~2yZr&ajqhApoQ`<3oS5KV_MNwAEihj%8@Kq z;sii7JY+2peWy{6gr*Ubj3(saEyh7)j;%%;dZPn5g(L#tk1%8^X(AoCpXt>e+NWe0md4?~6&LkO`*BC0PP4l5URS42ul1r%=`bVL(52qoW1 zLTLnzhP%=+^GT*@NFsA+KD<>4EvHq$`g*z_>b@0OYXHfA6pLjtCYVX6-3-)h9%{81 zHJXe{%0va_qjE}6F;%FPdQ?aYZ{;04fR2m8WLcKu;(ZpMj#R;09@$Z5lr2uzn_ zFfo!9OG&`YCxAM8gEEeSHjaZwv7nHX zfGcTGmsxs_o~IY+h2XnVpi3octrob_@YihBtK0ypHUj7p18f1dVJ?z{`C=MsC=1ip zJk(AhaHSMAQ;B-1MXfZTPMT38t*DPq`1~*tf!S9KI9f*LmLQTa6-q;$WQiP+Ckp&b zq7)fGrKkqZ?i3A3v76zUT17ipFMw`|K&Ql@OJsCN0=gsRT;`Hv=9vX%p;>H}n&oCC z+-5B_Y=gNU`P4zP)oeGVND;KQii4peR^sx}f6idaG5XyY-T zONOgWM-6Agx8>vfLXjvzGFXAcq(;=?q(vhpD=p%%Xv361LNAA-kE7AU1pOP2-c2@B z&2-GTvdvti+pEnY)S2~WquFG(;0#Th*#YMfYK6mnL|d^IvGAP{R-%;* zFOqI$TG>`E)RM;-CE$w+s|ra-9nNhuA`NM=4qI(j2ef%89CRdR+Oe45>2^Fa{$xAV zPPa4dY-E-B_G-JxF0sq(3cJd#vFq%5yU}h!dU6;}yTg{8P$%4pM8X*B5Pue)h)g9F zXN5AIY$q2dhF0UGK#5a^bfpR>2I`RKH9Ac=IdB+$u)~quP&XWBMWW#hiK_!^6M?j; zZaPpl8yK69$ykw(t`%+-aG(ySff|v{wEzp+z(K%)bbPJ^9wZWqNlGLpDY3u=ox}qb zlEF#oBoq267o4;j*ib^sfDTop2Ka#IWOw&<#)sk~qz|77DIcFLf&cw~?;Z~;6xcfoqUVc9H;%!clvP!gVo2=}=)27KzVXcmw!4}9sdyRI`9)sXmtF!p#=| z$*OUd$ip!2G)RXQ4)lseI;HE$z7ERQSNn)n38bnA$9gKL4Js%a2<7dbhff(kt9htY z1}3ZXS*y+GssNBkD#Pb)U{9K%w<4iF60knmP!?XwRs{vo%n$Q$nP5U2FDJ^$V1sm= z?I;NU7K@mhU9XcQvI<>~vrH5H4v}PiDA{Q#4hBtxxBeByd*yUWg zM6SVXwnL7@36@msZwYp{2~{15olRA9v7x1`d#OK-IApq1&0jiWkH?@;!D5Z22cCW%X!NF|g6MU1#dMqHY>OoDNY(z>;% zOSROcv_;caD=tk!T@n;6ZM9XulO`qZp{aSl-+g8xAyl7#f6wzi?;D?wHGA*1_S*Zb zz4qE`uf5Mn=qrm=ZYq^ZjsJGLN|lOV{tFQB$w1?xQdO?^d1ckE^2h3@y7WF)|7FwY z$vzX~CX9+3HqK}Gu<_$3#QVHD(kIS5-e>f9pYDCbea1}~F|tLaN);M9Sl9lz!u!#u zM%;4#|Gn?BTan2B-gm{VhT?bmtswl4w2itMB7TS7>?3}M-Aux-<@p`A2I4pR)W}=U z;`bZdu$$rHcf`#h_&sV{b&J2>*kVM!-{|2cw)OCn84W5`Zx@YfSMQkvoVbfB*ZLJ* zDyvj&+*PU#cv$>vUL8P>|3;KC#k8wRC2~kQe^o6ticnGJrV2o15R$g&SIJHs?V(D? z0Ay|OP#KB7=%MP!!Fc#zzK5#t1=M-YL)HFaT(Nuz@Bzj0s&yW!EcEYj|60V4oEi`0 z_15S)`^RT}sC^%mYG{kN5yRq#sZ?$2;8FPOb@AK2=xGJ}0H{q1g-jLii=v4hDpd{q zM&P&DzW|jgt;J}CFu4j4=%cDCe#bsS7tmr<%;*u5RjOaur!?T%WKt<~En5zc8HKK+ zTdFMJ`OL|s(8W!T8xE9^F=Q?H%`J^?rl492Q}8uMA<7z z0B*@B8~qtlb-w`O*=?w?y*5(ik^vTf3dG)@K=SQGq`ECZS*zJdo$rjYU4I~TdM-FG z?FG=KC$P&7Beh{T5Fc(s_OoqB`F{)IZ{`AQ2m!YLhd?x(3q-0FWkxqN*}pQ%{$NAb zB#`vf1H5_~*|%x{oI4EcnLhyL4na2j3xKKYrXT3tl8(|UlJTfi!BEWmCLAR<0N z*@V|rc$jf$?P3>X7u*Bqi{Bu%VgynX_5d8(fb8jBs8;hZzygZIvW9 z80;s>OP?T>_y$1BH_(RO71-zQqDD+>WRHG^)Pz?6B4L1|=?M}uv*F8u zz26ntEz5y8N$_VKfKC?y-lq!mN&$AjIuM_F8>zOGL6<*}O3MYw#&Jl6QgjPy1BA~* zpAY?r)Yg*#f2}~ZEo+eKN0NNd1E}v+e}w zYC&1cw~+d4JcL*)9n~s^01TnT*AE1uCP!-~d!L?$hjCqnR4#!S@)&u*~TCh(#gY1zP0gNp{5-G&|c4{K(HcUfm)p#J@ZV#~KAc!0P3gRS+IGNQVQh*pY0AT-SlvO=})I1qn zepv*tv<_-q?+aEh?*&4`p*=YVW#OBV^%{yA8~+06-xLUcKJS>($j+aDY&yZ}9;iEj zvux62q~4`baHS;M)(73SNkH^8fS=)al&PWtsvHE}i(WuXOhOO-bB1lOY{M9&I_v>r zI=A8m)PCK+^7!co80N5}I4AN&Kb@>1gdp`z<>kWRx&x3eeFjD(3fkCY` zKtzRs*mV@LM@&GBv_RR3&LF;33uQHAq^?pzdp-qr4NZo9 zC9(rq_E9{r_8I^$VDZekaRYTfyaG_C0l=0TD4RvuXLkUo8H^fPl#p!&5QjN6{F9I! z{2hArh7GBoE$G^Ze5|@&06!iENE?N+X(v#(st>ZstC7u}0I>8J7z`bXy1$G--5x`c ztxBb7MUq+zQ1;e()ELW=mNz52fhMgX4T`-jz>qzlyU2O;Y$3p}wAoSZk$Pt`5D_Hl zG#xcM{s}~-d}OCiMe2tJ=u0*&YlHb{e8(!3HQxkK@hXUW9|B!(+Hu<=q+U1%#QAZc zn@|(kYvobxwTZ~K+5zG!g8&j~krs~z*k6e3ob4cSVc7_>51=)3&jF%;I+!k@j%WUW zZ1^r@N4<}f+gm96=1tI5XpPjJkAcV}t6)A`Zz{v4nPB?H2LNGKfS8NGj)sqyQ}7Y0 zji;;@-v;6|r*oroz)smtlKDV*9Y@*WX#ibl9e+$i*$)i?e)|mBkLw|oycJmM1b`h~ zz@_hEfEpCjv~wu?>P^rMegmmv?}PXR$E~3Y8E~2!&wy^?+sO7LmrexLjshHt$8*%> zBKM&dpa~Ig`U9kLE~J@JR(C&0Cea-Jo`zJVZ-DUU^VVY4*y%9h@*UR_vP$PxY z`5Sj4xTOBdflo0Z^(kk{iGx6Fup!$f4&eDk0DiQhjdlXDZ!Q@0z1L0cxxr3*y6@K+X!rS zX#m2DnmC62>r8R}lnT1R#MXKfAe-}T2(^9gTr{-4BgzKO1p^bMc40Z{PO1cwf<$Cr z91N`cPLx%m>_6#)GGiLby0d?q-asmUJP_KCk?qm|{Nmn5>c>$4-QgJL+@U1B>8}|m z`w!nk*)q<{J$Y!dwI5Q#k7(Q*i1qIx``2k8)OC=$wgolD!z0e=QGhmfbplC^=_val z0-)Ak$bMcEP1dAM?9H{dSpur9p8-&lYx16bDC_ho7>xc2WfrEi8-bY51vg*`$_!(W z>RuZl#v7pdNtSIyYC;g`MpJjUEJo@#n&B0Pk*&lIReBd?7s=(T>Bu&lfz)z;keuoa z&^QZR=DrTlVJ8r0j{uD3qlU>y9pJ3E5QCKK0rdVJhins7elo51sOrcr%?I%{K1_Kw zIpPvPULX)j?8^(8$WF@!wm}NACn)=0X>Q(RuL^$ys}O3Ap9x?vJ)Wl9k?J-Dt&QFY z?1}FIM!W*Vs!b>xeg<`aq^mo79l)Eh02zBwqvY-n|qz0((EKbXPlDE+GsxiEX?pv?7S zU|(1VL`AZy9D!;c^y=sP0z`0yIK?TsoJRFqs;D=G{U+Vof)U_SpN}w~ewcL#%6{VD zed~i%udk7MZ#GCK@&V^?=C$P1XjT;nFOHULD}bisfJj;k#9BSFJ?TAsJq3+7>VdMc z^j__Qz@=S3R2x7SdvZh6xK|z7Jv4_0I3ZSYhtXyPfa{MSZnF}Iu~(2iP2HV9Rmq)( z?5L&S{1JzH^-PonBmi7J4#YlMkVeejnFW5+rUOJzLqm1P0WoPg5Fy+aR2v4+`5eGq zKK>F;PJbPMcX#&r2+Gp9&~Iss?6G{L7SUsD-y9^av`rJ)p=JAloj`k9dl0fd<&gS0 z2H;OKvNJgwt;xtrJb??y z?B}llQL!6Rq3?s~0t(hv6QIl2K;*`N%f2^&s6s0mGalJBTqa%$LrToIKHQQG=VqlD z5tl-dU7C!nEA{!MIjGjpin6}+JNumEbFhn<#et#IsCa8e*V0W)jRcgG7vezl`y;PqFj$m|ul)c8*A}NwZT!g2vZq^5=(VwRI z*C`iJ%G!8AjuvHk|Ub{T5uRu)Yx0p=Y3*EahYB50zSZOkT+5yn6B|zRz zV7m?mgR4~lvdA=p<*%ADmBd12dDY#Zm0%W}&PvdwR4j zNIt!dYVXlr>0Sc%$YNk)s{-4*4_JLT7OB7b1E^jHSYH`*SFfPPI=Y-cdVhg+TOXC+)M4?MOXX z`3}IMAz`UPaVDs7C%TXXHNAs#14aD=5pP>rM*0URJ7oo-~hA~pN zB6~a?+1_K2JuZVdmAi!3Xs>GjfNT$TV=Fhtv0T(Q`vSDEp=|eLq&9HFHifR=b-FI8 z6_Bbw=-MAt zvx9u-6CCNyF(`{;+1>G|_Vy5zg>^tSw<s6 z1Mq$qTn4IujX#L&T5d+Sv2K@d0nB=o_1*w%gHM5&F$_RWBe=975YHZiB;U#eU0p7G zZ_y~U<;q#JHNaiY+JLp_%Tg*s4=u_*-Hx*F$|JQs1Yq`V@SAoNWgbyrm3aVV0q=vj z6BicY^-Z0HvOJpl*mVFu(U7g0gBrWPM`~0hq{dL3BWda{Q2*YbIB(qrC{MqA-VT71 z$!O>sF0Mb*^4BD*IyX_{c`dNdMj>mUF(2>=utPbt1(a1Y?)Q68&hxn`Y)%7u(*Q)a z2B3uxvcH!@>Il6SGxq_%Fg|3Uc7DP@z{eEMyWBzcrC^_>DlfW+vVeGS`=AS*jBF#uGNLn(TE?zb<)n*04{TyzfOT_G){3^X?dw2H z)dO^h1A_r=fgMfjW8}{8G{scm8z44p0Qj1l0bN57Z()RQ1TD?BbIA7PfZn15l+gh- zI+O?YIDPN0xsxlHic~XpH@E@7kJ~|~;}jo9lbgd`Y7^=~K{Qewxqc*YU9HD$Zl#JK ziQ$@DFBGg6MFR0FBSmr4UBf=4Quz40IGL)`PYmk>_Hze=?pyYGpaErfUPS6DEx%s@ zK>Ju=*D?D`0I;sKz%kz=Tkbt@SuhD6{$&! zP;D&3HXl&O7e#=x5BZ(q^KSG5-E{82JEej|<`hrk@Whdyu`58~DPV)+0ph7hRlNb` zehiX84qi0vOX^0H<;?(tUpWVTjw8EsCsOTcjM_8w_X$0KUQN(vAqfB0DEn?b%HHEF zdx=)Sn-lCJM9vdOPawr^}f@CoqbRQt*6~eau1ricd6S0#fH_CwFn@HH{#j7VZYO<|)j6 zaR+qTUMPEeB2qye0iIb3?BsWlYEETsLe8f-vDYpGi1-*CD&&%?rAX{w0xVzv=eKW= z8bhgB3ed@;+{|xSfwD!jP$qFY|0fKf(gb8Tv8)HzimTg@>dv*N+BksW9Qe3FC|i9N z4GsPi;M895>qLKJT3@7YCIGxiX*8pgwUA&Pdr*VkT$KS}aG@7chl2q+jRm+k4&akp z0ChPRK01q3-=5@m2ds8oKv|dPknPLi(Qp-arJY>(5mIw0uy*xOW5=IJjpDjGEE8b$ zGE|#03ZQ>eWM_{D_@0tH(Gq2yHK?Okvk9 zyCe1W8Gy^=(rN+d;uAp9@D$2k+<-Dy#@9ZQkj)^;#dp!h=~2j@pi37czPsKhBrXB^L5b0JcsNWZUuj)f1k;9;gt^n z4$emQi}yg1ITK(UcOpCJJ1*adx*xLLwOnUj+6nC1a;PzFHxSFIz@ISQ8QL0UpK*Jb z8G%$N&B#o8($8|FQy3x04gsjV2qcw;5L*?gDRoiyCyka1cTavE4uCdyCwCE;+xh5bY8Lc?{EV2!HfcWDNk^P+qX$MxLEP+Eie+K%pg?7C4Vt~QD zft_6+sW-^wb=r;aSxD($L+X$(z;|Quyb`6c&xEW8yB5(C*;%w<*J&B*u<@m&>&6H@@j%mfTTRvY1?6B`*PX7$n_(a#^akN0G?j~@xB&i!#9AgFQvO~B+AOssNN=*cE15@ zq|JVo3qgJQAhT&PKVq*wpcN?KYH))pdNv4%L5%6!nju?}{EXMYWw{z{_TTwY=L_&*#x-BP61aejnakTSgmk}9<0 zp4>hpaXHy?0Srda#$M+P2&N_ch>qru9ME$EQDbaVfJ<~CVrBqLJOQwUx^{$K_ziaa zMiNrJ=&FU%w9^(Q;oo-^vQFFE%^-8t+=z2U%SP<>oEyG=yox*_{DcW9lt z(Dw{RS)&z5`3ynX>zoUVdm{VEYS7ghf$WGvJj^ma%yN1`mwKbdS2KXUeh{g<1>hXk z7@!vAyzeT?7Vbf639-|u@>l93<;TX8XvagD>gxhAUW*e<(RjO`9nJ?S8$tm8i3$yIsSkmpMC7jRDOI5Dt$J~$# zr+=R@6xp#Ikvdud>~r@c8%>gltk!2ZfL}kb>Ppl186#OQ{0X{7Q;}^y1Hevg+C<_n zY3uGa1$cb|vURxO_<0Sm^+q8zl`hWvT=UKh2l#9;NCG(bPg{^ZNn1Rdaj9eUeB*im zd!R9};e3vzvq92k9kLRi_a;x%&T=Mye+8+gTR?J&OW+0WSKsIMCX0Q}r3>*qr|BXt zEaOxtdu0i#{mS_6?fXbcv?}*$Ec+fs>US>rRVv~spW*0l>xydA>ENE3iR{rvAaSJ= z_y-^Q2W~ia*FdUp3aTCFx>}2#+ZCEauR+Lmnu$~ovg$@f-&hOTm2Ht7GXUAG(?F8W zvFy&6^j0ne9XT(jcSm;8OGx!whSWHk^)7wDSssLHt5~-mJ(>Bew*LsS?{r7qy^LV| z&P8d%JfyBo0`?6)?=c2Kmv08$yb&l%=ImbD9@)l!0UJ)?bfP1?eLp}f1$*&%)M!{8 zsQ^|}a~NlF2At*mIKs_EVJ?V2xQkwSeTLMB4FSG4BYUDXQmHopI&o#HNA^E(4|c05 z+U-rm?&|;(r~+@MA@vM>@84-Ld(+`dW>B`953p-F0Kd?I45Y2wMOU{fou{sJO*e5V zsz!HkA$NGObfT)&-vX?mbHyKe@<44eiaX}ly z=@Q!yWgmZwvgf&3`ICZO&azC-ydCwCs{0L6of!iSLwau=TmT|GK1mT4?Ijnr?{(>+N5nJ)u;N&DQT zDd-l>1okfj_<8Z6XAK4-IuWfkrkpqOY&)Djh@PzGa6i3=M=1r2dU3!3dG(ypAtX8siFT8#M74nJVX1O$j49SE}_ywWG{1q9bx0Hi&6Gz zCbC_>1(X!Dj&@@kPsrofqBR4ny+zeK#{=JFuCP0rAUk3tQVl1gZ1t;r zzz}51{fcbjXUNv&EvX2O(LSohG(E5b$;Cu2jktEdy%5=~e58DXP~$57tJxN$e&lXv z7LCV8i74~r^qWERdf*eJ=DdcoPV%fEw<10X}B-1A_8@Ae%x1zm;}v+&NUcpO37%27nhE za!E((naW7DV~wsdve&yH6+&(Ljyg1l9`}4LNnQkl!&QKg2BWMC7nYH9CEL@lb0ve@ z>ybLU0mQ*Cq2n#NLH(IF?70tts79lIhS__RP+>Sos^j8fPU~Hu%Qc~z2SI%rx27FX z_S{)ucSa)nCfV0%4+cYMs#;Mb!|s823YFp8=}1-J!Pl#=qna0|(9{@|`3*&CBYX8G z&FgknTfvomCd)2w02r_rh=%o$y4f2w>b;CqO|CfaB_LIoM(cDk5NXNae1Tr`s%U^a z)UdbcQ?K^~ST+VEn>l+XEkupaI2290qeIPxA=~LoWM>2cbSwbp{AhsPbwKRLz0kK& zKy;!N@Ov3$29|lu2Cy*lKD-~eBuxgkGdF-Y88iCv1hD-mVy^&{&E!%vhBG;as@!}5 zh}*pnR+}n-ZdoW0{*?f(aOqu2fn9tRDX&%lX}5tmu@zu$8)T1@^HmPdDo@spLs@!D zWc7EEJv;~5ew=wLs9YKf``Q(NReZMRrl83=T=(m7Ybo(5?{OIY!;y+4wh7(+_r3;6 z?~TZM(CZuW3c#8mJk08aNLe{h9Mln=%k2ft>&v zj6k((Ly&r%4IN>JR#LF7SeEiRQe&uB(`e>mP9XI%6@48MxitTOQGQ*k0C@j`vW^^u zJT5Fg+(O;F1Mt=~fIHOjI64!H=tcJE4^W>r;^;>JRmOv49(zBr21w@LMz5kPpsWh} zGL>g1XUX|R-gFwneadT-KsVziYIt`-S$YCe3A79y*-$?!Tz_tOFLC+2LIvqQ6{*6G zAnr(ex`o<#G83$B(?fZQi~rgffDkUxZY2JdYhDX(rdrMhVg!47m1X5uqne&$)RY=K z>?Ndv2cWfCoH#vchw4$pb#@{ZL+@)0=Vfgwe*&K^k4||xI^g>8z^#B5Z|#dR znO?>+cBqygKnNG%wl~-YO+gGTL$lLJZTk&nQ@H@`WA;}r9p4lDMzuYVkJR+3zXKmVD~%+RCDSr>9e45F|6b}Yb5 z#xhQFRy?1C>~&7|KRSa;TZYiPF+0NCaPi_OeAgYR*e*aczKYc66!DA$$kyW) zD)48da_CmPeF2CK*Fh4)rMC}9Yt=JIeRUtH4zGe_1|R>+L!fIr0AMf|(zGNnn9X&6 zZWO?2I`oniU?PX&v=>rm-a+d2d%$k1jO-xFej%S|26vU!$?E+HC~F#p)>eWqxMXv(P zrHxoI6yO(5k{$I>dgX}z_Z15)a;430ebNfzA_`Fq4}4ovBTa*_L?i| zzFQMzOTGljbcR&cyawz&|8r0R7L zujGyfHJC*giA)=+`&YX-Is9Y$G8 z8j4L{A=NtubpM%v)JrQ-RyP%?Q+xy~xoipnb}zNv=Q)6{f{>jX2himxy1O(APc-cc zvR%39w~;{`re5HfdoKmaZbsGG4F$MNg&RXbOuhg_U1Do}3Xn{TK7i?Xwvrn{;FET!jRqGRoI71_iwXlN6GH}`7oEqLg1 zT%HzP1<7lQMMLV2@jo zlDP(?&qXTE6WF@kLGB}i<^2IRe28jwI|Fff8bC6qLCrHDd5*2^;9mEQssJ7Of%xia zASRMaF1bvp0`NH<+)Cjn8#fqPwHH7oDtbX6dKJ(YVC@ha^JekI=1Kn6gs3a~==RZc-2wKcA4*UdPfR)soJAUA@V27KEZ{3vrE0aK(1j-~( zCV?^ulu4jW0%Z~?lR%jS$|O)Gfiek{NuW#uWfCZpK$!%}Bv2-SG6|GPpiBZ~5-5{E znFPutP$q#g36x2oOaf&RD3d^$1j-~(CV?^ulu4jW0%Z~?lR%jS$|O)Gfiek{NuW#u zWfCZpK$!#{l0bhcFHGvMkH|3KgF`A+jO8VjS?!mWTSGcvo9G&|I7ZS~(p+Ow4x4ZJ zre_yOp;}`9%Wz$-@JZ@_1#R4TOTXbJ6#a;14olBW|9rbtQ10DVjcU3_inge}Z9Mpq9n#>Yr5mi>6XG(6vt?7KE~ zEh$>>e=ea(hak`R2C*(iJkYJpc6)MKe04Tsjn)@$LOUSV9;>pOwIHkZp4}c}=|cG( zhWtbukY5S@VUZwI2?0r=H%C}2@hJuli5~QH(kexO4;3l$oc7<6XE9+?lAg*_mV8FZ zpoa{l0KMD(hXlE8(-Q<)B)Vq=Q(e7Tluc>!OIvTZD`M9}nyded(mZ-pk>~jb^0ee> zBOcMu*oF=bmFs;D<QJkjvS)<>J+UJ&K3w}#5;hC
    lf*|+WXTvxx_l0gF^>qIq__<^20<(w+666n9wU*ne+AzgcTuDZu`a5Y!; zI~>*zQe4A+r$kd{Bvbgk4?V@=dp4TUN8cy+!#SS=-Kk!%od`Nl3C%-8J?R-3C!9?}WB z9+@GUUS+ST-W1yBxmBHKicE zCCw$ij$4{BB2xA|$j)kWD^u$vcdJK+yU@oVy){@5J+KCQmNNL2IQT<2`cyQ(v?0`h zr_?$0AM2gor)a%{Jt=L)vyRM{uEB;txupWj36I(K`*!=xDQc-8_cM~QMKPaKiM2*y6mZG%Q{&LFs__~xF7QM~>szjd7g!rX7EtB#fVt$%6 zv+r|+69#pdm+x~}QQSQmK` ztl0yil-uU2mTB;5Ch6l`rSg7hDYs*+F5m!V)~HN}ut3S9cKkC@l3$#g= znR712s+~GSbWZ3?l9GPn2%~*yJls1qCuk=-rRMLJ)`@@HGp>Oxq=A3tl$K$#>0``} zOf1_N&&IaE29}E#ts#Z1Vw8IWM@*V|Z>~A>AR# zbMmwO=s~^%Hvx4a!-I;2L)RRQ?k8sp~=#oadhKCQ4`gmII(l!a7-@hQPt&*()Q*}mp7XOSX^^4KK zRrf8Bj%V8=Bji`H3Mwju!H^DMfbL{*2sT01;WlqE25)c-{^VrS&3lVu5bZg+cE50p zL2cAV6&S=x#bkfpd>vba2eKc8#X(tTVag!;L5_6;Im+Hs$UaCPDWv{7SURPSeTGx& z1Eh3Rr$9T3@HU=R4$G%OUT6Se_v4F%BiJEDXr?#|T+bL8k#h z?l`I{c05eZ0w<^XmSQxD)OV^w2b}8b_QAg=O~?}VAb~!d_=H~U=u*m2$f8ry)bBNM64^^ zx|T434wp;*2A0rLV8^B}W%o7MK4glL5~M!6iTNhiB)_!V@}n z*j7V+#Dgdhgl01=G@5)Cs`Rn$4nbSZ$r%O;MP;wPc%6qH%XBl-RO}>To0vA@M_%?3 zq6JM%hmbaD2BRPxR>*S5OFoA+&Td|4Gn_NZ_&U1^4W)r8H|R#WAxysI5W+`!aFN~U z&Q%Jqg`P9o&FAErHoM&qq2roiQbW=bCELItItO_ zsTva_Y=+IIiL59Gya6j?V$x<BZb`xZwGI z$K*{|MjoS(CDs35&p{vHFX^$y--Q7jE(K#i;|F7|_-Dqs*+T4=nPM;EfdxLp)+S^z zh-z_5^NsG)8oGJ`s+bP?crQdOEjcdc8`25+70A^;Kfbo*ifisEQQ1}M;(I6ie$hHK zB-)Z`7c0`!JPhZ%%~0r6LZ{AQ6JRK$#7d}MZ8*;*RPP*ORaCtwEcB(f2L7oUAB^L9 z#L9|hK_T5UTj5W3J2$f?IAb24 zrQ=1RVs|;sitY%@2gmd=Jf%R5a{@T`6No2ipFUo#H};EF$zw zbln_$dQIhaT?*IuX8Rq^z9${XmVFD{4*1{Gb<0GxZr7x5BCO_{@-8f>Qbnl%J@>t4 zO)Q8Aic)J?;TF--bKHVV}!kPJ76*wlg6ZW^0+8`WCxGFc7JK&fj|Pk|~mMWnWb`2NQk$RF!P z)`Rup3GtJ=*2KKnq6ImHhZa#95u8OxwpPiIY=(OXI&6*BisCVFOL97Z&=>IQlgz)^Zk6P)Jh-&%YfMxsL z)&F{YHQlF`V5h75uN8FH=8nNN4?jdLj{w=UFM=KO??A?dKD?88p6sX4`FQ zY{3UT&C!k+YxI}?SeDoX``zCEd%Z~83~y_Ht*!6<7;7sj|IUxeCw1NPb@h@lDO9S| zW2k1yalLbS|L<-#^&4(!zWG?8u3OStA~u1D#gFa#YvU_|BDFclQ6^v`AZ$qe+}cK~XC73zwt0xy-a&b+xIj5WzX=p!A&(froUk;sNt_ zT=Gu%W@g{DR_0>XXNYxT`==Te(Z1$0Z^%w`0!Ix8Psy8g=JG+79JS@X$7@#+HA-w8 zxlaQU-}}T8aZwi|sSVzkBQaK2%K=x*RTuNGLl}l}MPGcgP?UYIXLLq@IG3{;y&f-u z5;g$+!F;Y&zbGCW_JrfVL`?==E>%V_T^;njQy6pItkF+vD2-GHdb2`pU32zxtOg}tcF0QTaTg4LtARAiKx@LW+#JkvkP z;Q1|i-ZsM}HYuNET&F(_twyI;Ng-akDy}zlNdX8>#OTg+)mwXd{as^6!?eH68N2j$7}1Ww5c-$O^BPn+) z4#9%d)?kekq_GBTZ9&?MK;^VO5dI%FDKXY6a)o5-qtdq_B|G<22Vsi7%rCAlkDP7_ zb>Z*_sWBOhwjhnet1~J`dh(a+#Ga$Xc#GCGk8|sahF*F8YjAf8?bY|fi_Hk~;=^Ho z6+|P2BSIhLr=jxGkrp5$s6BHr)}SWVAY4LtS=osN1z3Yj89`$mxdGO>vq(HQ8PHKS zQE@n*dctOK@5bKX8>sk~5$G-24-}n@u?A|afh{uv+bG-veXM~Y8G*eWx%Sq;p&5ZA z966&SB3|_9r6#!9FMj^G6}nX{6z-U`aZh)6fEMhn?9~rJtj-6PdN9Q8E{-gU3XAo` z*}mR!{%ONPg!XlKcEk@bIzsj0JS6w%bd~C0y1VM}XP;ynAx%=l+iDbPIRQO|I~Alh z*Oc6)PiN0E*XiM9`g^XTm5gAPe9*#A|Gg>CGIJueL7LnIMWE3mJQcx>Id z*g-Q85FtOOke0#@{ULo-(9fR(x6BkF-+rOX%a_rg(#%IGZDzP!!sLI@5I4e7u(vHiQ~XG285ur$_eC6m!3C5OD02#> zd`gi}sw&T!;lTz<6SWXJ`Y+GIBS}F%j-W>$t8nZ2#OdMcDX)&*O1 zr;V~tQK#eD1#!E8vsd2?_}IN(PRQC4TNb6i7a#QZ(aRswwORN+w7Hh)&;)FG;t)%e zD&xG!vfmqz@(bb*#UACc?K)+YlZkMkGlO5H{b!#o@{dY!kDwv*XyR-M6N@X!#OY5| z5?jK6hYnV|{9T2BhbmP5y9!Mns_?_KCw2+r*0&+bf81nQI_Ynq6DOL7j@lg8et}GI0t4XB%J)+FKE0n=A zfWH;IA|Kgs*KQ{-u<(hHS2$Rd;s!rhU6qv`{(=^3SLj3PzYz~y%6#$UxirKI@ye~0 zMxqb$kknCD*I8CVro}VpFCuwRIO(ozus~exq;pcF+V@Pqh;aE9Y_X(+6ORSe_geOS zbXJcEoNN9csVKZL2wA?IgqIoq4qtHU4TQW7kz7l zf5AW@;(-SdCfpy_)VH%+cDCK`Fan3N?>V;&|DPBiJfiECEgkPC|AL*UI2Kl`lpXF~ z97_~`v{KVl-WoU!>PG+MfN~9@_U!}p%x$Euh5iR7x5iffo;t3jZ72U@uehtGnO#T@smd4hf)th<_Y;U_UK+BZ|WQ`A|)?>$n8X9hhM=Zr553yCj3B)v!%6cnOc!YS@`! z*vOvBYhM>qvKscnZ>}t5%2gLZr01-L)ZB7@=dDqx)~Iy|$T^%NDZta(&BtcgYn1U< z9PnVcUlyyf^=gRYBNw?bT^SE0^742fPzgjHIIr6&j`j9ZI(G9m6zsAYb{XYQ;J@N1 zhQamJSQTh1*!puGa|Br>M<*xX{y9 zzmjKb*CvA1!4l5NAmwze2etgEHKb_j{8ti+{&_Vh@-HoUUZuF0HiPWA;cS#=h>e6= zVo@Q*irK6;d5wnpf5HXFAXAUbT1+@Ztqd1343|iiVYt93nz&eCxX4(W&2YhJYKcE* zYEofzO)4LRKV9UZ zs^Au0)e^qKzu*o+K4B4z-p9Jc;t|C2+N&RBxAGDFE$Y<;_A1KJD@@dukMZ=u5A)c0 zr1fav5ct`+yN6vi$l_{ku4jH$3Mur@ob2Pf-%_BCt7|D}kWg3JZ~ zPWY4Ds`zJM@I2*12m^4sl-yGztUVQrmI!bQ#l~RdVYWI31ApHMgYmPnqG2du_Fz^o zImToB<8|ywPmSjh!Ca}2-ak~Mn==I?$^)YQd||}@fNl={SQhSyq)Or&JFAv9(m$8tR$bBIUgK zj}rIt9M|&Tsv*!0hY?;IoJi)ZW^w)Bao-u22oaF?JrM7WYcg1MZE7QqSYN_M!YH3v z3Tww`J|C+fsM!-MIrfm;5&Cz}ZsfHDg)?btBW;J7YG>n|V(O_1C=y6}(PeV1E zIs`xPA&o|PCfMfsiHo$@vWQzdB`e{=rlV3|QKgsh?C6NFuFk82ct$Pm4$>c09+G*- zy$3xMo0pQBB1)~K>M>ed0>Tz6z~8>&jmNnP@9P`~F^=r|c>3=*zYx&rKK7LfJ>W%X?d^CgD0(bR zOilQ0)r7(DD1L6I5f%sTnS>)>g9h(q^s#$j6Y4>85+q^(ik|eI`4rlr^hey-4pRFU zOol=BKaub}kLvw{H0JWLE{s#)kVERjgNYWBJI;#l7jq;^#z4iD&FFQNmLM+u@* zg;7c&`h)S)G%V)twk*Zp#pRlm+q&dUoau?$n3$sb0GNbg$W8+Te=wgv*iRmU2V^yz zwiym#4b8`^MfOS9Rj!1eVKq2H&Xz>1ErvX^fdp7+@t@w$AuP}udE{-*Tx=`#Dsw}z zQyLfFSy{;2DGPZ^qiOyq80@==%2IB~_fJn4>{j5LuS@9D}0O{hVWUUyL1|X(!q$znA|WrA^-!jkPGX2h>emBanZCwLOy&$m9Lv<@K%F=wr&poP$lnr=p&^W zdjCXE-JHuP;2oj^d|3>^4qfm$-$YMq;!P>h%Rlj^6{zoZ!HGA0k;uS{DN$bj2T@-) z_fu93Wz@s%gs(yCpKV1Zly7ZL?lC*ji&jQAZ?)j=g_RR^ChPmb>&6t%qir=5=GL_& zda2CMIL;A;sc|f3jQCbyulsBL@0njHarfUrLig_)!Yzvb17EBg*2tbY-=fI>hAw#) zq%K8xTJC9ZELGPURfrDcy0e4kLKZr?q{Y{lq6(FD)@{GSrGt0@LyeFFDsc@h{#uQ* zBAUmaA>{_BWDgMIz~klM&tt3n?@f+#_y%gJE^ev*NT;ueL43`JYc9b|qb@3kzK_;{ z&{EQL$@l29glZn`bk12~qCEY-)6IKW0D6=wj%SIdZ-_^Hl#x+(M_14WdlTj9=#U2; zSi!{M6${6M17SkDMGrGT3`B2HR0Spv3In~GXL)o)1h0pN<5_2i;Ovl-G8hSr#XNO) zzC%+`SVxcCeo{E~%t>Vz6ya8&vxZL?2=BX~$Qi#$5#2;gw2n<(6%KU)tKwE9T`>7N zjGm(t3KJm^#eXk0vSO6t>p7nT`tjg7c92DsXYoN6LR6}Yw<>WF-=K}Jg+Z~Y{i%s! zOMorLWYncL;(Z!Sydk*lKS;b5bkcFtpB|hiH!vr~RevR`ICOonEmcwmri5$v7LF>E z)ayw7W8?e(g9?iMq`8C*#pNR7LpzXjah)ICfgGIDw8Rd?6BqWxD>w)@aCPs8s|L=C zv5KS5w*Xgg;%4DqFgA}z;30YHf{*y_hlX0QABNraH)wTpUjvbEwzdCF|GSg>6zMUH z8|J8?J0(#sSdW>RZjKP_r;^1P%tP>7lij~Xvtnb0> zd;KCE)d%5_+wtO|{%`MfIc22yYwL>pYp)fZZ}8|1Ua8}JgRi{fLn`R-EGD{w(iPUHXL2%{WxnOft?P`2aEpVM&DPs?=% zDy$ynAsMp3LG2{o3*x<&()RZ?P3LzY&$o!O@&0 zcfc(h{37ozH^WhiC2^O^+*Wx)Tj)l)Db$&C8$jo{;?sB-bW^$a^a7rgVZMwUzKRg* zBQN0rDI<5dWW(IDOD=Y7f$&%t`!lpiF;u_^;JD`^HmG29AQ={CP^hZZjD7ryfnjm64K$~EXdd2cI)S5a%<%u} z4H2j2|2w~8J!(=kV+s*GR!Zb!||(&X)qpII*w`SBDaOu_$4NA-~vw`qC7^Q}Nx9Gxg`3GPyBpB58Umr@Pmc6M>~ zA4jMuCS;@lFKY^plW+Qf^Z%uOJvVV!d!TL`1QP=2nTBK~z;1}us55fj9_sG^RpoA}8vtfuNH z3T6{(24RhoY-s36t_`|c*FXUfCF$~T9y|MThb73kv(k_{8g9-v%vX@OV3U9EqqRg{Jc5$N9T09%#EZWhxn#af!s0Pz#09ubu^M#w5~nCs=)>vQ!sc8rVD;D%%9J8!Am(9a@Mx zk53jp+Ed;aNejcfw90)1$Hh2DOpPBvx=CYL>dA<*eq=mYKP-91qQ&D;f82m~Ssbmz zB6__I)7C|vj7gPYNcF-=c#H6u>!m^cz#>2z`#i_4&cJ9N) z<2pRM^2!WuYw{WjQM8RBPD|fz2HZUGklTwjVVi_YCc5NGu$|BwWFBcU)7G-w>9SZfXU-yESHr;-lgXoz#5v+iFfdn8R5GW}}KRi}eC0 zwfr)Ruu)c96L|-y9L^(g9=B0At>E^2FNGT%*qx-$Fzgib)Ub;`at*lA8Sdqf6dfz- z)BVvxK8owSldf|F<|5uYh3mW%JwvDD)NyvZB3X!8OEIrL0x{<-#cG3+hDCypkeen5 zcBMJHzu?~0-)Pf+V@8zZspy+m<6`~_BXUJ5_o%;u7mN(aM)@A&4Tgo785sE#p0h~i z`Tlow$>lNnj&CpEqh<64@QQttvE1u1m@RMU%LNVV09*jMB8@tC3%jtk;+zIQ0eW#> z6X0XS<}XG!`J6UJmz2g}0T{?5P&?M!v{2zE_ZQ4)gK@n2l~8RkTdXj{k6^Y=63li! z!mK8lxtLBnm}!u;B<5k=I|nZTU!6#v!e_)$gxERyVV9(QU}8^CXhcIxfvZ_(I)}<~ z9e6CD%7qz8HW_iNPQI>8qY~q;SnymZ*#Ev^$M}Xz199NMZ|qIuHylfxcs~8>c{TCY zWj|ah`)9A`@%@Mg_d6N;aNO~HaKE$It01`NtL5cSapiM0jB(MGPu}OW8VbxUK@I)G zsZY_3&m-T%xyT=ht(F;Ai!>4P=nEW-hO81_u|s0vkZ4?JI!twEf;! zhEm31DeRz<6>`-~gk1Z=K5!gP_s0xn_1V~lJme6GZ}M6S+$Og)nNY`6vxs9?auiv? zaVk0fg~f#&=YV5T%vi+vV=S+Ay{9s_G#w=uuOcpmSYMQ^;F3=+pE|g71Q+F@i&zx$ z(Z)^!i&{l2J|hc}6)YA5E5|!n+< zH+Qi47;OF*b?tvgHRv;J22O8Vn$#TjJ%|A+!@dR@qGZKGdGY0}0nuWRa(=*u5*w;g z0znV+J6Xgpl>9{Y0Y8m{pAGyhsk5N%;_KN_2Q6t6VOyedDxLWo>2W^dRw7>5>Bg>U z9`2GdU)TN3d}ZiV+y!!1f?&Krb684ucy4%k-#^_v9v2z>Pnbu=ddbs;RiR%LpwMRo z;95JD)c}oA{Ag>5A3ban3O#v8*V@uLRb67a5%a?@?J)>b06aR=J7Ay;M`hvWYLyZp z!HIPF(g*XgwQ?`)F?k_E9(0QZ>eNN2;PLpSJ=)^Gt5weNj^`adY{bf0Lp)*1I}S(Z z`Slj1^I`Btm8|Hw30PSxdhV681itp;`&7ighTxy1;~lb-Ng8X2#%k1}r2>j+Yf(%8 z!3I~!ik6xTLrWXrO2V|{FqZN7mK01;dzH|h<*sW29!QU7Qo+bX&s2G!S!_mRm1bT= zGyaZd(%_FiwizdX=X}d7njg){Qe*{7G2dk2w|M1@14~O*Ygtd`B)ME zV~9JNMD_vy`40Y-1pfho|JzT+AD{bGMM1wxnQ!nScr`O9TpGg93v`N*Ci8V#$LC-k zyuYk`4hEN)aE%Y|GaJ>hns9kr7j7pa<&F47JT-dIkcV3+DOx_S_)<)q6v$7EPQ(X~ z@YBqc3MW4{QW>q2BfvD$B%a%62!?7gRx4^mb$FEA8i9T>%3}vA^czS&P@&&U`k@Z` z-};~)zb96nPoJuW?mfACB|D28`b%HWarUqUQ4q)3!zZ2DB~A20{6LTUR?j?F09j47;({RM-XIhB^0TVynrabmm;S+0>5+SUe zJTVxKm={fq9E$DfM3_GL7;KSE@P=2vObIDTHnxS0oC~agPI9sJU)j&D|AH1U*Sjd7 z!br*&Xb?LPafXA~l;2@|;f;~87^{dj*#yK{Pcq6>^60LDtLyE9uJO;~oXGO)UnOHU zhatEk{tmWm=Jr9CczmsSo0EDa!U!wnRSxQHY%#;InQef2rD+xt+%R{5S;F1+1hp-t zz4AbA_I5`3C$3P~T8qG?*uIF^m9m2o0b(S55P0N%n1RQZ3_N05VV!Jmw2FA7Bm#Sm zxS>CuOGI>oNtB?srR+s>MtPI4^NwgHoNWX(#U^RBvPs%je3Qh8 zRti2toP2gFn=SkZK4}V{tcUq*b@KUC@X;b-DEQP=_<)JcR)`WjqWBTqQnca$u@w~I z?}vFtf~PG70u`T93r7wof(!*X$3!_5^ypOVR1kx4TB#F@vn@w-RJ;I#Tmd=&mGd~l z!SF0nIrn0U{@`l^mc(SZd?G|#39F-IV{I&rMq7_2^5Bl5GbKBcghKmnlG#KI+bAD9 z$12!yo<_Glj5eDHZJ!!~%7PAugXsbIij?#1T<15d+kjIk?^_o8ybE5=4VM>oaf-yF zWKVATb2-Oxs?y-AB^n%1N`nVc;VBw?=5Y;LP+#(}TolK|jf*w?pJ*V2=peU=azl0u z)8ryzsE*DZfB}%c6jBqt#dq}}K~5~$zo_31gZCM{G>5@E&_NNcjrt)k7W@z(u*)e( zDnkoP;vrs3!p1fux28=PHKRN=PmE*gqzk3FIO3qPF&4J}eVh14to;9X3zYR}?t}Hn zlGmiP`=i36_I$AHV9j%`Jh&IkS8Mpvjc(CTB8Aw}qHmGHXKe5eX&NF6mLzY!ROn(g zP5d%AXni-9hi3Zg2X)Kbq z(2Md=s4ZC!z%O2j;x}Sax!67GaGScDvCQ&Xr?Sj;M-4DnO2jfd6$El2eK0JuvxC6c z;AxbX=}h47pH_(~|pcsD}TmYHo(?o*WA5cKWm}c7>|IjfgyifoH6XmFl=+2 zGVY{zCi~(X6HKY`Hp4c@DdQJ|P*~uiOSuOU^8Z3C27B>mE~Ena!v~pj@`s2IIVKkx z<3oUz2X+OWBJERf%qtsZ*UM}|D_)om%>!B^-|CI$biO@|cOWsV=`NI)F90DJoR9Ai z?qsn4w_*&~)e7>i5)AOlqQan}yov~X@c%IOseDIIOnV$dhI%SRFixVERu{^L^~g{w z4@W)b*uP40f8=s2na)9WvPML}pjvz7{&0{vyrKA=m3V=VTG?Dv`JBzWA}pb{_2I{C zs-ynj*os0NX_;OwvK3y6@2!*wThWA#XMquIMSm!)&ERd6M+#Y}Q) zi`hW~K22x2=;m1b{0$mi${kDx|NdHC$`vGHO|maMZkRDts)*yP_0Sk8pPx~+nhz=Q ze1jG$<$}-0VFEQN`a55x{_(J|NLwF`tixJ@>Fyh2@mKzwT21L2{K+<5y+{5YSh%f^ zk9-jwkosrg>T6TSAFw-|TU|t&OZ@#cgqp+p+4{7Xcaq+46dm@3@xVdlWm(A6)(5X& zxNXu!t~r=(>6vb;RY; z^jo-met72p^DZCshu>F*t#N*0S?cO3#p!+1I|S;dcu9etzW94G>2Z~L?T24h{uP!s zSIb!9;`j-Kt{3ykL@;aMCpAQ$;=Lfgp9t|GglfOr83EI*=6I!xE zyy$98%)(Vy@z$vL+z`$#sHgVo$s6!~cpZKx%<6%)NN+!7G-V}VTwe9uLR%ePwaVgN|Axfq4A z#>tDjIB+z|o3X@kp8AIO+tfMpkEeCfb%Y< zn{pRZH62}>i;b`N+yg#Nr;qE3k6@I%YBPcBzT>LRaHO4AZ6c9YuG)l>0#|LuHx={a zp)adCZf({=;D$2;E`)pu6(}Sc&fydf@K|U|I|;<(?_8X}iPlAYv&r zLpd$Q$9Pay8D%S>0gjK0;^Uu=!iAzxgy{d~^Lm^wJkfKQYlkYoNL7{!5Hr);&lpWj zICdWygeu#sUjPmbFGU;DIlRX#NYY5MNFl*|4#!{1X$@_q);TWDm-1|-$xvC3yqXsC zzaQK;dHDM_Sc&jS4_*M+?D(FIQT`LnO1O%d=6ED1B%MlACgvju`QaHCqny=@ft7G% zT;-8CD;1~eO`NK&oT?A?Rl+nyf3`v5)fC~OItdZ_HmAw$K=}W#_bq@?6<7be*-f&* zl3gHyh*6^?iUu{ZqCmig$A+K;Hbgc=452OJ8ea&zfJ#W>O*EV9T3WTAZS|`ZY-#J) z(rPv0DxqI*2xie?ZoS8Z2 z%$alKoYzPxcSxw&=(q!^*=mDUR9k&HTUi`s?9;`|iW>#V_JxvjN)z~79F9M8U*}az zz)iP-<;H(e=zY!~`o-~7C83P^*50;N@4muyD_l4ir@E@hJ^KSt2jl*E+`HN+VKN`; ziR|^sK-I4OY&$X29UodY)^)r$48t^$Mxuyr$;jZbP3sg?DyqTM6*O;JM^olpF?&$R zrhQJ6esbk?YbLvhn!Pemth_Pdg#+fUk!A%y3F>H0oN|t&pMe5mIflBlBcs!ua3lQB53i1^j;e~usv^(x zpHY@VxLA=7X4Jb!_VNB8zWmZ1zhYzWcWEGHV+Kt2d+a3i4Vhn`{UFSdgYi3i#>WJ_ zLH~ZC_>wW`MpB9Nc1TCv9I0}yw62=?Jn?o?!Zp!yfn~5GB zjklJUo8%pJA6kd)*nj-gZ%6G~aq724l)G=ZwN%uH!)81_D%?|WmlXAuhrOUk1akxn ze7|-Ys|-nW8fy{{A^gk)j3dRp1pN;^EFw9vq={$}F*P{lG_6OtHpKtI=@sonR*$$@ zy+S&{8%ppv6nPgC2cMRLl@)h4<4yzroPW{YT8H#vdyF*PUGp|z`Y9{HTyfnb z-Yu9^s8eBz<8nDDc1;w-#eQl+c~Yy%2^rT830u)Q;J@~d7n2;T=sZcqkp4S0CvK3R zp28a(@Z=n*>j_jT>V4x{wcbuqZ>L&s^-cZOtAWGoNBF1k`X`F|^`2xpTXY)s;i_+k z(`*a};IzC*g`qYG!_?W*S}8v(4+V7}#B>fo*m-_)OfJkmTybg{6VJBa4=8pe)y|K|p^9 zCLUu4&VvN9%qp@9vE*r38T>Ec$Nu0?!q+!zU-~)u459dxdTtB5Yy31TDXKt}3Q1WG5a4UyZdz9d~n-P#MhYB;>1>Yy|r zHn@0yZ{Jj^lI`*9@(pYdLh7yG}7kF0vtXj1;`7`X}y5tiL_71Z3?SN-RBbyJUrFe;xuwB^jBf~m+F$piYPnv#Rw{V#HE?*xk z|1)UqMES7K3orlAc)`mb*atnzr})%Zu&5Nn4iw^8sN82{PvUz_PZ%W;xZ&`?Lta>e z&!E9k0-&`x{6f6o{yTbB z905h>0q|ftg;(=55Q-_I5x(ITQDDZVwF&UNfR!}P!LGu{#JI<~PqWTdgRx$Gl^F65 zfcwBbAM)umNEpJn#Ok7cZ4#EE3Wi#2{T)#tJcrJnY%M-yTJj3MZLdtN>;r4;$l4}es)0;m!`?p z4gw4XV`MZK6N4p=q>%SOPiCk*zRZ8;N^}t9T?(kRm%Ribr;qs{4EqE1)ZpIrEDZP+ zCl0L;ELO}TVBZ<4F6UdSPS~@Yz|iSMe`Qm2o{_c# z3(4A4mqM85zK`Vn`MwAA)loBfx4&D&-?xklzK>{4?+1#Kc$gehM6nsj32_lH$D!^Gh?*kCPx2LE^0~RM^_TWT!{U)! zB&B=cVB|_fFmlBg3`PzK(P%poxLX{`x}1k#UK`C`8H)pTtObH6S0#I**)=dl@hu)F zebnNe)fJfTVD)&(PcuVHaTObh*CcE82xk6bB2Hu>nEBo>p=nivnHMt5?^u;7NHUE- z;VJ;?YDaD!8+!@IvP|whtihn&PePHYk_3IEPD|SIOtS;dQ(h>7m|L;LLo0Tw!5Gtf z`xNuI7Q#GK`t^O64yRir!4tV#W(;-)?zd~d)(e#$rS9&v1)<>L`@o)r;)ZL%#jTOS z#h*MsJQJLwTH(XcsslXW79X@l_w_3o^dBLnJJOl1AV@BSU$sqwov z(tM|MTOQehn^5rXhiF~n!Mj(%%MekHpvyEcl$S$LQ-gQ&nCC@AX~EFlVB7h?Rs(k@ zfCdfqxfHb9u*1P}iHGFAVyx6?i)b|0*9jkl90yuy!o|fEkhp|Yw*eYqap%U}U{Eut zJR$r+n9b*g@xc`^qj{BGIuqoic{4KV*IYwsqe-%bS!G%?`uKHBuR>y>)CM*6SHaZC z@ZC=V+mOq7_-;w-0-xFiV|n~^1xqse6B6`ooS-z+pA<5357d){tf3zF6t~+7U~>&S z@*M2Q1p{E6z6`^bo4h6o0mZuN zJb5(EG2>*nF-pfIaDqh|t;mN%FN(uoaO(cKidrpz_b)IH2;|<`H+>Vzi9+MBQuR;Y zh${`rbr_h$b?B{gCG1=<2!h1t&>i=F^s_;8wS&cW`26q<=-Usbzc+pVA(#qPn;EEH zTSAkF7PmVC3nmD7nM%MheD0vQ-Mw+!gMb_G8Rkw0y9hniFJk+lT_;%5!K3G_IYF=7 zt^qs&Y_TDUf!j1A;NYq;g1?rdGGefh>@Z3VMkKHPTsqU`o>Uz*HO6z9bmlAf71cBK zQ?vA*vC^4t_XX86qo!s>d4@}86t}f{reSK9!EHLfR%+CP>9o}j$axA-0T1`2L-839 zZ+q2-P^|57BG$G_w?@Jbcq@V120YR|wxDP84pGGj9%ma4S>V_;4lbBRAY-fT|ip$8gt{o!p;F<%o4)Hat`5A{- z7pI-f`0Lu`+~g~*-q1!%HCCb_-70-G}sHdS(JkfCw5>e^`=#Rdpp%^t8KIVVJOftB#&Lf-xy&pL;U_G zdL6OVfz3?{wLJ|hz&GCY2q8}3Yi9^wQmd;UWI=ylJRzSwf)0kJ3_y>{cO3#o*zbAo zn%K)=RM>;So!ndoJB-+gwZ~h4q99&9kLDqWxQb2o2jqs;7T=I#Tks&FK#*o+qsv-G zksz|iqaXM!cKDz{F~IyA8KGq4JA8;in~ps>V#6uey4Z{}V`~G&(q0_b57_x$T!Xz< z$G#X2(BRoX&A$~&&aLby3CZ>?e*0@8JDoO$MblQYYKqdbZba6N><`FF(ceP={tDYu z;Q&S>>|6-IW&vQUR*KkGyc4BRyP@6@HS!(B279xP74!vQMt=Zm#R}l!kxlV1oENqN z#$p|v7$%&s+eZOoooHjL<;i;O8v#lScG3B!W=}}8YyzdPARDYZdg4~`f_&KD z?N&UOD(_DJ1aCaIJH@+$klXp3&V4>Tj8RGSK;kM_Z8F*^M$FsC{;t{4=`z{r?!M z(=Bwc*?1v$0+0@r$n|3Y4fo#HsVo9Ep$kQe#Nt~W%uiz%PT=S;n_*TU#`g?muQ{0W zJ!{A3qFHrc#K>RNeSVR{@I}xd*I6idH$(7l%lZ$bZfnVP`EOd0J*^x1_F#5o(7up9 zfM<7ePVGY!%zLOB%=@qi=ACvB&j|KJQOIsw>dhNJxNZ0#qWSzYfh^TvNJJs6r(-Gv zTMq^jN3i7V@d#-xPIAq((lN7S5!yQ0d*k>%i9(F$b)oT$-QK?Rlcbz%b8Rh;fmfGS zCBd`_MtQKa!okRCAl2gWE(d;?7jp~lt8nk?q=Y$Kdz8rbBw*oh#MjDozNIwqX*yHg z$RK*CP8jqn2}YF54XH-*+^!0I!b(RI&12^s_N_PoK_C8PZB>>D zt3%K-riDJs7N7lVHTn={C^jnM@aYi66%7DH6be;`hV*4iM*3-brwtL{Us!sakZ^Xc z;u$oK3;lGko21c;VSA9zem{)Mq7O)l-ZP!cKUc|d)pm20J}?(JVVYDrJSg!81t(He zn{>!4??vti4Xx!3yEz|I;qT3aUvh%1iM9g>OkC0@UR22ZzrtORIKReCMEf;sjI|F^ z(`~%zqeRomwTQeoABKsKTLGUt~!)EE>{ z$8XNP1!6wf8a^L{xSh7VFn6*r04v0)60pwb8gRQHSY01H`ZHKgRVEwxh|8AuY32p& zC-K+?m?btQXVILhYcS|AkYOL)N?OX48M%Q3u;=pI4tAFwXrvf-B)ves0Jq-E=7anq zEdyCN z?ht1BZv)}s$j80FfBJ-=yiwjtwwIfXE1?Z|%WIGHZ*>APH<4tfpC70uf?`!buQ)KQ zBAhH!=073fHL6= z!aN*fF2^GWs8Za~p>5$_k~_(&2tQ+u!)eXzq(LkGs}blT`}4k>DvH{uI^;S?uOTti z(qZwtArwm`O(e_f-D3q%etac-kivUD%6l|g$m47?zU1lzI6e%j6P73-dK$c{H$*;4 zvna8LAu8upe@?>}qjX>!l^!JVFMXu-NHrm!0xf|1T1XP)F%zuL<;ry~M$_%*P&=S6 zXx}U}fg2^fd2I}TBaF@m-WXO}A?SNuh`y!PzU{MUj%_1?R;LAitb*GkLqx<%3Bkm5 z{43HPnTdyjrFrS45KiG;hHFhS#q5fGijdGPG>G+3G96=YLsc!8U?2BbS|`;2`zm#~ zK;OuBO~EN(K?|z`rl(i9n$hgyNv=$4y$s_!+~10OR~seFd5DZt6@m_CxER9wAR{9FM&vv{u7# zHY+JIP_sV^Dv+RU6$qT3U~!d5zsv!~#hn?}R5<`nreF4R9RPlqHr44Lhk2{G=P*C7-uoZk zrrwSBRE&%xvXHh67YuszHn)aUPQF~7%_IywDq`jva!rtRtkw0cJ(lp4ieE4I+GljvA`sBw5 zk0G?kj}f-Rp64frKO}}f(1~RgoAP`_7||a5G2uXm)z|YD^b@q-CpW0Of045b7d=P;?VMhlj{t_4_&Ti`w_0E)?IZ;Ntt+ z2laiZi^caU`1t;^vwhze3G^)FL-<1i7tsff!~00IM}CZ^hfw#*kCjC}&mR<3gyA91 z^(abkvRelQMF=7R53@rJNu{~txR*00i|?l#6@GryZU`7mFnm~9dg9{nslniapg?&M z>xl&{b6@j4jlZwGUYT9V&`%X77e}Ek&Ecv2w7h2popp#-*GgA*73Kg~uj_GmrE`UM zhLPO~uUc3cVWrupvQ5B`{no7!{9YgD&3Nyq3?EAa2Tseey%jSG9Ra`n3>vK-0dIvf z2o)d)Tl9Ii;&Y;YqYR^Zqc7X&M=#?v`FqfeLn@=gAkoq*cvTbS&hd6d+Kz8gFJGh1+@ z^UrLhpNvM&`xtTFtjThg*_*W(riR|Eb-t|i@T!5$80>Fg^`NJhvA57CJw^ZHo72;~ zke0qFJ!Qi}>6_3K(e*#DM){n{DorMxYw!Cur1%~w0~SG+=^#th-|jh3XC|l4Wkj8v z2b8mtybnK%5`CQ4;>0RA!k_6!>WYmBq=5nJ`!R6`D%le2b*_MOvZW9IH<9h2hXbGQ z&0Nma_ca;AR}B|jT(!L>X)R}Q2eY&;}@JjfD3sF-B@CRy&hDM zW^dtE^&qwConA>84{lFxqu{or%P)pvq?tuS!CpMp#Q-86HBqbJWVceB=o;_ksq98P z`YP8!y@MmzF9=1#;FU;bd<}IVDIiHB=wManVN7%1=co^b!lps!X@n`m3mDm?1+qU4 zjnxTcZS>_qMQxJxUV~UCq&nk3%f_>zWurL0I8#Z8C$$3_4p&?*G>OFm01P&`2SR)P zi7HTfv7WqM&@!YXBom^z6A0*5xI2bs`t1G~o>R7Og<2yWA1DbaLjS_^ECbKU7O8o1 zo|pYziwwX13nJ%ZRSBF4y#LQl&78)?{Jc1vzWUx@!(rb-v#Vw!i50ZF2D>UxE3g^4 z!8RU?bHoPQ$IzY7A;LSMA9OY2YeF!sl436ns2$If#ZKC!FS`}ty91r!pMzBqtHK-; z>V?`X>Kgh7nFnvoO;~By+K60v$9bfZ6=&Xql26IpVL?Y z+jO?*Aeuh<$Kn0iXMALsU}$G48R3_Y1mKqg1)%YtQSl&88?{17ND3PbZi{Q(!vOLv zu7ffL#wZ7+&IjC_{`reV(7e)UGBGPO)MPzKo_{R<*p>K9?JPJ5QoJQC@F76TT=oWr zf^RKGI6P7v%{T!zGLFa9vE~M%!Bv7aKLAczK#7^HO}UQ4Cjiq1X!0X~su`*)R4$dY z8CPH7T8X6Mb*>4Ocq3z_$NfCqyEanRxjZZMe;t^K<9s-lTnFVkIrsXK*me&vj-4Ln zjlM)G6**8X5a^XK*1D>;Sf;-!AUS{^CYr8McJ+t z*|0;?h1q%tNL<9faW&&@@hzg){tOK#?nSRrH$D#a4^1hFV3_(w(g3OKB8WinZ4*;N z(?Y##9i}Aq23HTj0=f5GAm+!W@bT2Q{+m1=n1lfW4J}5<3(b_rdd-yGLwn4WuR#q; z&6)w>-F4`(o--x4I!NL##9TQ9K)Vuu0Pv^tkpU(IhfdW2>nM(e1`C!D?_z8Orxr%J zYj`~f4A>HIQBAiYc)$$lev`$3>U?HoF@W6vlKc+D4nWlKoA?%fkEP)=k09 zP+0DScBF~%FEOh_=2)){f#XkyVa3X|tY)QqnYbjY|Bd^N&EQASh)qvvqO z`W9qHBv!fP*?gva%%^E>@J8-{syyn`wAB5}hjFiQttAM0s{NPH(}UP4j-aP0d=op7 zy#Y0qYy6}A&=b87^z<;+5?3}J*>`mYPtIMoV#+q$6o5gGJKP zU%9D6Vh>t6a)#FU-n6tFe!qkMtOlZ`3^n7RXeo}oiL10U>hEW#B?nsdKS)bNQ-Yon zuMS%;`k$W=ABsVD8c%z}g=U})%FL$)b4&~}{!={3-2C||8f=OuNt?wyiC~lBIlp76 zJVEagwh{*oXEew79Ku5iw9r>B9T&TsP<#^`jb6?3*_$**+-H9lXC(dtGCK{16*EZ< zMl}4LwIB&IpKO0o8{N->D}I)(|EuWd7pW3e=10NLV&9ymAT4tfGB>dWYGw|RRI-QS zdN!d72%v)_o>11@($Yp zFIc;Vj#DrbF58h_HDU!gs`tR_$#AbD*L%mLomt?0kbBhW%{^+fSm+n^hwP2(KD|h8 z%kTKBcahomU|huk6^_|$9D=zV1fTIohT60?pzx$Iy-JTo@x#fB%x>e{2K|));S2$> zz?*0FJ{V8db!UTt>d&F$VJ2rj>h!HuaN3+#H^1Wpv{+QvDA&omQ5_|+9$PM+aG^J)?VO`Nn1kB;=M7RiNsQn zt~0_a`4srRh;`@>e7h-;U3a{jd|_`8lLwuGlAGC!XfP%MO-<)=z?Rs-Rvw}W!K^L^ zdX=@6Zhqhvk!l9;XT@gc>?}@ z-h)|^$>(`*#m0e$ip6T*V|gn@0Sl6NZf>VleXN6FfGg8#V~`udkdR}A!H+-JgR@d5@Z6bmwd$` zTM42RkP)N*nuA?~6Q%%*jHn!_fR;mv#9Y$6jews``C!k@ZrGne)i|{E1z1%DUQPbNL_3dkb0jC$giW527 z5SHEXB=MI7Tnzgd=p<;-oGolAM1tb0>F#@2%#rhEk(1S`xnO~}g-u4TUah$2L_e+2 z8Y@~b2iY)vZDGfW_Ht^-b~+S{`f@77AIMWg_;z@tZ#qZ_rZ$*>V6?Oel9X#Pz;Y;m zB09sHA?#&?}lJ5W-i$`4`uOyzEsF9 zs8xRbW+b5~^6)j3&EbGh@SI_wK{p|n&8B^uHUS>_s@;PAM-sNcV3=q{*5PE5s2zoN zLL~;c*)1Gc1oqg%e*PJNbAfn(fRAID9rr-iqipv9B-$TEBF>I;b6_0i z!jj;sh(Lse{SKr?h!CM@GI^Pgvai4+3S9IW<^TUAV16WH4lFDFm@xmJz%0gVAGR%G zeXk9l|0tqFaQ=(1=VtGM?CAL5g;0O`Drdv!#K9gIqSL)H2ZP!7`ZCN}++FUe=X#$! zQ2w+Wufz7+E^8vXD!vN-rryW0tNh7DpYLUsQ2Gv@ewRq^*vIoHBg=1)j&b`a=mJke zKA^9OSa~GnI{+jai@iaM)npl87qq~(jL6vrOY_z5nQ)G*(EwM32p9#Cj)RcTt6IYg zfdl&#t&nGX7xHY+LaL|`f@>rSvAp!B2T+RKAThoB7P`zsqvQgg_f@V( zE^Nj5K;azRT4C2-OZMzmS}~h2{lJf@q0SLFuQ_wq8se0xHjSjWiu16 zpYDG69w0HgYSkB?V|wVZhxJ4+HPdp;?h)+RC46)zvR~2HjVQ{AA!!IZ3^tCZ3Z1|z z)Xl+fE*{}Jjm+!;d={AIvp?mxb1@N;p-_mEZgxbm*>zNfE|)Tnl1iS^xre)2)x7*8D1?d_JL5mWWa3JGoQwNl(8Z1%`|KUUu{E5*hmz8l^Avjv z!@buzht+$-6h5lf5bQm4h!hGYs0a`pl!eT4$y4CtCeZ;$S0*YaC*p!<MA2r3dkIu1TU{&hy@P$i zr+PD{VVoL3(@E=koe-!HDC@W2M?krR5_0Iin>a06(65GOPjz(uDAkP&F>sJ%2#j%U zU5vxk!HeGy(j-G14)fArXah1YO)eX60!t{w^a# zC5OMV4foVr*qz330zr&cJKN;~$*}7>>RO09KqO@H9+6XGR!rfg zb9w1PpO0!HnThMGdP+_RYl_#jlD`dwF-eyVBwQZGqWZOZfVVdZV2V}(a>YfDpmjDz z(3GFcW|XK(X|SE)&2}fsJ_trw`f;An2XGYFd~#cS*94ey7f*HFj30IyrariL=z8w z$M?%S5eWbdL*M(IqzhLu;|yS%7x zQr(DFfcg&pn|dH`=E52AD>a@Nz0TvyVuUjXk2Ypt|!W>!%`GT z09lV9fyWyg)VV>{L;_8)vZdN?sxrnYv2tvY@Bj;CggCk!kM%07#({4E56+KxOz^_0 z=@NQ53O@N3h?^fr>aE|y_pm>$x+ZM>%?vT~5$A>Jv~Xi_vfsXw#x5Jvh*A+8%U{Px z@s1F4>Pmc`7`_Oi*qaq@31@{-92{c&8Pt6hZdo+=b<4|sD$BtRaghx*4yusrgN4-6 zQf)U|p6^7!0WgI27wbO9^j>*R#W5%g1x)v$I2a>wkY=1y8Cy^W^a71+G=_(qb2KQ@ zH&UXLc#?>HIIH2a5P0VW@*PQkj2OIgJdgdk!)SE za8S9(yVOL7;v-M7^gkvb$ig!n)iEJYdK);#QCw7$AgaMbk?E#jB}<^T=NPjXvRBOaC_I+GX>7$i6$ZUFC~kQKqDlIhvA6yRAxUBEOQgqLNA$yh(^5rwaKB+ui&4v0Y2B$Oa2{4(+MA))SHGh zDOo2iGa|SNj6iFR4wecAy`Ufh3f^1zEH@XKFr>Y91kLJ%+@kk6wNft8N#8S)52?Su zt$vTGxaZV^GEjnF&+A3gs9`uegu}!kXBFZtHCnt6!YmM#32xIL^Hk545_AHU6iVqR zbPT~vk#JD!MM>=-Vt>rmflK-kFG@l2m!8U z>aV0kUQ+YGCB4W?QZw}~3G-yW6JA{Qe1ZyNtxthCamZ+nS=#{ObU_!6eabDLae7O- znDrIV0EHRJLj~To_&|IvqEAGwN1+b6jjD-h92jIh2U*P&2{Mdq1@So8t3bBck_$`x zWnYOu>??77Ux~N(mAJ64#OZw{j_)gRR9}hIzXEu|jT{=P4)zgV(JEQs9$JhA@~5w= zW39(X>-F7lBftCJV82@(`P~(R{VpT&yOY}o38x|QyX}Mh?rkW8!|?LZV844j^1B-c z``wbr??w*xyK!OPS)J^C8Yg|vwUPZEcrT)Tzv%xvn#Mch)~-}iDnGteZ>>qjs4c9o z*(iQG#m~B*@Wf{Elm1iwR3&~|#E;`=B8&K0_B4NL5q z5PuKh&x^l}`1=q1{U`pO!{77xdjWsj@mGhxM*Qu=-(ma(CzL_nfX<~>?0cPNSH1=Y zVk4LnFg6Z$B^2da5urSJuOrX8C2F1_edWQ*z=pqwY^SxNK7{^RD@vTerTQozZH%~X zy+tiowktHV2#8E1w46R%*x1 zT64#S=c_r5NwyyR83gUk6KL9@Cg|vi?e)6^Fldflor8?eXjH0X%BZU6E8NA`cZ zzj@d$&uQ3bwRJ2{Nkop>De)a28}_e?%Rs)hrd6>S$h$^A-*x~@(~=$50laPjom+#E8DOCKh+LHJ=1Vu-4$NN&V&Wkj!04hm)ml%4Ngm+rA66yP3 zv#e^fn$h4y6v!LBKd}Ej-mD{N)(PIMB;KsVV6)=YW?9u{E%3y4yx-9*y{}ucv}nK< zhILb~+q`_`M7=oZ{RKaht$q#o7! zEwX`))Nen;B|fav;&`W-(txe=fj#`1@oQahzt+&AfqSx7<7o6ic_J~L+eRCZ$#fY( zmuOpUW+0u#LYIL-)QW8Y%S*L1(5y64CO{ul5P%UE9Bn;Wi#HB-FEn`t{dqLUo}}s4 zSSy!3Ut?_e zqv@G+h3py_1K_yIZR{sBG2VEE&dMIb0?+0^apO0pA1Q#zio+K$pUQB{?-rKAX0kiD6n*xyi7mHk)B!Y=Z3;z=lH& zaPw%HGM%6*rA{Y*dmJo9?;a{CQSNBC=MP+iOCCHv@MDH+kE<1l!ja=3$%F#Fir+z8G3&{+AO()mWPPrZ?)vL@^&ouwPnt6JXW&EHnOHC1#%%4VSH+;*!2Sq1Qk8Sh)_eWF z$C$)9GB*|nG=-1Dk*HeUt5&`igGV_GTek4v0ep_W8V%tKB8)5bh!=I&Zt5@%=wdub zJI&$W;VVsG1qa4uS|O^3apnXK+6-y`LG-&nWnV?lg)m9xCk~`eoyolQ47Zw!7DhYQ&@*WoYN^xPZ~Nyd46AyJT4F+=dSie<^iE6jNb&6 z1{9wODY$VBG3shHLxhA0NC{^YP-=N=3ihFk$FP$yGQ-wlba7O{JC|=xd>D>(hsV=3 z!AjQ)%ygY(qU&@ct}7l*NasJpQ~1vXI{p*gh0(C$(bP`~Pg{jn};fJR605WxDdhKww-<4rEBZwbvvGcmf zDx0gl=E`(@7C0&}xe256>ta$H^TA)Bb`x>#a-$6rz6PrXQkLM<6LV+Vc*Dtz z!|wC&ZN`n}RYT>OCc{i~M&l~8v}1h6Vb7;L(vG|%a3%<;b|VS}Q(~Nma6hl)+=9a* zQ%s(dyq5AQ4m%OF~k>Ei2MPP~KG+A8pM%A$B2B~m~9b^3xtfOVQ>#K3eaIUh9alLg10faHw=P&1@OL~?0}K1~cJyZdE8){Maoz+m^niE;z^@GSyZe}bfr z=7O=c-L-+)oN|4h)A=CMH>oL{Qn68{QL5K|8cJ*otLL73?oIk$B;XUIZPO!_t19b@ zqnZ1+p%pQRs6KCCa=48cwLhS7GfA9Dm(c@aGO^>oAXW%U0_uZ; z$R5NO+N2RpXve&PtOpz6O%}v^DH!FzFwuiqM1ANlF8td~eUL%0AnG1I0Z}P2g~y)* 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%0D` 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

    AgRKVGgxeXwvAvh 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 ZHfA*4Z1XOCj;5&=^9I94ZC`RD;mP>hEOCd&42 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%0A5CL$C~Y#;UY;_);-=qOe=n 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ÐUx6_8;cWB*xpPECNGjKx?o)(@L!nNRp z7rP@qBN8jEv=P8G2;R{hXOO-rKe$BanH^dQ(Vj#iXK1C9-Ljil2$?=#BwG!bHOkG- zD2`W6&_FuI-qwEe5@|A3HbEKJU8|SIxY&)VxNn9S;T=bX?FB7NTa10E`mGKasRB3!jPJQeZPUC;ak4EFPfP%)C59HKC z4=Lx=-;BcJlDAYmCJ>sh!dL_|$-^e6wDs_t;ARNxWM( zH_85H{|6@HF;Px>bGR@os!A^+ywe#PZTTR)|0f>5knq0r3kdJ&5s93H_t3q#pjWK0 zu-ky>eiiOmhH{`dcu6E9iSAJuzjDDn%&2Qh?dx?P$J#teP?5^L$tynQLUTXUHJ&*i z>*0-?G3t^T$Lh2lQFc2K!2}bu4D&j@vPlO91>g;#a?iaR;jqxsV97p!3+?Z_!e`1Rp}m)c_Rw8>EMbYgm~aZt z?n!}kzM7=-WqSLewR?EDC(=Kg?`p8fev{FUfT>RKFJEIF4>hQk7 z^B1va@VrrZhV~1dZP9xL&kLlwJ`qZJjf=5`y%E@;K(3Wcii;Jb{GfDgkL7nenzoSt_ zm`n%{6Y*^r>iFj+i+RZE{sbIHUEscida5Qb{_6nV4)jp(1>aZIj=1C4a){x@Fbh@AY$7XSZ+SsB6-2B(0I}f&Wxg0~t$yHAKKa4G8?;k=n%G>@^u}T9_#qqR}@Kit7 zJWY?vwNWK`T4`Vf(0lPtz+V{!Exw&ICN5t2u%3 z_^Xr?f#$t1axxlBSkWnb0L0b}l=Cf>av-BAXNYn_v3IqCayX@T&o!b`bLBP0)R1Q; zyPFO$K{*+8&vi8EIEi$eL^{q0>F^rlTTm2o##pu%@~BETUD!ehx;g7sbr8@H2*~t5 zg}opuU>Aq$49>xJ+aDMb1J+5zN41^J4iu=sSj0wkRuZ;x^?mF zww0|Xay*Sa;*0~`4vX1itf))xaaeS@SRsuSyDE@aK@V8mAwu5AS4Sx&l=2K{!pVLJ z{1u~-09hx>y#^_!Vpnd^EcY5Elrghv+GHTiUk8Hxp_jLC=u(lFZ6}tSt_#-IJ3iFO zclN=y5xzO!0L;b36}$9;rt14q^ZF(FX(~z8&(&Xqo9j4vRotP!^vsL;^^OlUG9N`` zUeE4^zP?V8IyN{ygeAlHp{lI7!#wQ_?ydoE9Vtf}jK!!FPKmDUrtR+o1fOXXNr{Wh zExlREZ={mIi+c(n7~V^Q;R3yV_u7NRX$FiCuS4#%K^c@CdX*~jmct{U*JrY$gNyJ^ zwKle#bR#4_q8wiN7iOgSX?EY9wR^F3v*`-#T~@%Zp>DNVu1U9UZpM*)vvqSUB_~pH zEKjb17F)ij56lwQ3Z9r!d$R{OYjlx?_0nGJ<{Infy;;qk$$;4GE5;oay|{bfesGf$ z_S4oMd!cb&!$vI)<5CNA!KApYD zz;@+H+GKbh#IG5@D`{&1h$T~X_c~aR-1kj&lrTOtFf9W|yNE{nKE3_)+ICX)~8c4gm6bpeuLQ41A6#JR-u?1uMiv3mJg z(ldHbj*EQ;vCF0Ove&R!x!7h*KPUShaagjAxIYG2gJa~iX*y3*XjK~f7PM<}X_^iv zHrr__fIu~HDh%uj_!T35b@NVOO+skN4x$^#g;*m~*ikg4f~ZqLv;#!=e7XRinH5nh zK_=gM1SVH#yqMUIi%lRwiI`M)nZ%Bn_{SyC{DXfSK|~mKnDU=f=80qwlpRql5=kNM zs=aO1-E@>x=u6fk!2e16C#$D{I&gnf9t=uDDZ1u3TWC?Tyu(~wv(})TL0)5*{gYK4 zD6e!W`|PJZQ?UM@pLKeJ!FQ{E!!6@N>*wPCO(7C^g2;}HS*@tu-nRM)>}<)RW-+@Q z{QaDy-w)Yh9ylyC8zC}ZNOKf3^!%(|5pR5h*_W%|a9dnx{Vn+K6wQ;(Yrk3|FT6h7 z7llnuKcpy&EM6apoM<4~`;rc91x?z#+eoPgqmE3lrgWAJu}mG=3o*!QzgQ6{jJk!x z%!2@~wV}EfHDT~{@+pJ$d*@*be3SKsw+oCd-i@T@r1;!f{+=FRkzPJ+UOg7JRxeR{ zKFj0VRa;=QL8og8T3>kA*jA8_AgYgdku)rZWxp5|TVX-yC4!i>@^-M=F; zXPvU2UNs&pdw0K{tUD||D;zv8uf%?4MTvJKqw2ODA)tFa*~%g1ZRI6O%X(L(=P{sX z{MYE2SD^4wP^;u9vA=7rK80e+Au&RMkMLqVWq)_&3^hJ7hfKo?c3OO54aAD4&HnC+ z%SFdfU>l8U|L#QL#M3UiqX<%JP#&l3%Fe9aS#@^*njAEqs&E4I{(>vSy=$tga=ko7 z;pA*TzVa4?;N^G}L?3X27b96K_-9e@wn#xfH$)Npo|P%U7q2Rig@W3Mh$PWAOdCa$ z_l;G)&uddqo7!48lp$nf$4wO`5)bXSZI8^>|M#8*KUNkcgFm`(o}L8Wl9ZEYk)}YD zzYL18@ldaUvz~`r7%0az!EI28gkbneFjQn@K)LFe3%}d7mINh@91B<1HsU++oEN&;H*^sU% z_}|pnMby{@!5@8|A>f@`8c4;o){2oou6j<4C^q1-SYtLA5^6m0a;@I_yeTtyjFhUO z4Y5eG$n|>b)27Uo#}H*(-jQC?G>DD!Cg=_{?!EDfkWW-@&%Z%nl_6qC$?RLuLa5C8 zesl)-{T7%zxuu@RZjO9gif_S~9Lc#zjNGS$^66UjnQqM9Y2D&u_34 zj{5nVI%~WJairdkVNTTawiRWeiEPC6HzlRB5(em1esjqIco=a!6_RV=kh1lZf8s5z;KM zusAq|#sm8@J|w3g#X!zFw=#P;#Au^PI%c|MB)cX+7I%D5C$JwwWuPMASLmWZ!Z9EL zt2KEOPhj^(a(pkGV>fcR1a=Os!u~Ikrv!Ndzr|-54%5JYiZOxvm{Rd8q(Pip0!?97 zgL{_OVJ3uKgIz$Wy*_#e&TzSHvxHUZYn$FjPD z(+aSLOJ=UDb+V604&9N8Hj~)%d$evsD!cd05HvOtrQdKU9x|Qdos%9Qh+P`k`v)+9 zsDUlq!Ur~5veJeMc*8yg2xOZ#5%$QWHZHq6K)0`e&!O*enE4>$acnOnKz01cu$&J` zuuP0h{i^fWA0yv);CnESwt-Lbu{a=&@ku9K&Rg@@FMiEoQM!VchF060w>tAV4txOYfW;fc@(oA1CLXg--)z;ofu87Y@r1XZe{YF0@7C$x%cL5Diqd zByEwxI@1oWa{}V4!p*R5vQUB^hphjB5ErAH8L@YT=WImpm_Y3|1TUf`r~C-=!0@cN zj%^iX*;SG1<^y9G2=*d~Y0x4xJW>XJfu405A?X6lZH$&2A|&0cHdhaWV--nn0x*Q+ zTu+S1K9h8+R{1Fcc8~vLEUv*2`qbv>-bKKZk5sC_lWiJSAkUgYb{95?#qw_4YWo%> z(WR{%S-5J{R82XdG1c&OTewA5kFFEG(uBhVP*%w3=m)%;_MmSm@1P=0k(ETC>iaCfB7niQm-XzsTfY?gRCMym0@8+J?(HY2tB4q5 zV-JU$#6Sfv7vt_^I4;pC%@}#eHJ-nLz&_w1OLl7^OGwrBnNmC47N573Pr4v8981d3 z9MlEHICB}z#)cbI8kDz#d3?p_%~u-^rQE@1jbzo7lBf8b+y^IN+MWeaF_R$*x)3rtKIhZ**+zk>|Gl`_Dd0<#O4QO?Ebe{reORT`z9 z!Kt0D6h!`ge1nmDDO5CA`%wP$PiSroen*zv=Xk&|rbz3bGjs(zfOVN5QuMqxt8nDT0mP?;DzIYM5O9d>ZDDWi zj%WV~As9~X5nx1~O}6`ST-bX?N?@6&SA7k^O_`J)!HKxXCa*6a5uEbO`8Zu$BTlm4 zqhLu@ahV%dNN$E9(huB-Q0|Xa}`9KPQ=^6Y&iog4p1o23`iV zvUe!Gm2N90ix*$=MBhzjdyDFXCLZC0c2n314WHnImH@uSozQL%JE8FpPA1Vp*F`?p zHw<(_yNuMOwCu1u(I_d#6h~@dp_5F#GaLvrgKKm6ak~Y$AosJIp95yk?tW&($}=Ro zB8VHo6US|3=Oe&Cl)ejO&Gmq(U~@KT_q{j@ApOdH^w*AqC~Nh5C{b2Hh*KSjq-0k< z^Y96j?5(ClH1u;G`EB?8?i6B67}=!%#(dsk$+26jQn8XKKFWm4)}3k<`Jrq!@%NO6 zjH0W}$OGZN3vCFFAoo6Ctv-ZT?p5dty+lAUeg7t{Rj(ljHCv5lRVVn1LoZQV7=+{y z?}S?R4KNCMM=}64;}EXLYYZB}&0Wm%8=xP8z-l@wx=u95p8F||Hnoo3PF}JZkro;U zw!j`l_TaC<&n|~S5clozZX^6T6-P3ym+3GlD?}bNp0t5~UvCVMfg%`b*kokVD`Jp^ zd!8SQ=?KR3tINWv!^P%dxxjkojb)>s1PMrf6Z z?Sc46+>6!x71I|;MtB8l+jW_xiYc>H?pOyGy>-4jGR@MWKyj8%_lR2FGvo7=jR|zoUar&9 zo}9^g|8y$Eh#-KQI^S)XCUye2yY(?N>bV7wSV}9e%Uoyh#I{{}-}pG&vpQUs9fFgQrFlx+t!K55SWkIByx@mzV$2u5$mM$@B(%NmbTzTk@XFcbvxzRnuY09Ru?x}m?ZYi< zUl~b;$7{vU2!kUYFKhKI6bR}*v9877mRhH!*v7@#@Y{(0y`|Qb%~zIM*VdF;Z;P4E zKb&eVweH*bEI&%SWo8IREo;h4t)J|iIRo3Ib%~|c{kLSA+EG_ssr9nZgPB`9p~Z)C z$$ML-MR`lEO~!*6|4m+uaXr{MxEjx{LGZ~=wA@;1t@X#wBtyY9Q)kY=`Q5q~2?iZt zIBqQhaN%a!V{(y*)@sjB$3rZ#oln`21tiO>{)({7r(Gy!`Gz>0?P5B=s^fkn8zB@R zINLlETZC0zUTcC)lBKxVljzPZMgUW9Nop|V6*_{%i*H_X!@N|Y7v#remrKovhBc&b zxd58Csc9Dwn1@ta;eryGoUl&k-9cYpY4lHJT!w8>@9L zP{$DgWu)g_+5_cvvQ0k##W=chUL-=03Se@Z^{#u??NGr+sbcLIb|Q%Zs#vHMYX=w> zK&KecdmKdOxm*<+%prqQ5Qmc;g2-;&+$G)-BV;$;1y#uR*z}+jAC?*zTBtLmf!kMf zXLVJS_i`nG}&5o{P6vG6{Ok#6gpOO`ss!*0lK`XNRyvIjyBd5JH# zA=?6}MQq4i=sjt{I0_;rbE5YMj=AZ-kh7$Y{S2aFiQ4(bfjTMd<4!{s;5AYVRAO_# z^&x>&C6K~!ReQNvzlqdAQhYZzmDNiYq#2}1-MK}2PbvZ)vjVN^fDS?1kh)la2%$JQk;SX^(Z*fXI{gIb8KH`TLr3?RnhV*(-wz|H zJGhV|h^{;j<0w%M8Kg9hqOrhG5wdd({Tr17hCGdhYz{p~(DSm`%_v=k?8wvjqU@1B zl)$p4GBho}$Cql4h*@AhJj7 zn=v=nbNvT4Ztyk44&ZvXnZ58MROu~;65t5ptAb+{Q>06X_>ju~rqPEQ%fse@ z*irNpe#i2#jVm_LQFIfupI@Mye;Z^QjPT4N{L1ijsQb*9_9P5jgR_*Yf%pP$jst5U z=`t64=Vt)c=d!%2O9yAiSx(}vF6$o>q;A9&g-KC&GqO!YU^T+D++c!{^s59>x=!Vg z1myJKarZR{%yta=LdZ~Y>^xM83$VGHaSQKOoLk2Yyix9FPP`OwE zff4*;cn*#50W*I*l_VU%c;y)OW(XxDaXN3ON-&g~YRL(h1$hLZ3wp(Z(8 z6YvPpFd61xNu=6fGr_*03hGiEX|M=Ngjz3^UBuIX&PgDS3E55g`B3*rsj4c37{_|l z7aW(>CB?W6MZrOZ+!XyM!!p zJ$JErpC2J%fyUYAe?+oXAREp;CzLD=%zT`NMyP2Bwju>s+F?5@6q?=%N6NH^d=gNL zgDyHL-1QLZE;sXrvDlA-SrwNF^KACrILTtz_o=|10zkoqkOehS&dW55ewGky5>mR%k%Ij<+!CUdKUj%w(AFgC;J3Kh$40f+C0@4i+m*)2k1x z9gnlO8cHlyT7#ouXj}dv)H^eDU{aTaT7(9YlRHRKjBD9IW1{6@d6y-SBio+GS^7O zudmwcY1uIO+VLyQ*S=$Y=+CIZ*jSOHla2(p0>-P@)VKwPR0^t(_B2p#C)KwJRF#ao60 zlZqwqh4YoAN1)xJj{q9qp(cHcedkfs(;GD6ql;ZnM8ls8*bGiph{M%L+?B`SI)%gD z&rQ?=iTt1XuFfd*6e|8M_RH^4Xvs`y_d`-T#U+#AF`}MRI$1eCv`8N~pNH--nbNr7 z3Scb5aORd3K|c^m>3}TuH0k6uR<3E}VNlb129fWDTYszY#Z|6uwUW)YWf$jB=B?r~u1(j#LH>c@Oj2Rjz!`;is6;%m01tgV7evw6pGnvUR)KvTuunJ#R)BpP z2h<7dV{CwZ9k8Fyv9B8z`(i+&sQ#wWvxua1A3uj9zydkYfYLCajqY0LQ}KxE2{w8Jk_UsgoCpl`Nuvp(>IYh`PB#()Q#XSIUw7?f z&qCLB8cu-&Nk5A&V>GL8L}lA)U?cD5?KHd^#t4_BsMTjQ+Y$B-7(E+uBBK;;*rp<1 zG>jXB_++A*s9{soJ2h+w50%=mUN`cF^YgQ7rZ{?WXxi6S-Y3sY_r}@uYfRSPlh1~u z5211@!Ps!r_<}Eha@kq*zY&faf%td;IEh(rCgX#*tDDc*N+^qkcOvnd;r3 z0L(z0((8WQW5RUXc*0HH3H1G%1w zm4Oh@+>Gso7 z)TkHBFm+>aW9rNy%D^$1+);z0Z;(MR$xb!h{x8(Z@RY7njcqGGGQf_9)F?ch)!o4M zV{PTVIOXrn-U~k$bnNzLs9!tH&rr8^nx3HrcBkPP>eNpCGsL2IQm3G=RCZS$CO1&e zWvZ7`y6WX*!!OdMvB-+K5*&qJOwS+{MT?amP%478oS{^Sz9N}_MZzltWoflvGz9hs z1B6{YEg5wgI};o2JFQhOVjT0Cj0TE1BfF;$UFbs>`m&ou7m9fonnV|xL>HPw7n(#D znzSzLuY6DK!YNLg=^!woOB;Sg7lcGJ3X6^C0+(n8bpaLfF5uUoHatQ19CBn%2lZ|F0$e{}+$=NmPIl!7 z*ZG`z+w(Pb&P)i;nYU>!(12KycxN!nP|%$#rp~ggJ)Q~b#7WHBqs|-3i+K~I8Hq)2 zSH@B^1_SCAd!x1LB|a4EP^A+FG3;&+Z6wi+6H4BRk#{3%{txJiHvI>8W#5op5gi#p zKfJLpD!5R$3}@#5R|GO2%$0^qQCSNZFKnwTKUC=ooTV36m)DP!vZ99MRicsVU19RV zgjo)1o2F9NB$c|X_(i&86BHIND9n&pC&pwLt~`LcU^wu0&)$qZ8O@0;_GW9D@@5&qGU`pqrBVvth&1FHi;u*q#2%7*OuM->N>C#*py>k zX%us0kLLn#s&w=w6~DRowb=K7AMI8bmg87hKAB3(ip+97X_xXfB?-^qY-F6S2WO*S zBX}468kG7GF66_F-iXu7$OwX+z846gr7U`lf+V#CAd}KdNZMGS42cb5XF(WJS0=DI zu|XsZ@r4(o4(uRvJ*~W$)mV8a+xL6M+TZ3YF1W{X!98;E1CEfc1Fu8>mu2iMSqu~c zB^;GN1q$qxMknbibXfo7##}7Cgvh~b;qYB%i%D76_=Q)*L2G<8miSutITrB(7tH@T zQk4Ayuje}aEP;Bt zh;srW4m66rkqXYWP-BCbxKr^j3(iDm{}H0m@WiKnQITQ`OG%$k#2~8adX?xwqZ&-9 z3kOmRgxT{TDPY0{6B74;nMBJN7LW}|A4E6w1%wlpFZeq|q;iYW133vhkz*MRiCy+% z)~erN++1ua>Kr5`b&Js};Zo9WAtmh=Qqpb%7xZ=uDTy;ngaA->X6*7@jQLG;o`zqN zkSz9HoDCAx#0G_Qw3}87%nYP*849VKp$h0xVL#~cZi+}kUMi}sSkO^-k((9QNj*!o zgT*(6S$tEN#Wxu^_ixfaOHI@EkF)q@O?J2#*iOfXH2mh`*8*&hMJ54vKdH{0%bES+ ztUAv`!R#$rbv(1+^{AQidipge4H@O;p5_dHVgto0CsD}BAOMB9DD;iH!lDquPK~S| z+EO*BE1E<%xGQfD*A?E8k@dr$xI4T4SqKU$@^lr7AC@iuw59BvbMVV$5KP};nTjZr z2x^H#q=#0~*k~LO2XJiBYAiI<54_L*^c~p!r9jNUF~?Y#NcDi!_1JF8%hPoYxtU}t z9XWd=xJ2z@a|mr)Ze%y8?G8!X)(BN0796=TU0q`FXmBYlT=gbalZ^eI3{WVMuvl*Q zlY|S#K_U|78?70beo6}_7iiZ*%M5Z$+V;1EYBup*0G4yDbLT=G2R}a_p`j-0;>jmb zvdbq!($}>e)z+C1GfFdRx6Z@_gi(u>rfD`VQ#t$8nlogQISFu2bRoJPkeuBO_X-@2 zUgza!WjH{J;rb&N{bN6ZA>}#1QlWA^hNY+!ZWuTpYurw=y1VuU&*fZkIRafU=@Si! zyETAs-~f|ODN;v~&?jRP&-KaJ#6y=vVJw=~_=i-24bv6T1#U9unIrn~ zB^EF*h=rVB5%T&&1h<3H-tfD90OU?!EpMI6-JtG{Do4I?&YSB z(^4wL@A)0#cj_bJ_o}D(?`{54s|%GCb)eu5-PA4wW=83!9+}LIKexO%fqrl6Dzz@D zFSQn*!0&O`U7o@74&+0rqIysoJUL)eReAC=6t_MM`p{Jd&VZ{McOJK1d8x{G2+rv+oW(B;J*TDQ^5`kPpxl^`T57@}VA4Zn>zd8F_n3tts93z6(}}ctw{fOG*to;>Z7b{BJ0=jsZT& zN)(61Dt3`KsSC{gH*JkaDY-KZowy}4Y+*|exDbhcxRLEQ)}0EWgEo0b8g&q<_=^t1 zt{3gE+?$Sv7GfJ#U80}heM$iO8#NR|&^XKl``?^gUrkOBXA(Y=>|_ZZOi~kOeAM>$ zLrp9TOumgB@^@F$eUW;P2`|UGYjY(-+h++Mc?@kGff*PqM%Q~L)_9Udo zsO)g?g}_z#7}$kB?X6@5{vyUqG+?M}`v`fCJl4K#Ick1PG%!or+jgu@&7ql%*CjMb z1$AwmK?4=R%kPmVZ~$DM?ZLQG%}5;8c9a5~#R{mjIz*H7;Ujzqv~>jk*4`TMp)7s~ zxT1j|=q0NLX}_vWfkIwN`zU}k5^yhQX?1NiZHEtBx*NSb)HbkZ8}YF((%OcNgweL9 z*2Cenw!>{*R7GEF+hgx`JRwbJt2vnT9x9_WRERWB5;wH3qjPv&u$NoZ2ambrPLFZ| zf6d^6;_qYatIX^Qm`TAsrM=YL4$lcsNp+1UCP3F)4BBq~kCAA_1EXT3(WT1cOMs1v zJ%)-8&;03zpsDoL8^)A+A1@&k{f_>=x)4qVZGZD_yc;hnYQ+%f9^2p}R5l-OKH2Qw z;Lo(aZQWi|dDuiE$UDYXxy}~K_zIe7YZC3W{Y`Bi3BThF|E>A6<~KIHfrdA9L_yJf zr1?m~j=``n(!aDdwYS!>9W;vFM8R!G>%>nLpHnDwESk#WrFdx^-&Z`h+I+cYb+mO6<7@k@y{%5c zS|B!x^3HXoSTADR?#_&@dzP!9V)Iw_u&*(SKhbgi37e>}!^Lmg7&&IG7V zLhHP9Gh^|pBv^mdnCL&8h8B-<~MKMl`GEFn3Qypj+kiPsuT9-QWxDd1feuJ~fA zPnx1toXRVfPn{3h?mk{S+qOR3NPEmLfB;|)7y}j$A3Xp2cqgW{1v62%vf*ITZ;=pu zy*=j90U4{bj9|#RRZkpD`W0pT$v=ZBk^H!$12#->sPsC>{1B%D!T4};`_f)=kEeKJ z$p}X6&Fh50urIH}nSU$$4LT14yLOyXV^@NKFt*)e9vo7Jy1}VV?#ztXz{xXn$>+*d zh}#3NT7pN!Zu%uTZw6yt-!&a4{ElR~cY^hYQ?RlMb1u1el=X-I4GdYUet^GjLvfbh zb06LD=$2WGhi-ecRzHU94UUc?$fa}|wFmx}4UU6I)V1Sy%F@2{NW0GGIM}|lvpv?? zz7&C=dBmu<$tbM482Q*Euv=`5VxJ#c0REPycsHs3k;G|s_tVbnf985@!c)pjO|0166qi4T(CRhV6 z@#lkBHK}*e;GY9-vPNXHHxM>2K;d@BiS|k4n3?^T67~>e&9m-{{u#6%ZbMKf#Ttp1 zr*g97@kK%@P8dTzO~ly{L&+Gy{@Zo2b;KP@+ezKvD!Tz*gRGzkax`eK73XW4^G0py zS_kcXV}3qllTv%5bT#`A;ABBDTn7xRN4W}EhR6@Y`+rBV_LvG_y#QO0R)71FOp<8a z7PmQg14{wRXmZZ55O2I#?{Pr<@M7c04(LwH;C-Hpfy+cGI;Tp7>WFQG`|)dfF6(FI{YU}zUijrL?c zp$tFy8a~_6*VX4C)88bw&aGpPekhCl5r7s*-T68O^?ZH>&AEtPOS%2osjkIJ1l>+&FmQ+*6sIaxa20Hi!eqhIy9C zo$D$>p^W{BEw{3F7Xe7MhG=0V+|PVXGh~5gs1J_JHDrks#Xxv-;au^Q3nVbWT-$9f zdxqRGJ_Wp5g^NLN&*Xw{&P=}_%aLamc}b&kGlH>zrgfFq#OQQ2p2W&)&Zl2ETO)jG zZk=)`lc(|$@}1__DZlEh5loOfUPmk|N@Dwtsr!S=v_}sX+~aOhQm^t*jNg~ueN)7 zqw}jH%!?5Wofgu6CLFl*5wM{HOZy%pH7SWPA_Yt4V|XDuN91`5c_@VrEaTgb(&o6m z6>l)@Y75c_4XS~3q|$FbsoSEVQK1KqQ*=@NbrbnZ6V$p^MJLz4SRu@1s7tK41h~fIsr5bvXr&@9i-5{MqD=P(8^yGDW6E? zk>PiP%09u%s#X7pzfcUr%P2^jwfcKVXgk{Oun9nBS*uopXSB9)sL=L<-$b=6xFpA6 zk&3B^RDjF^p`U*9REU=?E^cj68mY)EX-uRe@=3jv4mClVTHOOyN*P7{T#tSd{z&jh zZAVOfjYbC#?&nWYLIujf{Cp@fJT0+6)AZ3~WapBGGUj}FGVO+ka(ye!{0FBMntwqx1i z{zKAyn2pS$wmt~(m98QkM zCEoxNR;EKrp+awh;T0pw^gSS1VDBRM08MS5lL|FYD&!g)sF zoOHJ?f{bbCIY>?5Y1(9qsWIN8E!rk521Q^3i^z{!Q}bJ8`Opqm4bLZ@UZ zQjV8KA?5dZ1W{33FKbYKIXZDQkcEAw}7tFJ|2QmKg2R(sDAT26&84eq0)aEv^=fsE8fz|lX zU56{T{tHY3br$8s5d&uugLf%w%k`FZ#RyI=YyR>!uZ2gieD z$CQDyfuTQmOK?FrmEJEApMo=@Qy-Y5reZUr))VdfQiX-es&Hnnr}$8UUzdZZA<2MnVstpLhG|v% zqOP{1Gk3$}yBrrT9cr2%EI!nhy;pE@{cOe2{fZG5%W{VmXPL0N>_&0BzdS3e5y$l1 zjxNk^1U1ypZ(-ez6MF3VJ!a@-bQO4Nx#t8)qVKdjx)6>Vsw&zsry{~kXnu8QnaAwL zjj#{!LHUfJ9}SeJBYZ_VOBJaflLKN2?tC1Ph4hG6*%!#f=?d%jL5H9={!Su%KgS@F z=sTCtjpCESOBVYR)X1jX~P_DSEl%49;b}dMu#g z^)uL4LA3;*-ae`YDhW)<^qJgJgoFq>2i6x&T|P>usr=R1d}$>akLeY_9wn*IsPh3)8ysL@yXm~Y%6jG zucdltrE>;s@XksnVTQ`Ihs)sm(llk(axDwh(r#=oa&6kOPY2Qn(S@MAoXRl$YtD*COVPiT4?Wv267MUu(|^ar+z zdTCnaC~ilPuEb6aVTN;a0&LA}^o|?UxLrZ;=#;UF9@pW@9dT60cq&dR9%;gqvB9xQ zY(}lH=!_SSK({xR&{X1yYn$b4n;48~pXF?yxC}8{zQFYQUsFWPYdAv=n%Bu#ZHJuK zI0%DWSaSxyt5ex;U`ir%Q;695bN(^~oUk8O1V>n8fhPxU!S?4Qi-pZB7B*aqV&Tgg zbfgHWvj|HLl%!By;-)^(l~AbCwj4@T#gWcM!;mx$ItqB}!u^CSWi#gyO?5cg_pv?; z0U^%C9LvCGA-I(UCu*hGDF^vEn%PD8*6x6qWC@FPBN!Ck6H-W#+R$N+F<_DK2TbC` z*yvZ+n|mQxpyI(eKoLk>*mM=rhAO_jEjtu=0oZc=ANJk_AgXHnA3w-bMHv+pjdD~_ zOz?%8I=*IjD9TGg(bN!`0Y+iKd5Dx6rQS58>}KUHD=X_-+2h+aqpp>xm3FPrEH$mv zOc|v#v&1y{eb(OR%$%7yGtj+#zu*7w|MS3}wa+-g|K`a1)E@EniJdxzP1L_8wO84C_~V1*IJUSV2)h&E^FNS5 z&#m=Da`m*3x6h*|UC{d{oC(<;Q+J^?LM86o(ixHM!OnbvH<9n6mjss2^~Qs*50ja# z{v|vLd+R!$)}9Zz=M0+@KTit|?w}kRk?WGY7RXLS5k;8PzP3Ifnux{`&GiyB_Ie7w z35r94l8D3TFfd$uA^?4GHuktS<9gf}_pZQS`h<(rfWRs4jXOts+UuA#O44M}8#r zifIO_6rojnF7J=ubGeReT1|Jy@4*+~JcP#6J_W%Pu#Y%RArzBRB;oOFi5bXKMfIf5 z!+@E1WFcdNHtAn;rOc3+6k$*J7$%nXkS4xRBPEl)XQF44uBye-ELxQnk8;7wZ6Vu& zLCQOVe%PRukHs(!Yc)RrSyw|%B!*&d?Zx&TD*VXQTUdtSBs%DHtOE?YeB`FR%TKJW zz6bAt%j&7voxC%YzdT;8MadxlJtyc(Bh~ki0aoJFks;naVq%h{a7 zr!6xx;6$vQHl75JLc~bGx`dVPG(gTN8rKQ7^1fP9W!U-VVk;*zc`6r@4#N`q(CV@_ zFqbduhYyZf;}C#b$uaDaS;?c(?;p!_Xym!sI9vE%<0&YR&!t0i@ecN#-FP>hLZXW< zn#ZG2>~}l++^u0$MyL7f!xK>^k0v$dOou6}ehJ874g>26T6C1KqA-~dV2eTQEN&zO z+Ui9Z{IIIXksk~TwFj(oA@pPInL{Zni}KhwZ=y7EDwh|EqKqR^=Fzv?dLQMy%(+Cf zGb9bp(GsA7BfAB~#3Aj&wbC#Xp&$_{2qq}H%@47U1FlofoxVPdESSi7nmNw7MX zW1}Il&Dzeb3yR#?$&@z6A1m>eMj!d{o4txiJk>}=$8$@@P-C^UPoNNlMZ#Qgv%Szi zw@XCO0D%{hoUu|NIX8;R7?UX*7*a-mjPV9Namp_;3Q;hbBlZsU4?r#$t^fN4OtIAc z(TB>Vv;)jA9;GyEI=aI-IG3aZWov#bT0u|hF1J8)Icx=O2C7cN*8}5OEmzIN5rbhX zg2Xb#C$Pe*E+K>B_i76?KiP0fXi|Hz)vx_1sSQ+BQ}yJguMZcrt^N8iW=61Dq$|!= zv-S9f8$0i$15g8bzhHGzdziOF*nB7%MvweR!}8XmvG%SmM?RKJn#odV?YSUWK4F9{ zSe_K(XEOt|@v|)e2=%k+iJ5}&7(t_Zvm?6cZhXOKmn|Ji=9xky_FN*Z0|8D5yp}tGlThoK8K1L6)H#M@Pa{K(cGtAbFzG9vnfHg@YlUsq; zkwLbg@%Ej_BsxBZ7L;DzNwTnY7ZE!$#85({Z;7l2Mom1XwfoohPYT5Wkp)$?L?0^r zM9%zSC>f1+ca7hH0 z2f&Gr>AmaXcj7yN1*-$n3#vX|j*q3>LO)^nu|*cNO-E5Ez+sv2p??WqtAe&T5DDb* zgHQae+cEJ^s#Z*n81_wnkBWNOTiT$iy53(FXuiC|)?;&+tqbBCsSU8T$8RfJ2tEmK z^GEB;x?(Rf$>E#U45J;x2qp~dawawppaZeI-q)6Ac_u>AVQ;0ks@h+BHn?{k$p)ty z-1KYh-H3bnSi#25_<00alylX9=$2E?wPA0m>fBXBUybO$ljYQooC18zAqiR4bT_@6 zGd}{KVmWkoIC6{kKE$j_Z*@)!^HM==QvmWQsg5$}{g0|bS2lWP6;g%Xk>;bNLCB6j zB{Q7jrxS)Deth&&6o2^UyHR47<1`|vAB8>?mpRgm$4FN5g61MdV>Q1=W_|Kx8gpG^ z!!C#l3Q#`gVyJWM-7#nqyP9+CZ^HI0-jHPzW1U?Q82SH8jd^*RKO9e{Gq!LY)=t2H zUw85S2h0Y_wjMxb25Ek4YK?CT;ImQSB7Y?5Ud-0sVQp7`o{ZaUfyz16ue&0xZR@{g zPiT=vvqO5uG3_^9ex`?wtUNtOoa;Khz9JDV7*3LSa1?Y9%69J$?^x}JuO_?dA{H1Q zitWJ#i9@Qi2!~ESLQX?SvaB>-KGgeqRcmZJzLHbl0Ta83D5pLWBLE~IelJ>pM{05I zhv#sBv=t9MmVj39)_`p1I34#`lew-p*k@tw7)(o6uU52$5hpevrX84at)KZXo4_2 zzodVTFvTb&McWJk4FCUg8iqfCMpDD-mXM)jVLby1Mf?HUlss{?KbCB0!^7U1i7&}U z_}Ak2wVP-ITUjW+^4Gd*Vu=5znk(iuy5&1!G@qO6QC@tUP|Sq}`tz?B?ZGsB(T*4W zRQhK~teIGhhX|SA2jh5y4>0|4flGX~p&pq)NJVg}`UPyTPh-_=@EJ$XGWi?-3@T#y zo~CtF)%d8|`X21~J#ktdd-WZ~g|C2Nv-|OT`TRcrKo}LDf=i6zw zWAHXI#L5&96D*YK$jl^|OhVsjiyl$I$SDzMqg?A7qMD9Xi{Wi|*kY=%a-U8!k3Vo3 zAEcw@k$@Mfc3sxv`JSo|3Ht9pHvxW3j$y@SDB{Q`cwH9AImw7#-Xfds;s)p--+?nCm;y=I%Y?;VvI?g7EY8}>`VXmXmQ4B8bs!BUW zH8>4Jp^NrAv%GCgLL4C^s_Ejf3^IufR(FsN;zdqBwmJ3z`F?NyGXo?5VJ0V2spA%<;c1S z5-Bnzf@R%d@Eidm;lNhyKezt~%ete;I%GAlB3af&II=EW%sLg%x(H-gB+ELMiD?zV z9=Vrclb+4FBe$8Pw%fTw+VN_A>f zNdG~|yk-Nb%3v)?W3_jUHWmHpPR-|g&o2m9U4e)q87eeAc6{T^h$huQBj z_IsTDo?^fC?6-maUSPkM*l#2Iy~ci5Y-Fimzf0KfV)kogzh&%~zAx7lOV{9b$z?&;d<&@{>_ zWZTLoLg@W6&Zi3y~NKQDUfqN7ov} zS}RAF!!htBS6v%rjA5Liw!moXouM$sP^d;1DlrtQ#85q~bVz?Y5NoF#-G>~bJuuoU zV{Bp=>0!VK^UlyRU{xinG&-!{-~|c3ZOc?jTutS1b^yf=%5e_j7#)GpQ5mB>=c*Gh zI(g@+9;;KUlEXE+a7j$zN(|Kk4a{~1vChiTJKy)%@<7>dy7 zA|!?)lo%Ssqw5A@-ISwi&oR0Kqq{Oj11dI3_D#UJ$vZY4qI`2Xa;UvngEdG1ww)BI=u&zE2A z5q4i^ylsklGUK;ERaNpSjqX&~ihCrrr8}h@?{}CfMDBi%c)wT1sO1=^fpJWjIS6*`p>}l**jZwW_MNcC5`S9|7sVoFM;kQWtxBCvHk+A zUz9QQ9OGAD{Hlzh<9uBP#%1q(MKZn`HM&N*xEhs7o@bR}*%gqyqKxqg$M_8xzbRw9 z%rMe%HoWetceYjnt19`LMt99><8Addkn8B)eXz}i41Wiy-xc5L@b)_1URQh@1wGb; zw@u#Iu%Y9C!F!X8pD&-H}O`|7M^b(12bGxcSRsv(|yhe9k&enNlwz}|0F*eY7(G-_(JS-UZ zp(ze9jC8Ikyt1_gSXIeCYji)$+4@>yt37qv2|Ia z!wllRtcJq3ZP{gIzRtivi?`_1>%3@+4>*PoP4OJVNavcuD_?YKa8>eEjqa*kTvwIZ z%H)w=16!mm6l%o)jv;9b1&mP67S|eH**cBh17d+ohxQ0t@g?qE2OaiZcvO{qQlmR5 z=lrBHUym|+%f16mQY{L6SviKJUKB8-rU9>qm|5M>$(w`X~E=j7WL^M3Jr6IED{3Q_V2axtj6HRv}~SqDFU7&X$+{$tWHv z@1H2L6~QrlsF`0IDQW3k&3I+24p>#mziM=K^iQ5;G<~U=N{#_Fv&@T{ zxr1Xs&7@!P){2L%9KrbdO{4owE-o+qleUcHGTuK?6qg-qg29pxHS-a}Nat$CtGJ#4 zRzX$r^#YCVdf1AGaA!}#K%^@9ghqG5A;A-f>V&dRn9CVC39aEpuZ-mwKJ-c?!${|P z#Vf17Vku8m^7k6u_i_n(8Taf3GMM%;?)f{%@S#^$GK_StSG=;7%hny9`{I?YR*bDH8r>B+TVBRJUto6uWa(qv^AC>UL$5r< zFw(hR@ygZ$PRBls0b)hj(_2s!h z)i>t@RlRXP6ZhkApN#vep957pF9)jrel}3`+K+*%OBVxGx8h!f`v~06!TrO(2C6FT zfvS6c2vmLeQ=sbFFM+C)^?|Chh+`n`4Y;3-`+VH5N1UG^4#mlV8xLvpB6Zm}p(a+D&xlXf9fzT^-$;T3$06MXeW% z?i>RRqn2i@6=*cFX-+fdOtt>~FW{5iRvd*Z?*w3*9UbOUwTlkv`k3ZUbpaY}K-h}a z5_j4FWztV_(wITj1}bCR#W660str=cn8`6PgQ^W~p1uBzy%3ESo6()@g(#DzGh!h< z%%^HwD`Onv80e8`+bCna!!a_Z+fEr{49CFi zsa`qyXNq@&C zQ_VMn^v%i`wHyNzvf5jeG5Dmexd$+MG|%2b(3`KmqyKgPFR`xmdf4*cV3_ki#z>FPCF%+NY3P`xr~`Wh6Nhe1?pSH_@^QUC*%3hh~C3=PMCr9ykI zdG^{d_8K%=%+xyBYfvVAoK1hT%f{bMx$dMl+ezW&9gU%vDc{4Vx;e6uThz_KPL@)srHI8 z#tBxv%rInVe^bVIpJTv~p}pEXdvvr)mF}8GdyQ6tpi85@#>gI}uEwtFNE&xH(f6|d z#%nF?8rt8LG0Hgx>>AqZ${5oa#_h1gXq);UX3OY~l2s#;ukk}Hv`31qn5PXTRl4sq z+V8AOIbYv_rst}_gQRCbk93Xa+iiF&=^4+r>+x39G0in1^T{5eJEPHJZdcTB&^>18 z9;Lq9XkgFZ<_;zGlpaMP%<}h3{lB6$KDT^^Q_Wc)@U*L>tqkQ zM~S^1Y=YDb%IKy-Y`3FIz<%|e>ACEr8}$9Vg}eLK5zXWPFn2$D6!X#WBAZPm)WeR z)X`~LkGRhF+?5I9D7y3uG0Og(PC!U$)30V4<{}5f0Wo8%`trFpza() z)IrU$*Fe)Dy5BTfOb|QS^Va`iGp1&-|D(j-lN>|RMG95-E{-AUqvqI419m}`4im*% zOca-~YELD{OD`ycAxOQTuodHQ57UmUCuC=Au%!G2iUW5HF*-0i3jt(Of9U@S)Alve{0lN7WpA z+i50MXV+*k@9bpH%V_RFPTI$4u7qRw&}Nf4hN#V&WAA3h-VYir=AWJHc^S=JV3VP~ zMsuHX3?JHT3&#+(S##_yqls1BPZ}-ep`Gk`8O=@MqG^bP_+i?t0n>EMY zx0pVy(*2^*VmjK%o|n|->ymSgzPW+sjyYP06p8_(FgqS0QF22^|`=hhnv zTRD;I80SdN1EUYeaB4CSi~xplJJ)0iJ)^LdCwbM9dR7X$?!k+!8z2tb!dAS65U!SH zGB6u~W#52T*#0-5O^~XneUR$AjzOxsVfuNxb&%?0yC78}?k{u+QVFcv* zpBECO+7ue33c~#xor6?6gM(CoxGz)%sXF1lH|`7C2C4Rh1*xpzL8=u&L8=cCM-1-2 z=oF+n6&R$t4fm@N=P=y=Uq8WcBLO!ga6Q<*RG(RY5+v9=ImaJ#K@56|VfQ6p96OSE3dvkcfmS6V(1YFrRi_=cuMlt|Y}yX{ z62PjYRWkXlg8Ww4^?1IkI&HIk7DHTX&mvfDg`w5n&>3MwM(A4Zbj9 z;1n^?-WvmwphYOrnne89fp|@127-U~vzJ6G<%*Ngm~;vF5rn@s1^8V(@TE*8@mxT_nz@8`{-U?^ zN%)Px-$D3m(}DlKH~ji!yxCPhp8bxZUx!4Avt>k~j$&M@Ou>Oo@nsTrb~3Otl(F~i zt4`Z!uRDJQOfaO+NJa6%VDErwES$-S?wN*qTfb#D?cN+M#oV{o< zaaw0rQ>2o-_fh&OoN6+q-#wfZb9LG&dwoY)I8rYWjAshh)jgb2dA;URUWvdVP^_^M zfiExkPBcllNFM)g1Yb|VH&O7%+=ExA9kZ+2$@o1Cd?HYDknjsV@weOc$fN4CgZ9}B zuC*Wkf$l5q{ZP!S(>B=?+4J@GX+ivcD7)WoFAR0Yb3bVdMD=?IJex#?>u30Cu2IHb zMEQ~A*&L+!4qm1B58KZ|aZ`zY4sQ652voownPaFRRy+c7S3GDDp~u3(?*~lD%1(c2!#4 z^4d^)2jp-46UaNTe$YNvuCPgjhe$&)E%6C_HO15g*avJ+CaGJpo5^E`eLI7P?OOpI zDW(dwijkwjzl_L*W`f*OMRLfGdQ4}@!q+3zL<+T!n3&)msw(M}tiN=M^*4tiey7Nf zgFrA57*Ej#xf5_pl2ZNa5iIY|Q2l!gIZ!ikD(G!Ht0WaCQHLC;KUGP=woXB?yS)Xg zu5O^Z6j&!yA@#ie=qTG+w{8T{iJ<6jbEi|Cw#L5aGb*<`?1ij7IBd^laIHNDu>J)* z%k;JO6uMhacMcv`fyZN{kXbAT;Hx=CLfa24XOdie)#!iCKzt4w)L&aqA-7V<$J|3! zS095F(H<=ea{pmGL8y6-m}gMuKDflk{d6unNR>E9 zERdR~Op3{!`a5;9_GJV{726vw?s4j9aP+ zKTX~bqjI~4@G}YjBTxLp_LIL;3$ew15$TlTk@_3e2+E7oav~Br9YpSRCn76R6o2X| zC!I;G{!`H7(-3rmdr-n(icTKs@q>6-{~-#8vqV#FwV}}KNjk0FLzDhLWk2>Eg>SHT zh02upXL7BBUaZ+b@qPxXGA^B73co=Ne+at8CHz_nznArRQZCW2v+ri|-)P^?V2yn%pbOut9CVj4x|A17mFd!W?lrXUj__>!N1@i{ zAk+l+P^9M)S-gksqvi2#hrCpdc!P+-Rw{gf?i8GPNj_>0FQIct{oD(T?m_!0cE8=; zmGwIg+QS&!ZVwjWZub75{W9w}9JFs0@wX7R zPMVsxziIH*G*Hs1R=D!ok~_-x7?zH8_DjbpT|4Xh5JAm@(EiR(Jn~guw{xi7VzJ|rK*}jF{udy#hAC>Snu=~ySb%2iir8cL?5$PQi z>2Zp5j*m!X%v7iCu}_3B9rU(>UW9{Qd!jd&#Me%l9`V%+-C0L?s%M8u!7?Fy3SUjs zOoaagl}Hw^rZ61X7&Hwolv1l5{S z94L0HpmKY4aX1+$69iHdu8B^y6P| z<9Z<=j^ER>xbA`~;wJulHl9x!D5wsM;P(Z2#TJ9QPak!!2?lFgsoqv>n3!kM7aNim zs|)gs#Rh#ZM@+@WdF4h^nYCiJw$Na*rk3XCS&gNp0r~kHrC2Zu^MrEznuIdJDpUxw z1+7ph7;tYDQiW0>U&w>c2%kw9fIBguBL)HZS@=s5rV80Yu8<&P2k8u9cJCg9#Gq=B|xu;INymWE43J@%&>PgD2vwy3#zEzg6f?(XBqXw z+YxtQlPE46eJ0G7`71>~y`w9Gajgc21>mU!JeI(3M%i;-I;2XEw^M~olqfaIW*$o3 z0^nL5NYju?DxEgSu85^JLFkV^p6YzyQiPVGEsjkR#(Y1U_zQoz;`}U!b_hCX)MMc zrN@kVqg(@!q)e;XBRMUqpFH+VM*ok*ngz~CCs3)gh(dPAPYp?znn$VgOZA2^(Ka<0 z9Md=2B9+3Jg5tbFi@J|GCnY^IduDEOs&+zdnl@{4KlPX~YW7l|Z7oVi49Zk7-?lPH-^w9!gv$r)1{B zjq)!49Pmu}Xh2T#9+@(>#g?CMu<+KPC9<|4{mwSTvn=N2TWxv8)F$LX1DUL>>ziXX zS`EqQ?5fMnrB;Kwz))^5tLIf%4HmVvD9?lvu+V0(poq9L`6QkLXr%%kY=0RK*R3Wv|qAt!e7ebUwh#b>Rf-T9@ ze58#ewE(H(TGgBMDDA|3B7Uha%cVhOq8RsTlr)kRwdrQGkX(vR$;qky5t)(nw2U6l zO{t&B`(vc1sJ~33B3?s{;Lx=fss>-Y&+p6$?xR{s+*1gtAD++hm{Le3g7_!M>o4`` zsAVVmycYIlX{Iq%0$Q@EY%E2+7i!6}@Qj{NkA~VH?^l8>PS2X2gZRAHb$Qq%$bgRr zy@wIIa9I;Ga&i+g(z7yBc~79A)SPd~)f+4etfggO)#X0dQkGZF#}%&6^KIrbbE!1a zG?mH-fQHzs%rF&Ks7p--b!maxC3vjsEsw?hp%_K18Y5@5GX`}@UWIy|L2WTO#~E@7 z^N1|vxkW}jjnNR&dE?|wS86Rn4T4%?=@(I?xTIU&|IITiL`PMw7jlR$`4~e!QdFZP z@Y+MADwCBWsVDB5w^Ww%p}lBaO=a4EevZ@&XHhtQ`T~>JfiW2KE_OUmfTE!0Hjk_b zYEi=%VANC*t1dI@(YudT=a=Y^53dReSe;Utu@+s8;;+VMQ zC6Ct)s!=fxp5z|t#e0r^OPEd}T_kT0ebJ(kRi?4bpw2HgQc5#Z5>XaVSd7*Rb$*c{ ze}USvz*tsh(2r8X`jVbkV$c(Q0z=P4p+(D=qF38Y7F$_ashMO}YC=(fV$H}>FEW@d z(okB?KJ#;Hh-XbrkjcR{ms6OI@m`BD4#(dBI7zDRb_Z7t6z9TI_yBH?>K4WAPQ|#d zd`(dOFrMG^VR%54&zw4o{Ix_G%j2KeOC$&q$`P!3c0BYrU!LCD_rV%dHD+p z&1m8EYEfats%;iBPn4RCg+>$l0OE7C(S(*g4|(8T)+i3wzO@wVf8LK)YLCmyWJ5tQ zs+P2m<&cN+Xiq5?PFUVvSy=mOWo5n`HJVC4^&+L-pVXd7WrJ!T=_~hZ+0?T9j533n zSp`R_6N+K%fxz=iO;&ShF{*Z%GnB!!D9dV|HE0fX#Zvpu9we%emZX{ zW|;#{`KUV;nutp2AVB4`^LVrFq`_%C67Wak%Yr3O8Y#y6jAND~syKE09LiZ)GXHSA zvzYFZQq8%D11Iq;^?an?eCm0QiL#gRH^e;~{xtrE{Gr_O#^2!oHvR_x8~nv^Q(m&G z#VIROo0INlcakBxRhE{NyBL?&IvJXq#$nWh^|VE0q0QD}^pM_+T}s~mJ1HvH6*rdI zZ6Y)SjkU?5$a|o2E4yTeEpzKX@UaQE#CuY8(R<7U=3*3c3D6R`dDn;1NXwUn%)2aF z+C!2vEZ4J=9`!vgAiYN86RTS@XwOxpJ7d01ZzvFd35$z z*C_;O^TEOpXu6@oFk!fGn=nEc2?@mmQJy*1%Iw2~95gI=Xwc8rIl2#te7GUm?Fo_EOUfZWwx-zy z>U|cnGEd`F8h^_BD(<#?qR|q$lSRt}x-`N|ho9mjrxv2&q!A;{e2}J~o+)va3w);? zdXSekig=)l_Y7oe|YMql4KYv+B`#_7%GKxken)F-FD93LHXK3sdG zIc$7EJ@InZ+B>=6<9f;R#buI?(QPXJd|!W*FL|B!&JRh2%EKS$=#TP4;~#g;;GHkm z5s^2^P-&&U9k-HjtUt<^Tu!c~zqt~_!`w6Ok-S`-aBulcPahV=4iOEc=aZ+nU zHd~r+qrL_8`3aMUpwT_eBRShEo>%f;Oz4soup}4r;sa=6JflU>G#5rksn&I}H7G;iNCcY49X_;$xH%XYV%#WUV+@WqIh7Zvtd!d^ zkEorY9_ZeTJJAI$b1*6|mEwE0j03Z)belhFHcW#?BCnqf8{z!f;_?=YIe)fTIQf%Y ziwTG(Yr%jbSv-seY`e2juc*gMePZ4Qlg*v?f#<^~?{m*a*)s!=pu86$$H~PzT0uh; zNxv1q>f#=+oQ;;$1*ybK^Sw$X#nZk++Jov$A=+Qk0%W@t7dD6th_>3qB;B+L^vG(? z%coKPV7Qd@?4+sb+EjJY)TtR$N2!bQEQyABwn7>>u_<|a0`ovgN!}>6Y%ZVZ#KO&r z9yClpAbLwYVewaEy+8o|1?`9t!t8OJyMTHDKBZY6}2m=C`0p*XVf#S!1z$E&8dZy zU$8-v(NU|{V*7o1lv%a;3vEWTApy1_!(ywr)C^JDBtn3)FjK9?j=O;#aVQ6u zhi7p*D2Vv6Ooxn#*2iL=3T%@p5yod32SSU-9xWZCkWoxrVHXo!)=%VwM@hC>YO!2b zu6ggnS!4xXR99SePO}<|WdjyhO~dVGyltNb?LxD!u5BxE(~@#YZ7a7tc`u12^U(SX zp;m+W9I|Z*{SuU1-YO44Ox(ife5O?D1>qQt0Y#hg&_ThfyJLA@C<7&ydW-TtS2mBG+mlauLsh-XzphZF#e@b zsC=Z(+-6KM{^VoS93$#exg|@SQE+CsYktc|2NtHsp$hwoxZpZ0#iPrJn+?hBFkO*QPd>R?*NnN*S}j!AlV+yUt}&Z_5Je)bFF!nbJtj8H>Qe zSW$wgUr2Zqf=Z?q;b_)huE*TlccSy}#P5`amgNzx<93Zn&Y`RS--(aXLu-SKkRe%` zY3+1NWaS#O>)pS@2gPY^QOva7gygS$H9+4y*pus<4TFPKCsf?u2>%CS`@}63?x`e6 zkPXhew9$dWJg_y(h^B-${_y5F`AA^pk@wpvEu`H@r^$N({3-PfwXiv-0CN3G^@c11 zRC~w{P{3*n)dDSQ?Q{{F_W~1}vAz819Jio@$@z<+X(Pm#3Yi@IRYg z-+ai^OLHjHBk^eV-O?^L`>;>vn~h~KoTC7EJd>3KE=Tu#kn`2NHsU3xdA$E#*~&}A z|6F=nmPanUiFMN>R~%K<<4v>q)x7LIYj^Wu{`c~$dEWk=^mx~o^86uxMv2jCrBw=< zDVa&RQ=W z$3Z6%?ZA!*-X>%Z30AdF;QrU)FA&>@(D-0gylB@IS4^>?1n5ua>wr8rY`KmTL^S6x z0h(QIfpQ%uOlRpL-LJe?t0nzI*R{CP+$;6gd28nyM-oT^ zFS)%X9endu;(SI<61LRNI{S2qNF!O{rP(N2QzozLQb-P45}x{9w8x0%?WDGpM)uSS zQE8E{)}@^zGcXpQ+52qlSo3zx7Hx0N9C5X~pd8QwW-*gfOa-M`=+`^d3FkW*X{8ah ztK_9#2DOmX*CK78)B|wm%`;9OUrXX@X&gw<6q~_Z!K~0?aya)>&~GPcRvR?>VO1*_W$WbBg$AzdVA)&5 zwT9f1I*M7qFviG4KZ~tF#QafdNuJR}W;!h4DmF0VZe5gcS5cs_WM~Mc;yfPz4#~7LFN)pCfHq?j(9yUhN@ZpgJ zt;K?_FwBlld!PkNb!lBc?8j4g6sbd@{(pX(RG+6cAAVD=t%XQ#1(*jdzxk+tUoNp*|?6eew z#lU+N=ZQ#o^YXC%wzyc_!pq}72%HI^BjF4h7OYwd*+}XUpv!T$iIF}XB z81|cseR9QEM%-_dIvZ=Fv4@9@)|C1AD6A;6w7?iPG;#ka$EJqfP;4ln)wtNNX&4~J z=m`|!vsRR~I5t@5U}3?|hkRI;Ek5G%j0gSsycS2qk@Z+jEJhfM^{whWHKt*VDDOxu zqxMJANi*_i9r~ao&x-ZYdi5-}%6*Ok`<`^m zuyDuJLb@@GZod}MC4PP8yNutv7~Q2UqnoF1mb9z@oAXSC1{7yx?p^ZIt`wPKePINA z$wwBMqd2KqC`^>t@{81%teZ72E^iKTQBrELs*&ZTdXzGYLW0FA<(W^|ry{36tN?`$aO z4`?5=p$t0_Ad?Kf^W)ZW{qJHNnM$qH<W=KZLiH^gul#SXC13Y-?D%Xf|Wxj>%9? z%UG~-P~s?JWw5FUj_&gcEG)$sRFp|Neri5^=l%`=8VfQXKO3S@kqN zWDQpaR|7`@-RD^)x_ss}4t*mFc1ZA51GH0uY{dpVAv@QB zxP5SSaH>l119%wj7~FBVQ*iZg4R9CWF2OazU4s)g1*rnyLf}H-RB+*NYPeXq5paoc zbK#2NR={nB+Xr_6F8q1m!0F*uz-@s$2p8}I(hoNRZZupX+zhxCaBJY!!)<}v2X_HZ z{r4bMD%=vd*Wv2m8sVZgBOKfsxYyxkgXbN9hvBZlg};b6;3!Z2%qur{UY^CEk0F}5 zx%pT=#e1*0xn+6ia>BqPq(tc)qx`FgMqRJx#_!bbDDcrMHYhJRx;PFR<&W7%jDZqf2LBy!OW^t-z!G?F#k>A+ac~3SqT$9Oz-R>S1OF1ZJK*LnDzN5Z{QzwZ zn!9M8%uj-$r+7}i^3no!Gna-l#jHz!lUNFESk}dn2#S(4WEHDF-`9 zGg}ZZV?*tZ;=tia@Ik zCd_r>wS+xkZhmPQHb#0C>|C4PimnhH#vo;-FgIzUFn4Npb_(S&&wp8|aewB6IKopM zp|a02&OlyaZfS|h$OfktBQHI8<`f>UO>PCiA;l= zQ}ZD_<<=5`xaturTd3ovP8|AC-K&=xA{5lw&_n7($7Gx+20^VORg=K10M57Q>Z>Kq zjIc5sE%iOcz+$k8MyLgIeo=)2c|o1Ph7}kC@zYAwsbtb|>X3x#qZogqU<;(t1({6Z z(1nKa1KNh~(JeHX3}{K>NR`r)xp2h7+&mZ$E9jseX24(rHz{3x;hBrqJdh`41ZUTx zQX^}S=6XRHFkpZnt=S~ooD+|6Ks-^{Yop&oNk zQUn2uG7UKMrdI+l-a(8(k9UhFt=~ke_-pGS}>Z}7oe#&i zA2mum9W9p!b$dow=tCHai;ZO#qlG#WxMHc05OjNi@h1+*;`J!M4CkwqlnJqF&L`nB zJ^{feLi&`7X}_&+}21mBp>;~tHE4=)}A35Otup8NaV@S;)JIUIsD+bf>ERL zND)zw4)5u{%xI$SCq3ymOAzkDc@x&91flcs%z~d|80XS?laj+@Vd%(Ul^<-%-(Wu; z5LrKbEuKx&398#+2Yw7^{}EmTo;8dXRO4XxeWMS5HgQz2YB=cKKMG@LJSV(Oc=qEk zL3MVdpi0KMmh?l~R1=Su|F+xYMVI+JWHcSTO;WRpCT$3h;+R#}M z=&i%3X)rJomaMesOY?2iD`tiXA`0t0=9DZvQiWfB4jIjtD(#k(W(tdtqvgmqS{+C` z*Jys2%AO=U)H%qIR{ap<=hD#%LVA+tQ8L;%W)S&F3{)bh?9i%1nsX+oT$X7sC9VFY zJzrF&5ohi;VlTAy$H(jbnv}0=$*0p5= z(wri#1EtfmNKPaN>C96-R;v2C24E&qGOtqoVh%rT#M(AmDtI)tgi~7_4FhmTd*nF9 zOZlJ%M|8H8wC+`G^h8F21R+T96QJn)gM^?~s(_@Vq(Hic4T6Ml#i&PQ&Ik?>ZW}Zx zCo>qzP#uC_A!KgRTwIv=D_e{!Bp6SFg^-XCyaG1;Q)rJXsIu}emG@L4LjS*1{^j1v z@W4RCxN_ynK+Jg#s?4lhC4>kueMe;GRDuE`&CFayvBp%cszfLO(H0dIg@gnzE-x!D zD{D5s80rr|>@i3`?UX4N^8nH9Xe)AeGyDOf|52I08h)gQT@T3o56b*&W&Vd`{=drn z56k>pTRCaIDf5fbD1uNtMLdE(Tx+;iLV&QRoZFlNgdkzi9PX#*7q)Ugo!(0}T*-1v zJA~vbIuc6FNf$5Nlr|uwEz&_tW7PVlKER=3LVOvA~?+ zK9A>z;6H(V@pe3KjkDtip*`(}x!XdqT_xIyb)5F=z)yxtf$I&I07vhYE=t29q=L>X za7}?LwtFj@gb<_w&9FRC{qfe8NK{Y-gf4Joif}{5l5DLlX&$?35(fXSTgmi7XV9GNQjLE`JKSY50 z7z=*LPtQ}*6Uob-V^0h78~P6#GzibiYIuD)bbElR68;!-u!{T}M1K+1G;9_9DJa`@ zqCZ9@s2W6nrMNzf;*hRXtTM?(?nx&G@OwIMoSx8HtRx8)_k^2(XERYw-JjE`u<3Z3 zjZjlr{!&05hIXi=;T@f^Mo4QPX4DQ}PR}P0X^HgfyJ%osIdF9N3_{7YT`md;$2d0rM_D!kMKTgwHQR+@N8kdI%Z@0HVW?K?}VT ztb@V|8a8OhJJ2n~@SV_zzVw*larm`q=pVzSr47{U2UajzdR(#UG+b)(RN!JXCQckx zQZkAkY?{S-0PHbJ1ogxCm5t|&G2G_Br*}N3^Dz0942@wF{aLI($8R`IJ)ZFRI9=yG zr)>dE2}6p5dgiXrY0nn*G+m!k|DNJ@QsD6urt=wbGYN4>X-Wq5c_P1Qc+MqCdX##^ z{G#WaYYI!fBYu&e@{2Al{Ds_$mHl)&JHIl}7O??1ZfOnZBJnxxt;rYtoF5wJQIC>e zoG&w|%AX=H**(pJ@{99Hqc47O{&+5N{y0U>AMa}tCg+jPR-_$_v~H1KoZnKHXPj?$ zOzA8K&*xfjNmr%_(*Oq|5A^u0aHJ465Al!23xq>|)RWe;F(qNju?4KXn}~5&3I0YQ z@13Io>NCedvr*e7T|3^!TqE2bxP5SSa0lTI!ySV=1=j%A2p8}U<`Ll{;G*DS;9}th z!3~8Q0XG_MJX|8&M7UJAOt@^gxp2jBRye|60=EKg4ct1ojc{AwYT$Om?Sb0|cNp#h zoS(?_HTXmRi8(?zHC!y*2)IPJOt`slWpFFtHo$F#+YNUNt{(0ZoUk49qHqy#QE-Fc zM#D{n%Z8f^R}5DPw;paY9O2i%?S`v^I}XS7WgiD3f!>xnc0w>A(&wzFB zL+(5Hx&td<4VxYwD`&z8r4X2lsIZWpB957 zZfD^+A(f++rH$fumTjsh+%{weSDZtBI+kx9De=nbC99EqH+USlb?%HPV0Dw)Q*KFd z&1v@(a1qm9Xp$L?3nd=oJXQ(Cp}nRZlMC=mdm?BB6ZIRYOi?PEPmgjut`eee3{cG@ zJKH?`F8-6~$|W!5E|*aAd`tO9dxhxg2&Xl(!{@bSMvFE*D}_C$F)F>Ii>COnxHXHd zU=Y_C1>m{#J_$B`ekKM@{uLW6A`Xr3B%GG`LxJB3jxH>Y(qdiHA_HG+&mZEqz39XH z1e+NvZmpSEK8Ts@6y7_fwpEG~I5-a808=d%dWk&ISX1^siJSjsWYIFtWGu#nVb;;n z@OQ-}v$Aa2n65(lP?g9M8@tQ+PsIWoo`%fQGFutPlFJSJae)z4kv|pCWHdzk3l{=0 zDXmv)4LpSBV$a3|18kr9MvFmfAvWoO#1&s#CQCEDbdiZ0Pt#y=PUNdhID6?ZCrZ@Z z_#<3C@hg)I*&66_leMdm)AB3}I2yBqNc_opNwHuJoKf$=gd8U|AuX>=Rx$%YQ=*lc zkdl~P>Kfc7EGw;)I$#0Uoo5PZHMp?NI3^p7lt*c>IHUCGN*8N=yyFrfJId5j=L$Xw zz@JUSf)Z&N10%!iFH$7bd6-kcn|tQaE)*wdwHK| zJ~U7qMlqQj1^cULMP&lUCj43ey%dL252m`j&&GI9y42{SyZ*(%TFU=ipDW)@ge}Y0 z-wN1}-2Yth@9}f~`L*zpQ@Gd9`Pa&?Wq(q5d75I}+3_sFA< zt^eEOPi%Pdsi!wS^Xzk*o`2!*n_qnCuG#Z%|Ln=Bw%Ih+!VF@5+#Me+p#Ctf@n?UqCf993YE9~!v(z`o7QRe;l#teDq!WKPfx^?SdX-&pw$;gD62bWxBrW zllh_B3x@O-FN1F|c-;fBya*J=MxvX60p=jJMtu5qUB*p#RXX2maVM zGyiW3_rB1@KIws&0U=#WO)1??-ALNwhx8f$NXW7SK-U>fBfa`^5^f&yZ%Xh*>K^MxRSj?bM2NBM-S-TO)aQ2h zdE&|X!p^4FouBM~amd0>QzpLm>9gM_O})E2CE%Zn*IjP4!+O&iVa|ouZ66+eG5qZ# zC%-j^8B!<5ly^D)Yst=s5~h5%_mRHSUOxF{-_x5nyzpN%!zPTMRM&9n!m8ePe^An9 zMrpwN3A^URHBJoa@MGl6jlacQxb(@m=LdA#xbVyE_az#a`kAh%o}Avj!nO&k9!|XR z_GsIxdmrvH?vn+hwyyr>zNbQxlhTSpUpV^vLk~xN+o_>wP~XI@fBR8;&$eA3x0>(PL6x|N@;mopVP0kp;D$AJniMy2WEu6@UK33)9+gzIluPO zeYQpQiLswe*rS^v>m^lcq7s8{OilqQI=@){(G*}oO(5|bMW|i znmaS*Z2B}_dorV>B&_Gf`03wI?^GN8*r9VVE6zRodATO#mRI9?Oi+(_<NfcMIYx zS8cs*Y;4W@4}G(xTZsPB!Swk}!`jcEUKsxN(eWQ^Ze3jT#E=C?K6vey?M8hcr03M7 z+{&x3?Vt9;X7!{e8gm|dxy|)g{qA}pc9QXt_iyPJx%;D+4t#NV(MQAghfe$I;k8eG z^!Vm~O^%LObfI1ARhutcRXs*s>oD>AS02cpsXFto$LfuT`iwQ7+WME5*3RlRGJb*(b!6Uoky?W_;T&yBq%+s=APSu|x5$XkFEny-z;W*7DktrofeP39lP%{o`U+ zkhtmb;jU(Yy7(d}?0w;o_&?{=OpJf88l@aPf@&;Oyek zrKg@ab3}9HnbLXXQ-)T3SUH#5E&{n?DBVH*QC-}m<5UlYQ5^gNny`{74_x#{I+yNxTNalZcg()R`i?4A7j55JuFD*c%U zEk|3Q+VEpWVY{b0zxd^wZ~of;(Gix1cBY)$_gMejN5+i^`}H3Wsl#tuy#HI>{@QPP zjqRNC?Q8eve*a5()yHR^n>BTy|Co$3IvTGFs;@6iZJjjdgl_Ar1BU+Nxzgu88E3jP zX6xnh+R1f$4ip}5-27^xX74Nin7*gD?UPSFBGgWtHRk^JCS4kSWNKRd(S;xMjJ(qN zo}@|h55IJ1N$QD^4bMMe6IP8r)s<)q zuujHxsg})Qeddnue?Wyq#Jh|kD$ENPi z+coc{!(ZL^&Dr>xyrK*1-hF&ur}!ddqv}*Y{LT-b>euB`n{g>WfA+%j<+i(5y(_^h}z5aFbr`1uN`o40Y_gmfm8L+$mzM!{0KKEY} zj!ka;* z9&_h+s(Ds(V6|oGPjkOL^zn!NzcmKkc3(}@4?zzXoHM0#D?M8MuY;?<~cm;qI9+5F5?Ne^20WIu2%=R@nhgS%>Uru-v0`)0j4%znL7 zao&{O-H*QW$eT~5|MX1enJdQ@-kl%Z|LK9>JlTs1g`isf?j572-&X$Ji0A$_CgZ6C z_ryMRd6V^{E4v;$6FGmxsoX6as(udstzp#{TWW6~`{};dR+f$H@#NfH>_*u!afKyR_ zlZ;&~>Ki}*KaoHyR7rpIX9HRbegW+Szrc=yUr>b5D(DuWRdBS>DkM(u4;d!-w;n6_ zx0xsew3#Xdw4Eaagc^mwP@53g?p`6V{aPU~>}eq=>{TI1^_~#a;WHt)!*Lxfl;Z6Y@MwdwY@Uz_fq`?b00N58f=wQkim zGP+e;-hK8VU}`V)aP{b+sQL=R#=rOp<8@&|<)iD-U-~6b`1o$X7O4=kbR0@) za1BdyhBVjCS6v#!ESpCk7-=DXg#Dcg68mORz7@g%*89eKBa$S}nd~Lt1M_QM=+=*i5{9 zeH1_Ck8*|9N%8$0TwbpE?21RVoKiw-HcUt*L8^_;%N^erkFL0$JW`pWGybUFxXRxd zADzMM)IL4deCs&^G;Ojp~!;&U; zUheTwi$lANDDUX|AI;%Y4)K*(JimR(kGC_V$w}8c>%Kb=q_r1|GLhE{PdvW9jLv11 zE_WO%5hO2)k@G5Hddi5_s_@-9&Q!S5BOE6!X;rBbEoynB)w@dX`KgwCmlH1ma$V{k zFUgG82j`kuN{Kt(B39-NXa$HqeM!`LQN5-%Tha&AhMO1;eap~!xz~S5hfA%bTsOP6 zv783gRIXE;dX3i|XFbdZhg2q|K8vKAC$E$JZVyFRHkS*kvyE#pP}_g z@*WNKg36&AC}t|(@-R}nN$cO#j4$HdDLr~ltCy%}<@(&2kF?5>N}H6A7Q{g-lk-IF z)?E85e@~qA)N`3S-;r*kmdRCT$ltq%^=!lGyRuaBJlk+urAc{5<%Hx%sV#(`w2yST z;z%o_NKZSj&EEv6==&Gb@Mwq3UoZ2kzU4St;Kah8j@=YG_{WRS6X2f#|LtsrGWz$T zpH@zl!JmNVS@5rr;cSsTKPJNuInMF3fjn{lw2k(Vq(cZqZNt92fn> zXXptYmiUPg{gdF&6#ciuUo85G&yAv=csMTlC%}JA^pmV2PCEG+3V$+Ij8I%NL_hIR zDf)@GEux?3?}I-PJ57lHOQN6fqrT(M2|rWx6Mh-|ly>5O9sIO&lAhPVpN`!wv{t1~ z=5G}J7$yl(r?7S!_>4FBlMs@^t`Pn7e2eI(cl50pk`EO@?nIhnqaAIZtO!%p8QGV*-pNKV2B%3Ad`R#Zk2TzmUxWX4a7pX4%i29 zH(+1DeSrM{4+7o_cnq*V;3>dZzy`oLz)OGw0j~iL2Mo9pq$1mVC?Fl`5e_&KFcOe< zV@Cmw1B?Y64>%N%>ceP2(p8CoRIXD2sr+RFQrVsjNaa)yNcz7RkjknRkm}76Kq`ML z0I5u@0VJKW4loCB10d<7&44tv*a~j3=$j{^n((%Qp7zzet! z0u+8jxd2oFh5)JoTLaRblD2?@a32ad9{^?;;sHUoA7tN{!M+ymGJ@GxL^zHUcgH#90R_ zEcnDe@nBT|U<@Fg;yMDbHQ+?RHh?n#Ljj8byZ;~d-UrTx>i-{~W!EmDEs`WQ7F+(! z%$+-T?#$dfi^bB$V*M+{vX@=f?%F>riA^e%N|ClwZBnUJDwRsL2@$bHrFhp?(pD;! zq7vWdYtEd#v)7`}|IhF9a~^y4Ij{5QbzbM3*ZKE4bMFO~0uA5-U=$|2a$q!YB`_Aa z7T6fL8Q2848`u9cs`=(B$0$nL-}&q0=s><#4T^h%Dt!G>XpjbxV~N9Rv+Wb-CR=UH-O zt6<1zx``l1zoAEtzGs3V<42!eBgd_aMZz?Po^B&q!pYJ3m>k(y$dRp^9NGTK(K((R zea?;?S;iPLn!dk@9N7=aWy7vXE)y+AF67vOraE>2I=_>nPeqZVUw$LUZ*Ax^Rph2P z>8CjS$Sy;!#Nk`)$U`4>clsuoF)@)*U-}9#6VP_2uQ0&UFXH)035s=;2O&(m|4krzc&c_T%*@o$QX& z0_RWPvO@8^JxE8pLt0Fewj*67n)4%_CHXi%(p{<_rdQjM?T$Xf-OHg#r%8S~-;yKU zrt*0El8#gV@$yO6yF)tKuae8P5ivy=B8=9k#6z2(YPaB;(bTs zkLto@pK90j^4hwxdx)@Zu+KhTUfY&5Ugpw0Ow*>JKGZtBo!+6FGIw9nT?ma+-qvhh8XydD%4hQm zSr(Wh`!e-CmyfKKRN5#fp3N)0Yx{=H6XE=9o(RY1+5Ez~z~%+Ah%r}Wx8E>~%oFvT zjq&iD<{lG$?0GlW;X>n+`Yk*kFrDjN+wN{1ipZXA)hng89o)Q6>|?qEjI76Cj501awb?)yP4yU2TQ6z{3gKG9WE))@ z&t&TpF^1{8oS38hR6^bSe1@U*g<^Zx_A#p)*FZi#2G;Up>B)M?HXU+|KOcRZ|7EqG`DE$SU2_!i?^C-MVElWz>QC{*YsUzS?;VjpJtBTct)4J> z_>9WsBg-mtES}kV!}7EHfiO*0S?0p$0oFpK8{CoYisssA*rvJxi(&Po-8b1dDb0M) zyMar9pHevRIp7*#1#koK4&W}}4&XlEhrmO?4}j6lV&k6xwgkQcOayKKD!{$K6d=ud z8NhA8Ea02KV&G;V*$6KI&If%zumU&*NVdm|f$Km|AR6*U0k?ssJ=I>|wZH?wmw{xX zZ2*jG9*a8=qyrrdYz>;${UqQ`K(g7!05#AwCz0)zY`LkRmjg!u?*wK8X^trcz5rYR zd)Az#8Bd;1S?mz__zx<6i}~ z25tl<0oMRE;77nzU=?r_kk*H6U?s2=xD!Y==ElGUpx+0U1OEkF3H%ti7Wgi3Gw?;= zZs1$M8sIMA5#S1794s_X16u<>2POd*12teZFctV3a1?MmFdO&f3E0?R>{85>VKWV$;rfvrK`089ct4%C3tfvLb{z+&XP z05}TtmB2NiI{>pmX8}urZvYnn-v*WgR|8i9*8{x-nfpvM5o7WWmf z2K0Jh^m(!IuLBc+j{!~Ky}jF#%odX;P%m)?#8v@IKUji2a7Xd4P4+B>N zp9fX~p9EF``vI$g1;8`zzpn+D9bgvrrp&Q@QzrIjZhAbd32r*ev9j@f8@>7Hj?Zzd zi9CL?W5wh26vtY}>0DTr-1&2H(sR?acXrd^H*T1`(<0)-@5i!uI#Ijxhb=2Cex|Fw zbh2ir&Iu9cO%}@j(;HG@F3cWE?_u(CnC*{Si7B4;*Wq`**qMjkF{1BFs>_Sn32Dd4 z9NCiT{VJLh$dO##(c-+#nB6c778d5%d5n0v>G1nxES~xCgTL-rukcGoL@n$jpV+8t5zr3UY|6Bmq+bSZ^F9i3Fx=FbYy(p{PdofJAL@OI9Yk&{$})~ z+Wup7HZ;hce=6?g+%&zL=BByjo9avQ7r5G!(RJl3sMTGTo-8qLekBp{^fo1rCwm-y z_dch|-bP%QV|Gw_+nUp4pW-(j%*IbNZy$DM=Qj-8mJ-$<79ZAUM$>=JpU(L7{<@o< zigCjnv%iJqWA?%D*rdA`8mqj2neEdZPyA`@GRN#E{6+=qxovL@e?Kj=^U~X(%rQGO zze(YCcz(mf?s(YylsrAPFTeR=cR$@>72#_ov)$4g-OMpt>y+B@$LyJ5`MJH3hY(Hg zGxGLhw%IAQb2_tY(|_ie-J9R^(A^33XLvj^+cdw?p?I=)^3sT=xsd)d$Ly)@csAa` z@kCFp)jwu?rvJ>bdkK15p3_ubSbvy(lHZWgT^W_{PEY*9^8vFThvi}S9Q;O&-Ki0O z-d@bU$#2>OtbNS#$Y%^r^AXQ!J|fvY3BRGEyE+;_;Wwn2eK{--vloWP52M5NVKn_` zj@_&9n?8Q8L7!OS@ys^GIgqW0)+Nq?+u+>sWRr8pQ;TwmxUDKo(>+f36A#Qz#@4>b zHP#&$xh}FedaIj82i?K(5z6g)Ebhd7bWg*jp|nJE>4~Ph2l^FP-X6r8Qn1yW-4}%0 zpM9gKo2Gjxeq)MrhOJ*=ePZ`g{3ey+X*`Gfm)%3rX9bvJ_f`e9>p9aV_CK=T?zqT$ zv-_s$kcK&SClr>8*{En9Wixe{W+RK!JU^qeYvp1zeUmM7j4rC3HyB-9yRNc3sBrnY z`I98k$s2})bTo!LXnCU96Gujc{~wPHKf9jFT+j9+SwYFBI~>+ZIzN+Z-!M)%Zo9K< z(T=Fx!^#K7AE5+y^yY~8G6c-6#nOk;Tcqr?M!j%ud+De40Xskb*=$|^csRpw{pyBu zO6{_!g}Oq}*yvt-8i z`0-}Rht)n!%P;u-?!TRqtF4CkEprx+|9GwFt*2w+2R;`QKN$Y!XJX=OVYs9cRy#c&>Dw?GQW7yT1&W2LCgKjO)F; z89bR>Y&ZJXBkSAeJsRcUbrgs(M&2H0)aV8IGla~d9D7J-PRO?he$li-zLX*dYe9<) z6wH;`#$7x!{e!G04q7Maz9uUh&bBT*Jfyo8L%)9e*-Hk|2o!qiWa~Jjz4>* zV2O3n7k4%-J?ck%@b(^`-e)97~RKW^>G*kQGKy%pl$X|O2xq;=!Ys?8%mz_0cuzunyW|`t{NA@2%Q^U*#?P_UfXTm#l}beYoR}x6cQ^fw#?=^0GB6uj1UAhHa65-=MQT zT5HWq8?^0f0rg2v?6Ai3s^uLyNh$bQMgGS#Ub_1=>zzT<6R&Q5NkFLnwn69b)>&J( z_Lz6c``?>FMebW`dcR?Pd--j@p8Yj`0eIZx=VESq(|UZy%gZ0V9lsEqU~asBYNgfp z&o6$w?K+v-b5*d}Th=oNuix7DmUaQ5s`xx>?OWEaX<21A8IQeUT^i9(5Bftzli}MedgH(OWwA!3fs)IzQuf1v1VBDB^xZ|vUM99Z>RP+ z_GjX|8>}JO`+N6E=n)Xa#^;ud-)MC||H&5)e2)CW?`_)rve9ah8SH-HPZsD!t(M=m z$*Q_{>CtXWelTHq%N>>Qj`dzf^7xer_$B4^w#V;Y^NzLAb7yw9DAccF`^4qeX6vDj zH{JNwri6fSa75GQ+csODSL}Fr%~xozs&9V!eDoIU>+0jP8YCn_o)7xB|8|R&koZe( za}V?*x#6uV^4_)PUfK1PRo{D%f9S@Sg{@Z6lUZpwhfrR@AG7x_*lHD4ly>NN9PO3d z`xl|AtD@6El? z_tN!m^h|!=y7ko#y%S8xvnc0+duF|F-8-iH#WR0_{*PKE&U*2EYtH=R%$MMH{;HJX!Z}u#F`8p#dq#7tc;gd0J;$=E7|k)gA)`4aJh9tO&#`(q zqd6uW|JaV_IPO_Sb1WarXpU89Gn!-B+aKBaIj)?=XpU79qd68F_|Q(zG5&Ezb4&^` znqzWDMsuv%x697Yaol5!=9oQ&(HxI-V>HLo-*(#hIhMW3XpX}5jOKV`5TiMkp6}#$ zu;8l?SbZF`AMU3WHFo4k6jfa0R0|F1nD>9L0~`v-5MTyob>o(?>I!V|5!wa~${8HakDZgDV)# zv0y5rISM@)&9Ut8Ry#jOp_0+HNR9D-+Ev^2FV4)fP5$`RX0}%Z%BVMO9ckN0!4pFE zPe;-33Fnh7WMbxcdp|ifKZ~v>h1@K*%^y2~MU2g!S&)yN=0qf*_=$y1{7g|8J5z$s z6UJh*N_OqBdHD6^%!&BfUP{SaOTf4`vG!e77O)NI44{3N25b*n>l|y}MJ59;2E8yb z*1p@#Mtn2S1;Dd`OAt=G`(?lwU@5}s&T9qebAc;?3BXmrroh!ey5n98JP%k2q`S7w zzzcv?K)T!A4Qvgp2GX5n4Uq0C4+1*?j{rLYj{@zpXs1~FjyD?E8R1QVfPa%ipV)nc ze&N?N$bWEdT_#74bGq&shlid}Y#ED*5*iAz_+5eaf+frqjtj@5jyF6Wd;IL9)|F*n5mmAll%^gKF@f`%eE*LAU>&y=RJdXN@bfc*iD>UsAD~!SO zzt=?<;11Gc@2dz^5q;qtfd0L_&*VGP0%uy_Obh&9Yk>u`@P1*px^pE>mAjp=Y6mGD zuRE?-NSh(jQEO9nC2j*qd0PIzL9xZ3hW_}zBqy}tuG6luq8k) zGo|IzzMFSse$IP0(pS~Pd!G|_5Xj}GwDs|h%+GnRxF$BfTaR#EDV*{rJ7K8~QaYZ; zEpudEo@N))&yV0s?NQG80Xc6RDb7?^RCNS|HaEN?RZA$o!o5I>>S;f;Z)l6Ios2 z9i((TkGmfu^YSzYkv`4I%fqNW#yMfRK+c=e)+cjhe$HpqwRjh=9^UJmu+1*sl(s(J zk@-3ARY)H#h3iV;l)tqTmf#?z<9Xce5t)~#IfV3M>fu}9gq1o->3AMD-^jc?P0}2^ z4;;al+Ih1RwhPE*rnL37MPz=?do9w(%VBvaoOmZXVIq+8rnL3(j?B+_kD813d+Xs{ z=7cQ-@;0Hg_3@6(&w1}g`pxz5-s^C$@>^grxwvUQ^oo zct_^vy!Rn}Sv|a$IAIk)KF%p^eY_*{bKb45!~6F2@IL5-9d+@hwDs|h%+GnJA-$&5 zZ4=6$=7eQ9Na=VUw{Az~1yeVycGDqg;yq7_i1NHD0yiCTX zK+c=e*2g3ANuK1Sx{X|^G~riJrRILV#n zgpC2Z$10_-Pwq$_oc~dzFOT3)`Byn%Yk|DYDQ$gi9+{u>PP`ubp9tQRKhDqU6Yn6U z<9Xa|5}B8$Nk;lKCoc~pna4R{xj@dF($*()WPZ+P4AQTxhxa-sY_p3urLB*5WPZ-O z6zQY&a9t^!d2GC$|N4(Zp`!@J4} z+w0;@Y3t)1nV<7Mga7p{kTNey@LwM#R6Y?UR6idjq)QEiOWHRQX2S1*k56bM%!jXn zzu@9V!YKF!@T=jg;X8C_B&5T?3*WjUp5Yh3Z-I|XY$Ry#74RvY8VT>fx9;3X$bqkb zzpzUq;YRq*NsWY3_$~0QFF_gb_riY*pKxg-;Y#=o@Nr!m2?l&A{7U#5c(EI3_?7Ux z;p4j_Km1boD){&wjf8RVmGG^5A`X5Ld_NIk@R|g9;Wxv_$&G}r@Mqk=uLXt93>X2B-IZwK!{C%+47TX}tH*#}pP6=1j=WEX*2HP?$e?%#578g5sHDiV7!;85+tB zWfq0T;HQN>vJ=sxAZxrM!VVyLa_bqK`G2Mb&a}Xp7C6%ar)Ys>SKJqKgm^c7=UgG4 z@1;5NeHq6NF^lP|DuwJ6c4k-wbg{H;bF@DtPiGFwH_DZUho!p0ki>Sxn{IF8`qt&? zMBBVbuJi=4szck)pFMW@L_WsY;DuRKk9D(Cf1__<=Z=zgp{s7+hqS#fBJqdN#f;!jA#ATP^D zG{0Bj@zgFQ$t<4gOKDE#sO`ul+yB|W**j0v5gtwLKz=slBiah&yVppeK zC_LE}S@;zzt2x5xJryeJ2=Wt8Vv?N7+9nPNver>Lw>*`o8-;BKlFU^=YMb3a(vNBf zYk<@?2Z1y$k2olxK14TiusM*@wFFZBHbCN^0Cbm&pgJzuMfLlf)s6aucv1dcs0Y=J z%4$1+)otHt>NXBCQr>JJ)vW+Xbt`qk%YgOCMCBmaNgW>xl(+0+HdjzN3m{j0nJA7N zrH}8x%53FeTOikiwI|8X%Of5%7Ra7T&v(3Acg}toH1VRbQa+H)$;m)U%N@zWJ+&>h zN4ArOXlh?-tD}&G%Az|ffRMCBuxXlOR-zs&9h&Bp6`+3uP4%O+k&gIPbYgw55=eTn z+QB!0JRjjA&~b<_2S)PYG^I=K$l_ChRA(wfxU6nnd3xUdL{r`}Cl7_2r^!RPzysy!_<# zCH|C--UrJ*MLLq94C9m1FK}>?gG+(bE)N2!T^@62LP}3aW9bafi)5GQ#z7+oYSA#PJb3SG$F+klH8?0>d!JK z9FO)Ku)sx=T#G>4^9qpCxE;ylrX!#E{6*!ayZUG?>JXWhXj}h)$wWAAz@qT{LVS2Q zA*Cl@1AZh6%>_rC_K6!@w+zl3N$T)l_N`#+J@qNI3#Cg%UgAgcFTyj0jjD$q$+H^k z8=`GT>0Wczy|-N9PP7e_C;gJJzHW%%%hPgsDZPO76dnhp@OURb$$aQE`6(aqD07vm zrPpm6N<)s9NzXx*t;MsQwA8i>@$BAr@-@Pi5%JW1gIlqDc39VNJy)HkOlof$H^PvU z%SJpGUCP>`97yt307PDaxZv$+bB#rvIwD?q(c4 zQ8#%Ta-@1uyDULDB zTzZiF57OHOIsYhsfzx&*SHWrWQ#Q&|;cD+Sr^!RTohCn(Noh$hYfh1t_zFE)IdMR{Zyh=w zNb!Wkj~vkzu6nf2ICb4AeU&SH>OV-&N@D*hztDq?yEq`#$zD@V!-sNHTG~ICrw01B7NII9~ zpa|q;5>lQrgi-m#Z`3Ku=jqd(x>5QCr%6wFsC+uFQ(J69da5VAF9Z-~_ljcQ2Z=pk z8f5taG|57d@uS%OV{JqkR4&O)`N>r|ZN3{wWmE&Hk7^wHAdu#rBS4d;h@e&*h;$i#J(5 zJ4_Du$pMEC@p3zA2Xd6Y($$A;N1t4WSPtwRhO)B8IcZ780zA8Ar1!2ke?n@Dcqbpx zuf((c&I%WgHF)0T(3F{<+j%{SM|F_pBOd%6EO-3P$>I225_^ujg2_Vt+7{0yJTHg% z&^t?nZa(MhVLtTERAl^xt;6wq+py;XS2^?RDTm%&isVz%BFyK}OW5;T7oTnQ@S%5< zBKfrOh558{_MpO*EFIOmC7u;{cfIL-p-4X6wJ;xgUnw#^%M~y8U}>|Ra!3y%%h=}F zVHdj6EQ^qX-YtqOXJ)Uk9NA8vS2;YWKKt+-Sr)xR;u~k3JpOOQwGFX&;@#5Gh1p}6EF|k9JiB$9($RZEgl?UC1D}+qFfPY#mmGcb zqT)xvyW=D4(fuJ7|I33>@kik)EjiAQ>`-pH;C7Z~<84v#JK*iauJrEmuPTp<&xCj9 zcgIT$qvCaVichA0j=S-WsM>jx*OkZ797Mk0s_;3q49^s{2*}eB^7)FMd41gVfBfF4 z_^040p4=*D>_=bC_>gY4#Isxf>HR87%jKf^rG2{-^<{QMyY21Sz|P0zh>Tw<){T$U zr&lsg9iMTU_*;gZI{#0niLV@b>inHflYjrJhIQ&6S-&fuX7T%+c8iQJeV)aS0~R>X z)DOHpBh#x}PF>#pPJDgkUHyK;`0?;={%*ac@Fx$SI==MxQ^)^sn)vhx{+lE8X>Bb1 zav0_`Cwxsr{Ggb+@!KNew??t}leOPS;neZ|4t3)R#6n+K1Xylg`g3t-RhY#-{;fp|CPr$vJDhO}(5`=%jZ^pNb{S*|0 z_u31>CS4GkS%||Ii_~-xgpuHt3qKeBF8CGj8{of!7pBAt=fZb__rVWij~8AI`=?++wqk zsYR2xRPM<9f>0h0Cpp~W6%}O82uBh@4Helcb}Al0ZF9z*X@UPp3p{thn<<0#C%?vd z;CN%(K{)NUEl^lwd;)CBJS|7EC%9cyf}8s1&kc|-viyINoAO1<@K5rcEDgy(^(Gq# z*|pnlVRrEC+f(?=3m^a=m3JH~>N9enX0rtjsXe+lV#EZ?`hjqvsIn&nrXod2AM?HogJ z;W6aXt3OQ;#(p~aQ~AX7J9mFp{RiG%n!_bKA<2JnK>SG^D>&h#?!Q>D|K02}$4|%# zO`MdSGkHqx)V%zHX@y0_CDUh=&YZ>M?$x_bO5c9{QwI#ZEba0^gVTo$9hNbC#K=*j zulV0xum3UWPO65^dHkemnD9R)@_%ZhJ-~oGxn)@2l>1Nb z=Q^$e={2N3nP*(X|M~jK?QA?Iavd)z=P_sSpR_>kgKQ7d!|F96EoVGFb%_sR_AQ+d zDk#p$&r43`JlyF{mdKrE?9k9eoP$bmyc~~@b0!xRXN8%8sXMKe=t`YGesb~%D-oG; zCX6jAF3icBlstCia4V5ME;_cjFf*sP2my>C5@zP+=1<5h&M%}uIhlo@P#mv@jqb8j zLUdm2ODD(Vp`pyI-X#+!h6=-?y3>x&%o=MK7s1}0rWc*4Q$j^kit`JStzKej$T!h1 zW_kQ!mUZgxPM?xf7@AOgvRrlB%$;vQUe;-H*3Ii~@BhlScD2j!0aFWdldZ&Ip$R30 zImI&v6o;lJ4tjx^u$;qR8L2*ycH@(-W zBrnG`A>JOjoLD&};YN1e#_MA;+j>(n0lF`+Q007@HKeOtiO^651p zH!|aic~GATg`v#iP5h_`#VWV@pMN^*1i{{*#4+p!K$wl}K|*E>q6hMy64G8ilJ(o1ETj_}E^3(xB2O>c?r@ zr%w4Nb{XsQe<04uvO>C(42N3LPTwxIgZ7^YQaiv;RkFLx%k#5Jazlgii~C{iV1r%r zPEbX4JO+EMly&-VMD23LCK;M^)vWPeRhv*Ji@VQ9gld<#x+{}QmJvC5(=&5(Fy|Le zDw&FDJ!0Cg!w+9kjrGd5F4jrr=9e4Fn^c@#Pa@RIosR69`4h($X68*gVd1Qk4nqXr zvpu6ej_!1YScPGVtuI-fa%p{=Sduq^R(^axcW!Q-n$(rCFf=JtS`SBexy3UJLNN7C z%y+uM9cQnlg@u_j@ul7~#_&$4gVv2^h(6TUkb0nr@)VZ zp9nt-{&x5k@T=js!S91V3g7aHSRoN!gC7W=1wRXZ0em_9^YEMCcf$LI-#geklAz_)_@$;8($~h2IRn5B?~8;wrQ& zd=Nejegu3rd@1~m@Jr!Wz`qK=3H}54@8E@}V}(}mJ>Y}zsqk08=fcl{za72;el`3i z_`UEo@JHd}(VhwLB7AT7LGV|==fcl{FNc2~ejCx~ga1i)ANsotej9l8S!n-I-q6gvtbF{K@VN~J;}Sca-RNiJ zPr-$@aK0Uuk&V+}77I!cdNH#}s8?Rr0CpLVt9Wef1;G>557+$km><5Jicu}Zu@c79v+qjx&q%eF~-=SQ7Zv&+3my;XnRg8L% zFDVWcL5>L&$__geN4r*pP7H^pqC;~-eM=FVM4^52rsovq=g~Q2L}p=5=6Em^(xb^{ zMGOStix~T;Y!h=?Eg27?eN;+GL2eGLWFaRcoj9gt78TouFMLu}fJWt^79>X&84Ltr zr_+M9L6GDo$~PFtj@-74bP*F*4F@ANrPiEePQ0{zz`lK}QN_#Xv(`E!L9g+NNR6 zN?H~YN@Fr`ax2PoH|Fzp*|o_bO%qp{j?5_ZBMKchvk2C)44l|{6;a{zB#ft+y86-! z-$-DORoHC{GYe-54^SFn)+;NkkY4B!RyIt_&%_TQ+VLp$y_k_XS)o2S2W8~j&Cq)$ zByQ%Ch1DNp3OUhr_B0^~&ohc92I0N1jLcw}UpRB55YrH4j|deOVVIH9&WjnImu;(X zR_*Z|m9c-jsSmZ?Nux7kGD3w@bMnY?<-C|AOl>%z$RY9z`=MV;3K1D9LWc|8qlc8h zRFsahFwId=#6Dzp#*ai@=F-JsX*os3sTeH6B=AZJjW3xrDOAXLykXa=IJ2<0q<{wU zNMRC%u=Zx1i`KiW@6bVg)A+bfjvktsQ-l%f*vhdbj2>E?J3Ma&rX1m7=sH=J)AMs| zSw=z@$OQY+6b!JEqHGL>!kM;ILWVo8UoIk9c&bbOh{1trdssnEo?TO+C?+Gf$myvP zdZw<(%qxDhXRI(PxawZ5NNVKheIK&IpY;M6MQIt=kVMtWp z(wy3{_I|@!UCPMk3MP0OqPYv~;)I^|GZXRcXb9wR>Qh{p%StR1{%AP3q`062#&h(| zFx&7C4gd4RQ1rwqK9+~!dVr7QzNJEqGiJFKub?@)SD$ozmkHG;1v-TZ01Fv-9HtN& zTeTsJF$+#D$Se%8(vfCq!?Zq^XBO1b8I;E!7$K%6LNT-nt(%j@LWQH0f>wo;(8Nqk zG--VXq+nKrHk3?d1DhqJH6S~xA5_I&%Y>=+bH5ziYE!HCEk)h)BEyj9T03kIHU*Td zmoT>uJyIy-^7J9)!~1>0jU>_FzL!%gyg=>IC*59UH`~woQ!!*PL*#+imWYs%LKn*G zT6tJQkn9iGGf#a{KT!X=BEqZHk0*&4DJ-XQoB>W+BM2KQgcX+o4Md4|McG4xs?9EG zFu(0(65Coy_50C9WAI`X>p*kOu;N<1)@)52M(-U8s{K4P#PsrSl8(4LLl){J92406 z5Ff?=UAxLN<(z2&)&hMuH53xz$@SUMQ0NFh0KOmmYWS3@hQcJgoO}V^Ef#@|@q>fk zir5X}o#T&t3&NvFBLD{>?BcfgZbaY+gbjml-A526;a%j>cy31N>T&OM!gnM({))dE z3aL@iLi2Xff(BoPyh-tbFaSKWFGYD*MBAR&WE%L6J^JxOxCYlm*YOogqJ=l$IqnGx z!ae+(7t2@K+H5M{jV^n|}&?6PKr#PpMpT zF~COf^YMI>9TI*X4Z5|<`v|eC3Hej? z%%Z71rb}HCaPrET7%Jjs6IL2nB_x=|g(XF{Nzvif;WXSl9qfF_S>%{x9U38pp=l*3 z1!jlBoas2mLe+|>e52fL%9jL^gqxg6NcL9up<|CNhrzbHGw`T7U(iD zGq)(zC81|6AG7DlOEG)ak;&{?TRCJmd-8SzabkCz2|3dO|Nm}*0()K;ru%O6ZPGr{ zTIrqj$@*2sFUED|E#`9bd2_Gn3(O9z3QP=^29E}51sI1GJ4@0%DV{-|)yk_%GxdD+ zVm03v&_-xI{L}pl{44yg`#1UD^MB(1%~S{ud}F%ou&QKVd-*tguG0CPySMl@-+3d@^tcC>Uqqw*3&@Q zsO```(Z14R&2!8P%@Ki6U~8Z{xXfBlb*;qrp91a?SBcMy?~1#`FT@|ki==O)U!J`jTX+ zf;At|N=y)Yii$W!oG6xvv&4tQC&abl>*9X#pm_q_gDnPJY-zQ#M9XUpvp%wFNX}}u z2^lJ8iz}s9rH`b2@>!llPqJsAXN)J)GuPIb1ocwYRC}po)up~ieKFcu+6CzGUfNLY zYOPe8qur(@`E&I${cgQV|484b|Dyk)#~LGyknx1E)O_6h(EP%zF%LmE%|O3ETHxK_ z^XRd?RQ^Gn=Kw9Gc2bd4D%~XAA$>0$l#WZWa=u(FUoYP(|0w?kJ!s@9G=?+@Nzy}FvAj#f9RAF9XIPQH=8@xCLzhT7lSCjW>2 zZ~P7Q_WC7yFa1hAq)*Y`K`lSikLbtrmPRil&nPiA8M}?YjmhRlvtgh~pi5w2;ETZb z!KKzp>kaE2>jUc(>uc*f8c#T|FM%BG#Y>?VgT!&ri)yh3n(&siRk~MxL_Qbw)I9?{ z>CpHWJufL6mEPW5ud1f1cS5#HeQUHgwVfCPt^7&;3I2EdRsN6tUqM@Mg|JA9NZq<6|4#V8vG-eV=c3`kxU6uG|ch+ zfs$y5Q^aZFHR4m^bK+~__u}uOAYCstm9yn-awE_Ao)O+j-qG4p?NRLu?WlIH|5J?c zCVITyR#)_7yVctpoeYnm8~u#SjH`?(MzJx|c-Gis6q>WmdFCc_x7j+-4lR@%xH|A$ z;PpUN;N!qofttXUU^}Z5bhDQ=+!|wLTQ^#_S@&8GS_dsbj1tyDzE)zAXo-WxtHdm^ z0Hf(9@oup~d{lf^{8;>#=#g~kC26ztx%89tw-hbMV?=e4y>hbLR~{@+lV`{~UE;YrL;}Kk|O%{nmTfdkkfrjd{PD>cdzY zq)t?e)tl9&>c3RcXZc2GA#H&s_+$K?{ayWDe{cT~{|Ns$|5X2M|8@Rb{ZIL~LI*nN z-So@!Tz!@Pfo>R=nuD<}j5SNlet}7Wyuhr$+(32U$G~ras9>Yu)tCXkwuJO3p()N8 z?@K>O7s>C-pUPb@_mp_HdG>f{o?oSGP|oqT@+NpYd3$;Lc`x%W^Df7zc?Pn-im|iF zyA7?i+xwY!pZ7cOLGSP0quvH;oZ4LNpeC#R)J%1bdY8IeZQ@JvUFIwB-R*nT_qi`x zyF?p=HY|rOAJaPfFY|}|v;22poqGjq##jC${$_dyJ)oE9PwQXn7onYRGd5y;dCdaU zX0~}f*3vu8a`PecG4pA2jrp3n-rQnVnID^f9FfZP(zNzj}_o+W&ZB6iX_I2~gKFt^O z_4TFshWW1WWnw;Kh%5%eJgbJlbEyZXQMSBzDdh5H6Z1*QaM1a1nHW857H91p|< z&ktT4d^q?b*03Lgu~tvZXAQRQv{qpc@s3r66%B1u5G9apvZ>foOcRHSS7IJrB5o85 zFkjy*Jt?)qIJ-+Omw%Oy$qhXokLH==ndZ6Ov)^;bbGFh(S*|>#yrBH4H1@_riw1kg zU>+&3_5QfGx!O`~qb8`Gq5HC`sX?^pKs8+*p^m|*%U1I+5@xAo>W%6`=u)}*pt?eR zQeCaSq^?uftDDvB>Mr$DwOZY;9#DT#kEqA6yJ_N!_qFo1^>u*WiM|28F}}xq&->P5 zP8YNctn@c%i?v>QsXkYquP@LS>WlRKdRId<6hkviBgz_TU1vQ^^)8FD&*Kfn3$c>l zD*hx1vf}OU4S9>a7yCx}#`?0*v$@dhO}?|Vc&(+@T5GHAGVU|ins1of&E|n%Acy!Y zf^Gpm^ECIi^R4iG=39gwof}+DaTQVa9_>6&lBdE`h@I8v{*n4veHwc0H@y;b=F&jp zVDsRe=$|9ObF7Y5l6AFpz4f|PO|v(?Xcf(txxN}@7K8LLdio?@P|03-YbOA!(^v81badj2e-56gl-w?D!fp0zP_Ji*aUo6IW znf9>ul=eDStIx1!yTsqa@3H5r8~q#nTQJhw>xo!Z)AdQ1v!-G9@T|T@e+8O)SU;*q z8A(PTBh|RvxYk%|+;2Q(ylB)Ie;SQ2_HzT%f?ciE(9UC2|H>%aj@(c@TRcy^NK6#F zV<%~deZ&FSaor(Si3hOP8ZPaY4#^jIdU!&fTt&9mO~A?E%=o~+H3{_FI zl@~f;TwEkQh&3pHxir~R?zvN0qqOv9p+%#yukWuu>#y{`@Bb2`Gg?1S@1(1GAMBi7 zMva>p?V*2tjiJU3#%g1$@u3lIw!jWQ)qKvZHe)c4wF+Dm=oQEajK;nE%^#L6YF`t{D8b! z{y^R<@5lU>%qD@Em>0L=Hm-raf1icDStIEZ zNt1H0H?5TRNX3}vo|Bt+`g?Bl-0ykD^S!63(oq?wOjaJmSb9nMSozRvVa_U3?@%k$ zH!weatsYbxK{7w)p|QRee$AihU+#YcbM?pmw)#MQv_4zEQ-2$K%4+PK1*3`4+30F) zHx3v_ji%`T-sUv(LG#=|0amMfFi*dUJ?&q?=GeVGjs0W;d+$c`Q=+Jgw}|(OhjEI^ zmtK}Wl+Keyd5ruj_HIAPG1yaH>-kQJ^7il=-hA(VZw%V43C8O0*ypyyXbosXv@Goh z?CJ*kC;PAQKj&ZPZ>%@R$<5SJ*GAbVb6QB@x1XS_PzJvy!e`Vf1n~z z8Tc&F$U4tTvF2O%TkCKd5)v8+yU^!Ph?~W4aOU|F`^mGUbENjr&Nb4T(!0`5oPG*$ z+IvCXja~jgtQ$Asr1!h0xw2GwTIudx>)nODg@pAWLmh<`VVs(UH6d3mP*X6gXZlwA zzV!WwUcO$tQ+q%=tTn*;sQPRjyTpI7hl{mVC8tI%5eeg3Qb#s0PaJ^p?EfS#}4sE;wqv3G7_UTiKlpETdX z-uWj}4-^Ex3`SYq(aH;~r>r&DXEqRWAx}qfxR@(WmL9=5?qXS!U&0A`pZph26d}*! zI4iaCslMLEC}XlQ*Vt^dG~1X7*u8c$Wm7YQW{Nq`OgBfEW6bepo>^?p!fy6PbD?<` z_E`_2ho3Z8n%Ji6Cq+QL@z774` zCFglV>T|vqv?u-Dan~$VHo&``xLd?LosAXiNpT%U+TY@(k|pIzbEH)`4;_?ZWJT^L zm&musugKfwzvZ(%mtu`pu|oI8$}q^tFs?Ah8550ML#S#XtOLIc>09h%f5u$*2TlP| zatt*84$NxzV5~lb9slE=r#v$;pEU9|@izCKi=Ay7Z#(Z^?=-bUovB`{UZ>uGUH5J3 z4Bz?Mg<5;9qt-?1s`b=7S`_wLxBKtH%yFOpL5$zW{2{DSF-BvfnQ@MBo^gS35qj!r z%+)WNub8i+w>Dx=dT*dp@RDHnpcM2%n*zaJ=(z{5vv|~c0;Bgi>qYAo%-s!yZjk*k zae#EWG(;LMjh3#GGBG21<+rc{-GY969~$+E{4ZI+H^w(b+JGSig@lH7duviRCBfH4 z7sQ5m*Ot~GI?4IOfV~0^#%ZZcoG&gA7mACpXDb(%;ncK3TnQ`5qmo~KL-u>#^9+S8 zBolK&ruv&Y%LgU}4FwI5;M1{V-{~8Onc)-dSFOmu5NF|waMpZA?_mruDlvkFm{VbQ zio@yR{(!Kkp?&Y$9Xq%J%*wB;Z>w9>9XPq}QNK{Xfo0-X>=rK5F7$uze@(yDxRP|L zqM>aA>#UTbeINEei+$`nICX#R|I>dC&Xw0-XRusft-qmf(FYjgao#R7?le|m?s?Dn z+%U|c(AP(>+u8z)QevQIpf_glZGk4i#NbQ8@9h0iLwns3#5rhzhoNaZ#Bas(q*Q5~ zR4lEKUXZq6hx9x2rLo*rzF6)q%W@y=WdD?#Vz)qN#Pv82eTcp65l^aeCsxI0u%>TT z7J8T3r=ezQD|N7X1?&%O=UL*L1Ix>LpP^l;bv2XC!a!+YPGElE`rzHzW510P_}<_* z!JmWi*2Pv=YamX$cUViTt=1p3o2hJQ&n>rlo`kjT5~ZJ#tK8~+#JdNlQBfU&{q8E5Iycwe+dinR(%yod;IKBvpQIal16bW=8#fsr z89y4gnimJOK%d~%un1IQ9cf`D;@o|OH5K|;X>G*0aIf`^^%JunR^go$bdeyQC7vU; z7jM7{^St=7_yf+g9VEXr0_$NJ#^)0GKG-f^g1+v+Jl@vR0d|@)tdIvWlM4q~|N3xB z+NQR|-s*YS4Z35eP^I@a78xO&MvoUaBC z1b+)&Y8kK&Tx~7HJp8t`%i0H<%1`LwXxpX|h5cW5Q4`mof4>yFNIj*?uxeim`^7@( zE@_{X3Om3E`6~Hkxj!synVvlCbtWnMlpmBB@A=qY6nZbkZeqE*26nV>RM}_xdgJsq z#y8t{wKiM31!u4%tSrg?t8rSL;-BfC>tEu35o_c|)TXgsq+bVX;XC@d#w9er;nywb z{fDXEV(%<(3#^#Qn5AYJw;B%`9ZUr$^J~nT&HFH4;~9U-?Vqi=NpnS*vLWOK8z9Z36(8I z+xL#=i^Ifo^#1zUW>=g;<^+Xg7T!~-@V@KY#sbY^-td!JT+^Nq);DNnmgdqEq97AW+W;k^E({}9G#dss&|80VYzK6o7C z)fKzD$zrj1J@@RWDfj^vf+MgG#A8q07uLG;z=%LL zY$P`aZVxODJP~*%@B;SM+XFiT-$ECEwa;HIFq6}+U_fvXb_F@XykJrAX4uvi2cLk3 zz7X7kk-ancEzZ!t1{+&6t}d~9SRQMDH3;_B94pT%vTn9+w-#gWf5v*j+JgPjPU~Ci zN7@^gMGNzBhHES~7h8yzh&@CPPA`MdgE?ZJSR~#o-i~&BLVQMiLEIv47k6R?`%(N= zY%DdGT3~!Z zI0=qYCtwdYRlQZcTYX3UK>b+Vt2V~YJI7b-n~B+PDeM{_!Lm^eOHaJk5Btgym<#8^ zuJJBT3}nmr6T5IP#!_GGHH-Z>``_|!!>Q;a=u;!?*V6PM`UspSp4Qjuuj}h^NAauP z#gGjjR{oKg|Ci%*@jNW@dyLN5AFHN;72q!P>K>evzJ>+156(yT1>VH2u1zpKcx7;0 zFcd7qYVcNYQ*dkWE1aR*V(#sX9n`hhL)~WGMLTJn(WCAAg9NOfqUc5IUkUqcNSp_Y z{o6Q2{)F8t+3ed%9i=2GMaq_5hrMwxPA&VTIJp%@&18ADya4my26?Oeg?w0!_B4jg zbPGp$p!;r3;;G1hp;IA$njfAbTwSwO+Mje=G~{{VN`Gx9)|3zGkku0Jjkz!!|xI@LJ%@zz>1HaeE|NL##>G zH0Z!qOQ?z#XiK7t6VT^hh-0M%(gF1Do${MFC6Dynf*s@*&pe!n=U_w}_V!i3(}S4( z-Y~zyJ}%nc8-FFHdWPcmWQ6wz+;epcc&L33Mhh(gSBX@kJEd~z0W1$O_B@^IHI2I< zzx7b=Q>Mb+xypROv~6$+F*g4X#81U@q}I|!3bQIsr~R53W6$A5 zuy~Y8b0wdAnS2Nq`_{NQGjXpt4p#5^o~8C~W}9cA;_auTbzfp+?~d~ zSV3MUS(9Vz{pc-ndnKg&s0iL0y?3aceUJG18<&~aVV5-=*7{??JdzdfebW8SZn1;3 z0~VHM@6 z-UTtjC_sW-0K3q$xOGXuXuVu1Qyze2tPnQ>8@)eykEvsP6Mc&?uT|p)tSfc|H)`?z zzOb(r>6Q9ioYl+CU!Y45ST9=}tV6`NjP*%tu_NY_<>Gg+bKC??epGq}_kDBZAxbf< zXOH@h;iflLTZGZl-aiKSr`P%8^>1)f`i$8YGggZAF;)m+QH+oPmXpQp_I)AUl8(mt zeT^?e`-s;3iWvJmRU%g_w`-PP(+BBS;pXx=*wfy^zM1$9!F|j$SkrDsn;$gVm>o#sV`h@zT`j+}0?6T3=3vb66;uBvV?F;>E%s_LE zhm0qUS7G58YQBq|-;ZV~*4RP8b-_Ks5ts*JghZ5mTomNSp0?+>K^ zK2Jh-UcxD0J!}%&aZCIuZs7JqmwtgZ9mAZ{M2eSMNo}#eO~SgW;9eL;aPE*d3W z4U5`jsQ^~B+0s1B4Yx~6r2C`_=`oyGpO@B3Z{VKiU8xH9sC%U^r5dR}9ik4#*!#M{ zu%e8FHGV91DU&cS=R`hcA7>)G5B>5AHm+aE9!Wkv>x~73U-0}rWrz6BYSM6;$9~MwsEp8?L{qW^aJ`K-0}*G8rinpqp)4YNlm4en0pgou~cAV zG38>lRGqDAI4vam#@V+4^L-0^3w=w_Hp^h?U+G)rTZ5a2b-oS0&Ax5eckjk3wa-`M zJK$?--xy@$9fDG{OIdIQZfSR;eX4`|=-m)2+QQor7~A+|I_wRrpsTyF53UyX!B%nr z*0e*=SduE*mMh+ttgS6ulGIHSp}U%7LVHti)=iVrr3`5B7@T^uuy@IY78m2jeYRAF z8FT^8NQh<5<0zE+6JxOg&BUYRE?gh!K!#rI)oF$QQU|` z%W-m3+_<)sTjKhgKCcSw4(!E!$b4Ek)ToiF`L&YNnX*bVa`d$i7nNe=1uoz;5KO-EbQ61 zCojNxtJFImR^mn29hKvJ-dao06160)8+IiM-cm8OWb95-wKOdqC+1Pw7_BnECE8Uh zQ%$W@OuyoSO`&64vcy{1G`t6r983wO;x;iom=PQm9E06vRxlfPi>y!QzsaV6t;RdD@cVUb4W!NjO!HTvGJH~zbLEKBk87++jqZ@9AvjV%AwdMxw z(f8sGvOKUNusW~~daw%`Z~$YJk6;C@nTA%(3Kn2QEI_MO1lz(s(GB|n6Z`cvD+BhD zEGrkSKsMQhsQoh3d=+ZF4(skV>?HTXE^q)Vuzfdnu#r#>-H8_I=CUnp zrZE^vxfn&WF@hFi^w2JK6-LcEjF@d0EqgIi4q%iV#rp_NF*@2}WOT!*Ffk(1FdD|l zS#mDka+!@Y+CuESm&q$|Qd@(a_XgW$x)=7_1K7tM#Yv(m=EAmkGp8FYD<w`lEbsQd}X1s1eUE8xWib3-Tek-o3abzZJ%;LIfT7_w703ZrMIm&5hp_h zqb~&`F9YK)3uCU>JKG*{OEB72;P!A0PKz6Gf4B>F)qS`@JcM@wqH%}VQf;dy;ucY% z50BtC4{&8B)WAY?1aFnaDe-tKB0)(~L`74Ql~mlsjl!);wo-ueQrZ7&?|h+B$)h+v zXU{te!9XBPFibEIUSJVqMr9v?Kp+qZ1i}P@fj}S-2n2$GFu_0|OfV1(1Oj2g1OwrP z2?hdT0)apv7(9Cn`?*(keY>x1U2GQh_xs)NpL_532zyE|KcPdN<>&cjK4kh9k%o%l zgG2rehni%sY?4y=V23iyP%kuLg*zCbUleQVk`H(xOOHyD+ zhR`D?;5##C&W0f*n-@82HY7XeK-$8%PLkm<=@v6Ef=!aA%2u`sE8Jao;e{dF6YqM$ zc5lWUb_qMInBA>aBM+jGHwK?fn&MUeV88Z@^Q&W6d@csx|Mz+k74?eC+W^j3)7QT- zt4WtKr7W|{IDB$R@KXvPWfDqsc^|4QGsWioSp;LR@65I-F8p zV5`pFp{{)tRdh5|^?ZQ|L??v-;+s^5sY(;tt zg!dKS6DF2R-0%y%)j@Hc2G7|enmeHQUNI~vS%HqNVneWdp^7Pp6{YNe*C}Waq=t&s zEf_Tvp_XE_qMNoJ&PHnAr{)8#_>I=QL9L&Ys}R>CTex1a|AXTR)Z^^gy}lRIs=Jk= z+P28JjH%>Drqfc#5%s%2R&R!?t!T}*$+wK0Db>1Qx+=9AQ={*6MJ7433lytCZFZOs zNo7u`$c5J9%k>7o#(R|$5?3)Au$!<(09WkEHvGt6AMDV`6MDazMX3#u-obtP7C(s^|Q~=NLQ& zYS}qTQ9~g_wS2VdFNMnd&HBRk zk0{WN{@oEBTiwlPbyzI}M-GZ;j@bo7;OAVjv>*jHem7iYt$zH(5&s6djCVsaq zX3@gDZJ4(Q>poD&Gv^7;m3Q7N*Pg+(X}DGrlj6MYw2}vKtaz_EFCOydk-D!pUOlPr zF8-@V_v32kGazB%-8@hQ3wChgz}D2ljwytN_iEj`S_?yJLEP7jI#^K&2dxE*YN(W| zr8X=&U~4aRu%%mirI!+)Yf=Su{FjGIjc}qVn6i%V^wejDAE_fZp*uT+R8$#G9I{gk z;X#A$ql`D|^15?6h7H|;MK;WZ=X@A0hTAOC#V*?+|1!Lc(S8fPchPtsq=tBon8}#Y zO=v%w=cjeGR(yWm>ezuuk0CtrfF25yEZ~wr-$9)2+TMV-t#Zo&+$9~CyM02h8u->n z?&^$8O~7q5Is0oVgA;FlTQh@C82YQJS5wb0g}ZmZrReiqIC_pJd(TNWx& this._terminal.rows; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Buffer.prototype, "isCursorInViewport", { + get: function () { + var absoluteY = this.ybase + this.y; + var relativeY = absoluteY - this.ydisp; + return (relativeY >= 0 && relativeY < this._terminal.rows); + }, + enumerable: true, + configurable: true + }); + Buffer.prototype._getCorrectBufferLength = function (rows) { + if (!this._hasScrollback) { + return rows; + } + var correctBufferLength = rows + this._terminal.options.scrollback; + return correctBufferLength > exports.MAX_BUFFER_SIZE ? exports.MAX_BUFFER_SIZE : correctBufferLength; + }; + Buffer.prototype.fillViewportRows = function () { + if (this._lines.length === 0) { + var i = this._terminal.rows; + while (i--) { + this.lines.push(this._terminal.blankLine()); + } + } + }; + Buffer.prototype.clear = function () { + this.ydisp = 0; + this.ybase = 0; + this.y = 0; + this.x = 0; + this._lines = new CircularList_1.CircularList(this._getCorrectBufferLength(this._terminal.rows)); + this.scrollTop = 0; + this.scrollBottom = this._terminal.rows - 1; + this.setupTabStops(); + }; + Buffer.prototype.resize = function (newCols, newRows) { + var newMaxLength = this._getCorrectBufferLength(newRows); + if (newMaxLength > this._lines.maxLength) { + this._lines.maxLength = newMaxLength; + } + if (this._lines.length > 0) { + if (this._terminal.cols < newCols) { + var ch = [this._terminal.defAttr, ' ', 1, 32]; + for (var i = 0; i < this._lines.length; i++) { + if (this._lines.get(i) === undefined) { + this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols)); + } + while (this._lines.get(i).length < newCols) { + this._lines.get(i).push(ch); + } + } + } + var addToY = 0; + if (this._terminal.rows < newRows) { + for (var y = this._terminal.rows; y < newRows; y++) { + if (this._lines.length < newRows + this.ybase) { + if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) { + this.ybase--; + addToY++; + if (this.ydisp > 0) { + this.ydisp--; + } + } + else { + this._lines.push(this._terminal.blankLine(undefined, undefined, newCols)); + } + } + } + } + else { + for (var y = this._terminal.rows; y > newRows; y--) { + if (this._lines.length > newRows + this.ybase) { + if (this._lines.length > this.ybase + this.y + 1) { + this._lines.pop(); + } + else { + this.ybase++; + this.ydisp++; + } + } + } + } + if (newMaxLength < this._lines.maxLength) { + var amountToTrim = this._lines.length - newMaxLength; + if (amountToTrim > 0) { + this._lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + } + this._lines.maxLength = newMaxLength; + } + if (this.y >= newRows) { + this.y = newRows - 1; + } + if (addToY) { + this.y += addToY; + } + if (this.x >= newCols) { + this.x = newCols - 1; + } + this.scrollTop = 0; + } + this.scrollBottom = newRows - 1; + }; + Buffer.prototype.translateBufferLineToString = function (lineIndex, trimRight, startCol, endCol) { + if (startCol === void 0) { startCol = 0; } + if (endCol === void 0) { endCol = null; } + var lineString = ''; + var line = this.lines.get(lineIndex); + if (!line) { + return ''; + } + var startIndex = startCol; + endCol = endCol || line.length; + var endIndex = endCol; + for (var i = 0; i < line.length; i++) { + var char = line[i]; + lineString += char[exports.CHAR_DATA_CHAR_INDEX]; + if (char[exports.CHAR_DATA_WIDTH_INDEX] === 0) { + if (startCol >= i) { + startIndex--; + } + if (endCol >= i) { + endIndex--; + } + } + else { + if (char[exports.CHAR_DATA_CHAR_INDEX].length > 1) { + if (startCol > i) { + startIndex += char[exports.CHAR_DATA_CHAR_INDEX].length - 1; + } + if (endCol > i) { + endIndex += char[exports.CHAR_DATA_CHAR_INDEX].length - 1; + } + } + } + } + if (trimRight) { + var rightWhitespaceIndex = lineString.search(/\s+$/); + if (rightWhitespaceIndex !== -1) { + endIndex = Math.min(endIndex, rightWhitespaceIndex); + } + if (endIndex <= startIndex) { + return ''; + } + } + return lineString.substring(startIndex, endIndex); + }; + Buffer.prototype.setupTabStops = function (i) { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } + else { + this.tabs = {}; + i = 0; + } + for (; i < this._terminal.cols; i += this._terminal.options.tabStopWidth) { + this.tabs[i] = true; + } + }; + Buffer.prototype.prevStop = function (x) { + if (x == null) { + x = this.x; + } + while (!this.tabs[--x] && x > 0) + ; + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + }; + Buffer.prototype.nextStop = function (x) { + if (x == null) { + x = this.x; + } + while (!this.tabs[++x] && x < this._terminal.cols) + ; + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + }; + return Buffer; +}()); +exports.Buffer = Buffer; + + + +},{"./utils/CircularList":30}],2:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("./Buffer"); +var EventEmitter_1 = require("./EventEmitter"); +var BufferSet = (function (_super) { + __extends(BufferSet, _super); + function BufferSet(_terminal) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._normal = new Buffer_1.Buffer(_this._terminal, true); + _this._normal.fillViewportRows(); + _this._alt = new Buffer_1.Buffer(_this._terminal, false); + _this._activeBuffer = _this._normal; + _this.setupTabStops(); + return _this; + } + Object.defineProperty(BufferSet.prototype, "alt", { + get: function () { + return this._alt; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BufferSet.prototype, "active", { + get: function () { + return this._activeBuffer; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BufferSet.prototype, "normal", { + get: function () { + return this._normal; + }, + enumerable: true, + configurable: true + }); + BufferSet.prototype.activateNormalBuffer = function () { + this._alt.clear(); + this._activeBuffer = this._normal; + this.emit('activate', this._normal); + }; + BufferSet.prototype.activateAltBuffer = function () { + this._alt.fillViewportRows(); + this._activeBuffer = this._alt; + this.emit('activate', this._alt); + }; + BufferSet.prototype.resize = function (newCols, newRows) { + this._normal.resize(newCols, newRows); + this._alt.resize(newCols, newRows); + }; + BufferSet.prototype.setupTabStops = function (i) { + this._normal.setupTabStops(i); + this._alt.setupTabStops(i); + }; + return BufferSet; +}(EventEmitter_1.EventEmitter)); +exports.BufferSet = BufferSet; + + + +},{"./Buffer":1,"./EventEmitter":7}],3:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.wcwidth = (function (opts) { + var COMBINING_BMP = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + ]; + var COMBINING_HIGH = [ + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + function bisearch(ucs, data) { + var min = 0; + var max = data.length - 1; + var mid; + if (ucs < data[0][0] || ucs > data[max][1]) + return false; + while (max >= min) { + mid = (min + max) >> 1; + if (ucs > data[mid][1]) + min = mid + 1; + else if (ucs < data[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidthBMP(ucs) { + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + if (bisearch(ucs, COMBINING_BMP)) + return 0; + if (isWideBMP(ucs)) { + return 2; + } + return 1; + } + function isWideBMP(ucs) { + return (ucs >= 0x1100 && (ucs <= 0x115f || + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || + (ucs >= 0xac00 && ucs <= 0xd7a3) || + (ucs >= 0xf900 && ucs <= 0xfaff) || + (ucs >= 0xfe10 && ucs <= 0xfe19) || + (ucs >= 0xfe30 && ucs <= 0xfe6f) || + (ucs >= 0xff00 && ucs <= 0xff60) || + (ucs >= 0xffe0 && ucs <= 0xffe6))); + } + function wcwidthHigh(ucs) { + if (bisearch(ucs, COMBINING_HIGH)) + return 0; + if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) { + return 2; + } + return 1; + } + var control = opts.control | 0; + var table = null; + function init_table() { + var CODEPOINTS = 65536; + var BITWIDTH = 2; + var ITEMSIZE = 32; + var CONTAINERSIZE = CODEPOINTS * BITWIDTH / ITEMSIZE; + var CODEPOINTS_PER_ITEM = ITEMSIZE / BITWIDTH; + table = (typeof Uint32Array === 'undefined') + ? new Array(CONTAINERSIZE) + : new Uint32Array(CONTAINERSIZE); + for (var i = 0; i < CONTAINERSIZE; ++i) { + var num = 0; + var pos = CODEPOINTS_PER_ITEM; + while (pos--) + num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos); + table[i] = num; + } + return table; + } + return function (num) { + num = num | 0; + if (num < 32) + return control | 0; + if (num < 127) + return 1; + var t = table || init_table(); + if (num < 65536) + return t[num >> 4] >> ((num & 15) << 1) & 3; + return wcwidthHigh(num); + }; +})({ nul: 0, control: 0 }); + + + +},{}],4:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CHARSETS = {}; +exports.DEFAULT_CHARSET = exports.CHARSETS['B']; +exports.CHARSETS['0'] = { + '`': '\u25c6', + 'a': '\u2592', + 'b': '\u0009', + 'c': '\u000c', + 'd': '\u000d', + 'e': '\u000a', + 'f': '\u00b0', + 'g': '\u00b1', + 'h': '\u2424', + 'i': '\u000b', + 'j': '\u2518', + 'k': '\u2510', + 'l': '\u250c', + 'm': '\u2514', + 'n': '\u253c', + 'o': '\u23ba', + 'p': '\u23bb', + 'q': '\u2500', + 'r': '\u23bc', + 's': '\u23bd', + 't': '\u251c', + 'u': '\u2524', + 'v': '\u2534', + 'w': '\u252c', + 'x': '\u2502', + 'y': '\u2264', + 'z': '\u2265', + '{': '\u03c0', + '|': '\u2260', + '}': '\u00a3', + '~': '\u00b7' +}; +exports.CHARSETS['A'] = { + '#': '£' +}; +exports.CHARSETS['B'] = null; +exports.CHARSETS['4'] = { + '#': '£', + '@': '¾', + '[': 'ij', + '\\': '½', + ']': '|', + '{': '¨', + '|': 'f', + '}': '¼', + '~': '´' +}; +exports.CHARSETS['C'] = + exports.CHARSETS['5'] = { + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['R'] = { + '#': '£', + '@': 'à', + '[': '°', + '\\': 'ç', + ']': '§', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': '¨' +}; +exports.CHARSETS['Q'] = { + '@': 'à', + '[': 'â', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '`': 'ô', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': 'û' +}; +exports.CHARSETS['K'] = { + '@': '§', + '[': 'Ä', + '\\': 'Ö', + ']': 'Ü', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'ß' +}; +exports.CHARSETS['Y'] = { + '#': '£', + '@': '§', + '[': '°', + '\\': 'ç', + ']': 'é', + '`': 'ù', + '{': 'à', + '|': 'ò', + '}': 'è', + '~': 'ì' +}; +exports.CHARSETS['E'] = + exports.CHARSETS['6'] = { + '@': 'Ä', + '[': 'Æ', + '\\': 'Ø', + ']': 'Å', + '^': 'Ü', + '`': 'ä', + '{': 'æ', + '|': 'ø', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['Z'] = { + '#': '£', + '@': '§', + '[': '¡', + '\\': 'Ñ', + ']': '¿', + '{': '°', + '|': 'ñ', + '}': 'ç' +}; +exports.CHARSETS['H'] = + exports.CHARSETS['7'] = { + '@': 'É', + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' + }; +exports.CHARSETS['='] = { + '#': 'ù', + '@': 'à', + '[': 'é', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '_': 'è', + '`': 'ô', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'û' +}; + + + +},{}],5:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var CompositionHelper = (function () { + function CompositionHelper(textarea, compositionView, terminal) { + this.textarea = textarea; + this.compositionView = compositionView; + this.terminal = terminal; + this.isComposing = false; + this.isSendingComposition = false; + this.compositionPosition = { start: null, end: null }; + } + CompositionHelper.prototype.compositionstart = function () { + this.isComposing = true; + this.compositionPosition.start = this.textarea.value.length; + this.compositionView.textContent = ''; + this.compositionView.classList.add('active'); + }; + CompositionHelper.prototype.compositionupdate = function (ev) { + var _this = this; + this.compositionView.textContent = ev.data; + this.updateCompositionElements(); + setTimeout(function () { + _this.compositionPosition.end = _this.textarea.value.length; + }, 0); + }; + CompositionHelper.prototype.compositionend = function () { + this.finalizeComposition(true); + }; + CompositionHelper.prototype.keydown = function (ev) { + if (this.isComposing || this.isSendingComposition) { + if (ev.keyCode === 229) { + return false; + } + else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { + return false; + } + else { + this.finalizeComposition(false); + } + } + if (ev.keyCode === 229) { + this.handleAnyTextareaChanges(); + return false; + } + return true; + }; + CompositionHelper.prototype.finalizeComposition = function (waitForPropogation) { + var _this = this; + this.compositionView.classList.remove('active'); + this.isComposing = false; + this.clearTextareaPosition(); + if (!waitForPropogation) { + this.isSendingComposition = false; + var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); + this.terminal.handler(input); + } + else { + var currentCompositionPosition_1 = { + start: this.compositionPosition.start, + end: this.compositionPosition.end, + }; + this.isSendingComposition = true; + setTimeout(function () { + if (_this.isSendingComposition) { + _this.isSendingComposition = false; + var input = void 0; + if (_this.isComposing) { + input = _this.textarea.value.substring(currentCompositionPosition_1.start, currentCompositionPosition_1.end); + } + else { + input = _this.textarea.value.substring(currentCompositionPosition_1.start); + } + _this.terminal.handler(input); + } + }, 0); + } + }; + CompositionHelper.prototype.handleAnyTextareaChanges = function () { + var _this = this; + var oldValue = this.textarea.value; + setTimeout(function () { + if (!_this.isComposing) { + var newValue = _this.textarea.value; + var diff = newValue.replace(oldValue, ''); + if (diff.length > 0) { + _this.terminal.handler(diff); + } + } + }, 0); + }; + CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) { + var _this = this; + if (!this.isComposing) { + return; + } + if (this.terminal.buffer.isCursorInViewport) { + var cellHeight = Math.ceil(this.terminal.charMeasure.height * this.terminal.options.lineHeight); + var cursorTop = this.terminal.buffer.y * cellHeight; + var cursorLeft = this.terminal.buffer.x * this.terminal.charMeasure.width; + this.compositionView.style.left = cursorLeft + 'px'; + this.compositionView.style.top = cursorTop + 'px'; + this.compositionView.style.height = cellHeight + 'px'; + this.compositionView.style.lineHeight = cellHeight + 'px'; + var compositionViewBounds = this.compositionView.getBoundingClientRect(); + this.textarea.style.left = cursorLeft + 'px'; + this.textarea.style.top = cursorTop + 'px'; + this.textarea.style.width = compositionViewBounds.width + 'px'; + this.textarea.style.height = compositionViewBounds.height + 'px'; + this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; + } + if (!dontRecurse) { + setTimeout(function () { return _this.updateCompositionElements(true); }, 0); + } + }; + ; + CompositionHelper.prototype.clearTextareaPosition = function () { + this.textarea.style.left = ''; + this.textarea.style.top = ''; + }; + ; + return CompositionHelper; +}()); +exports.CompositionHelper = CompositionHelper; + + + +},{}],6:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var C0; +(function (C0) { + C0.NUL = '\x00'; + C0.SOH = '\x01'; + C0.STX = '\x02'; + C0.ETX = '\x03'; + C0.EOT = '\x04'; + C0.ENQ = '\x05'; + C0.ACK = '\x06'; + C0.BEL = '\x07'; + C0.BS = '\x08'; + C0.HT = '\x09'; + C0.LF = '\x0a'; + C0.VT = '\x0b'; + C0.FF = '\x0c'; + C0.CR = '\x0d'; + C0.SO = '\x0e'; + C0.SI = '\x0f'; + C0.DLE = '\x10'; + C0.DC1 = '\x11'; + C0.DC2 = '\x12'; + C0.DC3 = '\x13'; + C0.DC4 = '\x14'; + C0.NAK = '\x15'; + C0.SYN = '\x16'; + C0.ETB = '\x17'; + C0.CAN = '\x18'; + C0.EM = '\x19'; + C0.SUB = '\x1a'; + C0.ESC = '\x1b'; + C0.FS = '\x1c'; + C0.GS = '\x1d'; + C0.RS = '\x1e'; + C0.US = '\x1f'; + C0.SP = '\x20'; + C0.DEL = '\x7f'; +})(C0 = exports.C0 || (exports.C0 = {})); +; + + + +},{}],7:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter = (function () { + function EventEmitter() { + this._events = this._events || {}; + } + EventEmitter.prototype.on = function (type, listener) { + this._events[type] = this._events[type] || []; + this._events[type].push(listener); + }; + EventEmitter.prototype.off = function (type, listener) { + if (!this._events[type]) { + return; + } + var obj = this._events[type]; + var i = obj.length; + while (i--) { + if (obj[i] === listener || obj[i].listener === listener) { + obj.splice(i, 1); + return; + } + } + }; + EventEmitter.prototype.removeAllListeners = function (type) { + if (this._events[type]) { + delete this._events[type]; + } + }; + EventEmitter.prototype.once = function (type, listener) { + function on() { + var args = Array.prototype.slice.call(arguments); + this.off(type, on); + listener.apply(this, args); + } + on.listener = listener; + this.on(type, on); + }; + EventEmitter.prototype.emit = function (type) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (!this._events[type]) { + return; + } + var obj = this._events[type]; + for (var i = 0; i < obj.length; i++) { + obj[i].apply(this, args); + } + }; + EventEmitter.prototype.listeners = function (type) { + return this._events[type] || []; + }; + EventEmitter.prototype.destroy = function () { + this._events = {}; + }; + return EventEmitter; +}()); +exports.EventEmitter = EventEmitter; + + + +},{}],8:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var Buffer_1 = require("./Buffer"); +var Types_1 = require("./renderer/Types"); +var CharWidth_1 = require("./CharWidth"); +var InputHandler = (function () { + function InputHandler(_terminal) { + this._terminal = _terminal; + } + InputHandler.prototype.addChar = function (char, code) { + if (char >= ' ') { + var ch_width = CharWidth_1.wcwidth(code); + if (this._terminal.charset && this._terminal.charset[char]) { + char = this._terminal.charset[char]; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + if (!ch_width && this._terminal.buffer.x) { + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1]) { + if (!this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][Buffer_1.CHAR_DATA_WIDTH_INDEX]) { + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2]) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][Buffer_1.CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][3] = char.charCodeAt(0); + } + } + else { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][Buffer_1.CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][3] = char.charCodeAt(0); + } + this._terminal.updateRange(this._terminal.buffer.y); + } + return; + } + if (this._terminal.buffer.x + ch_width - 1 >= this._terminal.cols) { + if (this._terminal.wraparoundMode) { + this._terminal.buffer.x = 0; + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(true); + } + else { + this._terminal.buffer.lines.get(this._terminal.buffer.y).isWrapped = true; + } + } + else { + if (ch_width === 2) + return; + } + } + row = this._terminal.buffer.y + this._terminal.buffer.ybase; + if (this._terminal.insertMode) { + for (var moves = 0; moves < ch_width; ++moves) { + var removed = this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).pop(); + if (removed[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0 + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]; + } + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 0, [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]); + } + } + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, ch_width, char.charCodeAt(0)]; + this._terminal.buffer.x++; + this._terminal.updateRange(this._terminal.buffer.y); + if (ch_width === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, '', 0, undefined]; + this._terminal.buffer.x++; + } + } + }; + InputHandler.prototype.bell = function () { + this._terminal.bell(); + }; + InputHandler.prototype.lineFeed = function () { + if (this._terminal.convertEol) { + this._terminal.buffer.x = 0; + } + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(); + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + this._terminal.emit('linefeed'); + }; + InputHandler.prototype.carriageReturn = function () { + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.backspace = function () { + if (this._terminal.buffer.x > 0) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.tab = function () { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + }; + InputHandler.prototype.shiftOut = function () { + this._terminal.setgLevel(1); + }; + InputHandler.prototype.shiftIn = function () { + this._terminal.setgLevel(0); + }; + InputHandler.prototype.insertChars = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j = this._terminal.buffer.x; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row).splice(j++, 0, ch); + this._terminal.buffer.lines.get(row).pop(); + } + }; + InputHandler.prototype.cursorUp = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + }; + InputHandler.prototype.cursorDown = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.cursorForward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.cursorBackward = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + this._terminal.buffer.x -= param; + if (this._terminal.buffer.x < 0) { + this._terminal.buffer.x = 0; + } + }; + InputHandler.prototype.cursorNextLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.cursorPrecedingLine = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + this._terminal.buffer.x = 0; + }; + InputHandler.prototype.cursorCharAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + }; + InputHandler.prototype.cursorPosition = function (params) { + var col; + var row = params[0] - 1; + if (params.length >= 2) { + col = params[1] - 1; + } + else { + col = 0; + } + if (row < 0) { + row = 0; + } + else if (row >= this._terminal.rows) { + row = this._terminal.rows - 1; + } + if (col < 0) { + col = 0; + } + else if (col >= this._terminal.cols) { + col = this._terminal.cols - 1; + } + this._terminal.buffer.x = col; + this._terminal.buffer.y = row; + }; + InputHandler.prototype.cursorForwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + } + }; + InputHandler.prototype.eraseInDisplay = function (params) { + var j; + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y + 1; + for (; j < this._terminal.rows; j++) { + this._terminal.eraseLine(j); + } + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y; + while (j--) { + this._terminal.eraseLine(j); + } + break; + case 2: + j = this._terminal.rows; + while (j--) + this._terminal.eraseLine(j); + break; + case 3: + var scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows; + if (scrollBackSize > 0) { + this._terminal.buffer.lines.trimStart(scrollBackSize); + this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0); + this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0); + this._terminal.emit('scroll', 0); + } + break; + } + }; + InputHandler.prototype.eraseInLine = function (params) { + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 2: + this._terminal.eraseLine(this._terminal.buffer.y); + break; + } + }; + InputHandler.prototype.insertLines = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var scrollBottomRowsOffset = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + var scrollBottomAbsolute = this._terminal.rows - 1 + this._terminal.buffer.ybase - scrollBottomRowsOffset + 1; + while (param--) { + this._terminal.buffer.lines.splice(scrollBottomAbsolute - 1, 1); + this._terminal.buffer.lines.splice(row, 0, this._terminal.blankLine(true)); + } + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.deleteLines = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j; + j = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.buffer.ybase - j; + while (param--) { + this._terminal.buffer.lines.splice(row, 1); + this._terminal.buffer.lines.splice(j, 0, this._terminal.blankLine(true)); + } + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.deleteChars = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param--) { + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 1); + this._terminal.buffer.lines.get(row).push(ch); + } + this._terminal.updateRange(this._terminal.buffer.y); + }; + InputHandler.prototype.scrollUp = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.scrollDown = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 0, this._terminal.blankLine()); + } + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + }; + InputHandler.prototype.eraseChars = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + var row = this._terminal.buffer.y + this._terminal.buffer.ybase; + var j = this._terminal.buffer.x; + var ch = [this._terminal.eraseAttr(), ' ', 1, 32]; + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row)[j++] = ch; + } + }; + InputHandler.prototype.cursorBackwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.prevStop(); + } + }; + InputHandler.prototype.charPosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.HPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.repeatPrecedingCharacter = function (params) { + var param = params[0] || 1; + var line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + this._terminal.buffer.y); + var ch = line[this._terminal.buffer.x - 1] || [this._terminal.defAttr, ' ', 1, 32]; + while (param--) { + line[this._terminal.buffer.x++] = ch; + } + }; + InputHandler.prototype.sendDeviceAttributes = function (params) { + if (params[0] > 0) { + return; + } + if (!this._terminal.prefix) { + if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?1;2c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[?6c'); + } + } + else if (this._terminal.prefix === '>') { + if (this._terminal.is('xterm')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>0;276;0c'); + } + else if (this._terminal.is('rxvt-unicode')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>85;95;0c'); + } + else if (this._terminal.is('linux')) { + this._terminal.send(params[0] + 'c'); + } + else if (this._terminal.is('screen')) { + this._terminal.send(EscapeSequences_1.C0.ESC + '[>83;40003;0c'); + } + } + }; + InputHandler.prototype.linePosAbsolute = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y = param - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + }; + InputHandler.prototype.VPositionRelative = function (params) { + var param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + }; + InputHandler.prototype.HVPosition = function (params) { + if (params[0] < 1) + params[0] = 1; + if (params[1] < 1) + params[1] = 1; + this._terminal.buffer.y = params[0] - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + this._terminal.buffer.x = params[1] - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + }; + InputHandler.prototype.tabClear = function (params) { + var param = params[0]; + if (param <= 0) { + delete this._terminal.buffer.tabs[this._terminal.buffer.x]; + } + else if (param === 3) { + this._terminal.buffer.tabs = {}; + } + }; + InputHandler.prototype.setMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.setMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = true; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = true; + break; + case 2: + this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(1, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(2, Charsets_1.DEFAULT_CHARSET); + this._terminal.setgCharset(3, Charsets_1.DEFAULT_CHARSET); + break; + case 3: + this._terminal.savedCols = this._terminal.cols; + this._terminal.resize(132, this._terminal.rows); + break; + case 6: + this._terminal.originMode = true; + break; + case 7: + this._terminal.wraparoundMode = true; + break; + case 12: + break; + case 66: + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = params[0] === 9; + this._terminal.vt200Mouse = params[0] === 1000; + this._terminal.normalMouse = params[0] > 1000; + this._terminal.mouseEvents = true; + this._terminal.element.classList.add('enable-mouse-events'); + this._terminal.selectionManager.disable(); + this._terminal.log('Binding to mouse events.'); + break; + case 1004: + this._terminal.sendFocus = true; + break; + case 1005: + this._terminal.utfMouse = true; + break; + case 1006: + this._terminal.sgrMouse = true; + break; + case 1015: + this._terminal.urxvtMouse = true; + break; + case 25: + this._terminal.cursorHidden = false; + break; + case 1049: + case 47: + case 1047: + this._terminal.buffers.activateAltBuffer(); + this._terminal.selectionManager.setBuffer(this._terminal.buffer); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + break; + case 2004: + this._terminal.bracketedPasteMode = true; + break; + } + } + }; + InputHandler.prototype.resetMode = function (params) { + if (params.length > 1) { + for (var i = 0; i < params.length; i++) { + this.resetMode([params[i]]); + } + return; + } + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = false; + break; + case 20: + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = false; + break; + case 3: + if (this._terminal.cols === 132 && this._terminal.savedCols) { + this._terminal.resize(this._terminal.savedCols, this._terminal.rows); + } + delete this._terminal.savedCols; + break; + case 6: + this._terminal.originMode = false; + break; + case 7: + this._terminal.wraparoundMode = false; + break; + case 12: + break; + case 66: + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + break; + case 9: + case 1000: + case 1002: + case 1003: + this._terminal.x10Mouse = false; + this._terminal.vt200Mouse = false; + this._terminal.normalMouse = false; + this._terminal.mouseEvents = false; + this._terminal.element.classList.remove('enable-mouse-events'); + this._terminal.selectionManager.enable(); + break; + case 1004: + this._terminal.sendFocus = false; + break; + case 1005: + this._terminal.utfMouse = false; + break; + case 1006: + this._terminal.sgrMouse = false; + break; + case 1015: + this._terminal.urxvtMouse = false; + break; + case 25: + this._terminal.cursorHidden = true; + break; + case 1049: + case 47: + case 1047: + this._terminal.buffers.activateNormalBuffer(); + this._terminal.selectionManager.setBuffer(this._terminal.buffer); + this._terminal.refresh(0, this._terminal.rows - 1); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + break; + case 2004: + this._terminal.bracketedPasteMode = false; + break; + } + } + }; + InputHandler.prototype.charAttributes = function (params) { + if (params.length === 1 && params[0] === 0) { + this._terminal.curAttr = this._terminal.defAttr; + return; + } + var l = params.length; + var flags = this._terminal.curAttr >> 18; + var fg = (this._terminal.curAttr >> 9) & 0x1ff; + var bg = this._terminal.curAttr & 0x1ff; + var p; + for (var i = 0; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + fg = p - 30; + } + else if (p >= 40 && p <= 47) { + bg = p - 40; + } + else if (p >= 90 && p <= 97) { + p += 8; + fg = p - 90; + } + else if (p >= 100 && p <= 107) { + p += 8; + bg = p - 100; + } + else if (p === 0) { + flags = this._terminal.defAttr >> 18; + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 1) { + flags |= Types_1.FLAGS.BOLD; + } + else if (p === 4) { + flags |= Types_1.FLAGS.UNDERLINE; + } + else if (p === 5) { + flags |= Types_1.FLAGS.BLINK; + } + else if (p === 7) { + flags |= Types_1.FLAGS.INVERSE; + } + else if (p === 8) { + flags |= Types_1.FLAGS.INVISIBLE; + } + else if (p === 2) { + flags |= Types_1.FLAGS.DIM; + } + else if (p === 22) { + flags &= ~Types_1.FLAGS.BOLD; + flags &= ~Types_1.FLAGS.DIM; + } + else if (p === 24) { + flags &= ~Types_1.FLAGS.UNDERLINE; + } + else if (p === 25) { + flags &= ~Types_1.FLAGS.BLINK; + } + else if (p === 27) { + flags &= ~Types_1.FLAGS.INVERSE; + } + else if (p === 28) { + flags &= ~Types_1.FLAGS.INVISIBLE; + } + else if (p === 39) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + } + else if (p === 49) { + bg = this._terminal.defAttr & 0x1ff; + } + else if (p === 38) { + if (params[i + 1] === 2) { + i += 2; + fg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (fg === -1) + fg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } + else if (p === 48) { + if (params[i + 1] === 2) { + i += 2; + bg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (bg === -1) + bg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } + else if (p === 100) { + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } + else { + this._terminal.error('Unknown SGR attribute: %d.', p); + } + } + this._terminal.curAttr = (flags << 18) | (fg << 9) | bg; + }; + InputHandler.prototype.deviceStatus = function (params) { + if (!this._terminal.prefix) { + switch (params[0]) { + case 5: + this._terminal.send(EscapeSequences_1.C0.ESC + '[0n'); + break; + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + } + } + else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 6: + this._terminal.send(EscapeSequences_1.C0.ESC + '[?' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + case 15: + break; + case 25: + break; + case 26: + break; + case 53: + break; + } + } + }; + InputHandler.prototype.softReset = function (params) { + this._terminal.cursorHidden = false; + this._terminal.insertMode = false; + this._terminal.originMode = false; + this._terminal.wraparoundMode = true; + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + this._terminal.applicationCursor = false; + this._terminal.buffer.scrollTop = 0; + this._terminal.buffer.scrollBottom = this._terminal.rows - 1; + this._terminal.curAttr = this._terminal.defAttr; + this._terminal.buffer.x = this._terminal.buffer.y = 0; + this._terminal.charset = null; + this._terminal.glevel = 0; + this._terminal.charsets = [null]; + }; + InputHandler.prototype.setCursorStyle = function (params) { + var param = params[0] < 1 ? 1 : params[0]; + switch (param) { + case 1: + case 2: + this._terminal.setOption('cursorStyle', 'block'); + break; + case 3: + case 4: + this._terminal.setOption('cursorStyle', 'underline'); + break; + case 5: + case 6: + this._terminal.setOption('cursorStyle', 'bar'); + break; + } + var isBlinking = param % 2 === 1; + this._terminal.setOption('cursorBlink', isBlinking); + }; + InputHandler.prototype.setScrollRegion = function (params) { + if (this._terminal.prefix) + return; + this._terminal.buffer.scrollTop = (params[0] || 1) - 1; + this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1; + this._terminal.buffer.x = 0; + this._terminal.buffer.y = 0; + }; + InputHandler.prototype.saveCursor = function (params) { + this._terminal.buffer.savedX = this._terminal.buffer.x; + this._terminal.buffer.savedY = this._terminal.buffer.y; + }; + InputHandler.prototype.restoreCursor = function (params) { + this._terminal.buffer.x = this._terminal.buffer.savedX || 0; + this._terminal.buffer.y = this._terminal.buffer.savedY || 0; + }; + return InputHandler; +}()); +exports.InputHandler = InputHandler; + + + +},{"./Buffer":1,"./CharWidth":3,"./Charsets":4,"./EscapeSequences":6,"./renderer/Types":27}],9:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Types_1 = require("./Types"); +var MouseZoneManager_1 = require("./input/MouseZoneManager"); +var EventEmitter_1 = require("./EventEmitter"); +var protocolClause = '(https?:\\/\\/)'; +var domainCharacterSet = '[\\da-z\\.-]+'; +var negatedDomainCharacterSet = '[^\\da-z\\.-]+'; +var domainBodyClause = '(' + domainCharacterSet + ')'; +var tldClause = '([a-z\\.]{2,6})'; +var ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +var localHostClause = '(localhost)'; +var portClause = '(:\\d{1,5})'; +var hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; +var pathClause = '(\\/[\\/\\w\\.\\-%~]*)*'; +var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; +var queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; +var hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; +var negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; +var bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; +var start = '(?:^|' + negatedDomainCharacterSet + ')('; +var end = ')($|' + negatedPathCharacterSet + ')'; +var strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); +var HYPERTEXT_LINK_MATCHER_ID = 0; +var Linkifier = (function (_super) { + __extends(Linkifier, _super); + function Linkifier(_terminal) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._linkMatchers = []; + _this._nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; + _this._rowsToLinkify = { + start: null, + end: null + }; + _this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); + return _this; + } + Linkifier.prototype.attachToDom = function (mouseZoneManager) { + this._mouseZoneManager = mouseZoneManager; + }; + Linkifier.prototype.linkifyRows = function (start, end) { + var _this = this; + if (!this._mouseZoneManager) { + return; + } + if (!this._rowsToLinkify.start) { + this._rowsToLinkify.start = start; + this._rowsToLinkify.end = end; + } + else { + this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start; + this._rowsToLinkify.end = this._rowsToLinkify.end > end ? this._rowsToLinkify.end : end; + } + this._mouseZoneManager.clearAll(start, end); + if (this._rowsTimeoutId) { + clearTimeout(this._rowsTimeoutId); + } + this._rowsTimeoutId = setTimeout(function () { return _this._linkifyRows(); }, Linkifier.TIME_BEFORE_LINKIFY); + }; + Linkifier.prototype._linkifyRows = function () { + this._rowsTimeoutId = null; + for (var i = this._rowsToLinkify.start; i <= this._rowsToLinkify.end; i++) { + this._linkifyRow(i); + } + this._rowsToLinkify.start = null; + this._rowsToLinkify.end = null; + }; + Linkifier.prototype.setHypertextLinkHandler = function (handler) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; + }; + Linkifier.prototype.setHypertextValidationCallback = function (callback) { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback; + }; + Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) { + if (options === void 0) { options = {}; } + if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + throw new Error('handler must be defined'); + } + var matcher = { + id: this._nextLinkMatcherId++, + regex: regex, + handler: handler, + matchIndex: options.matchIndex, + validationCallback: options.validationCallback, + hoverTooltipCallback: options.tooltipCallback, + hoverLeaveCallback: options.leaveCallback, + priority: options.priority || 0 + }; + this._addLinkMatcherToList(matcher); + return matcher.id; + }; + Linkifier.prototype._addLinkMatcherToList = function (matcher) { + if (this._linkMatchers.length === 0) { + this._linkMatchers.push(matcher); + return; + } + for (var i = this._linkMatchers.length - 1; i >= 0; i--) { + if (matcher.priority <= this._linkMatchers[i].priority) { + this._linkMatchers.splice(i + 1, 0, matcher); + return; + } + } + this._linkMatchers.splice(0, 0, matcher); + }; + Linkifier.prototype.deregisterLinkMatcher = function (matcherId) { + for (var i = 1; i < this._linkMatchers.length; i++) { + if (this._linkMatchers[i].id === matcherId) { + this._linkMatchers.splice(i, 1); + return true; + } + } + return false; + }; + Linkifier.prototype._linkifyRow = function (rowIndex) { + var absoluteRowIndex = this._terminal.buffer.ydisp + rowIndex; + if (absoluteRowIndex >= this._terminal.buffer.lines.length) { + return; + } + var text = this._terminal.buffer.translateBufferLineToString(absoluteRowIndex, false); + for (var i = 0; i < this._linkMatchers.length; i++) { + this._doLinkifyRow(rowIndex, text, this._linkMatchers[i]); + } + }; + Linkifier.prototype._doLinkifyRow = function (rowIndex, text, matcher, offset) { + var _this = this; + if (offset === void 0) { offset = 0; } + var result = []; + var isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID; + var match = text.match(matcher.regex); + if (!match || match.length === 0) { + return; + } + var uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + var index = text.indexOf(uri); + if (matcher.validationCallback) { + matcher.validationCallback(uri, function (isValid) { + if (_this._rowsTimeoutId) { + return; + } + if (isValid) { + _this._addLink(offset + index, rowIndex, uri, matcher); + } + }); + } + else { + this._addLink(offset + index, rowIndex, uri, matcher); + } + var remainingStartIndex = index + uri.length; + var remainingText = text.substr(remainingStartIndex); + if (remainingText.length > 0) { + this._doLinkifyRow(rowIndex, remainingText, matcher, offset + remainingStartIndex); + } + }; + Linkifier.prototype._addLink = function (x, y, uri, matcher) { + var _this = this; + this._mouseZoneManager.add(new MouseZoneManager_1.MouseZone(x + 1, x + 1 + uri.length, y + 1, function (e) { + if (matcher.handler) { + return matcher.handler(e, uri); + } + window.open(uri, '_blank'); + }, function (e) { + _this.emit(Types_1.LinkHoverEventTypes.HOVER, { x: x, y: y, length: uri.length }); + _this._terminal.element.style.cursor = 'pointer'; + }, function (e) { + _this.emit(Types_1.LinkHoverEventTypes.TOOLTIP, { x: x, y: y, length: uri.length }); + if (matcher.hoverTooltipCallback) { + matcher.hoverTooltipCallback(e, uri); + } + }, function () { + _this.emit(Types_1.LinkHoverEventTypes.LEAVE, { x: x, y: y, length: uri.length }); + _this._terminal.element.style.cursor = ''; + if (matcher.hoverLeaveCallback) { + matcher.hoverLeaveCallback(); + } + })); + }; + Linkifier.TIME_BEFORE_LINKIFY = 200; + return Linkifier; +}(EventEmitter_1.EventEmitter)); +exports.Linkifier = Linkifier; + + + +},{"./EventEmitter":7,"./Types":14,"./input/MouseZoneManager":17}],10:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var EscapeSequences_1 = require("./EscapeSequences"); +var Charsets_1 = require("./Charsets"); +var normalStateHandler = {}; +normalStateHandler[EscapeSequences_1.C0.BEL] = function (parser, handler) { return handler.bell(); }; +normalStateHandler[EscapeSequences_1.C0.LF] = function (parser, handler) { return handler.lineFeed(); }; +normalStateHandler[EscapeSequences_1.C0.VT] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.FF] = normalStateHandler[EscapeSequences_1.C0.LF]; +normalStateHandler[EscapeSequences_1.C0.CR] = function (parser, handler) { return handler.carriageReturn(); }; +normalStateHandler[EscapeSequences_1.C0.BS] = function (parser, handler) { return handler.backspace(); }; +normalStateHandler[EscapeSequences_1.C0.HT] = function (parser, handler) { return handler.tab(); }; +normalStateHandler[EscapeSequences_1.C0.SO] = function (parser, handler) { return handler.shiftOut(); }; +normalStateHandler[EscapeSequences_1.C0.SI] = function (parser, handler) { return handler.shiftIn(); }; +normalStateHandler[EscapeSequences_1.C0.ESC] = function (parser, handler) { return parser.setState(ParserState.ESCAPED); }; +var escapedStateHandler = {}; +escapedStateHandler['['] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.CSI_PARAM); +}; +escapedStateHandler[']'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.OSC); +}; +escapedStateHandler['P'] = function (parser, terminal) { + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.DCS); +}; +escapedStateHandler['_'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['^'] = function (parser, terminal) { + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['c'] = function (parser, terminal) { + terminal.reset(); +}; +escapedStateHandler['E'] = function (parser, terminal) { + terminal.buffer.x = 0; + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['D'] = function (parser, terminal) { + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['M'] = function (parser, terminal) { + terminal.reverseIndex(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['%'] = function (parser, terminal) { + terminal.setgLevel(0); + terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET); + parser.setState(ParserState.NORMAL); + parser.skipNextChar(); +}; +escapedStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiParamStateHandler = {}; +csiParamStateHandler['?'] = function (parser) { return parser.setPrefix('?'); }; +csiParamStateHandler['>'] = function (parser) { return parser.setPrefix('>'); }; +csiParamStateHandler['!'] = function (parser) { return parser.setPrefix('!'); }; +csiParamStateHandler['0'] = function (parser) { return parser.setParam(parser.getParam() * 10); }; +csiParamStateHandler['1'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 1); }; +csiParamStateHandler['2'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 2); }; +csiParamStateHandler['3'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 3); }; +csiParamStateHandler['4'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 4); }; +csiParamStateHandler['5'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 5); }; +csiParamStateHandler['6'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 6); }; +csiParamStateHandler['7'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 7); }; +csiParamStateHandler['8'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 8); }; +csiParamStateHandler['9'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 9); }; +csiParamStateHandler['$'] = function (parser) { return parser.setPostfix('$'); }; +csiParamStateHandler['"'] = function (parser) { return parser.setPostfix('"'); }; +csiParamStateHandler[' '] = function (parser) { return parser.setPostfix(' '); }; +csiParamStateHandler['\''] = function (parser) { return parser.setPostfix('\''); }; +csiParamStateHandler[';'] = function (parser) { return parser.finalizeParam(); }; +csiParamStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); }; +var csiStateHandler = {}; +csiStateHandler['@'] = function (handler, params, prefix) { return handler.insertChars(params); }; +csiStateHandler['A'] = function (handler, params, prefix) { return handler.cursorUp(params); }; +csiStateHandler['B'] = function (handler, params, prefix) { return handler.cursorDown(params); }; +csiStateHandler['C'] = function (handler, params, prefix) { return handler.cursorForward(params); }; +csiStateHandler['D'] = function (handler, params, prefix) { return handler.cursorBackward(params); }; +csiStateHandler['E'] = function (handler, params, prefix) { return handler.cursorNextLine(params); }; +csiStateHandler['F'] = function (handler, params, prefix) { return handler.cursorPrecedingLine(params); }; +csiStateHandler['G'] = function (handler, params, prefix) { return handler.cursorCharAbsolute(params); }; +csiStateHandler['H'] = function (handler, params, prefix) { return handler.cursorPosition(params); }; +csiStateHandler['I'] = function (handler, params, prefix) { return handler.cursorForwardTab(params); }; +csiStateHandler['J'] = function (handler, params, prefix) { return handler.eraseInDisplay(params); }; +csiStateHandler['K'] = function (handler, params, prefix) { return handler.eraseInLine(params); }; +csiStateHandler['L'] = function (handler, params, prefix) { return handler.insertLines(params); }; +csiStateHandler['M'] = function (handler, params, prefix) { return handler.deleteLines(params); }; +csiStateHandler['P'] = function (handler, params, prefix) { return handler.deleteChars(params); }; +csiStateHandler['S'] = function (handler, params, prefix) { return handler.scrollUp(params); }; +csiStateHandler['T'] = function (handler, params, prefix) { + if (params.length < 2 && !prefix) { + handler.scrollDown(params); + } +}; +csiStateHandler['X'] = function (handler, params, prefix) { return handler.eraseChars(params); }; +csiStateHandler['Z'] = function (handler, params, prefix) { return handler.cursorBackwardTab(params); }; +csiStateHandler['`'] = function (handler, params, prefix) { return handler.charPosAbsolute(params); }; +csiStateHandler['a'] = function (handler, params, prefix) { return handler.HPositionRelative(params); }; +csiStateHandler['b'] = function (handler, params, prefix) { return handler.repeatPrecedingCharacter(params); }; +csiStateHandler['c'] = function (handler, params, prefix) { return handler.sendDeviceAttributes(params); }; +csiStateHandler['d'] = function (handler, params, prefix) { return handler.linePosAbsolute(params); }; +csiStateHandler['e'] = function (handler, params, prefix) { return handler.VPositionRelative(params); }; +csiStateHandler['f'] = function (handler, params, prefix) { return handler.HVPosition(params); }; +csiStateHandler['g'] = function (handler, params, prefix) { return handler.tabClear(params); }; +csiStateHandler['h'] = function (handler, params, prefix) { return handler.setMode(params); }; +csiStateHandler['l'] = function (handler, params, prefix) { return handler.resetMode(params); }; +csiStateHandler['m'] = function (handler, params, prefix) { return handler.charAttributes(params); }; +csiStateHandler['n'] = function (handler, params, prefix) { return handler.deviceStatus(params); }; +csiStateHandler['p'] = function (handler, params, prefix) { + switch (prefix) { + case '!': + handler.softReset(params); + break; + } +}; +csiStateHandler['q'] = function (handler, params, prefix, postfix) { + if (postfix === ' ') { + handler.setCursorStyle(params); + } +}; +csiStateHandler['r'] = function (handler, params) { return handler.setScrollRegion(params); }; +csiStateHandler['s'] = function (handler, params) { return handler.saveCursor(params); }; +csiStateHandler['u'] = function (handler, params) { return handler.restoreCursor(params); }; +csiStateHandler[EscapeSequences_1.C0.CAN] = function (handler, params, prefix, postfix, parser) { return parser.setState(ParserState.NORMAL); }; +var ParserState; +(function (ParserState) { + ParserState[ParserState["NORMAL"] = 0] = "NORMAL"; + ParserState[ParserState["ESCAPED"] = 1] = "ESCAPED"; + ParserState[ParserState["CSI_PARAM"] = 2] = "CSI_PARAM"; + ParserState[ParserState["CSI"] = 3] = "CSI"; + ParserState[ParserState["OSC"] = 4] = "OSC"; + ParserState[ParserState["CHARSET"] = 5] = "CHARSET"; + ParserState[ParserState["DCS"] = 6] = "DCS"; + ParserState[ParserState["IGNORE"] = 7] = "IGNORE"; +})(ParserState = exports.ParserState || (exports.ParserState = {})); +var Parser = (function () { + function Parser(_inputHandler, _terminal) { + this._inputHandler = _inputHandler; + this._terminal = _terminal; + this._state = ParserState.NORMAL; + } + Parser.prototype.parse = function (data) { + var l = data.length; + var j; + var cs; + var ch; + var code; + var low; + var cursorStartX = this._terminal.buffer.x; + var cursorStartY = this._terminal.buffer.y; + if (this._terminal.debug) { + this._terminal.log('data: ' + data); + } + this._position = 0; + if (this._terminal.surrogate_high) { + data = this._terminal.surrogate_high + data; + this._terminal.surrogate_high = ''; + } + for (; this._position < l; this._position++) { + ch = data[this._position]; + code = data.charCodeAt(this._position); + if (0xD800 <= code && code <= 0xDBFF) { + low = data.charCodeAt(this._position + 1); + if (isNaN(low)) { + this._terminal.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(this._position + 1); + } + if (0xDC00 <= code && code <= 0xDFFF) + continue; + switch (this._state) { + case ParserState.NORMAL: + if (ch in normalStateHandler) { + normalStateHandler[ch](this, this._inputHandler); + } + else { + this._inputHandler.addChar(ch, code); + } + break; + case ParserState.ESCAPED: + if (ch in escapedStateHandler) { + escapedStateHandler[ch](this, this._terminal); + break; + } + switch (ch) { + case '(': + case ')': + case '*': + case '+': + case '-': + case '.': + switch (ch) { + case '(': + this._terminal.gcharset = 0; + break; + case ')': + this._terminal.gcharset = 1; + break; + case '*': + this._terminal.gcharset = 2; + break; + case '+': + this._terminal.gcharset = 3; + break; + case '-': + this._terminal.gcharset = 1; + break; + case '.': + this._terminal.gcharset = 2; + break; + } + this._state = ParserState.CHARSET; + break; + case '/': + this._terminal.gcharset = 3; + this._state = ParserState.CHARSET; + this._position--; + break; + case 'N': + this._state = ParserState.NORMAL; + break; + case 'O': + this._state = ParserState.NORMAL; + break; + case 'n': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + case 'o': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + case '|': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + case '}': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + case '~': + this._terminal.setgLevel(1); + this._state = ParserState.NORMAL; + break; + case '7': + this._inputHandler.saveCursor(); + this._state = ParserState.NORMAL; + break; + case '8': + this._inputHandler.restoreCursor(); + this._state = ParserState.NORMAL; + break; + case '#': + this._state = ParserState.NORMAL; + this._position++; + break; + case 'H': + this._terminal.tabSet(); + this._state = ParserState.NORMAL; + break; + case '=': + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + case '>': + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + default: + this._state = ParserState.NORMAL; + this._terminal.error('Unknown ESC control: %s.', ch); + break; + } + break; + case ParserState.CHARSET: + if (ch in Charsets_1.CHARSETS) { + cs = Charsets_1.CHARSETS[ch]; + if (ch === '/') { + this.skipNextChar(); + } + } + else { + cs = Charsets_1.DEFAULT_CHARSET; + } + this._terminal.setgCharset(this._terminal.gcharset, cs); + this._terminal.gcharset = null; + this._state = ParserState.NORMAL; + break; + case ParserState.OSC: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._terminal.params.push(this._terminal.currentParam); + switch (this._terminal.params[0]) { + case 0: + case 1: + case 2: + if (this._terminal.params[1]) { + this._terminal.title = this._terminal.params[1]; + this._terminal.handleTitle(this._terminal.title); + } + break; + case 3: + break; + case 4: + case 5: + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + break; + case 46: + break; + case 50: + break; + case 51: + break; + case 52: + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + break; + } + this._terminal.params = []; + this._terminal.currentParam = 0; + this._state = ParserState.NORMAL; + } + else { + if (!this._terminal.params.length) { + if (ch >= '0' && ch <= '9') { + this._terminal.currentParam = + this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; + } + else if (ch === ';') { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = ''; + } + } + else { + this._terminal.currentParam += ch; + } + } + break; + case ParserState.CSI_PARAM: + if (ch in csiParamStateHandler) { + csiParamStateHandler[ch](this); + break; + } + this.finalizeParam(); + this._state = ParserState.CSI; + case ParserState.CSI: + if (ch in csiStateHandler) { + if (this._terminal.debug) { + this._terminal.log("CSI " + (this._terminal.prefix ? this._terminal.prefix : '') + " " + (this._terminal.params ? this._terminal.params.join(';') : '') + " " + (this._terminal.postfix ? this._terminal.postfix : '') + " " + ch); + } + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this); + } + else { + this._terminal.error('Unknown CSI code: %s.', ch); + } + this._state = ParserState.NORMAL; + this._terminal.prefix = ''; + this._terminal.postfix = ''; + break; + case ParserState.DCS: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + var pt = void 0; + var valid = void 0; + switch (this._terminal.prefix) { + case '': + break; + case '$q': + pt = this._terminal.currentParam; + valid = false; + switch (pt) { + case '"q': + pt = '0"q'; + break; + case '"p': + pt = '61"p'; + break; + case 'r': + pt = '' + + (this._terminal.buffer.scrollTop + 1) + + ';' + + (this._terminal.buffer.scrollBottom + 1) + + 'r'; + break; + case 'm': + pt = '0m'; + break; + default: + this._terminal.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '$r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + case '+p': + break; + case '+q': + pt = this._terminal.currentParam; + valid = false; + this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '+r' + pt + EscapeSequences_1.C0.ESC + '\\'); + break; + default: + this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix); + break; + } + this._terminal.currentParam = 0; + this._terminal.prefix = ''; + this._state = ParserState.NORMAL; + } + else if (!this._terminal.currentParam) { + if (!this._terminal.prefix && ch !== '$' && ch !== '+') { + this._terminal.currentParam = ch; + } + else if (this._terminal.prefix.length === 2) { + this._terminal.currentParam = ch; + } + else { + this._terminal.prefix += ch; + } + } + else { + this._terminal.currentParam += ch; + } + break; + case ParserState.IGNORE: + if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) { + if (ch === EscapeSequences_1.C0.ESC) + this._position++; + this._state = ParserState.NORMAL; + } + break; + } + } + if (this._terminal.buffer.x !== cursorStartX || this._terminal.buffer.y !== cursorStartY) { + this._terminal.emit('cursormove'); + } + return this._state; + }; + Parser.prototype.setState = function (state) { + this._state = state; + }; + Parser.prototype.setPrefix = function (prefix) { + this._terminal.prefix = prefix; + }; + Parser.prototype.setPostfix = function (postfix) { + this._terminal.postfix = postfix; + }; + Parser.prototype.setParam = function (param) { + this._terminal.currentParam = param; + }; + Parser.prototype.getParam = function () { + return this._terminal.currentParam; + }; + Parser.prototype.finalizeParam = function () { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; + }; + Parser.prototype.skipNextChar = function () { + this._position++; + }; + return Parser; +}()); +exports.Parser = Parser; + + + +},{"./Charsets":4,"./EscapeSequences":6}],11:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var MouseHelper_1 = require("./utils/MouseHelper"); +var Browser = require("./utils/Browser"); +var EventEmitter_1 = require("./EventEmitter"); +var SelectionModel_1 = require("./SelectionModel"); +var Buffer_1 = require("./Buffer"); +var DRAG_SCROLL_MAX_THRESHOLD = 50; +var DRAG_SCROLL_MAX_SPEED = 15; +var DRAG_SCROLL_INTERVAL = 50; +var WORD_SEPARATORS = ' ()[]{}\'"'; +var NON_BREAKING_SPACE_CHAR = String.fromCharCode(160); +var ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g'); +var SelectionMode; +(function (SelectionMode) { + SelectionMode[SelectionMode["NORMAL"] = 0] = "NORMAL"; + SelectionMode[SelectionMode["WORD"] = 1] = "WORD"; + SelectionMode[SelectionMode["LINE"] = 2] = "LINE"; +})(SelectionMode || (SelectionMode = {})); +var SelectionManager = (function (_super) { + __extends(SelectionManager, _super); + function SelectionManager(_terminal, _buffer, _charMeasure) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._buffer = _buffer; + _this._charMeasure = _charMeasure; + _this._enabled = true; + _this._initListeners(); + _this.enable(); + _this._model = new SelectionModel_1.SelectionModel(_terminal); + _this._activeSelectionMode = SelectionMode.NORMAL; + return _this; + } + SelectionManager.prototype._initListeners = function () { + var _this = this; + this._mouseMoveListener = function (event) { return _this._onMouseMove(event); }; + this._mouseUpListener = function (event) { return _this._onMouseUp(event); }; + this._buffer.lines.on('trim', function (amount) { return _this._onTrim(amount); }); + }; + SelectionManager.prototype.disable = function () { + this.clearSelection(); + this._enabled = false; + }; + SelectionManager.prototype.enable = function () { + this._enabled = true; + }; + SelectionManager.prototype.setBuffer = function (buffer) { + this._buffer = buffer; + this.clearSelection(); + }; + Object.defineProperty(SelectionManager.prototype, "selectionStart", { + get: function () { return this._model.finalSelectionStart; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "selectionEnd", { + get: function () { return this._model.finalSelectionEnd; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "hasSelection", { + get: function () { + var start = this._model.finalSelectionStart; + var end = this._model.finalSelectionEnd; + if (!start || !end) { + return false; + } + return start[0] !== end[0] || start[1] !== end[1]; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionManager.prototype, "selectionText", { + get: function () { + var start = this._model.finalSelectionStart; + var end = this._model.finalSelectionEnd; + if (!start || !end) { + return ''; + } + var startRowEndCol = start[1] === end[1] ? end[0] : null; + var result = []; + result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol)); + for (var i = start[1] + 1; i <= end[1] - 1; i++) { + var bufferLine = this._buffer.lines.get(i); + var lineText = this._buffer.translateBufferLineToString(i, true); + if (bufferLine.isWrapped) { + result[result.length - 1] += lineText; + } + else { + result.push(lineText); + } + } + if (start[1] !== end[1]) { + var bufferLine = this._buffer.lines.get(end[1]); + var lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]); + if (bufferLine.isWrapped) { + result[result.length - 1] += lineText; + } + else { + result.push(lineText); + } + } + var formattedResult = result.map(function (line) { + return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' '); + }).join(Browser.isMSWindows ? '\r\n' : '\n'); + return formattedResult; + }, + enumerable: true, + configurable: true + }); + SelectionManager.prototype.clearSelection = function () { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this.refresh(); + }; + SelectionManager.prototype.refresh = function (isNewSelection) { + var _this = this; + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(function () { return _this._refresh(); }); + } + if (Browser.isLinux && isNewSelection) { + var selectionText = this.selectionText; + if (selectionText.length) { + this.emit('newselection', this.selectionText); + } + } + }; + SelectionManager.prototype._refresh = function () { + this._refreshAnimationFrame = null; + this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd }); + }; + SelectionManager.prototype.selectAll = function () { + this._model.isSelectAllActive = true; + this.refresh(); + this._terminal.emit('selection'); + }; + SelectionManager.prototype._onTrim = function (amount) { + var needsRefresh = this._model.onTrim(amount); + if (needsRefresh) { + this.refresh(); + } + }; + SelectionManager.prototype._getMouseBufferCoords = function (event) { + var coords = this._terminal.mouseHelper.getCoords(event, this._terminal.element, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true); + if (!coords) { + return null; + } + coords[0]--; + coords[1]--; + coords[1] += this._terminal.buffer.ydisp; + return coords; + }; + SelectionManager.prototype._getMouseEventScrollAmount = function (event) { + var offset = MouseHelper_1.MouseHelper.getCoordsRelativeToElement(event, this._terminal.element)[1]; + var terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight); + if (offset >= 0 && offset <= terminalHeight) { + return 0; + } + if (offset > terminalHeight) { + offset -= terminalHeight; + } + offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD); + offset /= DRAG_SCROLL_MAX_THRESHOLD; + return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1)); + }; + SelectionManager.prototype.shouldForceSelection = function (event) { + return Browser.isMac ? event.altKey : event.shiftKey; + }; + SelectionManager.prototype.onMouseDown = function (event) { + if (event.button === 2 && this.hasSelection) { + return; + } + if (event.button !== 0) { + return; + } + if (!this._enabled) { + if (!this.shouldForceSelection(event)) { + return; + } + event.stopPropagation(); + } + event.preventDefault(); + this._dragScrollAmount = 0; + if (this._enabled && event.shiftKey) { + this._onIncrementalClick(event); + } + else { + if (event.detail === 1) { + this._onSingleClick(event); + } + else if (event.detail === 2) { + this._onDoubleClick(event); + } + else if (event.detail === 3) { + this._onTripleClick(event); + } + } + this._addMouseDownListeners(); + this.refresh(true); + }; + SelectionManager.prototype._addMouseDownListeners = function () { + var _this = this; + this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener); + this._dragScrollIntervalTimer = setInterval(function () { return _this._dragScroll(); }, DRAG_SCROLL_INTERVAL); + }; + SelectionManager.prototype._removeMouseDownListeners = function () { + this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener); + clearInterval(this._dragScrollIntervalTimer); + this._dragScrollIntervalTimer = null; + }; + SelectionManager.prototype._onIncrementalClick = function (event) { + if (this._model.selectionStart) { + this._model.selectionEnd = this._getMouseBufferCoords(event); + } + }; + SelectionManager.prototype._onSingleClick = function (event) { + this._model.selectionStartLength = 0; + this._model.isSelectAllActive = false; + this._activeSelectionMode = SelectionMode.NORMAL; + this._model.selectionStart = this._getMouseBufferCoords(event); + if (!this._model.selectionStart) { + return; + } + this._model.selectionEnd = null; + var line = this._buffer.lines.get(this._model.selectionStart[1]); + if (!line) { + return; + } + if (line.length >= this._model.selectionStart[0]) { + return; + } + var char = line[this._model.selectionStart[0]]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionStart[0]++; + } + }; + SelectionManager.prototype._onDoubleClick = function (event) { + var coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.WORD; + this._selectWordAt(coords); + } + }; + SelectionManager.prototype._onTripleClick = function (event) { + var coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.LINE; + this._selectLineAt(coords[1]); + } + }; + SelectionManager.prototype._onMouseMove = function (event) { + event.stopImmediatePropagation(); + var previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null; + this._model.selectionEnd = this._getMouseBufferCoords(event); + if (!this._model.selectionEnd) { + this.refresh(true); + return; + } + if (this._activeSelectionMode === SelectionMode.LINE) { + if (this._model.selectionEnd[1] < this._model.selectionStart[1]) { + this._model.selectionEnd[0] = 0; + } + else { + this._model.selectionEnd[0] = this._terminal.cols; + } + } + else if (this._activeSelectionMode === SelectionMode.WORD) { + this._selectToWordAt(this._model.selectionEnd); + } + this._dragScrollAmount = this._getMouseEventScrollAmount(event); + if (this._dragScrollAmount > 0) { + this._model.selectionEnd[0] = this._terminal.cols; + } + else if (this._dragScrollAmount < 0) { + this._model.selectionEnd[0] = 0; + } + if (this._model.selectionEnd[1] < this._buffer.lines.length) { + var char = this._buffer.lines.get(this._model.selectionEnd[1])[this._model.selectionEnd[0]]; + if (char && char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionEnd[0]++; + } + } + if (!previousSelectionEnd || + previousSelectionEnd[0] !== this._model.selectionEnd[0] || + previousSelectionEnd[1] !== this._model.selectionEnd[1]) { + this.refresh(true); + } + }; + SelectionManager.prototype._dragScroll = function () { + if (this._dragScrollAmount) { + this._terminal.scrollLines(this._dragScrollAmount, false); + if (this._dragScrollAmount > 0) { + this._model.selectionEnd = [this._terminal.cols - 1, Math.min(this._terminal.buffer.ydisp + this._terminal.rows, this._terminal.buffer.lines.length - 1)]; + } + else { + this._model.selectionEnd = [0, this._terminal.buffer.ydisp]; + } + this.refresh(); + } + }; + SelectionManager.prototype._onMouseUp = function (event) { + this._removeMouseDownListeners(); + if (this.hasSelection) + this._terminal.emit('selection'); + }; + SelectionManager.prototype._convertViewportColToCharacterIndex = function (bufferLine, coords) { + var charIndex = coords[0]; + for (var i = 0; coords[0] >= i; i++) { + var char = bufferLine[i]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + charIndex--; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1 && coords[0] !== i) { + charIndex += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + } + return charIndex; + }; + SelectionManager.prototype.setSelection = function (col, row, length) { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this._model.selectionStart = [col, row]; + this._model.selectionStartLength = length; + this.refresh(); + }; + SelectionManager.prototype._getWordAt = function (coords) { + var bufferLine = this._buffer.lines.get(coords[1]); + if (!bufferLine) { + return null; + } + var line = this._buffer.translateBufferLineToString(coords[1], false); + var startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords); + var endIndex = startIndex; + var charOffset = coords[0] - startIndex; + var leftWideCharCount = 0; + var rightWideCharCount = 0; + var leftLongCharOffset = 0; + var rightLongCharOffset = 0; + if (line.charAt(startIndex) === ' ') { + while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') { + startIndex--; + } + while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') { + endIndex++; + } + } + else { + var startCol = coords[0]; + var endCol = coords[0]; + if (bufferLine[startCol][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + leftWideCharCount++; + startCol--; + } + if (bufferLine[endCol][Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + rightWideCharCount++; + endCol++; + } + if (bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + rightLongCharOffset += bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += bufferLine[endCol][Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine[startCol - 1])) { + var char = bufferLine[startCol - 1]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + leftWideCharCount++; + startCol--; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + leftLongCharOffset += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + startIndex -= char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + startIndex--; + startCol--; + } + while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine[endCol + 1])) { + var char = bufferLine[endCol + 1]; + if (char[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + rightWideCharCount++; + endCol++; + } + else if (char[Buffer_1.CHAR_DATA_CHAR_INDEX].length > 1) { + rightLongCharOffset += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += char[Buffer_1.CHAR_DATA_CHAR_INDEX].length - 1; + } + endIndex++; + endCol++; + } + } + endIndex++; + var start = startIndex + + charOffset + - leftWideCharCount + + leftLongCharOffset; + var length = Math.min(this._terminal.cols, endIndex + - startIndex + + leftWideCharCount + + rightWideCharCount + - leftLongCharOffset + - rightLongCharOffset); + return { start: start, length: length }; + }; + SelectionManager.prototype._selectWordAt = function (coords) { + var wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionStart = [wordPosition.start, coords[1]]; + this._model.selectionStartLength = wordPosition.length; + } + }; + SelectionManager.prototype._selectToWordAt = function (coords) { + var wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; + } + }; + SelectionManager.prototype._isCharWordSeparator = function (charData) { + if (charData[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 0) { + return false; + } + return WORD_SEPARATORS.indexOf(charData[Buffer_1.CHAR_DATA_CHAR_INDEX]) >= 0; + }; + SelectionManager.prototype._selectLineAt = function (line) { + this._model.selectionStart = [0, line]; + this._model.selectionStartLength = this._terminal.cols; + }; + return SelectionManager; +}(EventEmitter_1.EventEmitter)); +exports.SelectionManager = SelectionManager; + + + +},{"./Buffer":1,"./EventEmitter":7,"./SelectionModel":12,"./utils/Browser":28,"./utils/MouseHelper":32}],12:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var SelectionModel = (function () { + function SelectionModel(_terminal) { + this._terminal = _terminal; + this.clearSelection(); + } + SelectionModel.prototype.clearSelection = function () { + this.selectionStart = null; + this.selectionEnd = null; + this.isSelectAllActive = false; + this.selectionStartLength = 0; + }; + Object.defineProperty(SelectionModel.prototype, "finalSelectionStart", { + get: function () { + if (this.isSelectAllActive) { + return [0, 0]; + } + if (!this.selectionEnd || !this.selectionStart) { + return this.selectionStart; + } + return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SelectionModel.prototype, "finalSelectionEnd", { + get: function () { + if (this.isSelectAllActive) { + return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1]; + } + if (!this.selectionStart) { + return null; + } + if (!this.selectionEnd || this.areSelectionValuesReversed()) { + return [this.selectionStart[0] + this.selectionStartLength, this.selectionStart[1]]; + } + if (this.selectionStartLength) { + if (this.selectionEnd[1] === this.selectionStart[1]) { + return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]]; + } + } + return this.selectionEnd; + }, + enumerable: true, + configurable: true + }); + SelectionModel.prototype.areSelectionValuesReversed = function () { + var start = this.selectionStart; + var end = this.selectionEnd; + if (!start || !end) { + return false; + } + return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]); + }; + SelectionModel.prototype.onTrim = function (amount) { + if (this.selectionStart) { + this.selectionStart[1] -= amount; + } + if (this.selectionEnd) { + this.selectionEnd[1] -= amount; + } + if (this.selectionEnd && this.selectionEnd[1] < 0) { + this.clearSelection(); + return true; + } + if (this.selectionStart && this.selectionStart[1] < 0) { + this.selectionStart[1] = 0; + } + return false; + }; + return SelectionModel; +}()); +exports.SelectionModel = SelectionModel; + + + +},{}],13:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BufferSet_1 = require("./BufferSet"); +var Buffer_1 = require("./Buffer"); +var CompositionHelper_1 = require("./CompositionHelper"); +var EventEmitter_1 = require("./EventEmitter"); +var Viewport_1 = require("./Viewport"); +var Clipboard_1 = require("./handlers/Clipboard"); +var EscapeSequences_1 = require("./EscapeSequences"); +var InputHandler_1 = require("./InputHandler"); +var Parser_1 = require("./Parser"); +var Renderer_1 = require("./renderer/Renderer"); +var Linkifier_1 = require("./Linkifier"); +var SelectionManager_1 = require("./SelectionManager"); +var CharMeasure_1 = require("./utils/CharMeasure"); +var Browser = require("./utils/Browser"); +var MouseHelper_1 = require("./utils/MouseHelper"); +var Sounds_1 = require("./utils/Sounds"); +var ColorManager_1 = require("./renderer/ColorManager"); +var MouseZoneManager_1 = require("./input/MouseZoneManager"); +var CharAtlas_1 = require("./renderer/CharAtlas"); +var document = (typeof window !== 'undefined') ? window.document : null; +var WRITE_BUFFER_PAUSE_THRESHOLD = 5; +var WRITE_BATCH_SIZE = 300; +var DEFAULT_OPTIONS = { + cols: 80, + rows: 24, + convertEol: false, + termName: 'xterm', + cursorBlink: false, + cursorStyle: 'block', + bellSound: Sounds_1.BellSound, + bellStyle: 'none', + enableBold: true, + fontFamily: 'courier-new, courier, monospace', + fontSize: 15, + lineHeight: 1.0, + letterSpacing: 0, + scrollback: 1000, + screenKeys: false, + debug: false, + cancelEvents: false, + disableStdin: false, + useFlowControl: false, + allowTransparency: false, + tabStopWidth: 8, + theme: null +}; +var Terminal = (function (_super) { + __extends(Terminal, _super); + function Terminal(options) { + if (options === void 0) { options = {}; } + var _this = _super.call(this) || this; + _this.browser = Browser; + _this.options = options; + _this.setup(); + return _this; + } + Terminal.prototype.setup = function () { + var _this = this; + Object.keys(DEFAULT_OPTIONS).forEach(function (key) { + if (_this.options[key] == null) { + _this.options[key] = DEFAULT_OPTIONS[key]; + } + _this[key] = _this.options[key]; + }); + this.parent = document ? document.body : null; + this.cols = this.options.cols; + this.rows = this.options.rows; + if (this.options.handler) { + this.on('data', this.options.handler); + } + this.cursorState = 0; + this.cursorHidden = false; + this.sendDataQueue = ''; + this.customKeyEventHandler = null; + this.applicationKeypad = false; + this.applicationCursor = false; + this.originMode = false; + this.insertMode = false; + this.wraparoundMode = true; + this.bracketedPasteMode = false; + this.charset = null; + this.gcharset = null; + this.glevel = 0; + this.charsets = [null]; + this.readable = true; + this.writable = true; + this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.curAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.params = []; + this.currentParam = 0; + this.prefix = ''; + this.postfix = ''; + this.writeBuffer = []; + this.writeInProgress = false; + this.xoffSentToCatchUp = false; + this.writeStopped = false; + this.surrogate_high = ''; + this.userScrolling = false; + this.inputHandler = new InputHandler_1.InputHandler(this); + this.parser = new Parser_1.Parser(this.inputHandler, this); + this.renderer = this.renderer || null; + this.selectionManager = this.selectionManager || null; + this.linkifier = this.linkifier || new Linkifier_1.Linkifier(this); + this._mouseZoneManager = this._mouseZoneManager || null; + this.buffers = new BufferSet_1.BufferSet(this); + this.buffer = this.buffers.active; + this.buffers.on('activate', function (buffer) { + _this.buffer = buffer; + }); + if (this.selectionManager) { + this.selectionManager.setBuffer(this.buffer); + } + }; + Terminal.prototype.eraseAttr = function () { + return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); + }; + Terminal.prototype.focus = function () { + if (this.textarea) { + this.textarea.focus(); + } + }; + Object.defineProperty(Terminal.prototype, "isFocused", { + get: function () { + return document.activeElement === this.textarea; + }, + enumerable: true, + configurable: true + }); + Terminal.prototype.getOption = function (key) { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + if (typeof this.options[key] !== 'undefined') { + return this.options[key]; + } + return this[key]; + }; + Terminal.prototype.setOption = function (key, value) { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + switch (key) { + case 'bellStyle': + if (!value) { + value = 'none'; + } + break; + case 'cursorStyle': + if (!value) { + value = 'block'; + } + break; + case 'lineHeight': + if (value < 1) { + console.warn(key + " cannot be less than 1, value: " + value); + return; + } + case 'tabStopWidth': + if (value < 1) { + console.warn(key + " cannot be less than 1, value: " + value); + return; + } + break; + case 'theme': + if (this.renderer) { + this._setTheme(value); + return; + } + break; + case 'scrollback': + value = Math.min(value, Buffer_1.MAX_BUFFER_SIZE); + if (value < 0) { + console.warn(key + " cannot be less than 0, value: " + value); + return; + } + if (this.options[key] !== value) { + var newBufferLength = this.rows + value; + if (this.buffer.lines.length > newBufferLength) { + var amountToTrim = this.buffer.lines.length - newBufferLength; + var needsRefresh = (this.buffer.ydisp - amountToTrim < 0); + this.buffer.lines.trimStart(amountToTrim); + this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0); + this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0); + if (needsRefresh) { + this.refresh(0, this.rows - 1); + } + } + } + break; + } + this[key] = value; + this.options[key] = value; + switch (key) { + case 'fontFamily': + case 'fontSize': + this.renderer.clear(); + this.charMeasure.measure(this.options); + break; + case 'enableBold': + case 'letterSpacing': + case 'lineHeight': + this.renderer.clear(); + this.renderer.onResize(this.cols, this.rows, false); + this.refresh(0, this.rows - 1); + case 'scrollback': + this.buffers.resize(this.cols, this.rows); + this.viewport.syncScrollArea(); + break; + case 'tabStopWidth': + this.buffers.setupTabStops(); + break; + case 'bellSound': + case 'bellStyle': + this.syncBellSound(); + break; + } + if (this.renderer) { + this.renderer.onOptionsChanged(); + } + }; + Terminal.prototype._onTextAreaFocus = function () { + if (this.sendFocus) { + this.send(EscapeSequences_1.C0.ESC + '[I'); + } + this.element.classList.add('focus'); + this.showCursor(); + this.emit('focus'); + }; + ; + Terminal.prototype.blur = function () { + return this.textarea.blur(); + }; + Terminal.prototype._onTextAreaBlur = function () { + this.refresh(this.buffer.y, this.buffer.y); + if (this.sendFocus) { + this.send(EscapeSequences_1.C0.ESC + '[O'); + } + this.element.classList.remove('focus'); + this.emit('blur'); + }; + Terminal.prototype.initGlobal = function () { + var _this = this; + this.bindKeys(); + on(this.element, 'copy', function (event) { + if (!_this.hasSelection()) { + return; + } + Clipboard_1.copyHandler(event, _this, _this.selectionManager); + }); + var pasteHandlerWrapper = function (event) { return Clipboard_1.pasteHandler(event, _this); }; + on(this.textarea, 'paste', pasteHandlerWrapper); + on(this.element, 'paste', pasteHandlerWrapper); + if (Browser.isFirefox) { + on(this.element, 'mousedown', function (event) { + if (event.button === 2) { + Clipboard_1.rightClickHandler(event, _this.textarea, _this.selectionManager); + } + }); + } + else { + on(this.element, 'contextmenu', function (event) { + Clipboard_1.rightClickHandler(event, _this.textarea, _this.selectionManager); + }); + } + if (Browser.isLinux) { + on(this.element, 'auxclick', function (event) { + if (event.button === 1) { + Clipboard_1.moveTextAreaUnderMouseCursor(event, _this.textarea); + } + }); + } + }; + Terminal.prototype.bindKeys = function () { + var _this = this; + var self = this; + on(this.element, 'keydown', function (ev) { + if (document.activeElement !== this) { + return; + } + self._keyDown(ev); + }, true); + on(this.element, 'keypress', function (ev) { + if (document.activeElement !== this) { + return; + } + self._keyPress(ev); + }, true); + on(this.element, 'keyup', function (ev) { + if (!wasMondifierKeyOnlyEvent(ev)) { + _this.focus(); + } + }, true); + on(this.textarea, 'keydown', function (ev) { + _this._keyDown(ev); + }, true); + on(this.textarea, 'keypress', function (ev) { + _this._keyPress(ev); + _this.textarea.value = ''; + }, true); + on(this.textarea, 'compositionstart', function () { return _this.compositionHelper.compositionstart(); }); + on(this.textarea, 'compositionupdate', function (e) { return _this.compositionHelper.compositionupdate(e); }); + on(this.textarea, 'compositionend', function () { return _this.compositionHelper.compositionend(); }); + this.on('refresh', function () { return _this.compositionHelper.updateCompositionElements(); }); + this.on('refresh', function (data) { return _this.queueLinkification(data.start, data.end); }); + }; + Terminal.prototype.open = function (parent) { + var _this = this; + var i = 0; + var div; + this.parent = parent || this.parent; + if (!this.parent) { + throw new Error('Terminal requires a parent element.'); + } + this.context = this.parent.ownerDocument.defaultView; + this.document = this.parent.ownerDocument; + this.body = this.document.body; + CharAtlas_1.initialize(this.document, this.options.allowTransparency); + this.element = this.document.createElement('div'); + this.element.classList.add('terminal'); + this.element.classList.add('xterm'); + this.element.setAttribute('tabindex', '0'); + this.parent.appendChild(this.element); + var fragment = document.createDocumentFragment(); + this.viewportElement = document.createElement('div'); + this.viewportElement.classList.add('xterm-viewport'); + fragment.appendChild(this.viewportElement); + this.viewportScrollArea = document.createElement('div'); + this.viewportScrollArea.classList.add('xterm-scroll-area'); + this.viewportElement.appendChild(this.viewportScrollArea); + this._mouseZoneManager = new MouseZoneManager_1.MouseZoneManager(this); + this.on('scroll', function () { return _this._mouseZoneManager.clearAll(); }); + this.linkifier.attachToDom(this._mouseZoneManager); + this.helperContainer = document.createElement('div'); + this.helperContainer.classList.add('xterm-helpers'); + fragment.appendChild(this.helperContainer); + this.textarea = document.createElement('textarea'); + this.textarea.classList.add('xterm-helper-textarea'); + this.textarea.setAttribute('autocorrect', 'off'); + this.textarea.setAttribute('autocapitalize', 'off'); + this.textarea.setAttribute('spellcheck', 'false'); + this.textarea.tabIndex = 0; + this.textarea.addEventListener('focus', function () { return _this._onTextAreaFocus(); }); + this.textarea.addEventListener('blur', function () { return _this._onTextAreaBlur(); }); + this.helperContainer.appendChild(this.textarea); + this.compositionView = document.createElement('div'); + this.compositionView.classList.add('composition-view'); + this.compositionHelper = new CompositionHelper_1.CompositionHelper(this.textarea, this.compositionView, this); + this.helperContainer.appendChild(this.compositionView); + this.charSizeStyleElement = document.createElement('style'); + this.helperContainer.appendChild(this.charSizeStyleElement); + this.charMeasure = new CharMeasure_1.CharMeasure(document, this.helperContainer); + this.syncBellSound(); + this.element.appendChild(fragment); + this.renderer = new Renderer_1.Renderer(this, this.options.theme); + this.options.theme = null; + this.viewport = new Viewport_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); + this.viewport.onThemeChanged(this.renderer.colorManager.colors); + this.on('cursormove', function () { return _this.renderer.onCursorMove(); }); + this.on('resize', function () { return _this.renderer.onResize(_this.cols, _this.rows, false); }); + this.on('blur', function () { return _this.renderer.onBlur(); }); + this.on('focus', function () { return _this.renderer.onFocus(); }); + this.charMeasure.on('charsizechanged', function () { return _this.renderer.onResize(_this.cols, _this.rows, true); }); + this.renderer.on('resize', function (dimensions) { return _this.viewport.syncScrollArea(); }); + this.selectionManager = new SelectionManager_1.SelectionManager(this, this.buffer, this.charMeasure); + this.element.addEventListener('mousedown', function (e) { return _this.selectionManager.onMouseDown(e); }); + this.selectionManager.on('refresh', function (data) { return _this.renderer.onSelectionChanged(data.start, data.end); }); + this.selectionManager.on('newselection', function (text) { + _this.textarea.value = text; + _this.textarea.focus(); + _this.textarea.select(); + }); + this.on('scroll', function () { + _this.viewport.syncScrollArea(); + _this.selectionManager.refresh(); + }); + this.viewportElement.addEventListener('scroll', function () { return _this.selectionManager.refresh(); }); + this.mouseHelper = new MouseHelper_1.MouseHelper(this.renderer); + this.charMeasure.measure(this.options); + this.refresh(0, this.rows - 1); + this.initGlobal(); + this.bindMouse(); + }; + Terminal.prototype._setTheme = function (theme) { + var colors = this.renderer.setTheme(theme); + if (this.viewport) { + this.viewport.onThemeChanged(colors); + } + }; + Terminal.applyAddon = function (addon) { + addon.apply(Terminal); + }; + Terminal.prototype.bindMouse = function () { + var _this = this; + var el = this.element; + var self = this; + var pressed = 32; + function sendButton(ev) { + var button; + var pos; + button = getButton(ev); + pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) + return; + sendEvent(button, pos); + switch (ev.overrideType || ev.type) { + case 'mousedown': + pressed = button; + break; + case 'mouseup': + pressed = 32; + break; + case 'wheel': + break; + } + } + function sendMove(ev) { + var button = pressed; + var pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) + return; + button += 32; + sendEvent(button, pos); + } + function encode(data, ch) { + if (!self.utfMouse) { + if (ch === 255) { + data.push(0); + return; + } + if (ch > 127) + ch = 127; + data.push(ch); + } + else { + if (ch === 2047) { + data.push(0); + return; + } + if (ch < 127) { + data.push(ch); + } + else { + if (ch > 2047) + ch = 2047; + data.push(0xC0 | (ch >> 6)); + data.push(0x80 | (ch & 0x3F)); + } + } + } + function sendEvent(button, pos) { + if (self.vt300Mouse) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + var data_1 = EscapeSequences_1.C0.ESC + '[24'; + if (button === 0) + data_1 += '1'; + else if (button === 1) + data_1 += '3'; + else if (button === 2) + data_1 += '5'; + else if (button === 3) + return; + else + data_1 += '0'; + data_1 += '~[' + pos.x + ',' + pos.y + ']\r'; + self.send(data_1); + return; + } + if (self.decLocator) { + button &= 3; + pos.x -= 32; + pos.y -= 32; + if (button === 0) + button = 2; + else if (button === 1) + button = 4; + else if (button === 2) + button = 6; + else if (button === 3) + button = 3; + self.send(EscapeSequences_1.C0.ESC + '[' + + button + + ';' + + (button === 3 ? 4 : 0) + + ';' + + pos.y + + ';' + + pos.x + + ';' + + pos.page || 0 + + '&w'); + return; + } + if (self.urxvtMouse) { + pos.x -= 32; + pos.y -= 32; + pos.x++; + pos.y++; + self.send(EscapeSequences_1.C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M'); + return; + } + if (self.sgrMouse) { + pos.x -= 32; + pos.y -= 32; + self.send(EscapeSequences_1.C0.ESC + '[<' + + (((button & 3) === 3 ? button & ~3 : button) - 32) + + ';' + + pos.x + + ';' + + pos.y + + ((button & 3) === 3 ? 'm' : 'M')); + return; + } + var data = []; + encode(data, button); + encode(data, pos.x); + encode(data, pos.y); + self.send(EscapeSequences_1.C0.ESC + '[M' + String.fromCharCode.apply(String, data)); + } + function getButton(ev) { + var button; + var shift; + var meta; + var ctrl; + var mod; + switch (ev.overrideType || ev.type) { + case 'mousedown': + button = ev.button != null + ? +ev.button + : ev.which != null + ? ev.which - 1 + : null; + if (Browser.isMSIE) { + button = button === 1 ? 0 : button === 4 ? 1 : button; + } + break; + case 'mouseup': + button = 3; + break; + case 'DOMMouseScroll': + button = ev.detail < 0 + ? 64 + : 65; + break; + case 'wheel': + button = ev.wheelDeltaY > 0 + ? 64 + : 65; + break; + } + shift = ev.shiftKey ? 4 : 0; + meta = ev.metaKey ? 8 : 0; + ctrl = ev.ctrlKey ? 16 : 0; + mod = shift | meta | ctrl; + if (self.vt200Mouse) { + mod &= ctrl; + } + else if (!self.normalMouse) { + mod = 0; + } + button = (32 + (mod << 2)) + button; + return button; + } + on(el, 'mousedown', function (ev) { + ev.preventDefault(); + _this.focus(); + if (!_this.mouseEvents || _this.selectionManager.shouldForceSelection(ev)) { + return; + } + sendButton(ev); + if (_this.vt200Mouse) { + ev.overrideType = 'mouseup'; + sendButton(ev); + return _this.cancel(ev); + } + if (_this.normalMouse) + on(_this.document, 'mousemove', sendMove); + if (!_this.x10Mouse) { + var handler_1 = function (ev) { + sendButton(ev); + if (_this.normalMouse) + off(_this.document, 'mousemove', sendMove); + off(_this.document, 'mouseup', handler_1); + return _this.cancel(ev); + }; + on(_this.document, 'mouseup', handler_1); + } + return _this.cancel(ev); + }); + on(el, 'wheel', function (ev) { + if (!_this.mouseEvents) + return; + if (_this.x10Mouse || _this.vt300Mouse || _this.decLocator) + return; + sendButton(ev); + ev.preventDefault(); + }); + on(el, 'wheel', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onWheel(ev); + return _this.cancel(ev); + }); + on(el, 'touchstart', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onTouchStart(ev); + return _this.cancel(ev); + }); + on(el, 'touchmove', function (ev) { + if (_this.mouseEvents) + return; + _this.viewport.onTouchMove(ev); + return _this.cancel(ev); + }); + }; + Terminal.prototype.destroy = function () { + _super.prototype.destroy.call(this); + this.readable = false; + this.writable = false; + this.handler = function () { }; + this.write = function () { }; + if (this.element && this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } + }; + Terminal.prototype.refresh = function (start, end) { + if (this.renderer) { + this.renderer.queueRefresh(start, end); + } + }; + Terminal.prototype.queueLinkification = function (start, end) { + if (this.linkifier) { + this.linkifier.linkifyRows(start, end); + } + }; + Terminal.prototype.showCursor = function () { + if (!this.cursorState) { + this.cursorState = 1; + this.refresh(this.buffer.y, this.buffer.y); + } + }; + Terminal.prototype.scroll = function (isWrapped) { + var newLine = this.blankLine(undefined, isWrapped); + var topRow = this.buffer.ybase + this.buffer.scrollTop; + var bottomRow = this.buffer.ybase + this.buffer.scrollBottom; + if (this.buffer.scrollTop === 0) { + var willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength; + if (bottomRow === this.buffer.lines.length - 1) { + this.buffer.lines.push(newLine); + } + else { + this.buffer.lines.splice(bottomRow + 1, 0, newLine); + } + if (!willBufferBeTrimmed) { + this.buffer.ybase++; + if (!this.userScrolling) { + this.buffer.ydisp++; + } + } + else { + if (this.userScrolling) { + this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0); + } + } + } + else { + var scrollRegionHeight = bottomRow - topRow + 1; + this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1); + this.buffer.lines.set(bottomRow, newLine); + } + if (!this.userScrolling) { + this.buffer.ydisp = this.buffer.ybase; + } + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + this.emit('scroll', this.buffer.ydisp); + }; + Terminal.prototype.scrollLines = function (disp, suppressScrollEvent) { + if (disp < 0) { + if (this.buffer.ydisp === 0) { + return; + } + this.userScrolling = true; + } + else if (disp + this.buffer.ydisp >= this.buffer.ybase) { + this.userScrolling = false; + } + var oldYdisp = this.buffer.ydisp; + this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0); + if (oldYdisp === this.buffer.ydisp) { + return; + } + if (!suppressScrollEvent) { + this.emit('scroll', this.buffer.ydisp); + } + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.scrollPages = function (pageCount) { + this.scrollLines(pageCount * (this.rows - 1)); + }; + Terminal.prototype.scrollToTop = function () { + this.scrollLines(-this.buffer.ydisp); + }; + Terminal.prototype.scrollToBottom = function () { + this.scrollLines(this.buffer.ybase - this.buffer.ydisp); + }; + Terminal.prototype.write = function (data) { + var _this = this; + this.writeBuffer.push(data); + if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { + this.send(EscapeSequences_1.C0.DC3); + this.xoffSentToCatchUp = true; + } + if (!this.writeInProgress && this.writeBuffer.length > 0) { + this.writeInProgress = true; + setTimeout(function () { + _this.innerWrite(); + }); + } + }; + Terminal.prototype.innerWrite = function () { + var _this = this; + var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); + while (writeBatch.length > 0) { + var data = writeBatch.shift(); + if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) { + this.send(EscapeSequences_1.C0.DC1); + this.xoffSentToCatchUp = false; + } + this.refreshStart = this.buffer.y; + this.refreshEnd = this.buffer.y; + var state = this.parser.parse(data); + this.parser.setState(state); + this.updateRange(this.buffer.y); + this.refresh(this.refreshStart, this.refreshEnd); + } + if (this.writeBuffer.length > 0) { + setTimeout(function () { return _this.innerWrite(); }, 0); + } + else { + this.writeInProgress = false; + } + }; + Terminal.prototype.writeln = function (data) { + this.write(data + '\r\n'); + }; + Terminal.prototype.attachCustomKeyEventHandler = function (customKeyEventHandler) { + this.customKeyEventHandler = customKeyEventHandler; + }; + Terminal.prototype.setHypertextLinkHandler = function (handler) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); + } + this.linkifier.setHypertextLinkHandler(handler); + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.setHypertextValidationCallback = function (callback) { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); + } + this.linkifier.setHypertextValidationCallback(callback); + this.refresh(0, this.rows - 1); + }; + Terminal.prototype.registerLinkMatcher = function (regex, handler, options) { + if (this.linkifier) { + var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); + this.refresh(0, this.rows - 1); + return matcherId; + } + return 0; + }; + Terminal.prototype.deregisterLinkMatcher = function (matcherId) { + if (this.linkifier) { + if (this.linkifier.deregisterLinkMatcher(matcherId)) { + this.refresh(0, this.rows - 1); + } + } + }; + Terminal.prototype.hasSelection = function () { + return this.selectionManager ? this.selectionManager.hasSelection : false; + }; + Terminal.prototype.getSelection = function () { + return this.selectionManager ? this.selectionManager.selectionText : ''; + }; + Terminal.prototype.clearSelection = function () { + if (this.selectionManager) { + this.selectionManager.clearSelection(); + } + }; + Terminal.prototype.selectAll = function () { + if (this.selectionManager) { + this.selectionManager.selectAll(); + } + }; + Terminal.prototype._keyDown = function (ev) { + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + if (!this.compositionHelper.keydown(ev)) { + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + return false; + } + var result = this._evaluateKeyEscapeSequence(ev); + if (result.key === EscapeSequences_1.C0.DC3) { + this.writeStopped = true; + } + else if (result.key === EscapeSequences_1.C0.DC1) { + this.writeStopped = false; + } + if (result.scrollLines) { + this.scrollLines(result.scrollLines); + return this.cancel(ev, true); + } + if (isThirdLevelShift(this.browser, ev)) { + return true; + } + if (result.cancel) { + this.cancel(ev, true); + } + if (!result.key) { + return true; + } + this.emit('keydown', ev); + this.emit('key', result.key, ev); + this.showCursor(); + this.handler(result.key); + return this.cancel(ev, true); + }; + Terminal.prototype._evaluateKeyEscapeSequence = function (ev) { + var result = { + cancel: false, + key: undefined, + scrollLines: undefined + }; + var modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0); + switch (ev.keyCode) { + case 0: + if (ev.key === 'UIKeyInputUpArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OA'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[A'; + } + } + else if (ev.key === 'UIKeyInputLeftArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OD'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[D'; + } + } + else if (ev.key === 'UIKeyInputRightArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OC'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[C'; + } + } + else if (ev.key === 'UIKeyInputDownArrow') { + if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OB'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[B'; + } + } + break; + case 8: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.BS; + break; + } + else if (ev.altKey) { + result.key = EscapeSequences_1.C0.ESC + EscapeSequences_1.C0.DEL; + break; + } + result.key = EscapeSequences_1.C0.DEL; + break; + case 9: + if (ev.shiftKey) { + result.key = EscapeSequences_1.C0.ESC + '[Z'; + break; + } + result.key = EscapeSequences_1.C0.HT; + result.cancel = true; + break; + case 13: + result.key = EscapeSequences_1.C0.CR; + result.cancel = true; + break; + case 27: + result.key = EscapeSequences_1.C0.ESC; + result.cancel = true; + break; + case 37: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'D'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3D') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'b' : EscapeSequences_1.C0.ESC + '[1;5D'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OD'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[D'; + } + break; + case 39: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'C'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3C') { + result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'f' : EscapeSequences_1.C0.ESC + '[1;5C'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OC'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[C'; + } + break; + case 38: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'A'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3A') { + result.key = EscapeSequences_1.C0.ESC + '[1;5A'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OA'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[A'; + } + break; + case 40: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'B'; + if (result.key === EscapeSequences_1.C0.ESC + '[1;3B') { + result.key = EscapeSequences_1.C0.ESC + '[1;5B'; + } + } + else if (this.applicationCursor) { + result.key = EscapeSequences_1.C0.ESC + 'OB'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[B'; + } + break; + case 45: + if (!ev.shiftKey && !ev.ctrlKey) { + result.key = EscapeSequences_1.C0.ESC + '[2~'; + } + break; + case 46: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[3;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[3~'; + } + break; + case 36: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'H'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OH'; + else + result.key = EscapeSequences_1.C0.ESC + '[H'; + break; + case 35: + if (modifiers) + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'F'; + else if (this.applicationCursor) + result.key = EscapeSequences_1.C0.ESC + 'OF'; + else + result.key = EscapeSequences_1.C0.ESC + '[F'; + break; + case 33: + if (ev.shiftKey) { + result.scrollLines = -(this.rows - 1); + } + else { + result.key = EscapeSequences_1.C0.ESC + '[5~'; + } + break; + case 34: + if (ev.shiftKey) { + result.scrollLines = this.rows - 1; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[6~'; + } + break; + case 112: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'P'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OP'; + } + break; + case 113: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'Q'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OQ'; + } + break; + case 114: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'R'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OR'; + } + break; + case 115: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'S'; + } + else { + result.key = EscapeSequences_1.C0.ESC + 'OS'; + } + break; + case 116: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[15;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[15~'; + } + break; + case 117: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[17;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[17~'; + } + break; + case 118: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[18;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[18~'; + } + break; + case 119: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[19;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[19~'; + } + break; + case 120: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[20;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[20~'; + } + break; + case 121: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[21;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[21~'; + } + break; + case 122: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[23;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[23~'; + } + break; + case 123: + if (modifiers) { + result.key = EscapeSequences_1.C0.ESC + '[24;' + (modifiers + 1) + '~'; + } + else { + result.key = EscapeSequences_1.C0.ESC + '[24~'; + } + break; + default: + if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = String.fromCharCode(ev.keyCode - 64); + } + else if (ev.keyCode === 32) { + result.key = String.fromCharCode(0); + } + else if (ev.keyCode >= 51 && ev.keyCode <= 55) { + result.key = String.fromCharCode(ev.keyCode - 51 + 27); + } + else if (ev.keyCode === 56) { + result.key = String.fromCharCode(127); + } + else if (ev.keyCode === 219) { + result.key = String.fromCharCode(27); + } + else if (ev.keyCode === 220) { + result.key = String.fromCharCode(28); + } + else if (ev.keyCode === 221) { + result.key = String.fromCharCode(29); + } + } + else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = EscapeSequences_1.C0.ESC + String.fromCharCode(ev.keyCode + 32); + } + else if (ev.keyCode === 192) { + result.key = EscapeSequences_1.C0.ESC + '`'; + } + else if (ev.keyCode >= 48 && ev.keyCode <= 57) { + result.key = EscapeSequences_1.C0.ESC + (ev.keyCode - 48); + } + } + else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { + if (ev.keyCode === 65) { + this.selectAll(); + } + } + break; + } + return result; + }; + Terminal.prototype.setgLevel = function (g) { + this.glevel = g; + this.charset = this.charsets[g]; + }; + Terminal.prototype.setgCharset = function (g, charset) { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } + }; + Terminal.prototype._keyPress = function (ev) { + var key; + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + this.cancel(ev); + if (ev.charCode) { + key = ev.charCode; + } + else if (ev.which == null) { + key = ev.keyCode; + } + else if (ev.which !== 0 && ev.charCode !== 0) { + key = ev.which; + } + else { + return false; + } + if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this.browser, ev))) { + return false; + } + key = String.fromCharCode(key); + this.emit('keypress', key, ev); + this.emit('key', key, ev); + this.showCursor(); + this.handler(key); + return true; + }; + Terminal.prototype.send = function (data) { + var _this = this; + if (!this.sendDataQueue) { + setTimeout(function () { + _this.handler(_this.sendDataQueue); + _this.sendDataQueue = ''; + }, 1); + } + this.sendDataQueue += data; + }; + Terminal.prototype.bell = function () { + var _this = this; + this.emit('bell'); + if (this.soundBell()) + this.bellAudioElement.play(); + if (this.visualBell()) { + this.element.classList.add('visual-bell-active'); + clearTimeout(this.visualBellTimer); + this.visualBellTimer = window.setTimeout(function () { + _this.element.classList.remove('visual-bell-active'); + }, 200); + } + }; + Terminal.prototype.log = function (text, data) { + if (!this.options.debug) + return; + if (!this.context.console || !this.context.console.log) + return; + this.context.console.log(text, data); + }; + Terminal.prototype.error = function (text, data) { + if (!this.options.debug) + return; + if (!this.context.console || !this.context.console.error) + return; + this.context.console.error(text, data); + }; + Terminal.prototype.resize = function (x, y) { + if (isNaN(x) || isNaN(y)) { + return; + } + if (x === this.cols && y === this.rows) { + if (!this.charMeasure.width || !this.charMeasure.height) { + this.charMeasure.measure(this.options); + } + return; + } + if (x < 1) + x = 1; + if (y < 1) + y = 1; + this.buffers.resize(x, y); + this.cols = x; + this.rows = y; + this.buffers.setupTabStops(this.cols); + this.charMeasure.measure(this.options); + this.refresh(0, this.rows - 1); + this.emit('resize', { cols: x, rows: y }); + }; + Terminal.prototype.updateRange = function (y) { + if (y < this.refreshStart) + this.refreshStart = y; + if (y > this.refreshEnd) + this.refreshEnd = y; + }; + Terminal.prototype.maxRange = function () { + this.refreshStart = 0; + this.refreshEnd = this.rows - 1; + }; + Terminal.prototype.eraseRight = function (x, y) { + var line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1, 32]; + for (; x < this.cols; x++) { + line[x] = ch; + } + this.updateRange(y); + }; + Terminal.prototype.eraseLeft = function (x, y) { + var line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + var ch = [this.eraseAttr(), ' ', 1, 32]; + x++; + while (x--) { + line[x] = ch; + } + this.updateRange(y); + }; + Terminal.prototype.clear = function () { + if (this.buffer.ybase === 0 && this.buffer.y === 0) { + return; + } + this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)); + this.buffer.lines.length = 1; + this.buffer.ydisp = 0; + this.buffer.ybase = 0; + this.buffer.y = 0; + for (var i = 1; i < this.rows; i++) { + this.buffer.lines.push(this.blankLine()); + } + this.refresh(0, this.rows - 1); + this.emit('scroll', this.buffer.ydisp); + }; + Terminal.prototype.eraseLine = function (y) { + this.eraseRight(0, y); + }; + Terminal.prototype.blankLine = function (cur, isWrapped, cols) { + var attr = cur ? this.eraseAttr() : this.defAttr; + var ch = [attr, ' ', 1, 32]; + var line = []; + if (isWrapped) { + line.isWrapped = isWrapped; + } + cols = cols || this.cols; + for (var i = 0; i < cols; i++) { + line[i] = ch; + } + return line; + }; + Terminal.prototype.ch = function (cur) { + if (cur) { + return [this.eraseAttr(), ' ', 1, 32]; + } + return [this.defAttr, ' ', 1, 32]; + }; + Terminal.prototype.is = function (term) { + return (this.options.termName + '').indexOf(term) === 0; + }; + Terminal.prototype.handler = function (data) { + if (this.options.disableStdin) { + return; + } + if (this.selectionManager && this.selectionManager.hasSelection) { + this.selectionManager.clearSelection(); + } + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + this.emit('data', data); + }; + Terminal.prototype.handleTitle = function (title) { + this.emit('title', title); + }; + Terminal.prototype.index = function () { + this.buffer.y++; + if (this.buffer.y > this.buffer.scrollBottom) { + this.buffer.y--; + this.scroll(); + } + if (this.buffer.x >= this.cols) { + this.buffer.x--; + } + }; + Terminal.prototype.reverseIndex = function () { + if (this.buffer.y === this.buffer.scrollTop) { + var scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop; + this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1); + this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true)); + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + } + else { + this.buffer.y--; + } + }; + Terminal.prototype.reset = function () { + this.options.rows = this.rows; + this.options.cols = this.cols; + var customKeyEventHandler = this.customKeyEventHandler; + var inputHandler = this.inputHandler; + var buffers = this.buffers; + this.setup(); + this.customKeyEventHandler = customKeyEventHandler; + this.inputHandler = inputHandler; + this.buffers = buffers; + this.refresh(0, this.rows - 1); + this.viewport.syncScrollArea(); + }; + Terminal.prototype.tabSet = function () { + this.buffer.tabs[this.buffer.x] = true; + }; + Terminal.prototype.cancel = function (ev, force) { + if (!this.options.cancelEvents && !force) { + return; + } + ev.preventDefault(); + ev.stopPropagation(); + return false; + }; + Terminal.prototype.matchColor = function (r1, g1, b1) { + return matchColor_(r1, g1, b1); + }; + Terminal.prototype.visualBell = function () { + return this.options.bellStyle === 'visual' || + this.options.bellStyle === 'both'; + }; + Terminal.prototype.soundBell = function () { + return this.options.bellStyle === 'sound' || + this.options.bellStyle === 'both'; + }; + Terminal.prototype.syncBellSound = function () { + if (!this.element) { + return; + } + if (this.soundBell() && this.bellAudioElement) { + this.bellAudioElement.setAttribute('src', this.options.bellSound); + } + else if (this.soundBell()) { + this.bellAudioElement = document.createElement('audio'); + this.bellAudioElement.setAttribute('preload', 'auto'); + this.bellAudioElement.setAttribute('src', this.options.bellSound); + this.helperContainer.appendChild(this.bellAudioElement); + } + else if (this.bellAudioElement) { + this.helperContainer.removeChild(this.bellAudioElement); + } + }; + return Terminal; +}(EventEmitter_1.EventEmitter)); +exports.Terminal = Terminal; +function globalOn(el, type, handler, capture) { + if (!Array.isArray(el)) { + el = [el]; + } + el.forEach(function (element) { + element.addEventListener(type, handler, capture || false); + }); +} +var on = globalOn; +function off(el, type, handler, capture) { + if (capture === void 0) { capture = false; } + el.removeEventListener(type, handler, capture); +} +function isThirdLevelShift(browser, ev) { + var thirdLevelKey = (browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + if (ev.type === 'keypress') { + return thirdLevelKey; + } + return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); +} +function wasMondifierKeyOnlyEvent(ev) { + return ev.keyCode === 16 || + ev.keyCode === 17 || + ev.keyCode === 18; +} +var vcolors = (function () { + var result = ColorManager_1.DEFAULT_ANSI_COLORS.map(function (c) { + c = c.substring(1); + return [ + parseInt(c.substring(0, 2), 16), + parseInt(c.substring(2, 4), 16), + parseInt(c.substring(4, 6), 16) + ]; + }); + var r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (var i = 0; i < 216; i++) { + result.push([ + r[(i / 36) % 6 | 0], + r[(i / 6) % 6 | 0], + r[i % 6] + ]); + } + var c; + for (var i = 0; i < 24; i++) { + c = 8 + i * 10; + result.push([c, c, c]); + } + return result; +})(); +var matchColorCache = {}; +function matchColorDistance(r1, g1, b1, r2, g2, b2) { + return Math.pow(30 * (r1 - r2), 2) + + Math.pow(59 * (g1 - g2), 2) + + Math.pow(11 * (b1 - b2), 2); +} +; +function matchColor_(r1, g1, b1) { + var hash = (r1 << 16) | (g1 << 8) | b1; + if (matchColorCache[hash] != null) { + return matchColorCache[hash]; + } + var ldiff = Infinity; + var li = -1; + var i = 0; + var c; + var r2; + var g2; + var b2; + var diff; + for (; i < vcolors.length; i++) { + c = vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + diff = matchColorDistance(r1, g1, b1, r2, g2, b2); + if (diff === 0) { + li = i; + break; + } + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + return matchColorCache[hash] = li; +} + + + +},{"./Buffer":1,"./BufferSet":2,"./CompositionHelper":5,"./EscapeSequences":6,"./EventEmitter":7,"./InputHandler":8,"./Linkifier":9,"./Parser":10,"./SelectionManager":11,"./Viewport":15,"./handlers/Clipboard":16,"./input/MouseZoneManager":17,"./renderer/CharAtlas":19,"./renderer/ColorManager":20,"./renderer/Renderer":24,"./utils/Browser":28,"./utils/CharMeasure":29,"./utils/MouseHelper":32,"./utils/Sounds":34}],14:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LinkHoverEventTypes; +(function (LinkHoverEventTypes) { + LinkHoverEventTypes["HOVER"] = "linkhover"; + LinkHoverEventTypes["TOOLTIP"] = "linktooltip"; + LinkHoverEventTypes["LEAVE"] = "linkleave"; +})(LinkHoverEventTypes = exports.LinkHoverEventTypes || (exports.LinkHoverEventTypes = {})); +; + + + +},{}],15:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Viewport = (function () { + function Viewport(terminal, viewportElement, scrollArea, charMeasure) { + var _this = this; + this.terminal = terminal; + this.viewportElement = viewportElement; + this.scrollArea = scrollArea; + this.charMeasure = charMeasure; + this.currentRowHeight = 0; + this.lastRecordedBufferLength = 0; + this.lastRecordedViewportHeight = 0; + this.lastRecordedBufferHeight = 0; + this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); + setTimeout(function () { return _this.syncScrollArea(); }, 0); + } + Viewport.prototype.onThemeChanged = function (colors) { + this.viewportElement.style.backgroundColor = colors.background; + }; + Viewport.prototype.refresh = function () { + if (this.charMeasure.height > 0) { + this.currentRowHeight = this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio; + if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { + this.lastRecordedViewportHeight = this.terminal.renderer.dimensions.canvasHeight; + this.viewportElement.style.height = this.lastRecordedViewportHeight + 'px'; + } + var newBufferHeight = Math.round(this.currentRowHeight * this.lastRecordedBufferLength); + if (this.lastRecordedBufferHeight !== newBufferHeight) { + this.lastRecordedBufferHeight = newBufferHeight; + this.scrollArea.style.height = this.lastRecordedBufferHeight + 'px'; + } + } + }; + Viewport.prototype.syncScrollArea = function () { + if (this.lastRecordedBufferLength !== this.terminal.buffer.lines.length) { + this.lastRecordedBufferLength = this.terminal.buffer.lines.length; + this.refresh(); + } + else if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { + this.refresh(); + } + else { + if (this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this.currentRowHeight) { + this.refresh(); + } + } + var scrollTop = this.terminal.buffer.ydisp * this.currentRowHeight; + if (this.viewportElement.scrollTop !== scrollTop) { + this.viewportElement.scrollTop = scrollTop; + } + }; + Viewport.prototype.onScroll = function (ev) { + var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + var diff = newRow - this.terminal.buffer.ydisp; + this.terminal.scrollLines(diff, true); + }; + Viewport.prototype.onWheel = function (ev) { + if (ev.deltaY === 0) { + return; + } + var multiplier = 1; + if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { + multiplier = this.currentRowHeight; + } + else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + multiplier = this.currentRowHeight * this.terminal.rows; + } + this.viewportElement.scrollTop += ev.deltaY * multiplier; + ev.preventDefault(); + }; + ; + Viewport.prototype.onTouchStart = function (ev) { + this.lastTouchY = ev.touches[0].pageY; + }; + ; + Viewport.prototype.onTouchMove = function (ev) { + var deltaY = this.lastTouchY - ev.touches[0].pageY; + this.lastTouchY = ev.touches[0].pageY; + if (deltaY === 0) { + return; + } + this.viewportElement.scrollTop += deltaY; + ev.preventDefault(); + }; + ; + return Viewport; +}()); +exports.Viewport = Viewport; + + + +},{}],16:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function prepareTextForTerminal(text, isMSWindows) { + if (isMSWindows) { + return text.replace(/\r?\n/g, '\r'); + } + return text; +} +exports.prepareTextForTerminal = prepareTextForTerminal; +function bracketTextForPaste(text, bracketedPasteMode) { + if (bracketedPasteMode) { + return '\x1b[200~' + text + '\x1b[201~'; + } + return text; +} +exports.bracketTextForPaste = bracketTextForPaste; +function copyHandler(ev, term, selectionManager) { + if (term.browser.isMSIE) { + window.clipboardData.setData('Text', selectionManager.selectionText); + } + else { + ev.clipboardData.setData('text/plain', selectionManager.selectionText); + } + ev.preventDefault(); +} +exports.copyHandler = copyHandler; +function pasteHandler(ev, term) { + ev.stopPropagation(); + var text; + var dispatchPaste = function (text) { + text = prepareTextForTerminal(text, term.browser.isMSWindows); + text = bracketTextForPaste(text, term.bracketedPasteMode); + term.handler(text); + term.textarea.value = ''; + term.emit('paste', text); + term.cancel(ev); + }; + if (term.browser.isMSIE) { + if (window.clipboardData) { + text = window.clipboardData.getData('Text'); + dispatchPaste(text); + } + } + else { + if (ev.clipboardData) { + text = ev.clipboardData.getData('text/plain'); + dispatchPaste(text); + } + } +} +exports.pasteHandler = pasteHandler; +function moveTextAreaUnderMouseCursor(ev, textarea) { + textarea.style.position = 'fixed'; + textarea.style.width = '20px'; + textarea.style.height = '20px'; + textarea.style.left = (ev.clientX - 10) + 'px'; + textarea.style.top = (ev.clientY - 10) + 'px'; + textarea.style.zIndex = '1000'; + textarea.focus(); + setTimeout(function () { + textarea.style.position = null; + textarea.style.width = null; + textarea.style.height = null; + textarea.style.left = null; + textarea.style.top = null; + textarea.style.zIndex = null; + }, 4); +} +exports.moveTextAreaUnderMouseCursor = moveTextAreaUnderMouseCursor; +function rightClickHandler(ev, textarea, selectionManager) { + moveTextAreaUnderMouseCursor(ev, textarea); + textarea.value = selectionManager.selectionText; + textarea.select(); +} +exports.rightClickHandler = rightClickHandler; + + + +},{}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var HOVER_DURATION = 500; +var MouseZoneManager = (function () { + function MouseZoneManager(_terminal) { + var _this = this; + this._terminal = _terminal; + this._zones = []; + this._areZonesActive = false; + this._tooltipTimeout = null; + this._currentZone = null; + this._lastHoverCoords = [null, null]; + this._terminal.element.addEventListener('mousedown', function (e) { return _this._onMouseDown(e); }); + this._mouseMoveListener = function (e) { return _this._onMouseMove(e); }; + this._clickListener = function (e) { return _this._onClick(e); }; + } + MouseZoneManager.prototype.add = function (zone) { + this._zones.push(zone); + if (this._zones.length === 1) { + this._activate(); + } + }; + MouseZoneManager.prototype.clearAll = function (start, end) { + if (this._zones.length === 0) { + return; + } + if (!end) { + start = 0; + end = this._terminal.rows - 1; + } + for (var i = 0; i < this._zones.length; i++) { + var zone = this._zones[i]; + if (zone.y > start && zone.y <= end + 1) { + if (this._currentZone && this._currentZone === zone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + } + this._zones.splice(i--, 1); + } + } + if (this._zones.length === 0) { + this._deactivate(); + } + }; + MouseZoneManager.prototype._activate = function () { + if (!this._areZonesActive) { + this._areZonesActive = true; + this._terminal.element.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.addEventListener('click', this._clickListener); + } + }; + MouseZoneManager.prototype._deactivate = function () { + if (this._areZonesActive) { + this._areZonesActive = false; + this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.removeEventListener('click', this._clickListener); + } + }; + MouseZoneManager.prototype._onMouseMove = function (e) { + if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) { + this._onHover(e); + this._lastHoverCoords = [e.pageX, e.pageY]; + } + }; + MouseZoneManager.prototype._onHover = function (e) { + var _this = this; + var zone = this._findZoneEventAt(e); + if (zone === this._currentZone) { + return; + } + if (this._currentZone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + if (this._tooltipTimeout) { + clearTimeout(this._tooltipTimeout); + } + } + if (!zone) { + return; + } + this._currentZone = zone; + if (zone.hoverCallback) { + zone.hoverCallback(e); + } + this._tooltipTimeout = setTimeout(function () { return _this._onTooltip(e); }, HOVER_DURATION); + }; + MouseZoneManager.prototype._onTooltip = function (e) { + this._tooltipTimeout = null; + var zone = this._findZoneEventAt(e); + if (zone && zone.tooltipCallback) { + zone.tooltipCallback(e); + } + }; + MouseZoneManager.prototype._onMouseDown = function (e) { + if (!this._areZonesActive) { + return; + } + var zone = this._findZoneEventAt(e); + if (zone) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + }; + MouseZoneManager.prototype._onClick = function (e) { + var zone = this._findZoneEventAt(e); + if (zone) { + zone.clickCallback(e); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }; + MouseZoneManager.prototype._findZoneEventAt = function (e) { + var coords = this._terminal.mouseHelper.getCoords(e, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows); + if (!coords) { + return null; + } + for (var i = 0; i < this._zones.length; i++) { + var zone = this._zones[i]; + if (zone.y === coords[1] && zone.x1 <= coords[0] && zone.x2 > coords[0]) { + return zone; + } + } + ; + return null; + }; + return MouseZoneManager; +}()); +exports.MouseZoneManager = MouseZoneManager; +var MouseZone = (function () { + function MouseZone(x1, x2, y, clickCallback, hoverCallback, tooltipCallback, leaveCallback) { + this.x1 = x1; + this.x2 = x2; + this.y = y; + this.clickCallback = clickCallback; + this.hoverCallback = hoverCallback; + this.tooltipCallback = tooltipCallback; + this.leaveCallback = leaveCallback; + } + return MouseZone; +}()); +exports.MouseZone = MouseZone; + + + +},{}],18:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var CharAtlas_1 = require("./CharAtlas"); +var Buffer_1 = require("../Buffer"); +exports.INVERTED_DEFAULT_COLOR = -1; +var DIM_OPACITY = 0.5; +var BaseRenderLayer = (function () { + function BaseRenderLayer(container, id, zIndex, _alpha, _colors) { + this._alpha = _alpha; + this._colors = _colors; + this._scaledCharWidth = 0; + this._scaledCharHeight = 0; + this._scaledCellWidth = 0; + this._scaledCellHeight = 0; + this._scaledCharLeft = 0; + this._scaledCharTop = 0; + this._canvas = document.createElement('canvas'); + this._canvas.id = "xterm-" + id + "-layer"; + this._canvas.style.zIndex = zIndex.toString(); + this._ctx = this._canvas.getContext('2d', { alpha: _alpha }); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + if (!_alpha) { + this.clearAll(); + } + container.appendChild(this._canvas); + } + BaseRenderLayer.prototype.onOptionsChanged = function (terminal) { }; + BaseRenderLayer.prototype.onBlur = function (terminal) { }; + BaseRenderLayer.prototype.onFocus = function (terminal) { }; + BaseRenderLayer.prototype.onCursorMove = function (terminal) { }; + BaseRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { }; + BaseRenderLayer.prototype.onSelectionChanged = function (terminal, start, end) { }; + BaseRenderLayer.prototype.onThemeChanged = function (terminal, colorSet) { + this._refreshCharAtlas(terminal, colorSet); + }; + BaseRenderLayer.prototype._refreshCharAtlas = function (terminal, colorSet) { + var _this = this; + if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) { + return; + } + this._charAtlas = null; + var result = CharAtlas_1.acquireCharAtlas(terminal, this._colors, this._scaledCharWidth, this._scaledCharHeight); + if (result instanceof HTMLCanvasElement) { + this._charAtlas = result; + } + else { + result.then(function (bitmap) { return _this._charAtlas = bitmap; }); + } + }; + BaseRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + this._scaledCellWidth = dim.scaledCellWidth; + this._scaledCellHeight = dim.scaledCellHeight; + this._scaledCharWidth = dim.scaledCharWidth; + this._scaledCharHeight = dim.scaledCharHeight; + this._scaledCharLeft = dim.scaledCharLeft; + this._scaledCharTop = dim.scaledCharTop; + this._canvas.width = dim.scaledCanvasWidth; + this._canvas.height = dim.scaledCanvasHeight; + this._canvas.style.width = dim.canvasWidth + "px"; + this._canvas.style.height = dim.canvasHeight + "px"; + if (!this._alpha) { + this.clearAll(); + } + if (charSizeChanged) { + this._refreshCharAtlas(terminal, this._colors); + } + }; + BaseRenderLayer.prototype.fillCells = function (x, y, width, height) { + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + }; + BaseRenderLayer.prototype.fillBottomLineAtCells = function (x, y, width) { + if (width === void 0) { width = 1; } + this._ctx.fillRect(x * this._scaledCellWidth, (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1, width * this._scaledCellWidth, window.devicePixelRatio); + }; + BaseRenderLayer.prototype.fillLeftLineAtCell = function (x, y) { + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, window.devicePixelRatio, this._scaledCellHeight); + }; + BaseRenderLayer.prototype.strokeRectAtCell = function (x, y, width, height) { + this._ctx.lineWidth = window.devicePixelRatio; + this._ctx.strokeRect(x * this._scaledCellWidth + window.devicePixelRatio / 2, y * this._scaledCellHeight + (window.devicePixelRatio / 2), width * this._scaledCellWidth - window.devicePixelRatio, (height * this._scaledCellHeight) - window.devicePixelRatio); + }; + BaseRenderLayer.prototype.clearAll = function () { + if (this._alpha) { + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + } + else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + } + }; + BaseRenderLayer.prototype.clearCells = function (x, y, width, height) { + if (this._alpha) { + this._ctx.clearRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + } + else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect(x * this._scaledCellWidth, y * this._scaledCellHeight, width * this._scaledCellWidth, height * this._scaledCellHeight); + } + }; + BaseRenderLayer.prototype.fillCharTrueColor = function (terminal, charData, x, y) { + this._ctx.font = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + this._ctx.textBaseline = 'top'; + this._clipRow(terminal, y); + this._ctx.fillText(charData[Buffer_1.CHAR_DATA_CHAR_INDEX], x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop); + }; + BaseRenderLayer.prototype.drawChar = function (terminal, char, code, width, x, y, fg, bg, bold, dim) { + var colorIndex = 0; + if (fg < 256) { + colorIndex = fg + 2; + } + else { + if (bold && terminal.options.enableBold) { + colorIndex = 1; + } + } + var isAscii = code < 256; + var isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold); + var isDefaultColor = fg >= 256; + var isDefaultBackground = bg >= 256; + if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground) { + var charAtlasCellWidth = this._scaledCharWidth + CharAtlas_1.CHAR_ATLAS_CELL_SPACING; + var charAtlasCellHeight = this._scaledCharHeight + CharAtlas_1.CHAR_ATLAS_CELL_SPACING; + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + if (bold && !terminal.options.enableBold) { + if (colorIndex > 1) { + colorIndex -= 8; + } + } + this._ctx.drawImage(this._charAtlas, code * charAtlasCellWidth, colorIndex * charAtlasCellHeight, charAtlasCellWidth, this._scaledCharHeight, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop, charAtlasCellWidth, this._scaledCharHeight); + } + else { + this._drawUncachedChar(terminal, char, width, fg, x, y, bold, dim); + } + }; + BaseRenderLayer.prototype._drawUncachedChar = function (terminal, char, width, fg, x, y, bold, dim) { + this._ctx.save(); + this._ctx.font = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + if (bold && terminal.options.enableBold) { + this._ctx.font = "bold " + this._ctx.font; + } + this._ctx.textBaseline = 'top'; + if (fg === exports.INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } + else if (fg < 256) { + this._ctx.fillStyle = this._colors.ansi[fg]; + } + else { + this._ctx.fillStyle = this._colors.foreground; + } + this._clipRow(terminal, y); + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + this._ctx.fillText(char, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop); + this._ctx.restore(); + }; + BaseRenderLayer.prototype._clipRow = function (terminal, y) { + this._ctx.beginPath(); + this._ctx.rect(0, y * this._scaledCellHeight, terminal.cols * this._scaledCellWidth, this._scaledCellHeight); + this._ctx.clip(); + }; + return BaseRenderLayer; +}()); +exports.BaseRenderLayer = BaseRenderLayer; + + + +},{"../Buffer":1,"./CharAtlas":19}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Browser_1 = require("../utils/Browser"); +exports.CHAR_ATLAS_CELL_SPACING = 1; +var charAtlasCache = []; +function acquireCharAtlas(terminal, colors, scaledCharWidth, scaledCharHeight) { + var newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors); + for (var i = 0; i < charAtlasCache.length; i++) { + var entry = charAtlasCache[i]; + var ownedByIndex = entry.ownedBy.indexOf(terminal); + if (ownedByIndex >= 0) { + if (configEquals(entry.config, newConfig)) { + return entry.bitmap; + } + else { + if (entry.ownedBy.length === 1) { + charAtlasCache.splice(i, 1); + } + else { + entry.ownedBy.splice(ownedByIndex, 1); + } + break; + } + } + } + for (var i = 0; i < charAtlasCache.length; i++) { + var entry = charAtlasCache[i]; + if (configEquals(entry.config, newConfig)) { + entry.ownedBy.push(terminal); + return entry.bitmap; + } + } + var newEntry = { + bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, colors.background, colors.foreground, colors.ansi), + config: newConfig, + ownedBy: [terminal] + }; + charAtlasCache.push(newEntry); + return newEntry.bitmap; +} +exports.acquireCharAtlas = acquireCharAtlas; +function generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors) { + var clonedColors = { + foreground: colors.foreground, + background: colors.background, + cursor: null, + cursorAccent: null, + selection: null, + ansi: colors.ansi.slice(0, 16) + }; + return { + scaledCharWidth: scaledCharWidth, + scaledCharHeight: scaledCharHeight, + fontFamily: terminal.options.fontFamily, + fontSize: terminal.options.fontSize, + colors: clonedColors + }; +} +function configEquals(a, b) { + for (var i = 0; i < a.colors.ansi.length; i++) { + if (a.colors.ansi[i] !== b.colors.ansi[i]) { + return false; + } + } + return a.fontFamily === b.fontFamily && + a.fontSize === b.fontSize && + a.scaledCharWidth === b.scaledCharWidth && + a.scaledCharHeight === b.scaledCharHeight && + a.colors.foreground === b.colors.foreground && + a.colors.background === b.colors.background; +} +var generator; +function initialize(document, alpha) { + if (!generator) { + generator = new CharAtlasGenerator(document, alpha); + } +} +exports.initialize = initialize; +var CharAtlasGenerator = (function () { + function CharAtlasGenerator(_document, alpha) { + this._document = _document; + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d', { alpha: alpha }); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + } + CharAtlasGenerator.prototype.generate = function (scaledCharWidth, scaledCharHeight, fontSize, fontFamily, background, foreground, ansiColors) { + var cellWidth = scaledCharWidth + exports.CHAR_ATLAS_CELL_SPACING; + var cellHeight = scaledCharHeight + exports.CHAR_ATLAS_CELL_SPACING; + this._canvas.width = 255 * cellWidth; + this._canvas.height = (2 + 16) * cellHeight; + this._ctx.fillStyle = background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + this._ctx.save(); + this._ctx.fillStyle = foreground; + this._ctx.font = fontSize * window.devicePixelRatio + "px " + fontFamily; + this._ctx.textBaseline = 'top'; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, 0, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, 0); + this._ctx.restore(); + } + this._ctx.save(); + this._ctx.font = "bold " + this._ctx.font; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight); + this._ctx.restore(); + } + this._ctx.restore(); + this._ctx.font = fontSize * window.devicePixelRatio + "px " + fontFamily; + for (var colorIndex = 0; colorIndex < 16; colorIndex++) { + if (colorIndex === 8) { + this._ctx.font = "bold " + this._ctx.font; + } + var y = (colorIndex + 2) * cellHeight; + for (var i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, y, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillStyle = ansiColors[colorIndex]; + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, y); + this._ctx.restore(); + } + } + this._ctx.restore(); + if (!('createImageBitmap' in window) || Browser_1.isFirefox) { + var result = this._canvas; + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d'); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + return result; + } + var charAtlasImageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height); + var r = parseInt(background.substr(1, 2), 16); + var g = parseInt(background.substr(3, 2), 16); + var b = parseInt(background.substr(5, 2), 16); + this._clearColor(charAtlasImageData, r, g, b); + var promise = window.createImageBitmap(charAtlasImageData); + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + return promise; + }; + CharAtlasGenerator.prototype._clearColor = function (imageData, r, g, b) { + for (var offset = 0; offset < imageData.data.length; offset += 4) { + if (imageData.data[offset] === r && + imageData.data[offset + 1] === g && + imageData.data[offset + 2] === b) { + imageData.data[offset + 3] = 0; + } + } + }; + return CharAtlasGenerator; +}()); + + + +},{"../utils/Browser":28}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var DEFAULT_FOREGROUND = '#ffffff'; +var DEFAULT_BACKGROUND = '#000000'; +var DEFAULT_CURSOR = '#ffffff'; +var DEFAULT_CURSOR_ACCENT = '#000000'; +var DEFAULT_SELECTION = 'rgba(255, 255, 255, 0.3)'; +exports.DEFAULT_ANSI_COLORS = [ + '#2e3436', + '#cc0000', + '#4e9a06', + '#c4a000', + '#3465a4', + '#75507b', + '#06989a', + '#d3d7cf', + '#555753', + '#ef2929', + '#8ae234', + '#fce94f', + '#729fcf', + '#ad7fa8', + '#34e2e2', + '#eeeeec' +]; +function generate256Colors(first16Colors) { + var colors = first16Colors.slice(); + var v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (var i = 0; i < 216; i++) { + var r = toPaddedHex(v[(i / 36) % 6 | 0]); + var g = toPaddedHex(v[(i / 6) % 6 | 0]); + var b = toPaddedHex(v[i % 6]); + colors.push("#" + r + g + b); + } + for (var i = 0; i < 24; i++) { + var c = toPaddedHex(8 + i * 10); + colors.push("#" + c + c + c); + } + return colors; +} +function toPaddedHex(c) { + var s = c.toString(16); + return s.length < 2 ? '0' + s : s; +} +var ColorManager = (function () { + function ColorManager() { + this.colors = { + foreground: DEFAULT_FOREGROUND, + background: DEFAULT_BACKGROUND, + cursor: DEFAULT_CURSOR, + cursorAccent: DEFAULT_CURSOR_ACCENT, + selection: DEFAULT_SELECTION, + ansi: generate256Colors(exports.DEFAULT_ANSI_COLORS) + }; + } + ColorManager.prototype.setTheme = function (theme) { + this.colors.foreground = theme.foreground || DEFAULT_FOREGROUND; + this.colors.background = theme.background || DEFAULT_BACKGROUND; + this.colors.cursor = theme.cursor || DEFAULT_CURSOR; + this.colors.cursorAccent = theme.cursorAccent || DEFAULT_CURSOR_ACCENT; + this.colors.selection = theme.selection || DEFAULT_SELECTION; + this.colors.ansi[0] = theme.black || exports.DEFAULT_ANSI_COLORS[0]; + this.colors.ansi[1] = theme.red || exports.DEFAULT_ANSI_COLORS[1]; + this.colors.ansi[2] = theme.green || exports.DEFAULT_ANSI_COLORS[2]; + this.colors.ansi[3] = theme.yellow || exports.DEFAULT_ANSI_COLORS[3]; + this.colors.ansi[4] = theme.blue || exports.DEFAULT_ANSI_COLORS[4]; + this.colors.ansi[5] = theme.magenta || exports.DEFAULT_ANSI_COLORS[5]; + this.colors.ansi[6] = theme.cyan || exports.DEFAULT_ANSI_COLORS[6]; + this.colors.ansi[7] = theme.white || exports.DEFAULT_ANSI_COLORS[7]; + this.colors.ansi[8] = theme.brightBlack || exports.DEFAULT_ANSI_COLORS[8]; + this.colors.ansi[9] = theme.brightRed || exports.DEFAULT_ANSI_COLORS[9]; + this.colors.ansi[10] = theme.brightGreen || exports.DEFAULT_ANSI_COLORS[10]; + this.colors.ansi[11] = theme.brightYellow || exports.DEFAULT_ANSI_COLORS[11]; + this.colors.ansi[12] = theme.brightBlue || exports.DEFAULT_ANSI_COLORS[12]; + this.colors.ansi[13] = theme.brightMagenta || exports.DEFAULT_ANSI_COLORS[13]; + this.colors.ansi[14] = theme.brightCyan || exports.DEFAULT_ANSI_COLORS[14]; + this.colors.ansi[15] = theme.brightWhite || exports.DEFAULT_ANSI_COLORS[15]; + }; + return ColorManager; +}()); +exports.ColorManager = ColorManager; + + + +},{}],21:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("../Buffer"); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var BLINK_INTERVAL = 600; +var CursorRenderLayer = (function (_super) { + __extends(CursorRenderLayer, _super); + function CursorRenderLayer(container, zIndex, colors) { + var _this = _super.call(this, container, 'cursor', zIndex, true, colors) || this; + _this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + _this._cursorRenderers = { + 'bar': _this._renderBarCursor.bind(_this), + 'block': _this._renderBlockCursor.bind(_this), + 'underline': _this._renderUnderlineCursor.bind(_this) + }; + return _this; + } + CursorRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + }; + CursorRenderLayer.prototype.reset = function (terminal) { + this._clearCursor(); + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + this.onOptionsChanged(terminal); + } + }; + CursorRenderLayer.prototype.onBlur = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.pause(); + } + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + }; + CursorRenderLayer.prototype.onFocus = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.resume(terminal); + } + else { + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + }; + CursorRenderLayer.prototype.onOptionsChanged = function (terminal) { + var _this = this; + if (terminal.options.cursorBlink) { + if (!this._cursorBlinkStateManager) { + this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, function () { + _this._render(terminal, true); + }); + } + } + else { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + } + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + }; + CursorRenderLayer.prototype.onCursorMove = function (terminal) { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.restartBlinkAnimation(terminal); + } + }; + CursorRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { + if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) { + this._render(terminal, false); + } + }; + CursorRenderLayer.prototype._render = function (terminal, triggeredByAnimationFrame) { + if (!terminal.cursorState || terminal.cursorHidden) { + this._clearCursor(); + return; + } + var cursorY = terminal.buffer.ybase + terminal.buffer.y; + var viewportRelativeCursorY = cursorY - terminal.buffer.ydisp; + if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) { + this._clearCursor(); + return; + } + var charData = terminal.buffer.lines.get(cursorY)[terminal.buffer.x]; + if (!charData) { + return; + } + if (!terminal.isFocused) { + this._clearCursor(); + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + return; + } + if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) { + this._clearCursor(); + return; + } + if (this._state) { + if (this._state.x === terminal.buffer.x && + this._state.y === viewportRelativeCursorY && + this._state.isFocused === terminal.isFocused && + this._state.style === terminal.options.cursorStyle && + this._state.width === charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]) { + return; + } + this._clearCursor(); + } + this._ctx.save(); + this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + }; + CursorRenderLayer.prototype._clearCursor = function () { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.width, 1); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + } + }; + CursorRenderLayer.prototype._renderBarCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillLeftLineAtCell(x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderBlockCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillCells(x, y, charData[Buffer_1.CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.fillStyle = this._colors.cursorAccent; + this.fillCharTrueColor(terminal, charData, x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderUnderlineCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillBottomLineAtCells(x, y); + this._ctx.restore(); + }; + CursorRenderLayer.prototype._renderBlurCursor = function (terminal, x, y, charData) { + this._ctx.save(); + this._ctx.strokeStyle = this._colors.cursor; + this.strokeRectAtCell(x, y, charData[Buffer_1.CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.restore(); + }; + return CursorRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.CursorRenderLayer = CursorRenderLayer; +var CursorBlinkStateManager = (function () { + function CursorBlinkStateManager(terminal, renderCallback) { + this.renderCallback = renderCallback; + this.isCursorVisible = true; + if (terminal.isFocused) { + this._restartInterval(); + } + } + Object.defineProperty(CursorBlinkStateManager.prototype, "isPaused", { + get: function () { return !(this._blinkStartTimeout || this._blinkInterval); }, + enumerable: true, + configurable: true + }); + CursorBlinkStateManager.prototype.dispose = function () { + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + }; + CursorBlinkStateManager.prototype.restartBlinkAnimation = function (terminal) { + var _this = this; + if (this.isPaused) { + return; + } + this._animationTimeRestarted = Date.now(); + this.isCursorVisible = true; + if (!this._animationFrame) { + this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + } + }; + CursorBlinkStateManager.prototype._restartInterval = function (timeToStart) { + var _this = this; + if (timeToStart === void 0) { timeToStart = BLINK_INTERVAL; } + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + } + this._blinkStartTimeout = setTimeout(function () { + if (_this._animationTimeRestarted) { + var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted); + _this._animationTimeRestarted = null; + if (time > 0) { + _this._restartInterval(time); + return; + } + } + _this.isCursorVisible = false; + _this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + _this._blinkInterval = setInterval(function () { + if (_this._animationTimeRestarted) { + var time = BLINK_INTERVAL - (Date.now() - _this._animationTimeRestarted); + _this._animationTimeRestarted = null; + _this._restartInterval(time); + return; + } + _this.isCursorVisible = !_this.isCursorVisible; + _this._animationFrame = window.requestAnimationFrame(function () { + _this.renderCallback(); + _this._animationFrame = null; + }); + }, BLINK_INTERVAL); + }, timeToStart); + }; + CursorBlinkStateManager.prototype.pause = function () { + this.isCursorVisible = true; + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + }; + CursorBlinkStateManager.prototype.resume = function (terminal) { + this._animationTimeRestarted = null; + this._restartInterval(); + this.restartBlinkAnimation(terminal); + }; + return CursorBlinkStateManager; +}()); + + + +},{"../Buffer":1,"./BaseRenderLayer":18}],22:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var GridCache = (function () { + function GridCache() { + this.cache = []; + } + GridCache.prototype.resize = function (width, height) { + for (var x = 0; x < width; x++) { + if (this.cache.length <= x) { + this.cache.push([]); + } + for (var y = this.cache[x].length; y < height; y++) { + this.cache[x].push(null); + } + this.cache[x].length = height; + } + this.cache.length = width; + }; + GridCache.prototype.clear = function () { + for (var x = 0; x < this.cache.length; x++) { + for (var y = 0; y < this.cache[x].length; y++) { + this.cache[x][y] = null; + } + } + }; + return GridCache; +}()); +exports.GridCache = GridCache; + + + +},{}],23:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var Types_1 = require("../Types"); +var LinkRenderLayer = (function (_super) { + __extends(LinkRenderLayer, _super); + function LinkRenderLayer(container, zIndex, colors, terminal) { + var _this = _super.call(this, container, 'link', zIndex, true, colors) || this; + _this._state = null; + terminal.linkifier.on(Types_1.LinkHoverEventTypes.HOVER, function (e) { return _this._onLinkHover(e); }); + terminal.linkifier.on(Types_1.LinkHoverEventTypes.LEAVE, function (e) { return _this._onLinkLeave(e); }); + return _this; + } + LinkRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = null; + }; + LinkRenderLayer.prototype.reset = function (terminal) { + this._clearCurrentLink(); + }; + LinkRenderLayer.prototype._clearCurrentLink = function () { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.length, 1); + this._state = null; + } + }; + LinkRenderLayer.prototype._onLinkHover = function (e) { + this._ctx.fillStyle = this._colors.foreground; + this.fillBottomLineAtCells(e.x, e.y, e.length); + this._state = e; + }; + LinkRenderLayer.prototype._onLinkLeave = function (e) { + this._clearCurrentLink(); + }; + return LinkRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.LinkRenderLayer = LinkRenderLayer; + + + +},{"../Types":14,"./BaseRenderLayer":18}],24:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var TextRenderLayer_1 = require("./TextRenderLayer"); +var SelectionRenderLayer_1 = require("./SelectionRenderLayer"); +var CursorRenderLayer_1 = require("./CursorRenderLayer"); +var ColorManager_1 = require("./ColorManager"); +var LinkRenderLayer_1 = require("./LinkRenderLayer"); +var EventEmitter_1 = require("../EventEmitter"); +var ScreenDprMonitor_1 = require("../utils/ScreenDprMonitor"); +var Renderer = (function (_super) { + __extends(Renderer, _super); + function Renderer(_terminal, theme) { + var _this = _super.call(this) || this; + _this._terminal = _terminal; + _this._refreshRowsQueue = []; + _this._refreshAnimationFrame = null; + _this._isPaused = false; + _this._needsFullRefresh = false; + _this.colorManager = new ColorManager_1.ColorManager(); + if (theme) { + _this.colorManager.setTheme(theme); + } + _this._renderLayers = [ + new TextRenderLayer_1.TextRenderLayer(_this._terminal.element, 0, _this.colorManager.colors, _this._terminal.options.allowTransparency), + new SelectionRenderLayer_1.SelectionRenderLayer(_this._terminal.element, 1, _this.colorManager.colors), + new LinkRenderLayer_1.LinkRenderLayer(_this._terminal.element, 2, _this.colorManager.colors, _this._terminal), + new CursorRenderLayer_1.CursorRenderLayer(_this._terminal.element, 3, _this.colorManager.colors) + ]; + _this.dimensions = { + scaledCharWidth: null, + scaledCharHeight: null, + scaledCellWidth: null, + scaledCellHeight: null, + scaledCharLeft: null, + scaledCharTop: null, + scaledCanvasWidth: null, + scaledCanvasHeight: null, + canvasWidth: null, + canvasHeight: null, + actualCellWidth: null, + actualCellHeight: null + }; + _this._devicePixelRatio = window.devicePixelRatio; + _this._updateDimensions(); + _this._screenDprMonitor = new ScreenDprMonitor_1.ScreenDprMonitor(); + _this._screenDprMonitor.setListener(function () { return _this.onWindowResize(window.devicePixelRatio); }); + if ('IntersectionObserver' in window) { + var observer = new IntersectionObserver(function (e) { return _this.onIntersectionChange(e[0]); }, { threshold: 0 }); + observer.observe(_this._terminal.element); + } + return _this; + } + Renderer.prototype.onIntersectionChange = function (entry) { + this._isPaused = entry.intersectionRatio === 0; + if (!this._isPaused && this._needsFullRefresh) { + this._terminal.refresh(0, this._terminal.rows - 1); + } + }; + Renderer.prototype.onWindowResize = function (devicePixelRatio) { + if (this._devicePixelRatio !== devicePixelRatio) { + this._devicePixelRatio = devicePixelRatio; + this.onResize(this._terminal.cols, this._terminal.rows, true); + } + }; + Renderer.prototype.setTheme = function (theme) { + var _this = this; + this.colorManager.setTheme(theme); + this._renderLayers.forEach(function (l) { + l.onThemeChanged(_this._terminal, _this.colorManager.colors); + l.reset(_this._terminal); + }); + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + return this.colorManager.colors; + }; + Renderer.prototype.onResize = function (cols, rows, didCharSizeChange) { + var _this = this; + this._updateDimensions(); + this._renderLayers.forEach(function (l) { return l.resize(_this._terminal, _this.dimensions, didCharSizeChange); }); + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + this.emit('resize', { + width: this.dimensions.canvasWidth, + height: this.dimensions.canvasHeight + }); + }; + Renderer.prototype.onCharSizeChanged = function () { + this.onResize(this._terminal.cols, this._terminal.rows, true); + }; + Renderer.prototype.onBlur = function () { + var _this = this; + this._runOperation(function (l) { return l.onBlur(_this._terminal); }); + }; + Renderer.prototype.onFocus = function () { + var _this = this; + this._runOperation(function (l) { return l.onFocus(_this._terminal); }); + }; + Renderer.prototype.onSelectionChanged = function (start, end) { + var _this = this; + this._runOperation(function (l) { return l.onSelectionChanged(_this._terminal, start, end); }); + }; + Renderer.prototype.onCursorMove = function () { + var _this = this; + this._runOperation(function (l) { return l.onCursorMove(_this._terminal); }); + }; + Renderer.prototype.onOptionsChanged = function () { + var _this = this; + this._runOperation(function (l) { return l.onOptionsChanged(_this._terminal); }); + }; + Renderer.prototype.clear = function () { + var _this = this; + this._runOperation(function (l) { return l.reset(_this._terminal); }); + }; + Renderer.prototype._runOperation = function (operation) { + if (this._isPaused) { + this._needsFullRefresh = true; + } + else { + this._renderLayers.forEach(function (l) { return operation(l); }); + } + }; + Renderer.prototype.queueRefresh = function (start, end) { + if (this._isPaused) { + this._needsFullRefresh = true; + return; + } + this._refreshRowsQueue.push({ start: start, end: end }); + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + } + }; + Renderer.prototype._refreshLoop = function () { + var _this = this; + var start; + var end; + if (this._refreshRowsQueue.length > 4) { + start = 0; + end = this._terminal.rows - 1; + } + else { + start = this._refreshRowsQueue[0].start; + end = this._refreshRowsQueue[0].end; + for (var i = 1; i < this._refreshRowsQueue.length; i++) { + if (this._refreshRowsQueue[i].start < start) { + start = this._refreshRowsQueue[i].start; + } + if (this._refreshRowsQueue[i].end > end) { + end = this._refreshRowsQueue[i].end; + } + } + } + this._refreshRowsQueue = []; + this._refreshAnimationFrame = null; + start = Math.max(start, 0); + end = Math.min(end, this._terminal.rows - 1); + this._renderLayers.forEach(function (l) { return l.onGridChanged(_this._terminal, start, end); }); + this._terminal.emit('refresh', { start: start, end: end }); + }; + Renderer.prototype._updateDimensions = function () { + if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) { + return; + } + this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio); + this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio); + this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight); + this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2); + this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing); + this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2); + this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight; + this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth; + this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio); + this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio); + this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows; + this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols; + }; + return Renderer; +}(EventEmitter_1.EventEmitter)); +exports.Renderer = Renderer; + + + +},{"../EventEmitter":7,"../utils/ScreenDprMonitor":33,"./ColorManager":20,"./CursorRenderLayer":21,"./LinkRenderLayer":23,"./SelectionRenderLayer":25,"./TextRenderLayer":26}],25:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var SelectionRenderLayer = (function (_super) { + __extends(SelectionRenderLayer, _super); + function SelectionRenderLayer(container, zIndex, colors) { + var _this = _super.call(this, container, 'selection', zIndex, true, colors) || this; + _this._state = { + start: null, + end: null + }; + return _this; + } + SelectionRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + this._state = { + start: null, + end: null + }; + }; + SelectionRenderLayer.prototype.reset = function (terminal) { + if (this._state.start && this._state.end) { + this._state = { + start: null, + end: null + }; + this.clearAll(); + } + }; + SelectionRenderLayer.prototype.onSelectionChanged = function (terminal, start, end) { + if (this._state.start === start || this._state.end === end) { + return; + } + this.clearAll(); + if (!start || !end) { + return; + } + var viewportStartRow = start[1] - terminal.buffer.ydisp; + var viewportEndRow = end[1] - terminal.buffer.ydisp; + var viewportCappedStartRow = Math.max(viewportStartRow, 0); + var viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1); + if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) { + return; + } + var startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0; + var startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols; + this._ctx.fillStyle = this._colors.selection; + this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); + var middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0); + this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); + if (viewportCappedStartRow !== viewportCappedEndRow) { + var endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols; + this.fillCells(0, viewportCappedEndRow, endCol, 1); + } + this._state.start = [start[0], start[1]]; + this._state.end = [end[0], end[1]]; + }; + return SelectionRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.SelectionRenderLayer = SelectionRenderLayer; + + + +},{"./BaseRenderLayer":18}],26:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var Buffer_1 = require("../Buffer"); +var Types_1 = require("./Types"); +var GridCache_1 = require("./GridCache"); +var BaseRenderLayer_1 = require("./BaseRenderLayer"); +var OVERLAP_OWNED_CHAR_DATA = [null, '', 0, -1]; +var TextRenderLayer = (function (_super) { + __extends(TextRenderLayer, _super); + function TextRenderLayer(container, zIndex, colors, alpha) { + var _this = _super.call(this, container, 'text', zIndex, alpha, colors) || this; + _this._characterOverlapCache = {}; + _this._state = new GridCache_1.GridCache(); + return _this; + } + TextRenderLayer.prototype.resize = function (terminal, dim, charSizeChanged) { + _super.prototype.resize.call(this, terminal, dim, charSizeChanged); + var terminalFont = terminal.options.fontSize * window.devicePixelRatio + "px " + terminal.options.fontFamily; + if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { + this._characterWidth = dim.scaledCharWidth; + this._characterFont = terminalFont; + this._characterOverlapCache = {}; + } + this._state.clear(); + this._state.resize(terminal.cols, terminal.rows); + }; + TextRenderLayer.prototype.reset = function (terminal) { + this._state.clear(); + this.clearAll(); + }; + TextRenderLayer.prototype.onGridChanged = function (terminal, startRow, endRow) { + if (this._state.cache.length === 0) { + return; + } + for (var y = startRow; y <= endRow; y++) { + var row = y + terminal.buffer.ydisp; + var line = terminal.buffer.lines.get(row); + this.clearCells(0, y, terminal.cols, 1); + for (var x = 0; x < terminal.cols; x++) { + var charData = line[x]; + var code = charData[Buffer_1.CHAR_DATA_CODE_INDEX]; + var char = charData[Buffer_1.CHAR_DATA_CHAR_INDEX]; + var attr = charData[Buffer_1.CHAR_DATA_ATTR_INDEX]; + var width = charData[Buffer_1.CHAR_DATA_WIDTH_INDEX]; + if (width === 0) { + continue; + } + if (code === 32) { + if (x > 0) { + var previousChar = line[x - 1]; + if (this._isOverlapping(previousChar)) { + continue; + } + } + } + var flags = attr >> 18; + var bg = attr & 0x1ff; + var isDefaultBackground = bg >= 256; + var isInvisible = flags & Types_1.FLAGS.INVISIBLE; + var isInverted = flags & Types_1.FLAGS.INVERSE; + if (!code || (code === 32 && isDefaultBackground && !isInverted) || isInvisible) { + continue; + } + if (width !== 0 && this._isOverlapping(charData)) { + if (x < line.length - 1 && line[x + 1][Buffer_1.CHAR_DATA_CODE_INDEX] === 32) { + width = 2; + } + } + var fg = (attr >> 9) & 0x1ff; + if (isInverted) { + var temp = bg; + bg = fg; + fg = temp; + if (fg === 256) { + fg = BaseRenderLayer_1.INVERTED_DEFAULT_COLOR; + } + if (bg === 257) { + bg = BaseRenderLayer_1.INVERTED_DEFAULT_COLOR; + } + } + if (width === 2) { + } + if (bg < 256) { + this._ctx.save(); + this._ctx.fillStyle = (bg === BaseRenderLayer_1.INVERTED_DEFAULT_COLOR ? this._colors.foreground : this._colors.ansi[bg]); + this.fillCells(x, y, width, 1); + this._ctx.restore(); + } + this._ctx.save(); + if (flags & Types_1.FLAGS.BOLD) { + this._ctx.font = "bold " + this._ctx.font; + if (fg < 8) { + fg += 8; + } + } + if (flags & Types_1.FLAGS.UNDERLINE) { + if (fg === BaseRenderLayer_1.INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } + else if (fg < 256) { + this._ctx.fillStyle = this._colors.ansi[fg]; + } + else { + this._ctx.fillStyle = this._colors.foreground; + } + this.fillBottomLineAtCells(x, y); + } + this.drawChar(terminal, char, code, width, x, y, fg, bg, !!(flags & Types_1.FLAGS.BOLD), !!(flags & Types_1.FLAGS.DIM)); + this._ctx.restore(); + } + } + }; + TextRenderLayer.prototype._isOverlapping = function (charData) { + if (charData[Buffer_1.CHAR_DATA_WIDTH_INDEX] !== 1) { + return false; + } + var code = charData[Buffer_1.CHAR_DATA_CODE_INDEX]; + if (code < 256) { + return false; + } + var char = charData[Buffer_1.CHAR_DATA_CHAR_INDEX]; + if (this._characterOverlapCache.hasOwnProperty(char)) { + return this._characterOverlapCache[char]; + } + this._ctx.save(); + this._ctx.font = this._characterFont; + var overlaps = Math.floor(this._ctx.measureText(char).width) > this._characterWidth; + this._ctx.restore(); + this._characterOverlapCache[char] = overlaps; + return overlaps; + }; + TextRenderLayer.prototype._clearChar = function (x, y) { + var colsToClear = 1; + var state = this._state.cache[x][y]; + if (state && state[Buffer_1.CHAR_DATA_WIDTH_INDEX] === 2) { + colsToClear = 2; + } + this.clearCells(x, y, colsToClear, 1); + }; + return TextRenderLayer; +}(BaseRenderLayer_1.BaseRenderLayer)); +exports.TextRenderLayer = TextRenderLayer; + + + +},{"../Buffer":1,"./BaseRenderLayer":18,"./GridCache":22,"./Types":27}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["BOLD"] = 1] = "BOLD"; + FLAGS[FLAGS["UNDERLINE"] = 2] = "UNDERLINE"; + FLAGS[FLAGS["BLINK"] = 4] = "BLINK"; + FLAGS[FLAGS["INVERSE"] = 8] = "INVERSE"; + FLAGS[FLAGS["INVISIBLE"] = 16] = "INVISIBLE"; + FLAGS[FLAGS["DIM"] = 32] = "DIM"; +})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); +; + + + +},{}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Generic_1 = require("./Generic"); +var isNode = (typeof navigator === 'undefined') ? true : false; +var userAgent = (isNode) ? 'node' : navigator.userAgent; +var platform = (isNode) ? 'node' : navigator.platform; +exports.isFirefox = !!~userAgent.indexOf('Firefox'); +exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); +exports.isMac = Generic_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); +exports.isIpad = platform === 'iPad'; +exports.isIphone = platform === 'iPhone'; +exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); +exports.isLinux = platform.indexOf('Linux') >= 0; + + + +},{"./Generic":31}],29:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter_1 = require("../EventEmitter"); +var CharMeasure = (function (_super) { + __extends(CharMeasure, _super); + function CharMeasure(document, parentElement) { + var _this = _super.call(this) || this; + _this._document = document; + _this._parentElement = parentElement; + _this._measureElement = _this._document.createElement('span'); + _this._measureElement.style.position = 'absolute'; + _this._measureElement.style.top = '0'; + _this._measureElement.style.left = '-9999em'; + _this._measureElement.style.lineHeight = 'normal'; + _this._measureElement.textContent = 'W'; + _this._measureElement.setAttribute('aria-hidden', 'true'); + _this._parentElement.appendChild(_this._measureElement); + return _this; + } + Object.defineProperty(CharMeasure.prototype, "width", { + get: function () { + return this._width; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CharMeasure.prototype, "height", { + get: function () { + return this._height; + }, + enumerable: true, + configurable: true + }); + CharMeasure.prototype.measure = function (options) { + this._measureElement.style.fontFamily = options.fontFamily; + this._measureElement.style.fontSize = options.fontSize + "px"; + var geometry = this._measureElement.getBoundingClientRect(); + if (geometry.width === 0 || geometry.height === 0) { + return; + } + if (this._width !== geometry.width || this._height !== geometry.height) { + this._width = geometry.width; + this._height = Math.ceil(geometry.height); + this.emit('charsizechanged'); + } + }; + return CharMeasure; +}(EventEmitter_1.EventEmitter)); +exports.CharMeasure = CharMeasure; + + + +},{"../EventEmitter":7}],30:[function(require,module,exports){ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter_1 = require("../EventEmitter"); +var CircularList = (function (_super) { + __extends(CircularList, _super); + function CircularList(_maxLength) { + var _this = _super.call(this) || this; + _this._maxLength = _maxLength; + _this._array = new Array(_this._maxLength); + _this._startIndex = 0; + _this._length = 0; + return _this; + } + Object.defineProperty(CircularList.prototype, "maxLength", { + get: function () { + return this._maxLength; + }, + set: function (newMaxLength) { + if (this._maxLength === newMaxLength) { + return; + } + var newArray = new Array(newMaxLength); + for (var i = 0; i < Math.min(newMaxLength, this.length); i++) { + newArray[i] = this._array[this._getCyclicIndex(i)]; + } + this._array = newArray; + this._maxLength = newMaxLength; + this._startIndex = 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "length", { + get: function () { + return this._length; + }, + set: function (newLength) { + if (newLength > this._length) { + for (var i = this._length; i < newLength; i++) { + this._array[i] = undefined; + } + } + this._length = newLength; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CircularList.prototype, "forEach", { + get: function () { + var _this = this; + return function (callbackfn) { + var i = 0; + var length = _this.length; + for (var i_1 = 0; i_1 < length; i_1++) { + callbackfn(_this.get(i_1), i_1); + } + }; + }, + enumerable: true, + configurable: true + }); + CircularList.prototype.get = function (index) { + return this._array[this._getCyclicIndex(index)]; + }; + CircularList.prototype.set = function (index, value) { + this._array[this._getCyclicIndex(index)] = value; + }; + CircularList.prototype.push = function (value) { + this._array[this._getCyclicIndex(this._length)] = value; + if (this._length === this._maxLength) { + this._startIndex++; + if (this._startIndex === this._maxLength) { + this._startIndex = 0; + } + this.emit('trim', 1); + } + else { + this._length++; + } + }; + CircularList.prototype.pop = function () { + return this._array[this._getCyclicIndex(this._length-- - 1)]; + }; + CircularList.prototype.splice = function (start, deleteCount) { + var items = []; + for (var _i = 2; _i < arguments.length; _i++) { + items[_i - 2] = arguments[_i]; + } + if (deleteCount) { + for (var i = start; i < this._length - deleteCount; i++) { + this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)]; + } + this._length -= deleteCount; + } + if (items && items.length) { + for (var i = this._length - 1; i >= start; i--) { + this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)]; + } + for (var i = 0; i < items.length; i++) { + this._array[this._getCyclicIndex(start + i)] = items[i]; + } + if (this._length + items.length > this.maxLength) { + var countToTrim = (this._length + items.length) - this.maxLength; + this._startIndex += countToTrim; + this._length = this.maxLength; + this.emit('trim', countToTrim); + } + else { + this._length += items.length; + } + } + }; + CircularList.prototype.trimStart = function (count) { + if (count > this._length) { + count = this._length; + } + this._startIndex += count; + this._length -= count; + this.emit('trim', count); + }; + CircularList.prototype.shiftElements = function (start, count, offset) { + if (count <= 0) { + return; + } + if (start < 0 || start >= this._length) { + throw new Error('start argument out of range'); + } + if (start + offset < 0) { + throw new Error('Cannot shift elements in list beyond index 0'); + } + if (offset > 0) { + for (var i = count - 1; i >= 0; i--) { + this.set(start + i + offset, this.get(start + i)); + } + var expandListBy = (start + count + offset) - this._length; + if (expandListBy > 0) { + this._length += expandListBy; + while (this._length > this.maxLength) { + this._length--; + this._startIndex++; + this.emit('trim', 1); + } + } + } + else { + for (var i = 0; i < count; i++) { + this.set(start + i + offset, this.get(start + i)); + } + } + }; + CircularList.prototype._getCyclicIndex = function (index) { + return (this._startIndex + index) % this.maxLength; + }; + return CircularList; +}(EventEmitter_1.EventEmitter)); +exports.CircularList = CircularList; + + + +},{"../EventEmitter":7}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function contains(arr, el) { + return arr.indexOf(el) >= 0; +} +exports.contains = contains; +; + + + +},{}],32:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var MouseHelper = (function () { + function MouseHelper(_renderer) { + this._renderer = _renderer; + } + MouseHelper.getCoordsRelativeToElement = function (event, element) { + if (event.pageX == null) { + return null; + } + var originalElement = element; + var x = event.pageX; + var y = event.pageY; + while (element) { + x -= element.offsetLeft; + y -= element.offsetTop; + element = 'offsetParent' in element ? element.offsetParent : element.parentElement; + } + element = originalElement; + while (element && element !== element.ownerDocument.body) { + x += element.scrollLeft; + y += element.scrollTop; + element = element.parentElement; + } + return [x, y]; + }; + MouseHelper.prototype.getCoords = function (event, element, charMeasure, lineHeight, colCount, rowCount, isSelection) { + if (!charMeasure.width || !charMeasure.height) { + return null; + } + var coords = MouseHelper.getCoordsRelativeToElement(event, element); + if (!coords) { + return null; + } + coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth); + coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight); + coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0)); + coords[1] = Math.min(Math.max(coords[1], 1), rowCount); + return coords; + }; + MouseHelper.prototype.getRawByteCoords = function (event, element, charMeasure, lineHeight, colCount, rowCount) { + var coords = this.getCoords(event, element, charMeasure, lineHeight, colCount, rowCount); + var x = coords[0]; + var y = coords[1]; + x += 32; + y += 32; + return { x: x, y: y }; + }; + return MouseHelper; +}()); +exports.MouseHelper = MouseHelper; + + + +},{}],33:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ScreenDprMonitor = (function () { + function ScreenDprMonitor() { + } + ScreenDprMonitor.prototype.setListener = function (listener) { + var _this = this; + if (this._listener) { + this.clearListener(); + } + this._listener = listener; + this._outerListener = function () { + _this._listener(window.devicePixelRatio, _this._currentDevicePixelRatio); + _this._updateDpr(); + }; + this._updateDpr(); + }; + ScreenDprMonitor.prototype._updateDpr = function () { + if (this._resolutionMediaMatchList) { + this._resolutionMediaMatchList.removeListener(this._outerListener); + } + this._currentDevicePixelRatio = window.devicePixelRatio; + this._resolutionMediaMatchList = window.matchMedia("screen and (resolution: " + window.devicePixelRatio + "dppx)"); + this._resolutionMediaMatchList.addListener(this._outerListener); + }; + ScreenDprMonitor.prototype.clearListener = function () { + if (!this._listener) { + return; + } + this._resolutionMediaMatchList.removeListener(this._outerListener); + this._listener = null; + this._outerListener = null; + }; + return ScreenDprMonitor; +}()); +exports.ScreenDprMonitor = ScreenDprMonitor; + + + +},{}],34:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg=='; + + + +},{}],35:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Terminal_1 = require("./Terminal"); +module.exports = Terminal_1.Terminal; + + + +},{"./Terminal":13}]},{},[35])(35) +}); +//# sourceMappingURL=xterm.js.map + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function attach(term, socket, bidirectional, buffered) { + bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; + term.socket = socket; + term._flushBuffer = function () { + term.write(term._attachSocketBuffer); + term._attachSocketBuffer = null; + }; + term._pushToBuffer = function (data) { + if (term._attachSocketBuffer) { + term._attachSocketBuffer += data; + } + else { + term._attachSocketBuffer = data; + setTimeout(term._flushBuffer, 10); + } + }; + var myTextDecoder; + term._getMessage = function (ev) { + var str; + if (typeof ev.data === "object") { + if (ev.data instanceof ArrayBuffer) { + if (!myTextDecoder) { + myTextDecoder = new TextDecoder(); + } + str = myTextDecoder.decode(ev.data); + } + else { + throw "TODO: handle Blob?"; + } + } + if (buffered) { + term._pushToBuffer(str || ev.data); + } + else { + term.write(str || ev.data); + } + }; + term._sendData = function (data) { + if (socket.readyState !== 1) { + return; + } + socket.send(data); + }; + socket.addEventListener('message', term._getMessage); + if (bidirectional) { + term.on('data', term._sendData); + } + socket.addEventListener('close', term.detach.bind(term, socket)); + socket.addEventListener('error', term.detach.bind(term, socket)); +} +exports.attach = attach; +; +function detach(term, socket) { + term.off('data', term._sendData); + socket = (typeof socket == 'undefined') ? term.socket : socket; + if (socket) { + socket.removeEventListener('message', term._getMessage); + } + delete term.socket; +} +exports.detach = detach; +; +function apply(terminalConstructor) { + terminalConstructor.prototype.attach = function (socket, bidirectional, buffered) { + return attach(this, socket, bidirectional, buffered); + }; + terminalConstructor.prototype.detach = function (socket) { + return detach(this, socket); + }; +} +exports.apply = apply; + +//# sourceMappingURL=attach.js.map + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function proposeGeometry(term) { + if (!term.element.parentElement) { + return null; + } + var parentElementStyle = window.getComputedStyle(term.element.parentElement); + var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')); + var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17); + var elementStyle = window.getComputedStyle(term.element); + var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')); + var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')); + var availableHeight = parentElementHeight - elementPaddingVer; + var availableWidth = parentElementWidth - elementPaddingHor; + var geometry = { + cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth), + rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight) + }; + return geometry; +} +exports.proposeGeometry = proposeGeometry; +; +function fit(term) { + var geometry = proposeGeometry(term); + if (geometry) { + if (term.rows !== geometry.rows || term.cols !== geometry.cols) { + term.renderer.clear(); + term.resize(geometry.cols, geometry.rows); + } + } +} +exports.fit = fit; +; +function apply(terminalConstructor) { + terminalConstructor.prototype.proposeGeometry = function () { + return proposeGeometry(this); + }; + terminalConstructor.prototype.fit = function () { + return fit(this); + }; +} +exports.apply = apply; + +//# sourceMappingURL=fit.js.map + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function winptyCompatInit(terminal) { + var isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0; + if (!isWindows) { + return; + } + terminal.on('linefeed', function () { + var line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1); + var lastChar = line[terminal.cols - 1]; + if (lastChar[3] !== 32) { + var nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y); + nextLine.isWrapped = true; + } + }); +} +exports.winptyCompatInit = winptyCompatInit; +function apply(terminalConstructor) { + terminalConstructor.prototype.winptyCompatInit = function () { + winptyCompatInit(this); + }; +} +exports.apply = apply; + +//# sourceMappingURL=winptyCompat.js.map + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/FluentTerminal.SystemTray/Client/index.html b/FluentTerminal.SystemTray/Client/index.html new file mode 100644 index 0000000..196ede2 --- /dev/null +++ b/FluentTerminal.SystemTray/Client/index.html @@ -0,0 +1,12 @@ + + + + + + + + +

    + + + \ No newline at end of file diff --git a/FluentTerminal.SystemTray/Client/style.css b/FluentTerminal.SystemTray/Client/style.css new file mode 100644 index 0000000..41f437c --- /dev/null +++ b/FluentTerminal.SystemTray/Client/style.css @@ -0,0 +1,24 @@ +* { + margin: 0; +} + +html { + -ms-overflow-style: none; + background: transparent; + height: 100%; + } + +body { + background: transparent; + height: 100%; +} + +#terminal-container { + width: 100%; + height: 100%; + margin: 0; +} + +.terminal { + background: transparent !important; +} diff --git a/FluentTerminal.SystemTray/Client/xterm.css b/FluentTerminal.SystemTray/Client/xterm.css new file mode 100644 index 0000000..b3ee50f --- /dev/null +++ b/FluentTerminal.SystemTray/Client/xterm.css @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/term.js + * @license MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + */ + +/** + * Default styles for xterm.js + */ + +.xterm { + font-family: courier-new, courier, monospace; + font-feature-settings: "liga" 0; + position: relative; + user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.xterm.focus, +.xterm:focus { + outline: none; +} + +.xterm .xterm-helpers { + position: absolute; + top: 0; + /** + * The z-index of the helpers must be higher than the canvases in order for + * IMEs to appear on top. + */ + z-index: 10; +} + +.xterm .xterm-helper-textarea { + /* + * HACK: to fix IE's blinking cursor + * Move textarea out of the screen to the far left, so that the cursor is not visible. + */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -10; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.xterm .composition-view { + /* TODO: Composition position got messed up somewhere */ + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.xterm .composition-view.active { + display: block; +} + +.xterm .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; + cursor: default; +} + +.xterm canvas { + position: absolute; + left: 0; + top: 0; +} + +.xterm .xterm-scroll-area { + visibility: hidden; +} + +.xterm .xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + left: -9999em; +} + +.xterm.enable-mouse-events { + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ + cursor: default; +} + +.xterm:not(.enable-mouse-events) { + cursor: text; +} diff --git a/FluentTerminal.SystemTray/Controllers/TerminalsController.cs b/FluentTerminal.SystemTray/Controllers/TerminalsController.cs new file mode 100644 index 0000000..198cf0c --- /dev/null +++ b/FluentTerminal.SystemTray/Controllers/TerminalsController.cs @@ -0,0 +1,33 @@ +using FluentTerminal.SystemTray.DataTransferObjects; +using FluentTerminal.SystemTray.Services; +using System; +using System.Linq; +using System.Net.Http; +using System.Web.Http; + +namespace FluentTerminal.SystemTray.Controllers +{ + public class TerminalsController : ApiController + { + private TerminalsManager _terminalsManager; + + public TerminalsController(TerminalsManager terminalsManager) + { + _terminalsManager = terminalsManager ?? throw new ArgumentNullException(nameof(terminalsManager)); + } + + [HttpPost] + [Route("terminals")] + public string Post() + { + var cols = int.Parse(this.Request.GetQueryNameValuePairs().SingleOrDefault(q => q.Key == "cols").Value); + var rows = int.Parse(this.Request.GetQueryNameValuePairs().SingleOrDefault(q => q.Key == "rows").Value); + var options = new TerminalOptions + { + Columns = cols, + Rows = rows + }; + return _terminalsManager.CreateTerminal(options); + } + } +} diff --git a/FluentTerminal.SystemTray/DataTransferObjects/TerminalOptions.cs b/FluentTerminal.SystemTray/DataTransferObjects/TerminalOptions.cs new file mode 100644 index 0000000..16744e0 --- /dev/null +++ b/FluentTerminal.SystemTray/DataTransferObjects/TerminalOptions.cs @@ -0,0 +1,10 @@ +namespace FluentTerminal.SystemTray.DataTransferObjects +{ + public class TerminalOptions + { + public int Rows { get; set; } + public int Columns { get; set; } + public string PWD { get; set; } + public string ShellExecutable { get; set; } + } +} diff --git a/FluentTerminal.SystemTray/FluentTerminal.SystemTray.csproj b/FluentTerminal.SystemTray/FluentTerminal.SystemTray.csproj new file mode 100644 index 0000000..2af7c27 --- /dev/null +++ b/FluentTerminal.SystemTray/FluentTerminal.SystemTray.csproj @@ -0,0 +1,199 @@ + + + + + Debug + AnyCPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD} + WinExe + FluentTerminal.SystemTray + FluentTerminal.SystemTray + v4.7 + 512 + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + app.manifest + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + + + + + False + ..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll + False + + + False + ..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.UI.Xaml.dll + False + + + + + + + + + + + + ..\..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade\Windows.WinMD + False + + + ..\..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\References\10.0.15063.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd + False + + + ..\..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\References\10.0.15063.0\Windows.Foundation.UniversalApiContract\4.0.0.0\Windows.Foundation.UniversalApiContract.winmd + False + + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + 0.14.0.59 + + + 5.2.3 + + + 3.1.0 + + + 5.3.0 + + + 0.4.2 + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + + + + xcopy /y "$(ProjectDir)BinaryDependencies\$(PlatformName)" "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" +xcopy /y /s "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" "$(SolutionDir)FluentTerminal.App\Win32" + + + + xcopy /y "$(SolutionDir)FluentTerminal.Client\dist" "$(ProjectDir)Client" + + \ No newline at end of file diff --git a/FluentTerminal.SystemTray/LoopbackEnabler.cs b/FluentTerminal.SystemTray/LoopbackEnabler.cs new file mode 100644 index 0000000..985a5f5 --- /dev/null +++ b/FluentTerminal.SystemTray/LoopbackEnabler.cs @@ -0,0 +1,330 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace FluentTerminal.SystemTray +{ + public class LoopbackEnabler + { + //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379595(v=vs.85).aspx + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct SID_AND_ATTRIBUTES + { + public IntPtr Sid; + public uint Attributes; + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_AC_CAPABILITIES + { + public uint count; + public IntPtr capabilities; //SID_AND_ATTRIBUTES + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_AC_BINARIES + { + public uint count; + public IntPtr binaries; + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_APP_CONTAINER + { + internal IntPtr appContainerSid; + internal IntPtr userSid; + [MarshalAs(UnmanagedType.LPWStr)] + public string appContainerName; + [MarshalAs(UnmanagedType.LPWStr)] + public string displayName; + [MarshalAs(UnmanagedType.LPWStr)] + public string description; + internal INET_FIREWALL_AC_CAPABILITIES capabilities; + internal INET_FIREWALL_AC_BINARIES binaries; + [MarshalAs(UnmanagedType.LPWStr)] + public string workingDirectory; + [MarshalAs(UnmanagedType.LPWStr)] + public string packageFullName; + } + + + // Call this API to free the memory returned by the Enumeration API + [DllImport("FirewallAPI.dll")] + internal static extern void NetworkIsolationFreeAppContainers(IntPtr pACs); + + // Call this API to load the current list of LoopUtil-enabled AppContainers + [DllImport("FirewallAPI.dll")] + internal static extern uint NetworkIsolationGetAppContainerConfig(out uint pdwCntACs, out IntPtr appContainerSids); + + // Call this API to set the LoopUtil-exemption list + [DllImport("FirewallAPI.dll")] + private static extern uint NetworkIsolationSetAppContainerConfig(uint pdwCntACs, SID_AND_ATTRIBUTES[] appContainerSids); + + + // Use this API to convert a string SID into an actual SID + [DllImport("advapi32.dll", SetLastError = true)] + internal static extern bool ConvertStringSidToSid(string strSid, out IntPtr pSid); + + [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool ConvertSidToStringSid( + [MarshalAs(UnmanagedType.LPArray)] byte[] pSID, + out IntPtr ptrSid); + + [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool ConvertSidToStringSid(IntPtr pSid, out string strSid); + + // Use this API to convert a string reference (e.g. "@{blah.pri?ms-resource://whatever}") into a plain string + [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] + internal static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf); + + // Call this API to enumerate all of the AppContainers on the system + [DllImport("FirewallAPI.dll")] + internal static extern uint NetworkIsolationEnumAppContainers(uint Flags, out uint pdwCntPublicACs, out IntPtr ppACs); + // DWORD NetworkIsolationEnumAppContainers( + // _In_ DWORD Flags, + // _Out_ DWORD *pdwNumPublicAppCs, + // _Out_ PINET_FIREWALL_APP_CONTAINER *ppPublicAppCs + //); + + //http://msdn.microsoft.com/en-gb/library/windows/desktop/hh968116.aspx + enum NETISO_FLAG + { + NETISO_FLAG_FORCE_COMPUTE_BINARIES = 0x1, + NETISO_FLAG_MAX = 0x2 + } + + public class AppContainer + { + public String appContainerName { get; set; } + public String displayName { get; set; } + public String workingDirectory { get; set; } + public String StringSid { get; set; } + public List capabilities { get; set; } + public bool LoopUtil { get; set; } + + public AppContainer(String _appContainerName, String _displayName, String _workingDirectory, IntPtr _sid) + { + this.appContainerName = _appContainerName; + this.displayName = _displayName; + this.workingDirectory = _workingDirectory; + String tempSid; + ConvertSidToStringSid(_sid, out tempSid); + this.StringSid = tempSid; + } + } + + internal List _AppList; + internal List _AppListConfig; + public List Apps = new List(); + internal IntPtr _pACs; + + public LoopbackEnabler() + { + LoadApps(); + } + + public void EnableForApp(string appName) + { + var app = Apps.SingleOrDefault(a => a.displayName == appName); + + if (app != null) + { + app.LoopUtil = true; + SaveLoopbackState(); + } + } + + public void LoadApps() + { + Apps.Clear(); + _pACs = IntPtr.Zero; + //Full List of Apps + _AppList = PI_NetworkIsolationEnumAppContainers(); + //List of Apps that have LoopUtil enabled. + _AppListConfig = PI_NetworkIsolationGetAppContainerConfig(); + foreach (var PI_app in _AppList) + { + AppContainer app = new AppContainer(PI_app.appContainerName, PI_app.displayName, PI_app.workingDirectory, PI_app.appContainerSid); + + var app_capabilities = LoopbackEnabler.getCapabilites(PI_app.capabilities); + if (app_capabilities.Count > 0) + { + //var sid = new SecurityIdentifier(app_capabilities[0], 0); + + IntPtr arrayValue = IntPtr.Zero; + //var b = LoopUtil.ConvertStringSidToSid(app_capabilities[0].Sid, out arrayValue); + //string mysid; + //var b = LoopUtil.ConvertSidToStringSid(app_capabilities[0].Sid, out mysid); + } + app.LoopUtil = CheckLoopback(PI_app.appContainerSid); + Apps.Add(app); + } + } + private bool CheckLoopback(IntPtr intPtr) + { + foreach (SID_AND_ATTRIBUTES item in _AppListConfig) + { + string left, right; + ConvertSidToStringSid(item.Sid, out left); + ConvertSidToStringSid(intPtr, out right); + + if (left == right) + { + return true; + } + } + return false; + } + + private static List getCapabilites(INET_FIREWALL_AC_CAPABILITIES cap) + { + List mycap = new List(); + + IntPtr arrayValue = cap.capabilities; + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < cap.count; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + mycap.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + return mycap; + + } + + private static List getContainerSID(INET_FIREWALL_AC_CAPABILITIES cap) + { + List mycap = new List(); + + IntPtr arrayValue = cap.capabilities; + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < cap.count; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + mycap.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + return mycap; + + } + + private static List PI_NetworkIsolationGetAppContainerConfig() + { + + IntPtr arrayValue = IntPtr.Zero; + uint size = 0; + var list = new List(); + + // Pin down variables + GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned); + GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned); + + uint retval = NetworkIsolationGetAppContainerConfig(out size, out arrayValue); + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < size; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + list.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + //release pinned variables. + handle_pdwCntPublicACs.Free(); + handle_ppACs.Free(); + + return list; + + + } + + private List PI_NetworkIsolationEnumAppContainers() + { + + IntPtr arrayValue = IntPtr.Zero; + uint size = 0; + var list = new List(); + + // Pin down variables + GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned); + GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned); + + //uint retval2 = NetworkIsolationGetAppContainerConfig( out size, out arrayValue); + + uint retval = NetworkIsolationEnumAppContainers((Int32)NETISO_FLAG.NETISO_FLAG_MAX, out size, out arrayValue); + _pACs = arrayValue; //store the pointer so it can be freed when we close the form + + var structSize = Marshal.SizeOf(typeof(INET_FIREWALL_APP_CONTAINER)); + for (var i = 0; i < size; i++) + { + var cur = (INET_FIREWALL_APP_CONTAINER)Marshal.PtrToStructure(arrayValue, typeof(INET_FIREWALL_APP_CONTAINER)); + list.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + //release pinned variables. + handle_pdwCntPublicACs.Free(); + handle_ppACs.Free(); + + return list; + + + } + + public bool SaveLoopbackState() + { + var countEnabled = CountEnabledLoopUtil(); + SID_AND_ATTRIBUTES[] arr = new SID_AND_ATTRIBUTES[countEnabled]; + int count = 0; + + for (int i = 0; i < Apps.Count; i++) + { + if (Apps[i].LoopUtil) + { + arr[count].Attributes = 0; + //TO DO: + IntPtr ptr; + ConvertStringSidToSid(Apps[i].StringSid, out ptr); + arr[count].Sid = ptr; + count++; + } + + } + + + if (NetworkIsolationSetAppContainerConfig((uint)countEnabled, arr) == 0) + { + return true; + } + else + { return false; } + + } + + private int CountEnabledLoopUtil() + { + var count = 0; + for (int i = 0; i < Apps.Count; i++) + { + if (Apps[i].LoopUtil) + { + count++; + } + + } + return count; + } + + public void FreeResources() + { + NetworkIsolationFreeAppContainers(_pACs); + } + + } +} diff --git a/FluentTerminal.SystemTray/Program.cs b/FluentTerminal.SystemTray/Program.cs new file mode 100644 index 0000000..60bb281 --- /dev/null +++ b/FluentTerminal.SystemTray/Program.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading; +using System.Windows.Forms; +using Microsoft.Owin.Hosting; +using Windows.ApplicationModel; + +namespace FluentTerminal.SystemTray +{ + public static class Program + { + private const string MutexName = "FluentTerminalMutex"; + + [STAThread] + public static void Main() + { + if (!Mutex.TryOpenExisting(MutexName, out Mutex mutex)) + { + mutex = new Mutex(false, MutexName); + + var loopbackEnabler = new LoopbackEnabler(); + loopbackEnabler.EnableForApp(Package.Current.DisplayName); + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + string baseAddress = "http://localhost:9000/"; + + using (WebApp.Start(url: baseAddress)) + { + Application.Run(new SystemTrayApplicationContext()); + } + mutex.Close(); + } + } + } +} diff --git a/FluentTerminal.SystemTray/Properties/AssemblyInfo.cs b/FluentTerminal.SystemTray/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..dfea57e --- /dev/null +++ b/FluentTerminal.SystemTray/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("FluentTerminal.SystemTray")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FluentTerminal.SystemTray")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly +// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("9edde318-0003-4553-b6f9-3fe5473563fd")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/FluentTerminal.SystemTray/Properties/Resources.Designer.cs b/FluentTerminal.SystemTray/Properties/Resources.Designer.cs new file mode 100644 index 0000000..812df01 --- /dev/null +++ b/FluentTerminal.SystemTray/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace FluentTerminal.SystemTray.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FluentTerminal.SystemTray.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Icon ähnlich wie (Symbol). + /// + internal static System.Drawing.Icon Square44x44Logo_scale_100 { + get { + object obj = ResourceManager.GetObject("Square44x44Logo_scale_100", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/FluentTerminal.SystemTray/Properties/Resources.resx b/FluentTerminal.SystemTray/Properties/Resources.resx new file mode 100644 index 0000000..2a81e71 --- /dev/null +++ b/FluentTerminal.SystemTray/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Square44x44Logo.scale-100.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/FluentTerminal.SystemTray/Properties/Settings.Designer.cs b/FluentTerminal.SystemTray/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e1b47aa --- /dev/null +++ b/FluentTerminal.SystemTray/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace FluentTerminal.SystemTray.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/FluentTerminal.SystemTray/Properties/Settings.settings b/FluentTerminal.SystemTray/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/FluentTerminal.SystemTray/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/FluentTerminal.SystemTray/Resources/Square44x44Logo.scale-100.ico b/FluentTerminal.SystemTray/Resources/Square44x44Logo.scale-100.ico new file mode 100644 index 0000000000000000000000000000000000000000..f45747cb9c8a555f62869fe54ca50183bce30783 GIT binary patch literal 101611 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 literal 0 HcmV?d00001 diff --git a/FluentTerminal.SystemTray/Services/Terminal.cs b/FluentTerminal.SystemTray/Services/Terminal.cs new file mode 100644 index 0000000..f5d2208 --- /dev/null +++ b/FluentTerminal.SystemTray/Services/Terminal.cs @@ -0,0 +1,174 @@ +using Fleck; +using FluentTerminal.SystemTray.DataTransferObjects; +using System; +using System.IO; +using System.IO.Pipes; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using static winpty.WinPty; + +namespace FluentTerminal.SystemTray.Services +{ + public class Terminal : IDisposable + { + private IntPtr _handle; + private Stream _stdin; + private Stream _stdout; + private bool _disposedValue; + private ManualResetEventSlim _connectedEvent; + + private IWebSocketConnection _webSocket; + + public int Id { get; } + + public string WebSocketUrl { get; } + + public event EventHandler ConnectionClosed; + + public Terminal(TerminalOptions options) + { + var configHandle = IntPtr.Zero; + var spawnConfigHandle = IntPtr.Zero; + var errorHandle = IntPtr.Zero; + + try + { + configHandle = winpty_config_new(WINPTY_FLAG_COLOR_ESCAPES, out errorHandle); + winpty_config_set_initial_size(configHandle, options.Columns, options.Rows); + + _handle = winpty_open(configHandle, out errorHandle); + if (errorHandle != IntPtr.Zero) + { + throw new Exception(winpty_error_code(errorHandle).ToString()); + } + + string exe = @"C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe"; + string args = ""; + string cwd = @"C:\"; + spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, exe, args, cwd, null, out errorHandle); + if (errorHandle != IntPtr.Zero) + { + throw new Exception(winpty_error_code(errorHandle).ToString()); + } + + _stdin = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out); + _stdout = CreatePipe(winpty_conout_name(_handle), PipeDirection.In); + + if (!winpty_spawn(_handle, spawnConfigHandle, out IntPtr process, out IntPtr thread, out int procError, out errorHandle)) + { + throw new Exception(winpty_error_code(errorHandle).ToString()); + } + } + finally + { + winpty_config_free(configHandle); + winpty_spawn_config_free(spawnConfigHandle); + winpty_error_free(errorHandle); + } + + + var port = Utilities.GetAvailablePort(49151); + + if (port == null) + { + throw new Exception("no port available"); + } + + Id = port.Value; + _connectedEvent = new ManualResetEventSlim(false); + WebSocketUrl = "ws://127.0.0.1:" + port; + var webSocketServer = new WebSocketServer(WebSocketUrl); + webSocketServer.Start(socket => + { + _webSocket = socket; + socket.OnOpen = () => + { + Console.WriteLine("open"); + _connectedEvent.Set(); + }; + socket.OnClose = () => + { + Console.WriteLine("closing"); + ConnectionClosed?.Invoke(this, EventArgs.Empty); + }; + socket.OnMessage = message => + { + var bytes = Encoding.ASCII.GetBytes(message); + _stdin.Write(bytes, 0, bytes.Length); + }; + }); + + ListenToStdOut(); + } + + private Stream CreatePipe(string pipeName, PipeDirection direction) + { + string serverName = "."; + if (pipeName.StartsWith("\\")) + { + int slash3 = pipeName.IndexOf('\\', 2); + if (slash3 != -1) + { + serverName = pipeName.Substring(2, slash3 - 2); + } + int slash4 = pipeName.IndexOf('\\', slash3 + 1); + if (slash4 != -1) + { + pipeName = pipeName.Substring(slash4 + 1); + } + } + + var pipe = new NamedPipeClientStream(serverName, pipeName, direction); + pipe.Connect(); + return pipe; + } + + private void ListenToStdOut() + { + Task.Run(async () => + { + _connectedEvent.Wait(); + var reader = new StreamReader(_stdout); + do + { + var offset = 0; + var buffer = new char[1024]; + var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset); + if (readChars > 0) + { + await _webSocket.Send(new String(buffer)); + } + } + while (!reader.EndOfStream); + }); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + _stdin?.Dispose(); + _stdout?.Dispose(); + } + + winpty_free(_handle); + + _disposedValue = true; + } + } + + ~Terminal() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} diff --git a/FluentTerminal.SystemTray/Services/TerminalsManager.cs b/FluentTerminal.SystemTray/Services/TerminalsManager.cs new file mode 100644 index 0000000..9bbe030 --- /dev/null +++ b/FluentTerminal.SystemTray/Services/TerminalsManager.cs @@ -0,0 +1,32 @@ +using FluentTerminal.SystemTray.DataTransferObjects; +using System.Collections.Generic; + +namespace FluentTerminal.SystemTray.Services +{ + public class TerminalsManager + { + private Dictionary _terminals = new Dictionary(); + + public TerminalsManager() + { + + } + + public string CreateTerminal(TerminalOptions options) + { + var terminal = new Terminal(options); + terminal.ConnectionClosed += OnTerminalConnectionClosed; + _terminals.Add(terminal.Id, terminal); + return terminal.WebSocketUrl; + } + + private void OnTerminalConnectionClosed(object sender, System.EventArgs e) + { + if (sender is Terminal terminal) + { + _terminals.Remove(terminal.Id); + terminal.Dispose(); + } + } + } +} diff --git a/FluentTerminal.SystemTray/Startup.cs b/FluentTerminal.SystemTray/Startup.cs new file mode 100644 index 0000000..85c9cb0 --- /dev/null +++ b/FluentTerminal.SystemTray/Startup.cs @@ -0,0 +1,25 @@ +using FluentTerminal.SystemTray.Services; +using Owin; +using System.Web.Http; +using Unity; + +namespace FluentTerminal.SystemTray +{ + public class Startup + { + public void Configuration(IAppBuilder appBuilder) + { + HttpConfiguration config = new HttpConfiguration(); + config.MapHttpAttributeRoutes(); + + var container = new UnityContainer(); + container.RegisterType(); + + config.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); + + //appBuilder.UseFileServer() + appBuilder.UseStaticFiles("/Client"); + appBuilder.UseWebApi(config); + } + } +} diff --git a/FluentTerminal.SystemTray/SystemTrayApplicationContext.cs b/FluentTerminal.SystemTray/SystemTrayApplicationContext.cs new file mode 100644 index 0000000..dc552be --- /dev/null +++ b/FluentTerminal.SystemTray/SystemTrayApplicationContext.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using Windows.ApplicationModel; +using Windows.ApplicationModel.AppService; +using Windows.ApplicationModel.Core; +using Windows.Foundation.Collections; + +namespace FluentTerminal.SystemTray +{ + public class SystemTrayApplicationContext : ApplicationContext + { + private AppServiceConnection connection = null; + private NotifyIcon notifyIcon = null; + + public SystemTrayApplicationContext() + + { + var openMenuItem = new MenuItem("Open App", new EventHandler(OpenApp)); + var exitMenuItem = new MenuItem("Exit", new EventHandler(Exit)); + + openMenuItem.DefaultItem = true; + + notifyIcon = new NotifyIcon(); + notifyIcon.DoubleClick += OpenApp; + notifyIcon.Text = "Fluent Terminal"; + notifyIcon.Icon = Properties.Resources.Square44x44Logo_scale_100; + notifyIcon.ContextMenu = new ContextMenu(new MenuItem[] { openMenuItem, exitMenuItem }); + notifyIcon.Visible = true; + } + + private async void OpenApp(object sender, EventArgs e) + { + IEnumerable appListEntries = await Package.Current.GetAppListEntriesAsync(); + await appListEntries.First().LaunchAsync(); + } + + private async void Exit(object sender, EventArgs e) + + { + var message = new ValueSet + { + { "exit", string.Empty } + }; + await SendMessage(message); + Application.Exit(); + } + + private async Task SendMessage(ValueSet message) + + { + if (connection == null) + { + connection = new AppServiceConnection + { + PackageFamilyName = Package.Current.Id.FamilyName, + AppServiceName = "FluentTerminalAppService" + }; + connection.ServiceClosed += Connection_ServiceClosed; + AppServiceConnectionStatus connectionStatus = await connection.OpenAsync(); + + if (connectionStatus != AppServiceConnectionStatus.Success) + { + MessageBox.Show("Status: " + connectionStatus.ToString()); + return; + } + } + await connection.SendMessageAsync(message); + } + + private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args) + { + connection.ServiceClosed -= Connection_ServiceClosed; + connection = null; + } + } +} \ No newline at end of file diff --git a/FluentTerminal.SystemTray/Utilities.cs b/FluentTerminal.SystemTray/Utilities.cs new file mode 100644 index 0000000..77cd728 --- /dev/null +++ b/FluentTerminal.SystemTray/Utilities.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; + +namespace FluentTerminal.SystemTray +{ + public static class Utilities + { + public static int? GetAvailablePort(int startingPort) + { + var usedPorts = new List(); + + var properties = IPGlobalProperties.GetIPGlobalProperties(); + + var connections = properties.GetActiveTcpConnections(); + usedPorts.AddRange(connections.Where(c => c.LocalEndPoint.Port >= startingPort).Select(c => c.LocalEndPoint.Port)); + + var endPoints = properties.GetActiveTcpListeners(); + usedPorts.AddRange(endPoints.Where(e => e.Port >= startingPort).Select(e => e.Port)); + + endPoints = properties.GetActiveUdpListeners(); + usedPorts.AddRange(endPoints.Where(e => e.Port >= startingPort).Select(e => e.Port)); + + usedPorts.Sort(); + + for (var i = startingPort; i < UInt16.MaxValue; i++) + { + if (!usedPorts.Contains(i)) + { + return i; + } + } + return null; + } + } +} diff --git a/FluentTerminal.SystemTray/app.manifest b/FluentTerminal.SystemTray/app.manifest new file mode 100644 index 0000000..a5e87dc --- /dev/null +++ b/FluentTerminal.SystemTray/app.manifest @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FluentTerminal.sln b/FluentTerminal.sln new file mode 100644 index 0000000..9fc512d --- /dev/null +++ b/FluentTerminal.sln @@ -0,0 +1,68 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2020 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTerminal.App", "FluentTerminal.App\FluentTerminal.App.csproj", "{41020100-3414-4E0A-9A8E-92D3C4179DF8}" + ProjectSection(ProjectDependencies) = postProject + {9EDDE318-0003-4553-B6F9-3FE5473563FD} = {9EDDE318-0003-4553-B6F9-3FE5473563FD} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTerminal.SystemTray", "FluentTerminal.SystemTray\FluentTerminal.SystemTray.csproj", "{9EDDE318-0003-4553-B6F9-3FE5473563FD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|Any CPU.ActiveCfg = Debug|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|ARM.ActiveCfg = Debug|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|ARM.Build.0 = Debug|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|ARM.Deploy.0 = Debug|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x64.ActiveCfg = Debug|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x64.Build.0 = Debug|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x64.Deploy.0 = Debug|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x86.ActiveCfg = Debug|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x86.Build.0 = Debug|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Debug|x86.Deploy.0 = Debug|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|Any CPU.ActiveCfg = Release|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|ARM.ActiveCfg = Release|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|ARM.Build.0 = Release|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|ARM.Deploy.0 = Release|ARM + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x64.ActiveCfg = Release|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x64.Build.0 = Release|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x64.Deploy.0 = Release|x64 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x86.ActiveCfg = Release|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x86.Build.0 = Release|x86 + {41020100-3414-4E0A-9A8E-92D3C4179DF8}.Release|x86.Deploy.0 = Release|x86 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|ARM.Build.0 = Debug|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|x64.ActiveCfg = Debug|x64 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|x64.Build.0 = Debug|x64 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|x86.ActiveCfg = Debug|x86 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Debug|x86.Build.0 = Debug|x86 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|Any CPU.Build.0 = Release|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|ARM.ActiveCfg = Release|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|ARM.Build.0 = Release|Any CPU + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|x64.ActiveCfg = Release|x64 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|x64.Build.0 = Release|x64 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|x86.ActiveCfg = Release|x86 + {9EDDE318-0003-4553-B6F9-3FE5473563FD}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {094EE77F-2C87-4E36-BBFF-C093D31D4DA7} + EndGlobalSection +EndGlobal diff --git a/xterm.js/.dockerignore b/xterm.js/.dockerignore new file mode 100644 index 0000000..c837dec --- /dev/null +++ b/xterm.js/.dockerignore @@ -0,0 +1,16 @@ +node_modules/ +*.swp +.lock-wscript +lib/ +Makefile.gyp +*.Makefile +*.target.gyp.mk +*.node +example/*.log +docs/ +npm-debug.log +/.idea/ +.env +build/ +.vscode/ +.git/ diff --git a/xterm.js/.editorconfig b/xterm.js/.editorconfig new file mode 100644 index 0000000..26230e9 --- /dev/null +++ b/xterm.js/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf + +[*.{j,t}s] +max_line_length = 100 + +[*.css] +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/xterm.js/.gitattributes b/xterm.js/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/xterm.js/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/xterm.js/.github/ISSUE_TEMPLATE.md b/xterm.js/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..3593535 --- /dev/null +++ b/xterm.js/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ + + +## Details +- Browser and browser version: +- OS version: +- xterm.js version: + +### Steps to reproduce + +1. +2. diff --git a/xterm.js/.gitignore b/xterm.js/.gitignore new file mode 100644 index 0000000..bf0c3d8 --- /dev/null +++ b/xterm.js/.gitignore @@ -0,0 +1,28 @@ +node_modules/ +*.swp +.lock-wscript +lib/ +Makefile.gyp +*.Makefile +*.target.gyp.mk +*.node +example/*.log +docs/ +npm-debug.log +/.idea/ +.env +build/ +.vscode/ +.DS_Store +fixtures/typings-test/*.js + +# Directories needed for code coverage +/coverage/ + +# Keep legacy files out of the repo, this can be removed when we merge v3 into master +dist/ +src/utils/TestUtils.ts +src/xterm.js + +# Keep the demo builds out of Git +demo/dist/ diff --git a/xterm.js/.gitmodules b/xterm.js/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/xterm.js/.mailmap b/xterm.js/.mailmap new file mode 100644 index 0000000..a8de62a --- /dev/null +++ b/xterm.js/.mailmap @@ -0,0 +1,7 @@ +Antonis Kalipetis +Antonis Kalipetis +Daniel Imms +Paris Kasidiaris +Paris Kasidiaris +Thanasis Daglis +Thanasis Daglis diff --git a/xterm.js/.npmignore b/xterm.js/.npmignore new file mode 100644 index 0000000..63069bd --- /dev/null +++ b/xterm.js/.npmignore @@ -0,0 +1,16 @@ +node_modules/ +*.swp +.lock-wscript +lib/*.test.js +lib/*.test.js.map +lib/test/ +Makefile.gyp +*.Makefile +*.target.gyp.mk +*.node +example/*.log +docs/ +npm-debug.log +/.idea/ +.env +build/ diff --git a/xterm.js/.travis.yml b/xterm.js/.travis.yml new file mode 100644 index 0000000..1878c3a --- /dev/null +++ b/xterm.js/.travis.yml @@ -0,0 +1,20 @@ +language: node_js +os: + - linux + - osx +node_js: + - 6 +before_install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq install g++-4.8 ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=g++-4.8 ; fi + - npm install -g npm@5.1.0 +env: + matrix: + - NPM_COMMAND=lint + - NPM_COMMAND=test +notifications: + email: false +script: npm run $NPM_COMMAND +after_success: npm run coveralls diff --git a/xterm.js/AUTHORS b/xterm.js/AUTHORS new file mode 100644 index 0000000..1bd4c87 --- /dev/null +++ b/xterm.js/AUTHORS @@ -0,0 +1,92 @@ +List of xterm.js contributors. Updated before every release. + +Aleksandr Andrienko +Aleksandr Andriienko +Alessandro Nadalin +Alexander Olsson +Alexey Kontsevoy +Anish Athalye +Anthony Lapenna +Antonis Kalipetis +Anton Skshidlevsky +Anton Yurovskykh +Artem Arbatskiy +Austin Robertson +ayapi +Ben Hall +Benjamin Fischer +Bill Church +Bob Reid +bottleofwater +Brian Mock +Bruno Ribeito +Carson Anderson +CHaBou +Christian Budde Christensen +Christof Marti +Christopher Jeffrey +coderaiser +Dan Brown +Daniel Griffen +Daniel Imms +Daniel Risacher +Dan Kaplun +Darin Morrison +dcylabs +Dominik Csapak +Edgar Andrés Margffoy Tuay +Elliot Saba +Exile +Felipe Gasper +ficristo +Gary Ritchie +hiro-su +Ian Lewis +imoses +InDieTasten +irokas +Jakob Gillich +Jean Bruenn +Jeremy Danyow +Joao Moreno +Joao Moreno +Johannes Zellner +Jon Masters +Jörg Breitbart +Justin Mecham +Kirill Merkushev +Luca +Lucian Buzzo +Lukas Drgon +Maël Nison +Marc Dumais +Martin Chloride +Martin Koppehel +Martin Wang +Matt Bierner +Michael Irwin +Mikko Karvonen +mofux +Nicolas Ramz +npezza93 +Oleksandr Andriienko +Paris Kasidiaris +Paris Kasidiaris +Peter Baumgarten +Rick Baker +runarberg +Samuel Williams +Saswat Das +Saul Costa +Shuanglei Tao +Steven Silvester +stuicey +t-amqi +Thanasis Daglis +thomas +Thomas Zilz +Tine Jozelj +Tyler Jewell +Vincent Woo +yutaka +YuviPanda diff --git a/xterm.js/CONTRIBUTING.md b/xterm.js/CONTRIBUTING.md new file mode 100644 index 0000000..8b33d18 --- /dev/null +++ b/xterm.js/CONTRIBUTING.md @@ -0,0 +1,52 @@ +# How to contribute to xterm.js + +- [Opening issues for bug reports or feature requests](#opening-issues) +- [Contributing code](#contributing-code) + +## Opening issues + +The preferred way to report bugs or request features is to use +[GitHub issues](http://github.com/sourcelair/xterm.js/issues). Before +opening an issue, read these pointers. + +### Opening issues effectively + +- Include information about **the browser in which the problem occurred**. Even + if you tested several browsers, and the problem occurred in all of them, + mention this fact in the bug report. Also include browser version numbers and + the operating system that you're on. + +- Mention which release of xterm.js you're using. Preferably, try also with + the current HEAD of the master branch, to ensure the problem has not already been + fixed. + +- Mention precisely what went wrong. What did you expect to happen? What happened instead? Describe the + exact steps a maintainer has to take to make the problem occur. + +- If the problem can not be reproduced in the [demo of xterm.js](README.md#demo), please provide an HTML document that demonstrates the problem. + +- Be polite. Issues with an indignant or belligerent tone tend to be moved to the + bottom of the pile. + +## Contributing code + +- Make sure you have a [GitHub account](https://github.com/join) +- Fork [xterm.js](https://github.com/sourcelair/xterm.js/) + ([how to fork a repo](https://help.github.com/articles/fork-a-repo)) +- Make your changes +- If your changes are easy to test or likely to regress, add tests. Tests go into `test`, directory. +- Follow the general code style of the rest of the project (see below). +- Submit a pull request +([how to create a pull request](https://help.github.com/articles/fork-a-repo)). + Don't put more than one feature/fix in a single pull request. + +By contributing code to xterm.js you + + - agree to license the contributed code under xterm.js' [MIT + license](LICENSE). + + - confirm that you have the right to contribute and license the code + in question. (Either you hold all rights on the code, or the rights + holder has explicitly granted the right to use it like this, + through a compatible open source license or through a direct + agreement with you.) diff --git a/xterm.js/Dockerfile b/xterm.js/Dockerfile new file mode 100644 index 0000000..22556f4 --- /dev/null +++ b/xterm.js/Dockerfile @@ -0,0 +1,19 @@ +FROM node:6 +MAINTAINER Paris Kasidiaris + +# Set the working directory +WORKDIR /usr/src/app + +# Set an entrypoint, to automatically install node modules +ENTRYPOINT ["/bin/bash", "-c", "if [[ ! -d node_modules ]]; then npm install; fi; exec \"${@:0}\";"] +CMD ["npm", "run", "start"] + +# First, install dependencies to improve layer caching +COPY package.json /usr/src/app/ +RUN npm install + +# Add the code +COPY . /usr/src/app + +# Run the tests and build, to make sure everything is working nicely +RUN npm run build && npm run test diff --git a/xterm.js/LICENSE b/xterm.js/LICENSE new file mode 100644 index 0000000..648a90e --- /dev/null +++ b/xterm.js/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2014-2016, SourceLair Private Company (https://www.sourcelair.com) +Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/xterm.js/Procfile b/xterm.js/Procfile new file mode 100644 index 0000000..063b78f --- /dev/null +++ b/xterm.js/Procfile @@ -0,0 +1 @@ +web: npm start diff --git a/xterm.js/README.md b/xterm.js/README.md new file mode 100644 index 0000000..1719efb --- /dev/null +++ b/xterm.js/README.md @@ -0,0 +1,170 @@ +# [![xterm.js logo](logo-full.png)](https://xtermjs.org) + +[![xterm.js build status](https://api.travis-ci.org/xtermjs/xterm.js.svg)](https://travis-ci.org/xtermjs/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/xterm/badge?style=rounded)](https://www.jsdelivr.com/package/npm/xterm) + +Xterm.js is a terminal front-end component written in JavaScript that works in the browser. + +It enables applications to provide fully featured terminals to their users and create great development experiences. + +## Features +- **Text-based application support**: Use xterm.js to work with applications like `bash`, `git` etc. +- **Curses-based application support**: Use xterm.js to work with applications like `vim`, `tmux` etc. +- **Mouse events support**: Xterm.js captures mouse events like click and scroll and passes them to the terminal's back-end controlling process +- **CJK (Chinese, Japanese, Korean) character support**: Xterm.js renders CJK characters seamlessly +- **IME support**: Insert international (including CJK) characters using IME input with your keyboard +- **Self-contained library**: Xterm.js works on its own. It does not require any external libraries like jQuery or React to work +- **Modular, event-based API**: Lets you build addons and themes with ease + +## What xterm.js is not +- Xterm.js is not a terminal application that you can download and use on your computer +- Xterm.js is not `bash`. Xterm.js can be connected to processes like `bash` and let you interact with them (provide input, receive output) + +## Getting Started + +First you need to install the module, we ship exclusively through [npm](https://www.npmjs.com/) so you need that installed and then add xterm.js as a dependency by running: + +``` +npm install +``` + +To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to the head of your html page. Then create a `
    ` onto which xterm can attach itself. + +```html + + + + + + + +
    + + + +``` + +Finally instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`. + +### Importing + +The proposed way to load xterm.js is via the ES6 module syntax. + +```javascript +import { Terminal } from 'xterm'; +``` + +*Note: There are currently no typings for addons so you will need to upcast if using TypeScript, eg. `(xterm).fit()`.* + +### Addons + +Addons are JavaScript modules that extend the `Terminal` prototype with new methods and attributes to provide additional functionality. There are a handful available in the main repository in the `src/addons` directory and you can even write your own, by using xterm.js' public API. + +To use an addon, just import the JavaScript module and pass it to `Terminal`'s `applyAddon` method: + +```javascript +import { Terminal } from xterm; +import * as fit from 'xterm/lib/addons/fit/fit'; + + +Terminal.applyAddon(fit); + +var xterm = new Terminal(); // Instantiate the terminal +xterm.fit(); // Use the `fit` method, provided by the `fit` addon +``` + +## Browser Support + +Since xterm.js is typically implemented as a developer tool, only modern browsers are supported officially. Here is a list of the versions we aim to support: + +- Chrome latest +- Edge latest +- Firefox latest +- Safari latest +- IE11 + +Xterm.js works seamlessly in Electron apps and may even work on earlier versions of the browsers but these are the browsers we strive to keep working. + +## Real-world uses +Xterm.js is used in several world-class applications to provide great terminal experiences. + +- [**SourceLair**](https://www.sourcelair.com/): In-browser IDE that provides its users with fully-featured Linux terminals based on xterm.js +- [**Microsoft Visual Studio Code**](http://code.visualstudio.com/): Modern, versatile and powerful open source code editor that provides an integrated terminal based on xterm.js +- [**ttyd**](https://github.com/tsl0922/ttyd): A command-line tool for sharing terminal over the web, with fully-featured terminal emulation based on xterm.js +- [**Katacoda**](https://www.katacoda.com/): Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies. +- [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE. +- [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams. +- [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by `xterm.js`. +- [**WebSSH2**](https://github.com/billchurch/WebSSH2): A web based SSH2 client using `xterm.js`, socket.io, and ssh2. +- [**Spyder Terminal**](https://github.com/spyder-ide/spyder-terminal): A full fledged system terminal embedded on Spyder IDE. +- [**Cloud Commander**](https://cloudcmd.io "Cloud Commander"): Orthodox web file manager with console and editor. +- [**Codevolve**](https://www.codevolve.com "Codevolve"): Online platform for interactive coding and web development courses. Live container-backed terminal uses `xterm.js`. +- [**RStudio**](https://www.rstudio.com/products/RStudio "RStudio"): RStudio is an integrated development environment (IDE) for R. +- [**Terminal for Atom**](https://github.com/jsmecham/atom-terminal-tab): A simple terminal for the Atom text editor. +- [**Eclipse Orion**](https://orionhub.org): A modern, open source software development environment that runs in the cloud. Code, deploy and run in the cloud. +- [**Gravitational Teleport**](https://github.com/gravitational/teleport): Gravitational Teleport is a modern SSH server for remotely accessing clusters of Linux servers via SSH or HTTPS. +- [**Hexlet**](https://en.hexlet.io): Practical programming courses (JavaScript, PHP, Unix, databases, functional programming). A steady path from the first line of code to the first job. +- [**Selenoid UI**](https://github.com/aerokube/selenoid-ui): Simple UI for the scallable golang implementation of Selenium Hub named Selenoid. We use XTerm for streaming logs over websockets from docker containers. +- [**Portainer**](https://portainer.io): Simple management UI for Docker. +- [**SSHy**](https://github.com/stuicey/SSHy): HTML5 Based SSHv2 Web Client with E2E encryption utilising `xterm.js`, SJCL & websockets. +- [**JupyterLab**](https://github.com/jupyterlab/jupyterlab): An extensible +computational environment for Jupyter, supporting interactive data science and scientific computing across all programming languages. +- [**Theia**](https://github.com/theia-ide/theia): Theia is a cloud & desktop IDE framework implemented in TypeScript. +- [**Opshell**](https://github.com/ricktbaker/opshell) Ops Helper tool to make life easier working with AWS instances across multiple organizations. +- [**Proxmox VE**](https://www.proxmox.com/en/proxmox-ve): Proxmox VE is a complete open-source platform for enterprise virtualization. It uses xterm.js for container terminals and the host shell. +- [**Script Runner**](https://github.com/ioquatix/script-runner): Run scripts (or a shell) in Atom. +- [**Whack Whack Terminal**](https://github.com/Microsoft/WhackWhackTerminal): Terminal emulator for Visual Studio 2017. +- [**VTerm**](https://github.com/vterm/vterm): Extensible terminal emulator based on Electron and React. +- [**electerm**](http://electerm.html5beta.com): electerm is a terminal/ssh/sftp client(mac, win, linux) based on electron/node-pty/xterm. +- [**Kubebox**](https://github.com/astefanutti/kubebox): Terminal console for Kubernetes clusters. + +Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. + +## Demo + +### Linux or macOS + +First, be sure that a C++ compiler such as GCC-C++ or Clang is installed, then run these commands: + +``` +npm install +npm start +``` + +Then open http://0.0.0.0:3000 in a web browser. + +### Windows + +First, ensure [node-gyp](https://github.com/nodejs/node-gyp) is installed and configured correctly, then run these commands. + +``` +npm install +npm start +``` + +Then open http://127.0.0.1:3000 in a web browser. + +*Note: Do not use ConEmu, as it seems to break the demo for some reason.* + +## Releases + +Xterm.js follows a monthly release cycle roughly. + +The existing releases are available at this GitHub repo's [Releases](https://github.com/sourcelair/xterm.js/releases), while the roadmap is available as [Milestones](https://github.com/sourcelair/xterm.js/milestones). + +## Development and Contribution + +Xterm.js is maintained by [SourceLair](https://www.sourcelair.com/) and a few external contributors, but we would love to receive contributions from everyone! + +To contribute either code, documentation or issues to xterm.js please read the [Contributing document](CONTRIBUTING.md) beforehand. The development of xterm.js does not require any special tool. All you need is an editor that supports JavaScript/TypeScript and a browser. You will need Node.js installed locally to get all the features working in the demo. + +## License Agreement + +If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. + +Copyright (c) 2014-2017, SourceLair, Private Company ([www.sourcelair.com](https://www.sourcelair.com/home)) (MIT License) + +Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) diff --git a/xterm.js/demo/app.js b/xterm.js/demo/app.js new file mode 100644 index 0000000..7604e9c --- /dev/null +++ b/xterm.js/demo/app.js @@ -0,0 +1,88 @@ +var express = require('express'); +var app = express(); +var expressWs = require('express-ws')(app); +var os = require('os'); +var pty = require('node-pty'); + +var terminals = {}, + logs = {}; + +app.use('/build', express.static(__dirname + '/../build')); + +app.get('/', function(req, res){ + res.sendFile(__dirname + '/index.html'); +}); + +app.get('/style.css', function(req, res){ + res.sendFile(__dirname + '/style.css'); +}); + +app.get('/dist/bundle.js', function(req, res){ + res.sendFile(__dirname + '/dist/bundle.js'); +}); + +app.get('/dist/bundle.js.map', function(req, res){ + res.sendFile(__dirname + '/dist/bundle.js.map'); +}); + +app.post('/terminals', function (req, res) { + var cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], { + name: 'xterm-color', + cols: cols || 80, + rows: rows || 24, + cwd: process.env.PWD, + env: process.env + }); + + console.log('Created terminal with PID: ' + term.pid); + terminals[term.pid] = term; + logs[term.pid] = ''; + term.on('data', function(data) { + logs[term.pid] += data; + }); + res.send(term.pid.toString()); + res.end(); +}); + +app.post('/terminals/:pid/size', function (req, res) { + var pid = parseInt(req.params.pid), + cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = terminals[pid]; + + term.resize(cols, rows); + console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.'); + res.end(); +}); + +app.ws('/terminals/:pid', function (ws, req) { + var term = terminals[parseInt(req.params.pid)]; + console.log('Connected to terminal ' + term.pid); + ws.send(logs[term.pid]); + + term.on('data', function(data) { + try { + ws.send(data); + } catch (ex) { + // The WebSocket is not open, ignore + } + }); + ws.on('message', function(msg) { + term.write(msg); + }); + ws.on('close', function () { + term.kill(); + console.log('Closed terminal ' + term.pid); + // Clean things up + delete terminals[term.pid]; + delete logs[term.pid]; + }); +}); + +var port = process.env.PORT || 3000, + host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0'; + +console.log('App listening to http://' + host + ':' + port); +app.listen(port, host); diff --git a/xterm.js/demo/index.html b/xterm.js/demo/index.html new file mode 100644 index 0000000..93399f9 --- /dev/null +++ b/xterm.js/demo/index.html @@ -0,0 +1,70 @@ + + + + xterm.js demo + + + + + + + +

    xterm.js: xterm, in the browser

    +
    +
    +

    Actions

    +

    + + +

    +
    +
    +

    Options

    +

    + +

    +

    + +

    +

    + +

    +

    + +

    +

    + +

    +
    +

    Size

    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +

    Attention: The demo is a barebones implementation and is designed for xterm.js evaluation purposes only. Exposing the demo to the public as is would introduce security risks for the host.

    + + + diff --git a/xterm.js/demo/main.js b/xterm.js/demo/main.js new file mode 100644 index 0000000..95b15a0 --- /dev/null +++ b/xterm.js/demo/main.js @@ -0,0 +1,179 @@ +import * as Terminal from '../build/xterm'; +import * as attach from '../build/addons/attach/attach'; +import * as fit from '../build/addons/fit/fit'; +import * as fullscreen from '../build/addons/fullscreen/fullscreen'; +import * as search from '../build/addons/search/search'; +import * as winptyCompat from '../build/addons/winptyCompat/winptyCompat'; + + +Terminal.applyAddon(attach); +Terminal.applyAddon(fit); +Terminal.applyAddon(fullscreen); +Terminal.applyAddon(search); +Terminal.applyAddon(winptyCompat); + + +var term, + protocol, + socketURL, + socket, + pid; + +var terminalContainer = document.getElementById('terminal-container'), + actionElements = { + findNext: document.querySelector('#find-next'), + findPrevious: document.querySelector('#find-previous') + }, + optionElements = { + cursorBlink: document.querySelector('#option-cursor-blink'), + cursorStyle: document.querySelector('#option-cursor-style'), + scrollback: document.querySelector('#option-scrollback'), + tabstopwidth: document.querySelector('#option-tabstopwidth'), + bellStyle: document.querySelector('#option-bell-style') + }, + colsElement = document.getElementById('cols'), + rowsElement = document.getElementById('rows'); + +function setTerminalSize() { + var cols = parseInt(colsElement.value, 10); + var rows = parseInt(rowsElement.value, 10); + var viewportElement = document.querySelector('.xterm-viewport'); + var scrollBarWidth = viewportElement.offsetWidth - viewportElement.clientWidth; + var width = (cols * term.renderer.dimensions.actualCellWidth + 20 /*room for scrollbar*/).toString() + 'px'; + var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px'; + + terminalContainer.style.width = width; + terminalContainer.style.height = height; + term.resize(cols, rows); +} + +colsElement.addEventListener('change', setTerminalSize); +rowsElement.addEventListener('change', setTerminalSize); + +actionElements.findNext.addEventListener('keypress', function (e) { + if (e.key === "Enter") { + e.preventDefault(); + term.findNext(actionElements.findNext.value); + } +}); +actionElements.findPrevious.addEventListener('keypress', function (e) { + if (e.key === "Enter") { + e.preventDefault(); + term.findPrevious(actionElements.findPrevious.value); + } +}); + +optionElements.cursorBlink.addEventListener('change', function () { + term.setOption('cursorBlink', optionElements.cursorBlink.checked); +}); +optionElements.cursorStyle.addEventListener('change', function () { + term.setOption('cursorStyle', optionElements.cursorStyle.value); +}); +optionElements.bellStyle.addEventListener('change', function () { + term.setOption('bellStyle', optionElements.bellStyle.value); +}); +optionElements.scrollback.addEventListener('change', function () { + term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); +}); +optionElements.tabstopwidth.addEventListener('change', function () { + term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); +}); + +createTerminal(); + +function createTerminal() { + // Clean terminal + while (terminalContainer.children.length) { + terminalContainer.removeChild(terminalContainer.children[0]); + } + term = new Terminal({ + cursorBlink: optionElements.cursorBlink.checked, + scrollback: parseInt(optionElements.scrollback.value, 10), + tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10) + }); + window.term = term; // Expose `term` to window for debugging purposes + term.on('resize', function (size) { + if (!pid) { + return; + } + var cols = size.cols, + rows = size.rows, + url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; + + fetch(url, {method: 'POST'}); + }); + protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; + socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/'; + + term.open(terminalContainer); + term.winptyCompatInit(); + term.fit(); + term.focus(); + + // fit is called within a setTimeout, cols and rows need this. + setTimeout(function () { + colsElement.value = term.cols; + rowsElement.value = term.rows; + + // Set terminal size again to set the specific dimensions on the demo + setTerminalSize(); + + fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { + + res.text().then(function (processId) { + pid = processId; + socketURL += processId; + socket = new WebSocket(socketURL); + socket.onopen = runRealTerminal; + socket.onclose = runFakeTerminal; + socket.onerror = runFakeTerminal; + }); + }); + }, 0); +} + +function runRealTerminal() { + term.attach(socket); + term._initialized = true; +} + +function runFakeTerminal() { + if (term._initialized) { + return; + } + + term._initialized = true; + + var shellprompt = '$ '; + + term.prompt = function () { + term.write('\r\n' + shellprompt); + }; + + term.writeln('Welcome to xterm.js'); + term.writeln('This is a local terminal emulation, without a real terminal in the back-end.'); + term.writeln('Type some keys and commands to play around.'); + term.writeln(''); + term.prompt(); + + term.on('key', function (key, ev) { + var printable = ( + !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey + ); + + if (ev.keyCode == 13) { + term.prompt(); + } else if (ev.keyCode == 8) { + // Do not delete the prompt + if (term.x > 2) { + term.write('\b \b'); + } + } else if (printable) { + term.write(key); + } + }); + + term.on('paste', function (data, ev) { + term.write(data); + }); +} diff --git a/xterm.js/demo/style.css b/xterm.js/demo/style.css new file mode 100644 index 0000000..1ab5f61 --- /dev/null +++ b/xterm.js/demo/style.css @@ -0,0 +1,16 @@ +body { + font-family: helvetica, sans-serif, arial; + font-size: 1em; + color: #111; +} + +h1 { + text-align: center; +} + +#terminal-container { + width: 800px; + height: 450px; + margin: 0 auto; + padding: 2px; +} diff --git a/xterm.js/docker-compose.yml b/xterm.js/docker-compose.yml new file mode 100644 index 0000000..03e88fb --- /dev/null +++ b/xterm.js/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3" + +services: + web: + build: . + volumes: + - ./:/usr/src/app + ports: + - ${XTERMJS_PORT:3000}:3000 diff --git a/xterm.js/fixtures/escape_sequence_files/NOTES b/xterm.js/fixtures/escape_sequence_files/NOTES new file mode 100644 index 0000000..bcadcb4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/NOTES @@ -0,0 +1,21 @@ +All tests are made for 80x25 terminal. Make sure to run tests with 80x25. + +Create .text files from xterm (expected output) +- open xterm +- resize xterm to 80x25 +- run `python run_tests.py` +- copy & paste whole window output into editor +- add 26th empty line (due to line handling in toString) - not a bug, a feature ;) +- advance to next test with ^D + + +Known problems +############## + + +t0031-HBP: + - no documentation at all about CSIj found - skipping + +t0050-ICH: + - bug in xterm? (cant ICH last real char, always sticks to last col) + - text used from https://github.com/MarkLodato/vt100-parser/blob/master/test/t0050-ICH.text diff --git a/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.in b/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.in new file mode 100644 index 0000000..2f36543 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.in @@ -0,0 +1,6 @@ + !"#$%&'()*+,-./ +0123456789:;<=>? +@ABCDEFGHIJKLMNO +PQRSTUVWXYZ[\]^_ +`abcdefghijklmno +pqrstuvwxyz{|}~ diff --git a/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.text b/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.text new file mode 100644 index 0000000..421f5a7 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0001-all_printable.text @@ -0,0 +1,25 @@ + !"#$%&'()*+,-./ +0123456789:;<=>? +@ABCDEFGHIJKLMNO +PQRSTUVWXYZ[\]^_ +`abcdefghijklmno +pqrstuvwxyz{|}~ + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0002-history.in b/xterm.js/fixtures/escape_sequence_files/t0002-history.in new file mode 100644 index 0000000..3bc7fbc --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0002-history.in @@ -0,0 +1,95 @@ + +! +" +# +$ +% +& +' +( +) +* ++ +, +- +. +/ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +: +; +< += +> +? +@ +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +[ +\ +] +^ +_ +` +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +{ +| +} +~ diff --git a/xterm.js/fixtures/escape_sequence_files/t0002-history.text b/xterm.js/fixtures/escape_sequence_files/t0002-history.text new file mode 100644 index 0000000..39bdf52 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0002-history.text @@ -0,0 +1,25 @@ +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +{ +| +} +~ + diff --git a/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.in b/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.in new file mode 100644 index 0000000..a679175 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.in @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyz0123456789 \ No newline at end of file diff --git a/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.text b/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.text new file mode 100644 index 0000000..097318d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0002j-simple_string.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrstuvwxyz0123456789 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.in b/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.in new file mode 100644 index 0000000..d110db8 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.in @@ -0,0 +1,83 @@ +a +ab +abc +abcd +abcde +abcdef +abcdefg +abcdefgh +abcdefghi +abcdefghij +abcdefghijk +abcdefghijkl +abcdefghijklm +abcdefghijklmn +abcdefghijklmno +abcdefghijklmnop +abcdefghijklmnopq +abcdefghijklmnopqr +abcdefghijklmnopqrs +abcdefghijklmnopqrst +abcdefghijklmnopqrstu +abcdefghijklmnopqrstuv +abcdefghijklmnopqrstuvw +abcdefghijklmnopqrstuvwx +abcdefghijklmnopqrstuvwxy +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyzA +abcdefghijklmnopqrstuvwxyzAB +abcdefghijklmnopqrstuvwxyzABC +abcdefghijklmnopqrstuvwxyzABCD +abcdefghijklmnopqrstuvwxyzABCDE +abcdefghijklmnopqrstuvwxyzABCDEF +abcdefghijklmnopqrstuvwxyzABCDEFG +abcdefghijklmnopqrstuvwxyzABCDEFGH +abcdefghijklmnopqrstuvwxyzABCDEFGHI +abcdefghijklmnopqrstuvwxyzABCDEFGHIJ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJK +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890a +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890ab +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abc +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcd +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcde +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdef +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghij +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijk +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmn +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrs +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrst diff --git a/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.text b/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.text new file mode 100644 index 0000000..fbe1c56 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0003-line_wrap.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890a +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890ab +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abc +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcd +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcde +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdef +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghij +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijk +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmn +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +r +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +rs +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +rst + diff --git a/xterm.js/fixtures/escape_sequence_files/t0003j-LF.in b/xterm.js/fixtures/escape_sequence_files/t0003j-LF.in new file mode 100644 index 0000000..9f52852 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0003j-LF.in @@ -0,0 +1,26 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 diff --git a/xterm.js/fixtures/escape_sequence_files/t0003j-LF.text b/xterm.js/fixtures/escape_sequence_files/t0003j-LF.text new file mode 100644 index 0000000..a6210e1 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0003j-LF.text @@ -0,0 +1,25 @@ +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 + diff --git a/xterm.js/fixtures/escape_sequence_files/t0004-LF.in b/xterm.js/fixtures/escape_sequence_files/t0004-LF.in new file mode 100644 index 0000000..4f4aa53 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0004-LF.in @@ -0,0 +1,83 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +0 +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t diff --git a/xterm.js/fixtures/escape_sequence_files/t0004-LF.text b/xterm.js/fixtures/escape_sequence_files/t0004-LF.text new file mode 100644 index 0000000..3756aca --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0004-LF.text @@ -0,0 +1,25 @@ +7 +8 +9 +0 +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t + diff --git a/xterm.js/fixtures/escape_sequence_files/t0004j-CR.in b/xterm.js/fixtures/escape_sequence_files/t0004j-CR.in new file mode 100644 index 0000000..d40432d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0004j-CR.in @@ -0,0 +1,7 @@ +1 x + 2 x + 3 x + 4 x + 5 x + 6 x + 7 x \ No newline at end of file diff --git a/xterm.js/fixtures/escape_sequence_files/t0004j-CR.text b/xterm.js/fixtures/escape_sequence_files/t0004j-CR.text new file mode 100644 index 0000000..beb0e35 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0004j-CR.text @@ -0,0 +1,25 @@ +x +x2 +x 3 +x 4 +x 5 +x 6 +x 7 + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0005-CR.in b/xterm.js/fixtures/escape_sequence_files/t0005-CR.in new file mode 100644 index 0000000..d5f545a --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0005-CR.in @@ -0,0 +1,82 @@ +b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a + b a diff --git a/xterm.js/fixtures/escape_sequence_files/t0005-CR.text b/xterm.js/fixtures/escape_sequence_files/t0005-CR.text new file mode 100644 index 0000000..dfcc049 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0005-CR.text @@ -0,0 +1,25 @@ +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b +a b + +a + +ab + diff --git a/xterm.js/fixtures/escape_sequence_files/t0006-IND.in b/xterm.js/fixtures/escape_sequence_files/t0006-IND.in new file mode 100644 index 0000000..614552f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0006-IND.in @@ -0,0 +1 @@ +aDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDtDuDvDwDxDyDzDADBDCDDDEDFDGDHDIDJDKDLDMDNDODPDQDRDSDTDUDVDWDXDYDZD0D1D2D3D4D5D6D7D8D9D0DaDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDt diff --git a/xterm.js/fixtures/escape_sequence_files/t0006-IND.text b/xterm.js/fixtures/escape_sequence_files/t0006-IND.text new file mode 100644 index 0000000..8c69a7f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0006-IND.text @@ -0,0 +1,25 @@ + 7 + 8 + 9 + 0 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + diff --git a/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.in b/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.in new file mode 100644 index 0000000..73d19c5 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.in @@ -0,0 +1,8 @@ +0 space: +1 space: +2 space: +3 space: +70 space: +71 space: +72 space: +73 space: diff --git a/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.text b/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.text new file mode 100644 index 0000000..f46caee --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0007-space_at_end.text @@ -0,0 +1,25 @@ +0 space: +1 space: +2 space: +3 space: +70 space: +71 space: +72 space: + +73 space: + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0008-BS.in b/xterm.js/fixtures/escape_sequence_files/t0008-BS.in new file mode 100644 index 0000000..0980d87 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0008-BS.in @@ -0,0 +1,7 @@ +abcdefghijklmnopqrstuvwxyz! +abc@ +# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop$ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq% +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr^ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrs& diff --git a/xterm.js/fixtures/escape_sequence_files/t0008-BS.text b/xterm.js/fixtures/escape_sequence_files/t0008-BS.text new file mode 100644 index 0000000..77d1710 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0008-BS.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrst!vwxyz +@bc +# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghij$lmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghij%lmnopq +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +^ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +&s + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0009-NEL.in b/xterm.js/fixtures/escape_sequence_files/t0009-NEL.in new file mode 100644 index 0000000..b541ec4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0009-NEL.in @@ -0,0 +1 @@ +aEabEabcEabcdEabcdeEabcdefEabcdefgEabcdefghEabcdefghiEabcdefghijEabcdefghijkEabcdefghijklEabcdefghijklmEabcdefghijklmnEabcdefghijklmnoEabcdefghijklmnopEabcdefghijklmnopqEabcdefghijklmnopqrEabcdefghijklmnopqrsEabcdefghijklmnopqrstEabcdefghijklmnopqrstuEabcdefghijklmnopqrstuvEabcdefghijklmnopqrstuvwEabcdefghijklmnopqrstuvwxEabcdefghijklmnopqrstuvwxyEabcdefghijklmnopqrstuvwxyzEabcdefghijklmnopqrstuvwxyzAEabcdefghijklmnopqrstuvwxyzABEabcdefghijklmnopqrstuvwxyzABCEabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEEabcdefghijklmnopqrstuvwxyzABCDEFEabcdefghijklmnopqrstuvwxyzABCDEFGEabcdefghijklmnopqrstuvwxyzABCDEFGHEabcdefghijklmnopqrstuvwxyzABCDEFGHIEabcdefghijklmnopqrstuvwxyzABCDEFGHIJEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQREabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890EabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890aEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdeEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghiEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijkEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnoEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrsEabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrst diff --git a/xterm.js/fixtures/escape_sequence_files/t0009-NEL.text b/xterm.js/fixtures/escape_sequence_files/t0009-NEL.text new file mode 100644 index 0000000..fbe1c56 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0009-NEL.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890a +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890ab +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abc +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcd +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcde +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdef +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghij +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijk +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmn +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +r +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +rs +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +rst + diff --git a/xterm.js/fixtures/escape_sequence_files/t0010-RI.in b/xterm.js/fixtures/escape_sequence_files/t0010-RI.in new file mode 100644 index 0000000..c2aeb67 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0010-RI.in @@ -0,0 +1,10 @@ +a +b +c +dMeMfMg +h +i +j....................................................................kMlMmMn + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0010-RI.text b/xterm.js/fixtures/escape_sequence_files/t0010-RI.text new file mode 100644 index 0000000..5320654 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0010-RI.text @@ -0,0 +1,25 @@ +a g n +h f m +ie l +j....................................................................k + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.in b/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.in new file mode 100644 index 0000000..14da12d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.in @@ -0,0 +1,47 @@ +And the third. + + + + + + + + + + + + + + + + + + + + +This should be the last line. +This one should be lost. +This one's a goner, too. MMMMMMMMMMMMMMMMMMMMMMMMThis is second line. MThis should be the first line. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.text b/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.text new file mode 100644 index 0000000..21cb1cf --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0011-RI_scroll.text @@ -0,0 +1,25 @@ +This should be the first line. +This is second line. +And the third. + + + + + + + + + + + + + + + + + + + + +This should be the last line. +This one should be lost. diff --git a/xterm.js/fixtures/escape_sequence_files/t0012-VT.in b/xterm.js/fixtures/escape_sequence_files/t0012-VT.in new file mode 100644 index 0000000..ee56208 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0012-VT.in @@ -0,0 +1 @@ +a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t \ No newline at end of file diff --git a/xterm.js/fixtures/escape_sequence_files/t0012-VT.text b/xterm.js/fixtures/escape_sequence_files/t0012-VT.text new file mode 100644 index 0000000..8c69a7f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0012-VT.text @@ -0,0 +1,25 @@ + 7 + 8 + 9 + 0 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + diff --git a/xterm.js/fixtures/escape_sequence_files/t0013-FF.in b/xterm.js/fixtures/escape_sequence_files/t0013-FF.in new file mode 100644 index 0000000..01198c2 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0013-FF.in @@ -0,0 +1 @@ +a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t diff --git a/xterm.js/fixtures/escape_sequence_files/t0013-FF.text b/xterm.js/fixtures/escape_sequence_files/t0013-FF.text new file mode 100644 index 0000000..16c9c2b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0013-FF.text @@ -0,0 +1,25 @@ + 8 + 9 + 0 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0014-CAN.in b/xterm.js/fixtures/escape_sequence_files/t0014-CAN.in new file mode 100644 index 0000000..64bae4a --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0014-CAN.in @@ -0,0 +1,8 @@ +abcdDefgh +abcdDefgh +abcd!Defgh +abcd!*Defgh +abcd[Defgh +abcd[!Defgh +abcd[2Defgh +abcd[*2;Defgh diff --git a/xterm.js/fixtures/escape_sequence_files/t0014-CAN.text b/xterm.js/fixtures/escape_sequence_files/t0014-CAN.text new file mode 100644 index 0000000..77a38fa --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0014-CAN.text @@ -0,0 +1,25 @@ +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0015-SUB.in b/xterm.js/fixtures/escape_sequence_files/t0015-SUB.in new file mode 100644 index 0000000..1bd237f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0015-SUB.in @@ -0,0 +1,8 @@ +abcdDefgh +abcdDefgh +abcd!Defgh +abcd!*Defgh +abcd[Defgh +abcd[!Defgh +abcd[2Defgh +abcd[*2;Defgh diff --git a/xterm.js/fixtures/escape_sequence_files/t0015-SUB.text b/xterm.js/fixtures/escape_sequence_files/t0015-SUB.text new file mode 100644 index 0000000..77a38fa --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0015-SUB.text @@ -0,0 +1,25 @@ +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh +abcdDefgh + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0016-SU.in b/xterm.js/fixtures/escape_sequence_files/t0016-SU.in new file mode 100644 index 0000000..7e52573 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0016-SU.in @@ -0,0 +1,17 @@ +HelloGoodbye + +UpDown +x + +-----------------------------------------------------------------------------x +------------------------------------------------------------------------------x +-------------------------------------------------------------------------------x +--------------------------------------------------------------------------------x +---------------------------------------------------------------------------------x +.............................................................................x +..............................................................................x +...............................................................................x +................................................................................x +.................................................................................x + +The End. diff --git a/xterm.js/fixtures/escape_sequence_files/t0016-SU.text b/xterm.js/fixtures/escape_sequence_files/t0016-SU.text new file mode 100644 index 0000000..2323fa3 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0016-SU.text @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + +The End. + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0017-SD.in b/xterm.js/fixtures/escape_sequence_files/t0017-SD.in new file mode 100644 index 0000000..ce76440 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0017-SD.in @@ -0,0 +1,54 @@ +A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X +a + b + c + d + e + f + g + h +------------------------------------------------------------------------------1 + + +-------------------------------------------------------------------------------2 + + +--------------------------------------------------------------------------------3 + + +---------------------------------------------------------------------------------4 + + +..............................................................................5 + + +...............................................................................6 + + +................................................................................7 + + +.................................................................................8 diff --git a/xterm.js/fixtures/escape_sequence_files/t0017-SD.text b/xterm.js/fixtures/escape_sequence_files/t0017-SD.text new file mode 100644 index 0000000..6e39cd9 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0017-SD.text @@ -0,0 +1,25 @@ + + +a + b + f + g + h 1 + + 2 + + +3 + + +-4------------------------------------------------------------------------------ + + 5 + + 6 + + 7 + + +8............................................................................... + diff --git a/xterm.js/fixtures/escape_sequence_files/t0020-CUF.in b/xterm.js/fixtures/escape_sequence_files/t0020-CUF.in new file mode 100644 index 0000000..9df6cd7 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0020-CUF.in @@ -0,0 +1,14 @@ +abcdefghijkl +abcdefghijkl +abcdefghijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +x +x +abcd diff --git a/xterm.js/fixtures/escape_sequence_files/t0020-CUF.text b/xterm.js/fixtures/escape_sequence_files/t0020-CUF.text new file mode 100644 index 0000000..b868261 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0020-CUF.text @@ -0,0 +1,25 @@ +abcdefg hijkl +abcdefg hijkl +abcdefg hijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +r @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ + x + x +abcd + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0021-CUB.in b/xterm.js/fixtures/escape_sequence_files/t0021-CUB.in new file mode 100644 index 0000000..b07f753 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0021-CUB.in @@ -0,0 +1,8 @@ +abcdefg!@ +abcdefg!@ +abcdefg!@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr@ +x diff --git a/xterm.js/fixtures/escape_sequence_files/t0021-CUB.text b/xterm.js/fixtures/escape_sequence_files/t0021-CUB.text new file mode 100644 index 0000000..9a1b385 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0021-CUB.text @@ -0,0 +1,25 @@ +abcdef!@ +!@cdefg +abcde!@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmn@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@q +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +@ +x + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0022-CUU.in b/xterm.js/fixtures/escape_sequence_files/t0022-CUU.in new file mode 100644 index 0000000..4c47f30 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0022-CUU.in @@ -0,0 +1,25 @@ +a +b +c +defg +h +i +j....................................................................klmn + + + + + + + + + + + +0123 + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0022-CUU.text b/xterm.js/fixtures/escape_sequence_files/t0022-CUU.text new file mode 100644 index 0000000..b786ade --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0022-CUU.text @@ -0,0 +1,25 @@ +a g n +h f m +ie l +j....................................................................k + + 3 + + + 2 + + 1 +0 + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.in b/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.in new file mode 100644 index 0000000..e0c9243 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.in @@ -0,0 +1,50 @@ +This is the first line. +This is the second line. +And the third. +This line should be deleted. + + + + + + + + + + + + + + + + + + + + + +Penultimate line. +This should be the last line. I have gone up all the way... + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.text b/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.text new file mode 100644 index 0000000..96b8726 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0023-CUU_scroll.text @@ -0,0 +1,25 @@ +I have gone up all the way... +This line should be deleted. + + + + + + + + + + + + + + + + + + + + + +Penultimate line. +This should be the last line. diff --git a/xterm.js/fixtures/escape_sequence_files/t0024-CUD.in b/xterm.js/fixtures/escape_sequence_files/t0024-CUD.in new file mode 100644 index 0000000..e971bbe --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0024-CUD.in @@ -0,0 +1,24 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x012345Bottom line. ABCDE  diff --git a/xterm.js/fixtures/escape_sequence_files/t0024-CUD.text b/xterm.js/fixtures/escape_sequence_files/t0024-CUD.text new file mode 100644 index 0000000..622c0b0 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0024-CUD.text @@ -0,0 +1,25 @@ +b 1 +c 2 +d 3 +e +f 4 +g +h +i 5 +j +k +l +m +n +o +p +q A +r B +s C +t D +u E +v +w +x + Bottom line. + diff --git a/xterm.js/fixtures/escape_sequence_files/t0025-CUP.in b/xterm.js/fixtures/escape_sequence_files/t0025-CUP.in new file mode 100644 index 0000000..b62631e --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0025-CUP.in @@ -0,0 +1 @@ +abcdefg diff --git a/xterm.js/fixtures/escape_sequence_files/t0025-CUP.text b/xterm.js/fixtures/escape_sequence_files/t0025-CUP.text new file mode 100644 index 0000000..44dc619 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0025-CUP.text @@ -0,0 +1,25 @@ + b + + +e + + + + + d + + + + + + + + + + g + + + + + f + diff --git a/xterm.js/fixtures/escape_sequence_files/t0026-CNL.in b/xterm.js/fixtures/escape_sequence_files/t0026-CNL.in new file mode 100644 index 0000000..8318682 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0026-CNL.in @@ -0,0 +1,2 @@ +abcdefghi +-------------------------------------------------------------------------abcdefghijlast line diff --git a/xterm.js/fixtures/escape_sequence_files/t0026-CNL.text b/xterm.js/fixtures/escape_sequence_files/t0026-CNL.text new file mode 100644 index 0000000..61ac27e --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0026-CNL.text @@ -0,0 +1,25 @@ +def + + + + +ghi +-------------------------------------------------------------------------abcdefg +hij + + + + + + + + + + + + + + + +last line + diff --git a/xterm.js/fixtures/escape_sequence_files/t0027-CPL.in b/xterm.js/fixtures/escape_sequence_files/t0027-CPL.in new file mode 100644 index 0000000..edafc49 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0027-CPL.in @@ -0,0 +1,6 @@ +erasedreplacement + + +line fourline two + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0027-CPL.text b/xterm.js/fixtures/escape_sequence_files/t0027-CPL.text new file mode 100644 index 0000000..847ed7c --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0027-CPL.text @@ -0,0 +1,25 @@ +replacement +line two + +line four + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0030-HPR.in b/xterm.js/fixtures/escape_sequence_files/t0030-HPR.in new file mode 100644 index 0000000..485720f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0030-HPR.in @@ -0,0 +1,14 @@ +abcdefghijkl +abcdefghijkl +abcdefghijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm@ +x +x +abcd diff --git a/xterm.js/fixtures/escape_sequence_files/t0030-HPR.text b/xterm.js/fixtures/escape_sequence_files/t0030-HPR.text new file mode 100644 index 0000000..b868261 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0030-HPR.text @@ -0,0 +1,25 @@ +abcdefg hijkl +abcdefg hijkl +abcdefg hijkl +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +r @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklm @ + x + x +abcd + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0031-HPB.in_ b/xterm.js/fixtures/escape_sequence_files/t0031-HPB.in_ new file mode 100644 index 0000000..13de738 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0031-HPB.in_ @@ -0,0 +1,8 @@ +abcdefg!@ +abcdefg!@ +abcdefg!@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqr@ +x diff --git a/xterm.js/fixtures/escape_sequence_files/t0031-HPB.text b/xterm.js/fixtures/escape_sequence_files/t0031-HPB.text new file mode 100644 index 0000000..9ec4087 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0031-HPB.text @@ -0,0 +1,25 @@ +abcdefg!@ +abcdefg!@ +abcdefg!@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmno@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq +r@ +x + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0032-VPB.in b/xterm.js/fixtures/escape_sequence_files/t0032-VPB.in new file mode 100644 index 0000000..30dd002 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0032-VPB.in @@ -0,0 +1,25 @@ +a +b +c +defg +h +i +j....................................................................klmn + + + + + + + + + + + +0123 + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0032-VPB.text b/xterm.js/fixtures/escape_sequence_files/t0032-VPB.text new file mode 100644 index 0000000..15f0d67 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0032-VPB.text @@ -0,0 +1,25 @@ +b +c +defg +h +i +j....................................................................klmn + + + + + + + + + + + +0123 + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.in b/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.in new file mode 100644 index 0000000..f58db4b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.in @@ -0,0 +1,50 @@ +This is the first line. +This is the second line. +And the third. +This line should be deleted. + + + + + + + + + + + + + + + + + + + + + +Penultimate line. +This should be the last line. I have gone up all the way... + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.text b/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.text new file mode 100644 index 0000000..0b20185 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0033-VPB_scroll.text @@ -0,0 +1,25 @@ +I have gone up all the way... + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0034-VPR.in b/xterm.js/fixtures/escape_sequence_files/t0034-VPR.in new file mode 100644 index 0000000..b9dc145 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0034-VPR.in @@ -0,0 +1,24 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x012345Bottom line. ABCDE  diff --git a/xterm.js/fixtures/escape_sequence_files/t0034-VPR.text b/xterm.js/fixtures/escape_sequence_files/t0034-VPR.text new file mode 100644 index 0000000..622c0b0 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0034-VPR.text @@ -0,0 +1,25 @@ +b 1 +c 2 +d 3 +e +f 4 +g +h +i 5 +j +k +l +m +n +o +p +q A +r B +s C +t D +u E +v +w +x + Bottom line. + diff --git a/xterm.js/fixtures/escape_sequence_files/t0035-HVP.in b/xterm.js/fixtures/escape_sequence_files/t0035-HVP.in new file mode 100644 index 0000000..781dfdb --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0035-HVP.in @@ -0,0 +1 @@ +abcdefg diff --git a/xterm.js/fixtures/escape_sequence_files/t0035-HVP.text b/xterm.js/fixtures/escape_sequence_files/t0035-HVP.text new file mode 100644 index 0000000..44dc619 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0035-HVP.text @@ -0,0 +1,25 @@ + b + + +e + + + + + d + + + + + + + + + + g + + + + + f + diff --git a/xterm.js/fixtures/escape_sequence_files/t0040-REP.in b/xterm.js/fixtures/escape_sequence_files/t0040-REP.in new file mode 100644 index 0000000..f1abf45 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0040-REP.in @@ -0,0 +1,7 @@ +x +< +abcdefg +abcdefg! + @ + . + ?- diff --git a/xterm.js/fixtures/escape_sequence_files/t0040-REP.text b/xterm.js/fixtures/escape_sequence_files/t0040-REP.text new file mode 100644 index 0000000..cae1ef9 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0040-REP.text @@ -0,0 +1,25 @@ +xxxxxx +< +abcdefg +abcd!fg + @@@@@@@@@ +@@@@@@@@@@@@ + . +.... + ? +?- + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0050-ICH.in b/xterm.js/fixtures/escape_sequence_files/t0050-ICH.in new file mode 100644 index 0000000..a629f20 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0050-ICH.in @@ -0,0 +1,23 @@ +abcdefghijklmnopqrstuvwxyz[15@ +abcdefghijklmnopqrstuvwxyz[80@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[17@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[18@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[19@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[20@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[21@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop[5@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq[5@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq[5@ +ICH at end:[5@ + +abcdefghijklmnopqrstuvwxyz[15@!@# +abcdefghijklmnopqrstuvwxyz[80@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[17@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[18@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[19@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[20@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789[21@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop[5@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq[5@!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopq[5@!@# +ICH at end:[5@!@# diff --git a/xterm.js/fixtures/escape_sequence_files/t0050-ICH.text b/xterm.js/fixtures/escape_sequence_files/t0050-ICH.text new file mode 100644 index 0000000..d787b8d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0050-ICH.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrstu +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 89 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 89 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 8 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW XYZ01234567890abcdefghijkl +ICH at end: + +abcdefghijklmnopqrstu!@# vwxyz +abcdefghijklmnopqrstu!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567!@# 89 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567!@# 89 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567!@# 8 +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567!@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop! +@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnop! +@# +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW!@# XYZ01234567890abcdefghijkl +ICH at end:!@# + diff --git a/xterm.js/fixtures/escape_sequence_files/t0051-IL.in b/xterm.js/fixtures/escape_sequence_files/t0051-IL.in new file mode 100644 index 0000000..e66a242 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0051-IL.in @@ -0,0 +1,23 @@ +ab +cd +ef +gh +ij +kl +mn +opQRST +1 +2 +3 +4 +5------------------------------------------------------------------------------ab +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 diff --git a/xterm.js/fixtures/escape_sequence_files/t0051-IL.text b/xterm.js/fixtures/escape_sequence_files/t0051-IL.text new file mode 100644 index 0000000..2d0f595 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0051-IL.text @@ -0,0 +1,25 @@ + +ef +gh +ij +QR +kl +mn +op +1 +2 +3 +b +4------------------------------------------------------------------------------a +5 +6 +7 +8 +9 +10 + + + +11 +12 + diff --git a/xterm.js/fixtures/escape_sequence_files/t0052-DL.in b/xterm.js/fixtures/escape_sequence_files/t0052-DL.in new file mode 100644 index 0000000..b5a5fe0 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0052-DL.in @@ -0,0 +1,15 @@ +a +b +c +d +e +f +g +hijklmnop + + +1 +2 +3 +4 x + diff --git a/xterm.js/fixtures/escape_sequence_files/t0052-DL.text b/xterm.js/fixtures/escape_sequence_files/t0052-DL.text new file mode 100644 index 0000000..10d24aa --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0052-DL.text @@ -0,0 +1,25 @@ +a +b +c +ijklmnop +g +h +1 +x +4 + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0053-DCH.in b/xterm.js/fixtures/escape_sequence_files/t0053-DCH.in new file mode 100644 index 0000000..d1f8807 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0053-DCH.in @@ -0,0 +1,12 @@ +abcdefghijklmnopqrstuvwxyz> +abcdefghijklmnopqrstuvwxyz>! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>! +------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +---------------------------------------------------------------------------------? +.............................................................................. +............................................................................... +............................................................................... +................................................................................. diff --git a/xterm.js/fixtures/escape_sequence_files/t0053-DCH.text b/xterm.js/fixtures/escape_sequence_files/t0053-DCH.text new file mode 100644 index 0000000..75c6b3b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0053-DCH.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqr>vwxyz +abcdefghijklmnopqr>!wxyz +>!mnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh +abcdefghijklmnopqrstuvwxyz0123456789ABC>!PQRSTUVWXYZ0123456789abcdefgh +------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------- +-? +.............................................................................. +............................................................................... +............................................................................... +................................................................................ +. + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0054-ECH.in b/xterm.js/fixtures/escape_sequence_files/t0054-ECH.in new file mode 100644 index 0000000..03a00d8 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0054-ECH.in @@ -0,0 +1,12 @@ +abcdefghijklmnopqrstuvwxyz> +abcdefghijklmnopqrstuvwxyz>! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>! +------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +---------------------------------------------------------------------------------? +.............................................................................. +............................................................................... +............................................................................... +................................................................................. diff --git a/xterm.js/fixtures/escape_sequence_files/t0054-ECH.text b/xterm.js/fixtures/escape_sequence_files/t0054-ECH.text new file mode 100644 index 0000000..a22cfbe --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0054-ECH.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqr> vwxyz +abcdefghijklmnopqr>! vwxyz +>! lmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh +abcdefghijklmnopqrstuvwxyz0123456789ABC>! OPQRSTUVWXYZ0123456789abcdefgh +------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------? +-------------------------------------------------------------------------------- +-? +.............................................................................. +............................................................................... +............................................................................... +................................................................................ +. + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0055-EL.in b/xterm.js/fixtures/escape_sequence_files/t0055-EL.in new file mode 100644 index 0000000..014658c --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0055-EL.in @@ -0,0 +1,8 @@ +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>< +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>< +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>< +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh>< +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh><! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh><! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh><! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh! diff --git a/xterm.js/fixtures/escape_sequence_files/t0055-EL.text b/xterm.js/fixtures/escape_sequence_files/t0055-EL.text new file mode 100644 index 0000000..a248f3b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0055-EL.text @@ -0,0 +1,25 @@ +abcdefghijklmnopqrstuvwxyz0123456789ABC> +abcdefghijklmnopqrstuvwxyz0123456789ABC> + FGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh + +abcdefghijklmnopqrstuvwxyz0123456789ABC>! + !FGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh + ! +abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefg! + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0056-ED.in b/xterm.js/fixtures/escape_sequence_files/t0056-ED.in new file mode 100644 index 0000000..fca4e54 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0056-ED.in @@ -0,0 +1,62 @@ +a +ab +abc +abcd +abcde +abcdef +abcdefg +abcdefgh +abcdefghi +abcdefghij +abcdefghijk +abcdefghijkl +abcdefghijklm +abcdefghijklmn +abcdefghijklmno +abcdefghijklmnop +abcdefghijklmnopq +abcdefghijklmnopqr +abcdefghijklmnopqrs +abcdefghijklmnopqrst +abcdefghijklmnopqrstu +abcdefghijklmnopqrstuv +abcdefghijklmnopqrstuvw +abcdefghijklmnopqrstuvwx +abcdefghijklmnopqrstuvwxy +abcdefghijklmnopqrstuvwxyz +A +AB +ABC +ABCD +ABCDE +ABCDEF +ABCDEFG +ABCDEFGH +ABCDEFGHI +ABCDEFGHIJ +ABCDEFGHIJK +ABCDEFGHIJKL +ABCDEFGHIJKLM +ABCDEFGHIJKLMN +ABCDEFGHIJKLMNO +ABCDEFGHIJKLMNOP +ABCDEFGHIJKLMNOPQ +ABCDEFGHIJKLMNOPQR +ABCDEFGHIJKLMNOPQRS +ABCDEFGHIJKLMNOPQRST +ABCDEFGHIJKLMNOPQRSTU +ABCDEFGHIJKLMNOPQRSTUV +ABCDEFGHIJKLMNOPQRSTUVW +ABCDEFGHIJKLMNOPQRSTUVWX +ABCDEFGHIJKLMNOPQRSTUVWXY! + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaav^ + + + +the end diff --git a/xterm.js/fixtures/escape_sequence_files/t0056-ED.text b/xterm.js/fixtures/escape_sequence_files/t0056-ED.text new file mode 100644 index 0000000..61a8ac7 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0056-ED.text @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + ! + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaav +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^ + + + +the end + diff --git a/xterm.js/fixtures/escape_sequence_files/t0057-ED3.in b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.in new file mode 100644 index 0000000..46606df --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.in @@ -0,0 +1,55 @@ +a +ab +abc +abcd +abcde +abcdef +abcdefg +abcdefgh +abcdefghi +abcdefghij +abcdefghijk +abcdefghijkl +abcdefghijklm +abcdefghijklmn +abcdefghijklmno +abcdefghijklmnop +abcdefghijklmnopq +abcdefghijklmnopqr +abcdefghijklmnopqrs +abcdefghijklmnopqrst +abcdefghijklmnopqrstu +abcdefghijklmnopqrstuv +abcdefghijklmnopqrstuvw +abcdefghijklmnopqrstuvwx +abcdefghijklmnopqrstuvwxy +abcdefghijklmnopqrstuvwxyz +A +AB +ABC +ABCD +ABCDE +ABCDEF +ABCDEFG +ABCDEFGH +ABCDEFGHI +ABCDEFGHIJ +ABCDEFGHIJK +ABCDEFGHIJKL +ABCDEFGHIJKLM +ABCDEFGHIJKLMN +ABCDEFGHIJKLMNO +ABCDEFGHIJKLMNOP +ABCDEFGHIJKLMNOPQ +ABCDEFGHIJKLMNOPQR +ABCDEFGHIJKLMNOPQRS +ABCDEFGHIJKLMNOPQRST +ABCDEFGHIJKLMNOPQRSTU +ABCDEFGHIJKLMNOPQRSTUV +ABCDEFGHIJKLMNOPQRSTUVW +ABCDEFGHIJKLMNOPQRSTUVWX +ABCDEFGHIJKLMNOPQRSTUVWXY +this +is +the +end diff --git a/xterm.js/fixtures/escape_sequence_files/t0057-ED3.note b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.note new file mode 100644 index 0000000..ca6d940 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.note @@ -0,0 +1,6 @@ +Xterm behaves oddly with CSI 3 J. This function is supposed to clear the +saved lines in history. Xterm does this, but a small number of lines of +history are not cleared. The number seems to vary with how high the window is +and how much output has recently been saved. There is no reason to simulate +this behavior, so the expected outputs are as if the entire history was +erased. diff --git a/xterm.js/fixtures/escape_sequence_files/t0057-ED3.text b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.text new file mode 100644 index 0000000..8230921 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0057-ED3.text @@ -0,0 +1,25 @@ +ABCDEF +ABCDEFG +ABCDEFGH +ABCDEFGHI +ABCDEFGHIJ +ABCDEFGHIJK +ABCDEFGHIJKL +ABCDEFGHIJKLM +ABCDEFGHIJKLMN +ABCDEFGHIJKLMNO +ABCDEFGHIJKLMNOP +ABCDEFGHIJKLMNOPQ +ABCDEFGHIJKLMNOPQR +ABCDEFGHIJKLMNOPQRS +ABCDEFGHIJKLMNOPQRST +ABCDEFGHIJKLMNOPQRSTU +ABCDEFGHIJKLMNOPQRSTUV +ABCDEFGHIJKLMNOPQRSTUVW +ABCDEFGHIJKLMNOPQRSTUVWX +ABCDEFGHIJKLMNOPQRSTUVWXY +this +is +the +end + diff --git a/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.in b/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.in new file mode 100644 index 0000000..d269150 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.in @@ -0,0 +1,9 @@ + 7v 12 + +38^ + + + + v7 +...ooo8^ + diff --git a/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.text b/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.text new file mode 100644 index 0000000..409198b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0060-DECSC.text @@ -0,0 +1,25 @@ + +3 + + v +... ^ + ooo + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.in b/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.in new file mode 100644 index 0000000..451fafa --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.in @@ -0,0 +1,9 @@ + v 12 + +3^ + + + + v +...ooo^ + diff --git a/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.text b/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.text new file mode 100644 index 0000000..409198b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0061-CSI_s.text @@ -0,0 +1,25 @@ + +3 + + v +... ^ + ooo + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.in b/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.in new file mode 100644 index 0000000..571f223 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.in @@ -0,0 +1,31 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9ABCDEFa +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +uvwxyz + +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.text b/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.text new file mode 100644 index 0000000..0940b07 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0070-DECSTBM_LF.text @@ -0,0 +1,25 @@ +1 + 2 + 6 + 7 + 8 + 9 ABC +DEF + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p +yz qrstu vwx +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.in b/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.in new file mode 100644 index 0000000..f9f6a42 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.in @@ -0,0 +1,3 @@ +1D2D3D4D5D6D7D8D9ABCDEFaDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDtDuvwxyz + +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.text b/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.text new file mode 100644 index 0000000..f6644fb --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0071-DECSTBM_IND.text @@ -0,0 +1,25 @@ + 2 + 6 + 7 + 8 + 9 ABC +DEF + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q +The end. rstu vwx + diff --git a/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.in b/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.in new file mode 100644 index 0000000..5df9e71 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.in @@ -0,0 +1,2 @@ +1E2E3E4E5E6E7E8E9aEbEcEdEeEfEgEhEiEjEkElEmEnEoEpEqErEsEtEu +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.text b/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.text new file mode 100644 index 0000000..1a0e4a1 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0072-DECSTBM_NEL.text @@ -0,0 +1,25 @@ +2 +5 +6 +7 +8 +9 + a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +The end. + diff --git a/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.in b/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.in new file mode 100644 index 0000000..fc7b7e4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.in @@ -0,0 +1,43 @@ +TOP 1 +TOP 2 +TOP 3 +TOP 4 +TOP 5 +TOP 6 - GONE + + + + + + + + + + + + +BOTTOM 6 - GONE +BOTTOM 5 +BOTTOM 4 +BOTTOM 3 +BOTTOM 2 +BOTTOM 1 + + + + +And the third. + + + + + + + + + + +This should be the last line. +This one should be lost. +This one's a goner, too. MMMMMMMMMMMMMMThis is second line. MThis should be the first line. +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.text b/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.text new file mode 100644 index 0000000..ce6dbc7 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0073-DECSTBM_RI.text @@ -0,0 +1,25 @@ +TOP 2 +TOP 3 +TOP 4 +TOP 5 +This should be the first line. +This is second line. +And the third. + + + + + + + + + + +This should be the last line. +BOTTOM 5 +BOTTOM 4 +BOTTOM 3 +BOTTOM 2 +BOTTOM 1 +The end. + diff --git a/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.in b/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.in new file mode 100644 index 0000000..1acbaf3 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.in @@ -0,0 +1,24 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x diff --git a/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.text b/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.text new file mode 100644 index 0000000..948e5d4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0074-DECSTBM_SU_SD.text @@ -0,0 +1,24 @@ +a + b + c + d + f + g + h + i + + j + k + l + m + + + + n + o + p + q + r + s + w + x diff --git a/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.in b/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.in new file mode 100644 index 0000000..b679113 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.in @@ -0,0 +1,24 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x12 diff --git a/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.text b/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.text new file mode 100644 index 0000000..486b91d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0075-DECSTBM_CUU_CUD.text @@ -0,0 +1,25 @@ +a +b +c +d +e +f +g +h +i +j2 +k +l +m +n +o +p +q +r +1 +t +u +v +w +x + diff --git a/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.in b/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.in new file mode 100644 index 0000000..58d20d2 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.in @@ -0,0 +1,33 @@ + 1 (IL on line 2, expect nothing) + 2 (DL on line 22, expect nothing) + 3 vvvv IL on line 5, expected: A_BC + 4 A + 5 B + 6 C + 7 D + 8 ^^^^ + 9 vvvv DL on line 11, expected: ACD_ +10 A +11 B +12 C +13 D +14 ^^^^ +15 vvvv IL on line 17, expected: A_ +16 A +17 B +18 ^^^^ +19 vvvv IL on line 21, expected: A_ +20 A +21 B +22 ^^^^ +23 vvvv IL on line 24, expected: _A +24 A + +25 B +26 ^^^^ +27 vvvv DL on line 28, expected: B_ +28 A +29 B +30 ^^^^ +31 +32 diff --git a/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.text b/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.text new file mode 100644 index 0000000..92c1033 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0076-DECSTBM_IL_DL.text @@ -0,0 +1,25 @@ + 8 ^^^^ + 9 vvvv DL on line 11, expected: ACD_ +10 A +12 C +13 D + +14 ^^^^ +15 vvvv IL on line 17, expected: A_ +16 A + +18 ^^^^ +19 vvvv IL on line 21, expected: A_ +20 A + +22 ^^^^ + +23 vvvv IL on line 24, expected: _A +25 B +26 ^^^^ +28 A + +29 B +30 ^^^^ +31 +32 diff --git a/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.in b/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.in new file mode 100644 index 0000000..b444362 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.in @@ -0,0 +1,32 @@ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24A +B +C +D +E +F +G + +Done. diff --git a/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.text b/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.text new file mode 100644 index 0000000..ea142e3 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0077-DECSTBM_quirks.text @@ -0,0 +1,25 @@ + 3 + 4 + A + 5 + 7 + C + 8 + 9 +10 +11 +12 +13 +14 +18 +19 +20 +21 +23 +24 + B + D + F + G +Done. + diff --git a/xterm.js/fixtures/escape_sequence_files/t0080-HT.in b/xterm.js/fixtures/escape_sequence_files/t0080-HT.in new file mode 100644 index 0000000..581e0ba --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0080-HT.in @@ -0,0 +1,14 @@ +a b c d e f g h i j k l + x +1 2 + 3 + +Tab before EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh @ +tab (2):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg @ + +Tab at EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi @ +with clipping: 4567890abcdefghi MD@ diff --git a/xterm.js/fixtures/escape_sequence_files/t0080-HT.text b/xterm.js/fixtures/escape_sequence_files/t0080-HT.text new file mode 100644 index 0000000..0683c21 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0080-HT.text @@ -0,0 +1,25 @@ +a b c d e f g h i j k +l + x +1 3 2 + + +Tab before EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab (2):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg @ + +Tab at EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +@ +with clipping: 4567890abcdefgh@ + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0081-TBC.in b/xterm.js/fixtures/escape_sequence_files/t0081-TBC.in new file mode 100644 index 0000000..744b7a5 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0081-TBC.in @@ -0,0 +1,19 @@ +default: +> 1 2 3 4 5 6 7 8 9 0 + +clear non-existant: x x +> 1 2 3 4 5 6 7 8 9 0 + +clear 2 and 4: x x +> 1 3 5 6 7 8 9 0 + +clear 0: x +> 1 3 5 6 7 8 9 0 + +clear after 0: .x +> 1 3 5 6 7 8 9 0 + +clear all: +> 0done + +TBC at end with clipping: ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdeMD! diff --git a/xterm.js/fixtures/escape_sequence_files/t0081-TBC.text b/xterm.js/fixtures/escape_sequence_files/t0081-TBC.text new file mode 100644 index 0000000..575e3fd --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0081-TBC.text @@ -0,0 +1,25 @@ +default: +> 1 2 3 4 5 6 7 8 9 0 + +clear non-existant: x x +> 1 2 3 4 5 6 7 8 9 0 + +clear 2 and 4: x x +> 1 3 5 6 7 8 9 0 + +clear 0: x +> 1 3 5 6 7 8 9 0 + +clear after 0: . +x +> 1 3 5 6 7 8 9 0 + +clear all: +> 0 +done + +TBC at end with clipping: ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcd! + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0082-HTS.in b/xterm.js/fixtures/escape_sequence_files/t0082-HTS.in new file mode 100644 index 0000000..2bd62d4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0082-HTS.in @@ -0,0 +1,8 @@ + 1 2 3 4 +abcdeHFghijklmnopqrstuvHWxyz + H 1 2 W 3 4 + +HTS at end: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdeHfgh + H 1 2 W 3 4 5 6 7 8 9 a b + +HTS at end with clipping: ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdeHMD! diff --git a/xterm.js/fixtures/escape_sequence_files/t0082-HTS.text b/xterm.js/fixtures/escape_sequence_files/t0082-HTS.text new file mode 100644 index 0000000..ecf66a5 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0082-HTS.text @@ -0,0 +1,25 @@ + 1 2 3 4 +abcdeFghijklmnopqrstuvWxyz + H 1 2 W 3 4 + +HTS at end: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcde +fgh + H 1 2 W 3 4 5 6 7 8 9 a +b + +HTS at end with clipping: ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcd! + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0083-CHT.in b/xterm.js/fixtures/escape_sequence_files/t0083-CHT.in new file mode 100644 index 0000000..838325d --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0083-CHT.in @@ -0,0 +1,18 @@ +abcdefghijkl +x +12 + 3 + +CHT before EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab (2):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg@ + +CHT at EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi@ +with clipping: 4567890abcdefghiMD@ + +aeg +e h +x diff --git a/xterm.js/fixtures/escape_sequence_files/t0083-CHT.text b/xterm.js/fixtures/escape_sequence_files/t0083-CHT.text new file mode 100644 index 0000000..071ed63 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0083-CHT.text @@ -0,0 +1,25 @@ +a b c d e f g h i j k +l + x +1 3 2 + + +CHT before EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefgh@ +tab (2):abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefg @ + +CHT at EOL: +no tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +@ +tab: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghi +@ +with clipping: 4567890abcdefgh@ + +a e g + e h + x + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0084-CBT.in b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.in new file mode 100644 index 0000000..a7dd5b1 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.in @@ -0,0 +1,16 @@ +a b c d e f g h i j k + <Iihfa +a + +default tab stops: +near end: abcdefg! +at end: abcdefgh! +at end (2): abcdefgh! +at end with clipping: abcdefghMD! +at end with clipping (2): abcdefghMD! + +set tab stop at column 80: Hv +at end: abcdefgh! +at end (2): abcdefgh! +at end with clipping: abcdefghMD! +at end with clipping (2): abcdefghMD! diff --git a/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text new file mode 100644 index 0000000..2fb8765 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text @@ -0,0 +1,25 @@ +a b c d e f g h i j k +a f h i < +a + +default tab stops: +near end: !bcdefg +at end: abcdefgh +! +at end (2): abcdefgh +! +at end with clipping: !bcdefgh +at end with clipping (2): ! abcdefgh + +set tab stop at column 80: v +at end: abcdefgh +! +at end (2): abcdefgh +! +at end with clipping: !bcdefgh +at end with clipping (2): ! abcdefgh + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text-xterm b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text-xterm new file mode 100644 index 0000000..7a2adc7 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0084-CBT.text-xterm @@ -0,0 +1,20 @@ +a b c d e f g h i j k +a f h i < +a + +default tab stops: +near end: !bcdefg +at end: abcdefgh +! +at end (2): abcdefgh +! +at end with clipping: !bcdefgh +at end with clipping (2): ! abcdefgh + +set tab stop at column 80: v +at end: abcdefgh +! +at end (2): abcdefgh +! +at end with clipping: !bcdefgh +at end with clipping (2): ! abcdefgh diff --git a/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.in b/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.in new file mode 100644 index 0000000..bf1eeaf --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.in @@ -0,0 +1,55 @@ +a[?47h +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y[?47lz +A[?47h +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y[?47lZ + --->[?47hhello[?47l<-- + + --->[?47h[?47l<--- + +fin diff --git a/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.text b/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.text new file mode 100644 index 0000000..7ac0135 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0090-alt_screen.text @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + z +AZ + <-- ---> + + ---> +<--- + +fin + diff --git a/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.in b/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.in new file mode 100644 index 0000000..40957e8 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.in @@ -0,0 +1,46 @@ +a +b +c +d +e +f +g +h +i +j +k +l +m +n +o +p +q +r +s +t +u +v +w +x +y +z +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +[?47h +one +two +three +four +five +six + +[?47l +11 diff --git a/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.text b/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.text new file mode 100644 index 0000000..4a326a4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0091-alt_screen_ED3.text @@ -0,0 +1,25 @@ + n + o + p + q + r + s + t + u + v + w + x + y + z + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + 11 diff --git a/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.in b/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.in new file mode 100644 index 0000000..3022a93 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.in @@ -0,0 +1,15 @@ +a + b7 + c[?47h + + >7 + + xxxxxxx8[?47l!8< + + + + + + + +The end. diff --git a/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.text b/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.text new file mode 100644 index 0000000..bab1503 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0092-alt_screen_DECSC.text @@ -0,0 +1,25 @@ +a + b< + c + + ! + + + + +The end. + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0100-IRM.in b/xterm.js/fixtures/escape_sequence_files/t0100-IRM.in new file mode 100644 index 0000000..5046f18 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0100-IRM.in @@ -0,0 +1,13 @@ +-------- insert single '!' --------------------------------------------abcdefghi +jklmnop! + + +-------- insert 0-9, with wraparound ----------------------------------abcdefghi +jklmnop0123456789 + +-------- repeat 3 '!' -------------------------------------------------abcdefghi +jklmnop! + + +-------- repeat 10 '!', with wraparound -------------------------------abcdefghi +jklmnop! diff --git a/xterm.js/fixtures/escape_sequence_files/t0100-IRM.text b/xterm.js/fixtures/escape_sequence_files/t0100-IRM.text new file mode 100644 index 0000000..f4f3eea --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0100-IRM.text @@ -0,0 +1,25 @@ +-------- insert single '!' --------------------------------------------abc!defgh +jklmnop + +-------- insert 0-9, with wraparound ----------------------------------abc012345 +6789jklmnop + +-------- repeat 3 '!' -------------------------------------------------abc!!!def +jklmnop + +-------- repeat 10 '!', with wraparound -------------------------------abc!!!!!! +!!!!jklmnop + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0101-NLM.in b/xterm.js/fixtures/escape_sequence_files/t0101-NLM.in new file mode 100644 index 0000000..554a0f3 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0101-NLM.in @@ -0,0 +1,10 @@ +a +b +c +d +e +f g h +i j k +l +m +n o p diff --git a/xterm.js/fixtures/escape_sequence_files/t0101-NLM.text b/xterm.js/fixtures/escape_sequence_files/t0101-NLM.text new file mode 100644 index 0000000..47f883f --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0101-NLM.text @@ -0,0 +1,25 @@ +a +b +c +d +e +f +g +h +k +l +m +n + o + p + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.in b/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.in new file mode 100644 index 0000000..c615659 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.in @@ -0,0 +1,4 @@ +-------- default: wraparound ----------------------------------------------abcdefgh[?7h +-------- set: wraparound ----------------------------------------------abcdefgh[?7l +-------- unset: no wraparound -------------------------------------------abcdefgh + this should be immediately below "no wraparound"[?7h diff --git a/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.text b/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.text new file mode 100644 index 0000000..c1f22de --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0102-DECAWM.text @@ -0,0 +1,25 @@ +-------- default: wraparound ----------------------------------------------abcd +efgh +-------- set: wraparound ----------------------------------------------abcd +efgh +-------- unset: no wraparound -------------------------------------------abcd + this should be immediately below "no wraparound" + + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.in b/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.in new file mode 100644 index 0000000..092462e --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.in @@ -0,0 +1,6 @@ +[?45ha +bA + +c-B + +dC!the endreally![?45l diff --git a/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.text b/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.text new file mode 100644 index 0000000..da830d5 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0103-reverse_wrap.text @@ -0,0 +1,25 @@ +c C +! + + + + + + + + + + + + + + + + + + + + + the end +really! + diff --git a/xterm.js/fixtures/escape_sequence_files/t0200-SGR.html b/xterm.js/fixtures/escape_sequence_files/t0200-SGR.html new file mode 100644 index 0000000..fa270a0 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0200-SGR.html @@ -0,0 +1,35 @@ +
    +Implemented non-color attributes:
    +
    + 1: This is bold.
    +
    + 3: This is italic.
    +
    + 4: This is underlined.
    +
    + 5: This is slowly blinking.
    +
    + 6: This is rapidly blinking.
    +
    + 7: This is inverse.
    +
    + 8: This is hidden.
    +
    + 9: This is struck out.
    +
    +21: This is double underlined.
    +
    +53: This is overlined.
    +
    +
    +
    +Unimplemented non-color attributes:
    +
    + 2: weight:feint
    +
    +20: style:fraktur
    +
    +51: frame:box
    +
    +52: frame:circle
    +
    diff --git a/xterm.js/fixtures/escape_sequence_files/t0200-SGR.in_ b/xterm.js/fixtures/escape_sequence_files/t0200-SGR.in_ new file mode 100644 index 0000000..3b37c93 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0200-SGR.in_ @@ -0,0 +1,33 @@ +Implemented non-color attributes: + + 1: This is bold. + + 3: This is italic. + + 4: This is underlined. + + 5: This is slowly blinking. + + 6: This is rapidly blinking. + + 7: This is inverse. + + 8: This is hidden. + + 9: This is struck out. + +21: This is double underlined. + +53: This is overlined. + + + +Unimplemented non-color attributes: + + 2: weight:feint + +20: style:fraktur + +51: frame:box + +52: frame:circle diff --git a/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.html b/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.html new file mode 100644 index 0000000..7218bf4 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.html @@ -0,0 +1,6 @@ +
    +This is inverse text with default fg and bg.
    +This is inverse text with red fg and default bg.
    +This is inverse text with default fg and red bg.
    +This is inverse text with green fg and red bg.
    +
    diff --git a/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.in_ b/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.in_ new file mode 100644 index 0000000..e7e63f9 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0220-SGR_inverse.in_ @@ -0,0 +1,4 @@ +This is inverse text with default fg and bg. +This is inverse text with red fg and default bg. +This is inverse text with default fg and red bg. +This is inverse text with green fg and red bg. diff --git a/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.in b/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.in new file mode 100644 index 0000000..b1e5491 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.in @@ -0,0 +1,7 @@ +Script started on Fri 27 Mar 2009 08:53:29 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +]0;mark@mark-desktop:~/vt100-to-htmlmark@mark-desktop:~/vt100-to-html$ bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST UVWXYZ1234567890abcdefghijklmnopqrstuvcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuv + +]0;mark@mark-desktop:~/vt100-to-htmlmark@mark-desktop:~/vt100-to-html$ exit + +Script done on Fri 27 Mar 2009 08:53:33 PM EDT diff --git a/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.text b/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.text new file mode 100644 index 0000000..5c785d0 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0500-bash_long_line.text @@ -0,0 +1,25 @@ +Script started on Fri 27 Mar 2009 08:53:29 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +mark@mark-desktop:~/vt100-to-html$ cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU +VWXYZ1234567890abcdefghijklmnopqrstuv +mark@mark-desktop:~/vt100-to-html$ exit + +Script done on Fri 27 Mar 2009 08:53:33 PM EDT + + + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.in b/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.in new file mode 100644 index 0000000..9053d8b --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.in @@ -0,0 +1,12 @@ +Script started on Sun 17 May 2009 06:20:41 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +]0;mark@mark-desktop:~/vt100-to-html/scriptsmark@mark-desktop:~/vt100-to-html/scripts$ ls +bash.script +]0;mark@mark-desktop:~/vt100-to-html/scriptsmark@mark-desktop:~/vt100-to-html/scripts$ ls / +bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +]0;mark@mark-desktop:~/vt100-to-html/scriptsmark@mark-desktop:~/vt100-to-html/scripts$ exit + +Script done on Sun 17 May 2009 06:20:52 PM EDT diff --git a/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.text b/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.text new file mode 100644 index 0000000..8114fc9 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0501-bash_ls.text @@ -0,0 +1,25 @@ +Script started on Sun 17 May 2009 06:20:41 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +mark@mark-desktop:~/vt100-to-html/scripts$ ls +bash.script +mark@mark-desktop:~/vt100-to-html/scripts$ ls / +bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +mark@mark-desktop:~/vt100-to-html/scripts$ exit + +Script done on Sun 17 May 2009 06:20:52 PM EDT + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.in b/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.in new file mode 100644 index 0000000..1f4eda8 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.in @@ -0,0 +1,10 @@ +Script started on Sun 17 May 2009 06:21:05 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +]0;mark@mark-desktop:~/vt100-to-html/scriptsmark@mark-desktop:~/vt100-to-html/scripts$ ls --color=auto / +bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +]0;mark@mark-desktop:~/vt100-to-html/scriptsmark@mark-desktop:~/vt100-to-html/scripts$ exit + +Script done on Sun 17 May 2009 06:21:11 PM EDT diff --git a/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.text b/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.text new file mode 100644 index 0000000..1892eea --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0502-bash_ls_color.text @@ -0,0 +1,25 @@ +Script started on Sun 17 May 2009 06:21:05 PM EDT +dircolors: /etc/DIR_COLORS: No such file or directory +mark@mark-desktop:~/vt100-to-html/scripts$ ls --color=auto / +bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +mark@mark-desktop:~/vt100-to-html/scripts$ exit + +Script done on Sun 17 May 2009 06:21:11 PM EDT + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.in b/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.in new file mode 100644 index 0000000..aca2d10 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.in @@ -0,0 +1,9 @@ +Script started on Sun 17 May 2009 06:21:21 PM EDT +]2;mark-desktop - ~/vt100-to-html/scripts% $ ~/vt100-to-html/scriptslls / +]2;mark-desktop - ls /bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +]2;mark-desktop - ~/vt100-to-html/scripts% $ ~/vt100-to-html/scripts + +Script done on Sun 17 May 2009 06:21:27 PM EDT diff --git a/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.text b/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.text new file mode 100644 index 0000000..19feb18 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0503-zsh_ls_color.text @@ -0,0 +1,25 @@ +Script started on Sun 17 May 2009 06:21:21 PM EDT +$ ls / ~/vt100-to-html/scripts +bin dev initrd.img lib64 opt selinux usr +boot etc initrd.img.old lost+found proc srv var +boot2 home lib media root sys vmlinuz +cdrom initrd lib32 mnt sbin tmp vmlinuz.old +$ ~/vt100-to-html/scripts + +Script done on Sun 17 May 2009 06:21:27 PM EDT + + + + + + + + + + + + + + + + diff --git a/xterm.js/fixtures/escape_sequence_files/t0504-vim.in b/xterm.js/fixtures/escape_sequence_files/t0504-vim.in new file mode 100644 index 0000000..cb68232 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0504-vim.in @@ -0,0 +1,56 @@ +Script started on Sun 15 Aug 2010 11:53:27 PM EDT +]0;mark-desktop - ~/vt100-to-html/test% $ ~/vt100-to-html/testlls +]0;mark-desktop - lsexpected_text t0016-SU.text t0050-ICH.text +input t0017-SD.in t0051-IL.in +run_all.py t0017-SD.text t0051-IL.text +t0001-all_printable.in t0020-CUF.in t0052-DL.in +t0001-all_printable.text t0020-CUF.text t0052-DL.text +t0002-history.in t0021-CUB.in t0053-DCH.in +t0002-history.text t0021-CUB.text t0053-DCH.text +t0003-line_wrap.in t0022-CUU.in t0054-ECH.in +t0003-line_wrap.text t0022-CUU.text t0054-ECH.text +t0004-LF.in t0023-CUU_scroll.in t0055-EL.in +t0004-LF.text t0023-CUU_scroll.text t0055-EL.text +t0005-CR.in t0024-CUD.in t0056-ED.in +t0005-CR.text t0024-CUD.text t0056-ED.text +t0006-IND.in t0025-CUP.in t0057-ED3.in +t0006-IND.text t0025-CUP.text t0057-ED3.note +t0007-space_at_end.in t0026-CNL.in t0057-ED3.text +t0007-space_at_end.text t0026-CNL.text t0060-DECSC.in +t0008-BS.in t0027-CPL.in t0060-DECSC.text +t0008-BS.text t0027-CPL.text t0061-CSI_s.in +t0009-NEL.in t0030-HPR.in t0061-CSI_s.text +t0009-NEL.text t0030-HPR.text t008x-alt_screen_ED.in +t0010-RI.in t0031-HPB.in t008x-IRM.in +t0010-RI.text t0031-HPB.text t008x-NLM.in +t0011-RI_scroll.in t0032-VPB.in t008x-save_cursor_mode.in +t0011-RI_scroll.text t0032-VPB.text t0500-bash_long_line.in +t0012-VT.in t0033-VPB_scroll.in t0500-bash_long_line.text +t0012-VT.text t0033-VPB_scroll.text t0501-bash_ls.in +t0013-FF.in t0034-VPR.in t0501-bash_ls.text +t0013-FF.text t0034-VPR.text t0502-bash_ls_color.in +t0014-CAN.in t0035-HVP.in t0502-bash_ls_color.text +t0014-CAN.text t0035-HVP.text t0503-zsh_ls_color.in +t0015-SUB.in t0040-REP.in t0503-zsh_ls_color.text +t0015-SUB.text t0040-REP.text typescript +t0016-SU.in t0050-ICH.in +]0;mark-desktop - ~/vt100-to-html/test% $ ~/vt100-to-html/testvvim +]0;mark-desktop - vim[?1000h[?1049h[?1h=[?12;25h[?12l[?25h[>c[?25l~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ [No Name] 0,0-1 AllVIM - Vi IMprovedversion 7.2.267by Bram Moolenaar et al.Vim is open source and freely distributableBecome a registered Vim user!type :help register for information type :q to exit type :help or  for on-line helptype :help version7 for version info]2;[No Name] - VIM]1;[No Name][?12l[?25h[?1000l[?1002hP+q436f\P+q6b75\P+q6b64\P+q6b72\P+q6b6c\P+q2332\P+q2334\P+q2569\P+q2a37\P+q6b31\[?25l-- INSERT --1 [?12l[?25h[?25lT         [+]1,2 ]2;[No Name] + - VIM]1;[No Name][?12l[?25h[?25lTh3 [?12l[?25h[?25lhi4 [?12l[?25h[?25lis5 [?12l[?25h[?25l6 [?12l[?25h[?25l i7 [?12l[?25h[?25lis8 [?12l[?25h[?25l9 [?12l[?25h[?25l a10[?12l[?25h[?25l1 [?12l[?25h[?25l t2 [?12l[?25h[?25lte3 [?12l[?25h[?25les4 [?12l[?25h[?25lst5 [?12l[?25h[?25lt.6 [?12l[?25h[?25l2,1 [?12l[?25h[?25l3,[?12l[?25h[?25lH2 [?12l[?25h[?25lHo3 [?12l[?25h[?25loe4 [?12l[?25h[?25l5 [?12l[?25h[?25l f6 [?12l[?25h[?25lfu7 [?12l[?25h[?25l6 [?12l[?25h[?25l5 [?12l[?25h[?25l4 [?12l[?25h[?25l3 [?12l[?25h[?25lop4 [?12l[?25h[?25lpe5 [?12l[?25h[?25lef6 [?12l[?25h[?25lfu7 [?12l[?25h[?25lul8 [?12l[?25h[?25lll9 [?12l[?25h[?25lly10[?12l[?25h[?25l1 [?12l[?25h[?25l i2 [?12l[?25h[?25lit3 [?12l[?25h[?25l4 [?12l[?25h[?25l w5 [?12l[?25h[?25lwi6 [?12l[?25h[?25lil7 [?12l[?25h[?25lll8 [?12l[?25h[?25l9 [?12l[?25h[?25l w20 [?12l[?25h[?25lwo1 [?12l[?25h[?25lor2 [?12l[?25h[?25lrk3 [?12l[?25h[?25lk.4 [?12l[?25h[?25l4,1 [?12l[?25h[?25l5,[?12l[?25h[?25l6,[?12l[?25h[?25l7,[?12l[?25h[?25l8,[?12l[?25h[?25l9,[?12l[?25h[?25l10,1[?12l[?25h[?25l1,[?12l[?25h[?25l2,[?12l[?25h[?25l3,[?12l[?25h[?25l4,[?12l[?25h[?25l5,[?12l[?25h[?25l6,[?12l[?25h[?25l7,[?12l[?25h[?25l8,[?12l[?25h[?25l9,[?12l[?25h[?25l20,[?12l[?25h[?25l1,[?12l[?25h[?25l2,[?12l[?25h[?25l +3,Bot[?12l[?25h[?25l +4,[?12l[?25h[?25l +5,[?12l[?25h[?25l +6,[?12l[?25h[?25l +7,[?12l[?25h[?25l +8,[?12l[?25h[?25l +9,[?12l[?25h[?25l +30,[?12l[?25h[?25l +1,[?12l[?25h[?25l +2,[?12l[?25h[?25l +3,[?12l[?25h[?25lI2 [?12l[?25h[?25l3 [?12l[?25h[?25l b4 [?12l[?25h[?25lbe5 [?12l[?25h[?25let6 [?12l[?25h[?25l7 [?12l[?25h[?25l i8 [?12l[?25h[?25lit9 [?12l[?25h[?25l10[?12l[?25h[?25l w1 [?12l[?25h[?25lwi2 [?12l[?25h[?25lil3 [?12l[?25h[?25lll4 [?12l[?25h[?25ll.5 [?12l[?25h[?25l4 [?12l[?25h[?25lThis is a test. + +Hopefully it will work.1,1 Top[?12l[?25h[?25lI bet it will. +~ ~ ~ ~ ~ ~ ~ ~ ~ [No Name] [+] 21,0-1 Bot[?12l[?25h[?25l0,[?12l[?25h[?25l19,[?12l[?25h[?25l8,[?12l[?25h[?25l7,[?12l[?25h[?25l6,[?12l[?25h[?25l5,[?12l[?25h[?25l:[?12l[?25hw[?25l[?12l[?25hq[?25l[?12l[?25h [?25lE32: No file name[?12l[?25h[?25l:[?12l[?25hw[?25l[?12l[?25h[?25l [?12l[?25hf[?25l[?12l[?25ho[?25l[?12l[?25ho[?25l[?12l[?25h [?25l"foo" [New] 33L, 85C writtenfoo ]2;foo (~/vt100-to-html/test) - VIM]1;foo[?12l[?25h[?25l:[?12l[?25hq[?25l[?12l[?25h [?25l[?1002l]2;mark-desktop - vim]1;mark-desktop - vim[?1l>[?12l[?25h[?1049l]0;mark-desktop - ~/vt100-to-html/test% $ ~/vt100-to-html/testeecho Yes! +]0;mark-desktop - echo Yes!Yes! +]0;mark-desktop - ~/vt100-to-html/test% $ ~/vt100-to-html/test + +Script done on Sun 15 Aug 2010 11:54:14 PM EDT diff --git a/xterm.js/fixtures/escape_sequence_files/t0504-vim.text b/xterm.js/fixtures/escape_sequence_files/t0504-vim.text new file mode 100644 index 0000000..7c20251 --- /dev/null +++ b/xterm.js/fixtures/escape_sequence_files/t0504-vim.text @@ -0,0 +1,25 @@ +t0005-CR.in t0024-CUD.in t0056-ED.in +t0005-CR.text t0024-CUD.text t0056-ED.text +t0006-IND.in t0025-CUP.in t0057-ED3.in +t0006-IND.text t0025-CUP.text t0057-ED3.note +t0007-space_at_end.in t0026-CNL.in t0057-ED3.text +t0007-space_at_end.text t0026-CNL.text t0060-DECSC.in +t0008-BS.in t0027-CPL.in t0060-DECSC.text +t0008-BS.text t0027-CPL.text t0061-CSI_s.in +t0009-NEL.in t0030-HPR.in t0061-CSI_s.text +t0009-NEL.text t0030-HPR.text t008x-alt_screen_ED.in +t0010-RI.in t0031-HPB.in t008x-IRM.in +t0010-RI.text t0031-HPB.text t008x-NLM.in +t0011-RI_scroll.in t0032-VPB.in t008x-save_cursor_mode.in +t0011-RI_scroll.text t0032-VPB.text t0500-bash_long_line.in +t0012-VT.in t0033-VPB_scroll.in t0500-bash_long_line.text +t0012-VT.text t0033-VPB_scroll.text t0501-bash_ls.in +t0013-FF.in t0034-VPR.in t0501-bash_ls.text +t0013-FF.text t0034-VPR.text t0502-bash_ls_color.in +t0014-CAN.in t0035-HVP.in t0502-bash_ls_color.text +t0014-CAN.text t0035-HVP.text t0503-zsh_ls_color.in +t0015-SUB.in t0040-REP.in t0503-zsh_ls_color.text +t0015-SUB.text t0040-REP.text typescript +t0016-SU.in t0050-ICH.in +$ vim ~/vt100-to-html/test +Script done on Sun 15 Aug 2010 11:54:14 PM EDT ~/vt100-to-html/test diff --git a/xterm.js/fixtures/typings-test/tsconfig.json b/xterm.js/fixtures/typings-test/tsconfig.json new file mode 100644 index 0000000..2dcff2e --- /dev/null +++ b/xterm.js/fixtures/typings-test/tsconfig.json @@ -0,0 +1,9 @@ +{ + "files": [ + "typings-test.ts" + ], + "compilerOptions": { + "module": "commonjs", + "target": "es5" + } +} diff --git a/xterm.js/fixtures/typings-test/typings-test.ts b/xterm.js/fixtures/typings-test/typings-test.ts new file mode 100644 index 0000000..a9653b1 --- /dev/null +++ b/xterm.js/fixtures/typings-test/typings-test.ts @@ -0,0 +1,234 @@ +/** + * @license MIT + */ + +/// + +import { Terminal } from 'xterm'; + +namespace constructor { + { + new Terminal(); + new Terminal({}); + new Terminal({ + cols: 1, + rows: 1 + }); + new Terminal({ + 'cols': 1, + 'cursorBlink': true, + 'cursorStyle': 'block', + 'disableStdin': false, + 'rows': 1, + 'scrollback': 10, + 'tabStopWidth': 2, + }); + } +} + +namespace properties { + { + const t: Terminal = new Terminal(); + const element: HTMLElement = t.element; + const textarea: HTMLTextAreaElement = t.textarea; + } +} + +namespace static_methods { + { + Terminal.applyAddon({}); + Terminal.applyAddon({}); + Terminal.applyAddon({}); + Terminal.applyAddon({}); + Terminal.applyAddon({}); + Terminal.applyAddon({}); + } +} + +namespace methods_core { + { + const t: Terminal = new Terminal(); + t.blur(); + t.focus(); + t.destroy(); + t.clear(); + t.refresh(0, 1); + t.reset(); + t.resize(1, 1); + t.write('foo'); + t.writeln('foo'); + } + { + const t: Terminal = new Terminal(); + // no arg + t.on('blur', () => {}); + t.on('focus', () => {}); + t.on('linefeed', () => {}); + t.on('selection', () => {}); + // args + t.on('data', () => {}); + t.on('data', (data: string) => console.log(data)); + t.on('key', () => {}); + t.on('key', (key: string) => console.log(key, event)); + t.on('key', (key: string, event: KeyboardEvent) => console.log(key, event)); + t.on('keydown', () => {}); + t.on('keydown', (event: KeyboardEvent) => console.log(event)); + t.on('keypress', () => {}); + t.on('keypress', (event: KeyboardEvent) => console.log(event)); + t.on('refresh', () => {}); + t.on('refresh', (data: {start: number, end: number}) => console.log(data)); + t.on('resize', () => {}); + t.on('resize', (data: {cols: number, rows: number}) => console.log(data)); + t.on('scroll', () => {}); + t.on('scroll', (ydisp: number) => console.log(ydisp)); + t.on('title', () => {}); + t.on('title', (title: string) => console.log(title)); + } + { + const t: Terminal = new Terminal(); + // no arg + t.off('blur', () => {}); + t.off('focus', () => {}); + t.off('linefeed', () => {}); + t.off('selection', () => {}); + // args + t.off('data', () => {}); + t.off('data', (data: string) => console.log(data)); + t.off('key', () => {}); + t.off('key', (key: string) => console.log(key, event)); + t.off('key', (key: string, event: KeyboardEvent) => console.log(key, event)); + t.off('keydown', () => {}); + t.off('keydown', (event: KeyboardEvent) => console.log(event)); + t.off('keypress', () => {}); + t.off('keypress', (event: KeyboardEvent) => console.log(event)); + t.off('refresh', () => {}); + t.off('refresh', (data: {element: HTMLElement, start: number, end: number}) => console.log(data)); + t.off('resize', () => {}); + t.off('resize', (data: {terminal: Terminal, cols: number, rows: number}) => console.log(data)); + t.off('scroll', () => {}); + t.off('scroll', (ydisp: number) => console.log(ydisp)); + t.off('title', () => {}); + t.off('title', (title: string) => console.log(title)); + } + { + const t: Terminal = new Terminal(); + const e: HTMLElement = null; + t.open(e); + } + { + const t: Terminal = new Terminal(); + t.attachCustomKeyEventHandler((e: KeyboardEvent) => true); + t.attachCustomKeyEventHandler((e: KeyboardEvent) => false); + } + namespace options { + { + const t: Terminal = new Terminal(); + const r01: string = t.getOption('cursorStyle'); + const r02: string = t.getOption('termName'); + const r03: boolean = t.getOption('cancelEvents'); + const r04: boolean = t.getOption('convertEol'); + const r05: boolean = t.getOption('cursorBlink'); + const r06: boolean = t.getOption('debug'); + const r07: boolean = t.getOption('disableStdin'); + const r08: boolean = t.getOption('popOnBell'); + const r09: boolean = t.getOption('screenKeys'); + const r10: boolean = t.getOption('useFlowControl'); + const r11: boolean = t.getOption('visualBell'); + const r12: string[] = t.getOption('colors'); + const r13: number = t.getOption('cols'); + const r14: number = t.getOption('rows'); + const r15: number = t.getOption('tabStopWidth'); + const r16: number = t.getOption('scrollback'); + const r18: (data: string) => void = t.getOption('handler'); + const r19: string = t.getOption('bellSound'); + const r20: string = t.getOption('bellStyle'); + const r21: boolean = t.getOption('enableBold'); + const r22: number = t.getOption('letterSpacing'); + const r23: boolean = t.getOption('allowTransparency'); + } + { + const t: Terminal = new Terminal(); + t.setOption('cursorStyle', 'bar'); + t.setOption('cursorStyle', 'block'); + t.setOption('cursorStyle', 'underline'); + t.setOption('termName', 'foo'); + t.setOption('cancelEvents', true); + t.setOption('convertEol', true); + t.setOption('cursorBlink', true); + t.setOption('debug', true); + t.setOption('disableStdin', true); + t.setOption('enableBold', true); + t.setOption('popOnBell', true); + t.setOption('screenKeys', true); + t.setOption('useFlowControl', true); + t.setOption('allowTransparency', true); + t.setOption('visualBell', true); + t.setOption('colors', ['a', 'b']); + t.setOption('letterSpacing', 1); + t.setOption('cols', 1); + t.setOption('rows', 1); + t.setOption('tabStopWidth', 1); + t.setOption('scrollback', 1); + t.setOption('handler', (data: string) => console.log(data)); + t.setOption('bellSound', 'foo'); + t.setOption('bellStyle', 'none'); + // t.setOption('bellStyle', 'visual'); + t.setOption('bellStyle', 'sound'); + // t.setOption('bellStyle', 'both'); + t.setOption('fontSize', 1); + t.setOption('lineHeight', 1); + t.setOption('fontFamily', 'foo'); + t.setOption('theme', {background: '#ff0000'}); + } + } + namespace scrolling { + { + const t: Terminal = new Terminal(); + t.scrollLines(-1); + t.scrollLines(1); + t.scrollLines(-1); + t.scrollLines(1); + t.scrollToTop(); + t.scrollToBottom(); + } + } + namespace selection { + { + const t: Terminal = new Terminal(); + const r1: boolean = t.hasSelection(); + const r2: string = t.getSelection(); + t.clearSelection(); + t.selectAll(); + } + } +} + +namespace methods_experimental { + { + const t: Terminal = new Terminal(); + t.registerLinkMatcher(/foo/, () => {}); + t.registerLinkMatcher(new RegExp('foo'), () => {}); + t.registerLinkMatcher(/foo/, () => {}, {}); + t.registerLinkMatcher(/foo/, (event: MouseEvent, uri: string) => { + console.log(event, uri); + return void 0; + }, {}); + t.registerLinkMatcher(/foo/, () => true, {}); + t.registerLinkMatcher(/foo/, () => false, {}); + t.registerLinkMatcher(/foo/, () => true, { + matchIndex: 1 + }); + t.registerLinkMatcher(/foo/, () => true, { + matchIndex: 1, + priority: 1, + validationCallback: (uri: string, callback: (isValid: boolean) => void) => { + console.log(uri, callback); + }, + tooltipCallback: (e: MouseEvent, uri: string) => { + console.log(e, uri); + }, + leaveCallback: () => {} + }); + t.deregisterLinkMatcher(1); + } +} diff --git a/xterm.js/gulpfile.js b/xterm.js/gulpfile.js new file mode 100644 index 0000000..49d67ed --- /dev/null +++ b/xterm.js/gulpfile.js @@ -0,0 +1,213 @@ +/** + * @license MIT + */ + +const browserify = require('browserify'); +const buffer = require('vinyl-buffer'); +const coveralls = require('gulp-coveralls'); +const fs = require('fs-extra'); +const gulp = require('gulp'); +const path = require('path'); +const istanbul = require('gulp-istanbul'); +const merge = require('merge-stream'); +const mocha = require('gulp-mocha'); +const sorcery = require('sorcery'); +const source = require('vinyl-source-stream'); +const sourcemaps = require('gulp-sourcemaps'); +const ts = require('gulp-typescript'); +const util = require('gulp-util'); +const webpack = require('webpack-stream'); + +let buildDir = process.env.BUILD_DIR || 'build'; +let tsProject = ts.createProject('tsconfig.json'); +let srcDir = tsProject.config.compilerOptions.rootDir; +let outDir = tsProject.config.compilerOptions.outDir; + +// Under some environments like TravisCI, this comes out at absolute which can +// break the build. This ensures that the outDir is absolute. +if (path.normalize(outDir).indexOf(__dirname) !== 0) { + outDir = `${__dirname}/${path.normalize(outDir)}`; +} + +/** + * Compile TypeScript sources to JavaScript files and create a source map file for each TypeScript + * file compiled. + */ +gulp.task('tsc', function () { + // Remove the ${outDir}/ directory to prevent confusion if files were deleted in ${srcDir}/ + fs.emptyDirSync(`${outDir}`); + + // Build all TypeScript files (including tests) to ${outDir}/, based on the configuration defined in + // `tsconfig.json`. + let tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject()); + let tsc = merge( + tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir)), + tsResult.dts.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir)) + ); + + let addons = ['attach', 'fit', 'fullscreen', 'search', 'terminado', 'winptyCompat', 'zmodem']; + let addonStreams = addons.map(function(addon) { + fs.emptyDirSync(`${outDir}/addons/${addon}`); + + let tsProjectAddon = ts.createProject(`./src/addons/${addon}/tsconfig.json`); + let tsResultAddon = tsProjectAddon.src().pipe(sourcemaps.init()).pipe(tsProjectAddon()); + let tscAddon = tsResultAddon.js + .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})) + .pipe(gulp.dest(`${outDir}/addons/${addon}`)); + + return tscAddon; + }); + + // Copy all addons from ${srcDir}/ to ${outDir}/ + let copyAddons = gulp.src([ + `${srcDir}/addons/**/**` + ]).pipe(gulp.dest(`${outDir}/addons`)); + + // Copy stylesheets from ${srcDir}/ to ${outDir}/ + let copyStylesheets = gulp.src(`${srcDir}/**/*.css`).pipe(gulp.dest(outDir)); + + // Join all streams into a single array + let streams = [tsc].concat(addonStreams).concat([copyAddons, copyStylesheets]); + + return merge.apply(this, streams); +}); + +/** + * Bundle JavaScript files produced by the `tsc` task, into a single file named `xterm.js` with + * Browserify. + */ +gulp.task('browserify', ['tsc'], function() { + // Ensure that the build directory exists + fs.ensureDirSync(buildDir); + + let browserifyOptions = { + basedir: buildDir, + debug: true, + entries: [`${outDir}/xterm.js`], + standalone: 'Terminal', + cache: {}, + packageCache: {} + }; + let bundleStream = browserify(browserifyOptions) + .bundle() + .pipe(source('xterm.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true, sourceRoot: '..'})) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(buildDir)); + + // Copy stylesheets from ${outDir}/ to ${buildDir}/ + let copyStylesheets = gulp.src(`${outDir}/**/*.css`).pipe(gulp.dest(buildDir)); + + return merge(bundleStream, copyStylesheets); +}); + +gulp.task('browserify-addons', ['tsc'], function() { + let searchOptions = { + basedir: `${buildDir}/addons/search`, + debug: true, + entries: [`${outDir}/addons/search/search.js`], + cache: {}, + packageCache: {} + }; + let searchBundle = browserify(searchOptions) + .external(path.join(outDir, 'Terminal.js')) + .bundle() + .pipe(source('./addons/search/search.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true, sourceRoot: ''})) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(buildDir)); + + let winptyCompatOptions = { + basedir: `${buildDir}/addons/winptyCompat`, + debug: true, + entries: [`${outDir}/addons/winptyCompat/winptyCompat.js`], + cache: {}, + packageCache: {} + }; + let winptyCompatBundle = browserify(winptyCompatOptions) + .external(path.join(outDir, 'Terminal.js')) + .bundle() + .pipe(source('./addons/winptyCompat/winptyCompat.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true, sourceRoot: ''})) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(buildDir)); + + // Copy all add-ons from outDir to buildDir + let copyAddons = gulp.src([ + // Copy JS addons + `${outDir}/addons/**/*` + ]).pipe(gulp.dest(`${buildDir}/addons`)); + + return merge(searchBundle, winptyCompatBundle, copyAddons); +}); + +gulp.task('instrument-test', function () { + return gulp.src([`${outDir}/**/*.js`]) + // Covering files + .pipe(istanbul()) + // Force `require` to return covered files + .pipe(istanbul.hookRequire()); +}); + +gulp.task('mocha', ['instrument-test'], function () { + return gulp.src([ + `${outDir}/*test.js`, + `${outDir}/**/*test.js`, + `${outDir}/*integration.js`, + `${outDir}/**/*integration.js` + ], {read: false}) + .pipe(mocha()) + .once('error', () => process.exit(1)) + .pipe(istanbul.writeReports()); +}); + +/** + * Run single test file by file name(without file extension). Example of the command: + * gulp mocha-test --test InputHandler.test + */ +gulp.task('mocha-test', ['instrument-test'], function () { + let testName = util.env.test; + util.log("Run test by Name: " + testName); + return gulp.src([`${outDir}/${testName}.js`, `${outDir}/**/${testName}.js`], {read: false}) + .pipe(mocha()) + .once('error', () => process.exit(1)) + .pipe(istanbul.writeReports()); +}); + +/** + * Use `sorcery` to resolve the source map chain and point back to the TypeScript files. + * (Without this task the source maps produced for the JavaScript bundle points into the + * compiled JavaScript files in ${outDir}/). + */ +gulp.task('sorcery', ['browserify'], function () { + let chain = sorcery.loadSync(`${buildDir}/xterm.js`); + chain.apply(); + chain.writeSync(); +}); + +gulp.task('sorcery-addons', ['browserify-addons'], function () { + var chain = sorcery.loadSync(`${buildDir}/addons/search/search.js`); + chain.apply(); + chain.writeSync(); +}); + +gulp.task('webpack', ['build'], function() { + return gulp.src('demo/main.js') + .pipe(webpack(require('./webpack.config.js'))) + .pipe(gulp.dest('demo/dist/')); +}); + +/** + * Submit coverage results to coveralls.io + */ +gulp.task('coveralls', function () { + gulp.src('coverage/**/lcov.info') + .pipe(coveralls()); +}); + +gulp.task('build', ['sorcery', 'sorcery-addons']); +gulp.task('test', ['mocha']); +gulp.task('default', ['build']); diff --git a/xterm.js/jsdoc.json b/xterm.js/jsdoc.json new file mode 100644 index 0000000..cd864c8 --- /dev/null +++ b/xterm.js/jsdoc.json @@ -0,0 +1,26 @@ +{ + "source": { + "include": [ + "src/" + ], + "exclude": [ + "src/test/" + ], + "excludePattern": "src/.+\\.test\\.(js|ts)$" + }, + "opts": { + "readme": "README.md", + "template": "node_modules/docdash", + "encoding": "utf8", + "destination": "docs/", + "recurse": true, + "verbose": true + }, + "plugins": [ + "plugins/markdown" + ], + "templates": { + "cleverLinks": false, + "monospaceLinks": false + } +} diff --git a/xterm.js/logo-full.png b/xterm.js/logo-full.png new file mode 100644 index 0000000000000000000000000000000000000000..53e0827c55ef0e008ac7a812b0d956abb957ae7f GIT binary patch literal 11635 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 a@fx2G;)6h^MSR4;zSNa { + let terminal: ITerminal; + let buffer: Buffer; + + beforeEach(() => { + terminal = new MockTerminal(); + terminal.cols = INIT_COLS; + terminal.rows = INIT_ROWS; + terminal.options.scrollback = 1000; + buffer = new Buffer(terminal, true); + }); + + describe('constructor', () => { + it('should create a CircularList with max length equal to rows + scrollback, for its lines', () => { + assert.instanceOf(buffer.lines, CircularList); + assert.equal(buffer.lines.maxLength, terminal.rows + terminal.options.scrollback); + }); + it('should set the Buffer\'s scrollBottom value equal to the terminal\'s rows -1', () => { + assert.equal(buffer.scrollBottom, terminal.rows - 1); + }); + }); + + describe('fillViewportRows', () => { + it('should fill the buffer with blank lines based on the size of the viewport', () => { + const blankLineChar = terminal.blankLine()[0]; + buffer.fillViewportRows(); + assert.equal(buffer.lines.length, INIT_ROWS); + for (let y = 0; y < INIT_ROWS; y++) { + assert.equal(buffer.lines.get(y).length, INIT_COLS); + for (let x = 0; x < INIT_COLS; x++) { + assert.deepEqual(buffer.lines.get(y)[x], blankLineChar); + } + } + }); + }); + + describe('resize', () => { + describe('column size is reduced', () => { + it('should not trim the data in the buffer', () => { + buffer.fillViewportRows(); + buffer.resize(INIT_COLS / 2, INIT_ROWS); + assert.equal(buffer.lines.length, INIT_ROWS); + for (let i = 0; i < INIT_ROWS; i++) { + assert.equal(buffer.lines.get(i).length, INIT_COLS); + } + }); + }); + + describe('column size is increased', () => { + it('should add pad columns', () => { + buffer.fillViewportRows(); + buffer.resize(INIT_COLS + 10, INIT_ROWS); + assert.equal(buffer.lines.length, INIT_ROWS); + for (let i = 0; i < INIT_ROWS; i++) { + assert.equal(buffer.lines.get(i).length, INIT_COLS + 10); + } + }); + }); + + describe('row size reduced', () => { + it('should trim blank lines from the end', () => { + buffer.fillViewportRows(); + buffer.resize(INIT_COLS, INIT_ROWS - 10); + assert.equal(buffer.lines.length, INIT_ROWS - 10); + }); + + it('should move the viewport down when it\'s at the end', () => { + buffer.fillViewportRows(); + // Set cursor y to have 5 blank lines below it + buffer.y = INIT_ROWS - 5 - 1; + buffer.resize(INIT_COLS, INIT_ROWS - 10); + // Trim 5 rows + assert.equal(buffer.lines.length, INIT_ROWS - 5); + // Shift the viewport down 5 rows + assert.equal(buffer.ydisp, 5); + assert.equal(buffer.ybase, 5); + }); + + describe('no scrollback', () => { + it('should trim from the top of the buffer when the cursor reaches the bottom', () => { + terminal.options.scrollback = 0; + buffer = new Buffer(terminal, true); + assert.equal(buffer.lines.maxLength, INIT_ROWS); + buffer.y = INIT_ROWS - 1; + buffer.fillViewportRows(); + buffer.lines.get(5)[0][1] = 'a'; + buffer.lines.get(INIT_ROWS - 1)[0][1] = 'b'; + buffer.resize(INIT_COLS, INIT_ROWS - 5); + assert.equal(buffer.lines.get(0)[0][1], 'a'); + assert.equal(buffer.lines.get(INIT_ROWS - 1 - 5)[0][1], 'b'); + }); + }); + }); + + describe('row size increased', () => { + describe('empty buffer', () => { + it('should add blank lines to end', () => { + buffer.fillViewportRows(); + assert.equal(buffer.ydisp, 0); + buffer.resize(INIT_COLS, INIT_ROWS + 10); + assert.equal(buffer.ydisp, 0); + assert.equal(buffer.lines.length, INIT_ROWS + 10); + }); + }); + + describe('filled buffer', () => { + it('should show more of the buffer above', () => { + buffer.fillViewportRows(); + // Create 10 extra blank lines + for (let i = 0; i < 10; i++) { + buffer.lines.push(terminal.blankLine()); + } + // Set cursor to the bottom of the buffer + buffer.y = INIT_ROWS - 1; + // Scroll down 10 lines + buffer.ybase = 10; + buffer.ydisp = 10; + assert.equal(buffer.lines.length, INIT_ROWS + 10); + buffer.resize(INIT_COLS, INIT_ROWS + 5); + // Should be should 5 more lines + assert.equal(buffer.ydisp, 5); + assert.equal(buffer.ybase, 5); + // Should not trim the buffer + assert.equal(buffer.lines.length, INIT_ROWS + 10); + }); + + it('should show more of the buffer below when the viewport is at the top of the buffer', () => { + buffer.fillViewportRows(); + // Create 10 extra blank lines + for (let i = 0; i < 10; i++) { + buffer.lines.push(terminal.blankLine()); + } + // Set cursor to the bottom of the buffer + buffer.y = INIT_ROWS - 1; + // Scroll down 10 lines + buffer.ybase = 10; + buffer.ydisp = 0; + assert.equal(buffer.lines.length, INIT_ROWS + 10); + buffer.resize(INIT_COLS, INIT_ROWS + 5); + // The viewport should remain at the top + assert.equal(buffer.ydisp, 0); + // The buffer ybase should move up 5 lines + assert.equal(buffer.ybase, 5); + // Should not trim the buffer + assert.equal(buffer.lines.length, INIT_ROWS + 10); + }); + }); + }); + + describe('row and column increased', () => { + it('should resize properly', () => { + buffer.fillViewportRows(); + buffer.resize(INIT_COLS + 5, INIT_ROWS + 5); + assert.equal(buffer.lines.length, INIT_ROWS + 5); + for (let i = 0; i < INIT_ROWS + 5; i++) { + assert.equal(buffer.lines.get(i).length, INIT_COLS + 5); + } + }); + }); + }); + + describe('buffer marked to have no scrollback', () => { + it('should always have a scrollback of 0', () => { + assert.equal(terminal.options.scrollback, 1000); + // Test size on initialization + buffer = new Buffer(terminal, false); + buffer.fillViewportRows(); + assert.equal(buffer.lines.maxLength, INIT_ROWS); + // Test size on buffer increase + buffer.resize(INIT_COLS, INIT_ROWS * 2); + assert.equal(buffer.lines.maxLength, INIT_ROWS * 2); + // Test size on buffer decrease + buffer.resize(INIT_COLS, INIT_ROWS / 2); + assert.equal(buffer.lines.maxLength, INIT_ROWS / 2); + }); + }); +}); diff --git a/xterm.js/src/Buffer.ts b/xterm.js/src/Buffer.ts new file mode 100644 index 0000000..623c385 --- /dev/null +++ b/xterm.js/src/Buffer.ts @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, IBuffer } from './Interfaces'; +import { CircularList } from './utils/CircularList'; +import { LineData, CharData } from './Types'; + +export const CHAR_DATA_ATTR_INDEX = 0; +export const CHAR_DATA_CHAR_INDEX = 1; +export const CHAR_DATA_WIDTH_INDEX = 2; +export const CHAR_DATA_CODE_INDEX = 3; +export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 + +/** + * This class represents a terminal buffer (an internal state of the terminal), where the + * following information is stored (in high-level): + * - text content of this particular buffer + * - cursor position + * - scroll position + */ +export class Buffer implements IBuffer { + private _lines: CircularList; + + public ydisp: number; + public ybase: number; + public y: number; + public x: number; + public scrollBottom: number; + public scrollTop: number; + public tabs: any; + public savedY: number; + public savedX: number; + + /** + * Create a new Buffer. + * @param _terminal The terminal the Buffer will belong to. + * @param _hasScrollback Whether the buffer should respect the scrollback of + * the terminal. + */ + constructor( + private _terminal: ITerminal, + private _hasScrollback: boolean + ) { + this.clear(); + } + + public get lines(): CircularList { + return this._lines; + } + + public get hasScrollback(): boolean { + return this._hasScrollback && this.lines.maxLength > this._terminal.rows; + } + + public get isCursorInViewport(): boolean { + const absoluteY = this.ybase + this.y; + const relativeY = absoluteY - this.ydisp; + return (relativeY >= 0 && relativeY < this._terminal.rows); + } + + /** + * Gets the correct buffer length based on the rows provided, the terminal's + * scrollback and whether this buffer is flagged to have scrollback or not. + * @param rows The terminal rows to use in the calculation. + */ + private _getCorrectBufferLength(rows: number): number { + if (!this._hasScrollback) { + return rows; + } + + const correctBufferLength = rows + this._terminal.options.scrollback; + + return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength; + } + + /** + * Fills the buffer's viewport with blank lines. + */ + public fillViewportRows(): void { + if (this._lines.length === 0) { + let i = this._terminal.rows; + while (i--) { + this.lines.push(this._terminal.blankLine()); + } + } + } + + /** + * Clears the buffer to it's initial state, discarding all previous data. + */ + public clear(): void { + this.ydisp = 0; + this.ybase = 0; + this.y = 0; + this.x = 0; + this._lines = new CircularList(this._getCorrectBufferLength(this._terminal.rows)); + this.scrollTop = 0; + this.scrollBottom = this._terminal.rows - 1; + this.setupTabStops(); + } + + /** + * Resizes the buffer, adjusting its data accordingly. + * @param newCols The new number of columns. + * @param newRows The new number of rows. + */ + public resize(newCols: number, newRows: number): void { + // Increase max length if needed before adjustments to allow space to fill + // as required. + const newMaxLength = this._getCorrectBufferLength(newRows); + if (newMaxLength > this._lines.maxLength) { + this._lines.maxLength = newMaxLength; + } + + // The following adjustments should only happen if the buffer has been + // initialized/filled. + if (this._lines.length > 0) { + // Deal with columns increasing (we don't do anything when columns reduce) + if (this._terminal.cols < newCols) { + const ch: CharData = [this._terminal.defAttr, ' ', 1, 32]; // does xterm use the default attr? + for (let i = 0; i < this._lines.length; i++) { + // TODO: This should be removed, with tests setup for the case that was + // causing the underlying bug, see https://github.com/sourcelair/xterm.js/issues/824 + if (this._lines.get(i) === undefined) { + this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols)); + } + while (this._lines.get(i).length < newCols) { + this._lines.get(i).push(ch); + } + } + } + + // Resize rows in both directions as needed + let addToY = 0; + if (this._terminal.rows < newRows) { + for (let y = this._terminal.rows; y < newRows; y++) { + if (this._lines.length < newRows + this.ybase) { + if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) { + // There is room above the buffer and there are no empty elements below the line, + // scroll up + this.ybase--; + addToY++; + if (this.ydisp > 0) { + // Viewport is at the top of the buffer, must increase downwards + this.ydisp--; + } + } else { + // Add a blank line if there is no buffer left at the top to scroll to, or if there + // are blank lines after the cursor + this._lines.push(this._terminal.blankLine(undefined, undefined, newCols)); + } + } + } + } else { // (this._terminal.rows >= newRows) + for (let y = this._terminal.rows; y > newRows; y--) { + if (this._lines.length > newRows + this.ybase) { + if (this._lines.length > this.ybase + this.y + 1) { + // The line is a blank line below the cursor, remove it + this._lines.pop(); + } else { + // The line is the cursor, scroll down + this.ybase++; + this.ydisp++; + } + } + } + } + + // Reduce max length if needed after adjustments, this is done after as it + // would otherwise cut data from the bottom of the buffer. + if (newMaxLength < this._lines.maxLength) { + // Trim from the top of the buffer and adjust ybase and ydisp. + const amountToTrim = this._lines.length - newMaxLength; + if (amountToTrim > 0) { + this._lines.trimStart(amountToTrim); + this.ybase = Math.max(this.ybase - amountToTrim, 0); + this.ydisp = Math.max(this.ydisp - amountToTrim, 0); + } + this._lines.maxLength = newMaxLength; + } + + // Make sure that the cursor stays on screen + if (this.y >= newRows) { + this.y = newRows - 1; + } + if (addToY) { + this.y += addToY; + } + + if (this.x >= newCols) { + this.x = newCols - 1; + } + + this.scrollTop = 0; + } + + this.scrollBottom = newRows - 1; + } + + /** + * Translates a buffer line to a string, with optional start and end columns. + * Wide characters will count as two columns in the resulting string. This + * function is useful for getting the actual text underneath the raw selection + * position. + * @param line The line being translated. + * @param trimRight Whether to trim whitespace to the right. + * @param startCol The column to start at. + * @param endCol The column to end at. + */ + public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol: number = null): string { + // Get full line + let lineString = ''; + const line = this.lines.get(lineIndex); + if (!line) { + return ''; + } + + // Initialize column and index values. Column values represent the actual + // cell column, indexes represent the index in the string. Indexes are + // needed here because some chars are 0 characters long (eg. after wide + // chars) and some chars are longer than 1 characters long (eg. emojis). + let startIndex = startCol; + endCol = endCol || line.length; + let endIndex = endCol; + + for (let i = 0; i < line.length; i++) { + const char = line[i]; + lineString += char[CHAR_DATA_CHAR_INDEX]; + // Adjust start and end cols for wide characters if they affect their + // column indexes + if (char[CHAR_DATA_WIDTH_INDEX] === 0) { + if (startCol >= i) { + startIndex--; + } + if (endCol >= i) { + endIndex--; + } + } else { + // Adjust the columns to take glyphs that are represented by multiple + // code points into account. + if (char[CHAR_DATA_CHAR_INDEX].length > 1) { + if (startCol > i) { + startIndex += char[CHAR_DATA_CHAR_INDEX].length - 1; + } + if (endCol > i) { + endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1; + } + } + } + } + + // Calculate the final end col by trimming whitespace on the right of the + // line if needed. + if (trimRight) { + const rightWhitespaceIndex = lineString.search(/\s+$/); + if (rightWhitespaceIndex !== -1) { + endIndex = Math.min(endIndex, rightWhitespaceIndex); + } + // Return the empty string if only trimmed whitespace is selected + if (endIndex <= startIndex) { + return ''; + } + } + + return lineString.substring(startIndex, endIndex); + } + + /** + * Setup the tab stops. + * @param i The index to start setting up tab stops from. + */ + public setupTabStops(i?: number): void { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } else { + this.tabs = {}; + i = 0; + } + + for (; i < this._terminal.cols; i += this._terminal.options.tabStopWidth) { + this.tabs[i] = true; + } + } + + /** + * Move the cursor to the previous tab stop from the given position (default is current). + * @param x The position to move the cursor to the previous tab stop. + */ + public prevStop(x?: number): number { + if (x == null) { + x = this.x; + } + while (!this.tabs[--x] && x > 0); + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + } + + /** + * Move the cursor one tab stop forward from the given position (default is current). + * @param x The position to move the cursor one tab stop forward. + */ + public nextStop(x?: number): number { + if (x == null) { + x = this.x; + } + while (!this.tabs[++x] && x < this._terminal.cols); + return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x; + } +} diff --git a/xterm.js/src/BufferSet.test.ts b/xterm.js/src/BufferSet.test.ts new file mode 100644 index 0000000..b9c1824 --- /dev/null +++ b/xterm.js/src/BufferSet.test.ts @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { ITerminal } from './Interfaces'; +import { BufferSet } from './BufferSet'; +import { Buffer } from './Buffer'; +import { MockTerminal } from './utils/TestUtils.test'; + +describe('BufferSet', () => { + let terminal: ITerminal; + let bufferSet: BufferSet; + + beforeEach(() => { + terminal = new MockTerminal(); + terminal.cols = 80; + terminal.rows = 24; + terminal.options.scrollback = 1000; + bufferSet = new BufferSet(terminal); + }); + + describe('constructor', () => { + it('should create two different buffers: alt and normal', () => { + assert.instanceOf(bufferSet.normal, Buffer); + assert.instanceOf(bufferSet.alt, Buffer); + assert.notEqual(bufferSet.normal, bufferSet.alt); + }); + }); + + describe('activateNormalBuffer', () => { + beforeEach(() => { + bufferSet.activateNormalBuffer(); + }); + + it('should set the normal buffer as the currently active buffer', () => { + assert.equal(bufferSet.active, bufferSet.normal); + }); + }); + + describe('activateAltBuffer', () => { + beforeEach(() => { + bufferSet.activateAltBuffer(); + }); + + it('should set the alt buffer as the currently active buffer', () => { + assert.equal(bufferSet.active, bufferSet.alt); + }); + }); +}); diff --git a/xterm.js/src/BufferSet.ts b/xterm.js/src/BufferSet.ts new file mode 100644 index 0000000..e31d227 --- /dev/null +++ b/xterm.js/src/BufferSet.ts @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, IBufferSet } from './Interfaces'; +import { Buffer } from './Buffer'; +import { EventEmitter } from './EventEmitter'; + +/** + * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and + * provides also utilities for working with them. + */ +export class BufferSet extends EventEmitter implements IBufferSet { + private _normal: Buffer; + private _alt: Buffer; + private _activeBuffer: Buffer; + + /** + * Create a new BufferSet for the given terminal. + * @param {Terminal} terminal - The terminal the BufferSet will belong to + */ + constructor(private _terminal: ITerminal) { + super(); + this._normal = new Buffer(this._terminal, true); + this._normal.fillViewportRows(); + + // The alt buffer should never have scrollback. + // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer + this._alt = new Buffer(this._terminal, false); + this._activeBuffer = this._normal; + + this.setupTabStops(); + } + + /** + * Returns the alt Buffer of the BufferSet + * @returns {Buffer} + */ + public get alt(): Buffer { + return this._alt; + } + + /** + * Returns the normal Buffer of the BufferSet + * @returns {Buffer} + */ + public get active(): Buffer { + return this._activeBuffer; + } + + /** + * Returns the currently active Buffer of the BufferSet + * @returns {Buffer} + */ + public get normal(): Buffer { + return this._normal; + } + + /** + * Sets the normal Buffer of the BufferSet as its currently active Buffer + */ + public activateNormalBuffer(): void { + // The alt buffer should always be cleared when we switch to the normal + // buffer. This frees up memory since the alt buffer should always be new + // when activated. + this._alt.clear(); + + this._activeBuffer = this._normal; + this.emit('activate', this._normal); + } + + /** + * Sets the alt Buffer of the BufferSet as its currently active Buffer + */ + public activateAltBuffer(): void { + // Since the alt buffer is always cleared when the normal buffer is + // activated, we want to fill it when switching to it. + this._alt.fillViewportRows(); + this._activeBuffer = this._alt; + this.emit('activate', this._alt); + } + + /** + * Resizes both normal and alt buffers, adjusting their data accordingly. + * @param newCols The new number of columns. + * @param newRows The new number of rows. + */ + public resize(newCols: number, newRows: number): void { + this._normal.resize(newCols, newRows); + this._alt.resize(newCols, newRows); + } + + /** + * Setup the tab stops. + * @param i The index to start setting up tab stops from. + */ + public setupTabStops(i?: number): void { + this._normal.setupTabStops(i); + this._alt.setupTabStops(i); + } +} diff --git a/xterm.js/src/CharWidth.ts b/xterm.js/src/CharWidth.ts new file mode 100644 index 0000000..d296b43 --- /dev/null +++ b/xterm.js/src/CharWidth.ts @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number { + // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c + // combining characters + const COMBINING_BMP = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + ]; + const COMBINING_HIGH = [ + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + // binary search + function bisearch(ucs: number, data: number[][]): boolean { + let min = 0; + let max = data.length - 1; + let mid; + if (ucs < data[0][0] || ucs > data[max][1]) + return false; + while (max >= min) { + mid = (min + max) >> 1; + if (ucs > data[mid][1]) + min = mid + 1; + else if (ucs < data[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidthBMP(ucs: number): number { + // test for 8-bit control characters + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + // binary search in table of non-spacing characters + if (bisearch(ucs, COMBINING_BMP)) + return 0; + // if we arrive here, ucs is not a combining or C0/C1 control character + if (isWideBMP(ucs)) { + return 2; + } + return 1; + } + function isWideBMP(ucs: number): boolean { + return ( + ucs >= 0x1100 && ( + ucs <= 0x115f || // Hangul Jamo init. consonants + ucs === 0x2329 || + ucs === 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi + (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables + (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs + (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms + (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms + (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms + (ucs >= 0xffe0 && ucs <= 0xffe6))); + } + function wcwidthHigh(ucs: number): 0 | 1 | 2 { + if (bisearch(ucs, COMBINING_HIGH)) + return 0; + if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) { + return 2; + } + return 1; + } + const control = opts.control | 0; + let table: number[] | Uint32Array = null; + function init_table(): number[] | Uint32Array { + // lookup table for BMP + const CODEPOINTS = 65536; // BMP holds 65536 codepoints + const BITWIDTH = 2; // a codepoint can have a width of 0, 1 or 2 + const ITEMSIZE = 32; // using uint32_t + const CONTAINERSIZE = CODEPOINTS * BITWIDTH / ITEMSIZE; + const CODEPOINTS_PER_ITEM = ITEMSIZE / BITWIDTH; + table = (typeof Uint32Array === 'undefined') + ? new Array(CONTAINERSIZE) + : new Uint32Array(CONTAINERSIZE); + for (let i = 0; i < CONTAINERSIZE; ++i) { + let num = 0; + let pos = CODEPOINTS_PER_ITEM; + while (pos--) + num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos); + table[i] = num; + } + return table; + } + // get width from lookup table + // position in container : num / CODEPOINTS_PER_ITEM + // ==> n = table[Math.floor(num / 16)] + // ==> n = table[num >> 4] + // 16 codepoints per number: FFEEDDCCBBAA99887766554433221100 + // position in number : (num % CODEPOINTS_PER_ITEM) * BITWIDTH + // ==> m = (n % 16) * 2 + // ==> m = (num & 15) << 1 + // right shift to position m + // ==> n = n >> m e.g. m=12 000000000000FFEEDDCCBBAA99887766 + // we are only interested in 2 LSBs, cut off higher bits + // ==> n = n & 3 e.g. 000000000000000000000000000000XX + return function (num: number): number { + num = num | 0; // get asm.js like optimization under V8 + if (num < 32) + return control | 0; + if (num < 127) + return 1; + let t = table || init_table(); + if (num < 65536) + return t[num >> 4] >> ((num & 15) << 1) & 3; + // do a full search for high codepoints + return wcwidthHigh(num); + }; +})({nul: 0, control: 0}); // configurable options diff --git a/xterm.js/src/Charsets.ts b/xterm.js/src/Charsets.ts new file mode 100644 index 0000000..0ee91d3 --- /dev/null +++ b/xterm.js/src/Charsets.ts @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { Charset } from './Types'; + +/** + * The character sets supported by the terminal. These enable several languages + * to be represented within the terminal with only 8-bit encoding. See ISO 2022 + * for a discussion on character sets. Only VT100 character sets are supported. + */ +export const CHARSETS: { [key: string]: Charset } = {}; + +/** + * The default character set, US. + */ +export const DEFAULT_CHARSET: Charset = CHARSETS['B']; + +/** + * DEC Special Character and Line Drawing Set. + * Reference: http://vt100.net/docs/vt102-ug/table5-13.html + * A lot of curses apps use this if they see TERM=xterm. + * testing: echo -e '\e(0a\e(B' + * The xterm output sometimes seems to conflict with the + * reference above. xterm seems in line with the reference + * when running vttest however. + * The table below now uses xterm's output from vttest. + */ +CHARSETS['0'] = { + '`': '\u25c6', // '◆' + 'a': '\u2592', // '▒' + 'b': '\u0009', // '\t' + 'c': '\u000c', // '\f' + 'd': '\u000d', // '\r' + 'e': '\u000a', // '\n' + 'f': '\u00b0', // '°' + 'g': '\u00b1', // '±' + 'h': '\u2424', // '\u2424' (NL) + 'i': '\u000b', // '\v' + 'j': '\u2518', // '┘' + 'k': '\u2510', // '┐' + 'l': '\u250c', // '┌' + 'm': '\u2514', // '└' + 'n': '\u253c', // '┼' + 'o': '\u23ba', // '⎺' + 'p': '\u23bb', // '⎻' + 'q': '\u2500', // '─' + 'r': '\u23bc', // '⎼' + 's': '\u23bd', // '⎽' + 't': '\u251c', // '├' + 'u': '\u2524', // '┤' + 'v': '\u2534', // '┴' + 'w': '\u252c', // '┬' + 'x': '\u2502', // '│' + 'y': '\u2264', // '≤' + 'z': '\u2265', // '≥' + '{': '\u03c0', // 'π' + '|': '\u2260', // '≠' + '}': '\u00a3', // '£' + '~': '\u00b7' // '·' +}; + +/** + * British character set + * ESC (A + * Reference: http://vt100.net/docs/vt220-rm/table2-5.html + */ +CHARSETS['A'] = { + '#': '£' +}; + +/** + * United States character set + * ESC (B + */ +CHARSETS['B'] = null; + +/** + * Dutch character set + * ESC (4 + * Reference: http://vt100.net/docs/vt220-rm/table2-6.html + */ +CHARSETS['4'] = { + '#': '£', + '@': '¾', + '[': 'ij', + '\\': '½', + ']': '|', + '{': '¨', + '|': 'f', + '}': '¼', + '~': '´' +}; + +/** + * Finnish character set + * ESC (C or ESC (5 + * Reference: http://vt100.net/docs/vt220-rm/table2-7.html + */ +CHARSETS['C'] = +CHARSETS['5'] = { + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' +}; + +/** + * French character set + * ESC (R + * Reference: http://vt100.net/docs/vt220-rm/table2-8.html + */ +CHARSETS['R'] = { + '#': '£', + '@': 'à', + '[': '°', + '\\': 'ç', + ']': '§', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': '¨' +}; + +/** + * French Canadian character set + * ESC (Q + * Reference: http://vt100.net/docs/vt220-rm/table2-9.html + */ +CHARSETS['Q'] = { + '@': 'à', + '[': 'â', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '`': 'ô', + '{': 'é', + '|': 'ù', + '}': 'è', + '~': 'û' +}; + +/** + * German character set + * ESC (K + * Reference: http://vt100.net/docs/vt220-rm/table2-10.html + */ +CHARSETS['K'] = { + '@': '§', + '[': 'Ä', + '\\': 'Ö', + ']': 'Ü', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'ß' +}; + +/** + * Italian character set + * ESC (Y + * Reference: http://vt100.net/docs/vt220-rm/table2-11.html + */ +CHARSETS['Y'] = { + '#': '£', + '@': '§', + '[': '°', + '\\': 'ç', + ']': 'é', + '`': 'ù', + '{': 'à', + '|': 'ò', + '}': 'è', + '~': 'ì' +}; + +/** + * Norwegian/Danish character set + * ESC (E or ESC (6 + * Reference: http://vt100.net/docs/vt220-rm/table2-12.html + */ +CHARSETS['E'] = +CHARSETS['6'] = { + '@': 'Ä', + '[': 'Æ', + '\\': 'Ø', + ']': 'Å', + '^': 'Ü', + '`': 'ä', + '{': 'æ', + '|': 'ø', + '}': 'å', + '~': 'ü' +}; + +/** + * Spanish character set + * ESC (Z + * Reference: http://vt100.net/docs/vt220-rm/table2-13.html + */ +CHARSETS['Z'] = { + '#': '£', + '@': '§', + '[': '¡', + '\\': 'Ñ', + ']': '¿', + '{': '°', + '|': 'ñ', + '}': 'ç' +}; + +/** + * Swedish character set + * ESC (H or ESC (7 + * Reference: http://vt100.net/docs/vt220-rm/table2-14.html + */ +CHARSETS['H'] = +CHARSETS['7'] = { + '@': 'É', + '[': 'Ä', + '\\': 'Ö', + ']': 'Å', + '^': 'Ü', + '`': 'é', + '{': 'ä', + '|': 'ö', + '}': 'å', + '~': 'ü' +}; + +/** + * Swiss character set + * ESC (= + * Reference: http://vt100.net/docs/vt220-rm/table2-15.html + */ +CHARSETS['='] = { + '#': 'ù', + '@': 'à', + '[': 'é', + '\\': 'ç', + ']': 'ê', + '^': 'î', + '_': 'è', + '`': 'ô', + '{': 'ä', + '|': 'ö', + '}': 'ü', + '~': 'û' +}; diff --git a/xterm.js/src/CompositionHelper.test.ts b/xterm.js/src/CompositionHelper.test.ts new file mode 100644 index 0000000..09a59f7 --- /dev/null +++ b/xterm.js/src/CompositionHelper.test.ts @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { CompositionHelper } from './CompositionHelper'; + +describe('CompositionHelper', () => { + let terminal; + let compositionHelper; + let compositionView; + let textarea; + let handledText; + + beforeEach(() => { + compositionView = { + classList: { + add: () => {}, + remove: () => {}, + }, + getBoundingClientRect: () => { + return { width: 0 }; + }, + style: { + left: 0, + top: 0 + }, + textContent: '' + }; + textarea = { + value: '', + style: { + left: 0, + top: 0 + } + }; + terminal = { + element: { + querySelector: () => { + return { offsetLeft: 0, offsetTop: 0 }; + } + }, + handler: (text: string) => { + handledText += text; + }, + buffer: { + isCursorInViewport: true + }, + charMeasure: { + height: 10, + width: 10 + }, + options: { + lineHeight: 1 + } + }; + handledText = ''; + compositionHelper = new CompositionHelper(textarea, compositionView, terminal); + }); + + describe('Input', () => { + it('Should insert simple characters', (done) => { + // First character 'ㅇ' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, 'ㅇ'); + // Second character 'ㅇ' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, 'ㅇㅇ'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert complex characters', (done) => { + // First character '앙' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, '앙'); + // Second character '앙' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = '앙ㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '앙아'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙앙'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, '앙앙'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert complex characters that change with following character', (done) => { + // First character '아' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아'; + setTimeout(() => { // wait for any textarea updates + // Start second character '아' in first character + compositionHelper.compositionupdate({ data: '앙' }); + textarea.value = '앙'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: '아' }); + textarea.value = '아아'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, '아아'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert multi-characters compositions', (done) => { + // First character 'だ' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'd' }); + textarea.value = 'd'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: 'だ' }); + textarea.value = 'だ'; + setTimeout(() => { // wait for any textarea updates + // Second character 'あ' + compositionHelper.compositionupdate({ data: 'だあ' }); + textarea.value = 'だあ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, 'だあ'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert multi-character compositions that are converted to other characters with the same length', (done) => { + // First character 'だ' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'd' }); + textarea.value = 'd'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: 'だ' }); + textarea.value = 'だ'; + setTimeout(() => { // wait for any textarea updates + // Second character 'ー' + compositionHelper.compositionupdate({ data: 'だー' }); + textarea.value = 'だー'; + setTimeout(() => { // wait for any textarea updates + // Convert to katakana 'ダー' + compositionHelper.compositionupdate({ data: 'ダー' }); + textarea.value = 'ダー'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, 'ダー'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert multi-character compositions that are converted to other characters with different lengths', (done) => { + // First character 'い' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'い' }); + textarea.value = 'い'; + setTimeout(() => { // wait for any textarea updates + // Second character 'ま' + compositionHelper.compositionupdate({ data: 'いm' }); + textarea.value = 'いm'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionupdate({ data: 'いま' }); + textarea.value = 'いま'; + setTimeout(() => { // wait for any textarea updates + // Convert to kanji '今' + compositionHelper.compositionupdate({ data: '今' }); + textarea.value = '今'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, '今'); + done(); + }, 0); + }, 0); + }, 0); + }, 0); + }, 0); + }); + + it('Should insert non-composition characters input immediately after composition characters', (done) => { + // First character 'ㅇ' + compositionHelper.compositionstart(); + compositionHelper.compositionupdate({ data: 'ㅇ' }); + textarea.value = 'ㅇ'; + setTimeout(() => { // wait for any textarea updates + compositionHelper.compositionend(); + // Second character '1' (a non-composition character) + textarea.value = 'ㅇ1'; + setTimeout(() => { // wait for any textarea updates + assert.equal(handledText, 'ㅇ1'); + done(); + }, 0); + }, 0); + }); + }); +}); diff --git a/xterm.js/src/CompositionHelper.ts b/xterm.js/src/CompositionHelper.ts new file mode 100644 index 0000000..ca5b4f4 --- /dev/null +++ b/xterm.js/src/CompositionHelper.ts @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal } from './Interfaces'; + +interface IPosition { + start: number; + end: number; +} + +/** + * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend + * events, displaying the in-progress composition to the UI and forwarding the final composition + * to the handler. + */ +export class CompositionHelper { + /** + * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or + * IME. This variable determines whether the compositionText should be displayed on the UI. + */ + private isComposing: boolean; + + /** + * The position within the input textarea's value of the current composition. + */ + private compositionPosition: IPosition; + + /** + * Whether a composition is in the process of being sent, setting this to false will cancel any + * in-progress composition. + */ + private isSendingComposition: boolean; + + /** + * Creates a new CompositionHelper. + * @param textarea The textarea that xterm uses for input. + * @param compositionView The element to display the in-progress composition in. + * @param terminal The Terminal to forward the finished composition to. + */ + constructor( + private textarea: HTMLTextAreaElement, + private compositionView: HTMLElement, + private terminal: ITerminal + ) { + this.isComposing = false; + this.isSendingComposition = false; + this.compositionPosition = { start: null, end: null }; + } + + /** + * Handles the compositionstart event, activating the composition view. + */ + public compositionstart(): void { + this.isComposing = true; + this.compositionPosition.start = this.textarea.value.length; + this.compositionView.textContent = ''; + this.compositionView.classList.add('active'); + } + + /** + * Handles the compositionupdate event, updating the composition view. + * @param {CompositionEvent} ev The event. + */ + public compositionupdate(ev: CompositionEvent): void { + this.compositionView.textContent = ev.data; + this.updateCompositionElements(); + setTimeout(() => { + this.compositionPosition.end = this.textarea.value.length; + }, 0); + } + + /** + * Handles the compositionend event, hiding the composition view and sending the composition to + * the handler. + */ + public compositionend(): void { + this.finalizeComposition(true); + } + + /** + * Handles the keydown event, routing any necessary events to the CompositionHelper functions. + * @param ev The keydown event. + * @return Whether the Terminal should continue processing the keydown event. + */ + public keydown(ev: KeyboardEvent): boolean { + if (this.isComposing || this.isSendingComposition) { + if (ev.keyCode === 229) { + // Continue composing if the keyCode is the "composition character" + return false; + } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { + // Continue composing if the keyCode is a modifier key + return false; + } else { + // Finish composition immediately. This is mainly here for the case where enter is + // pressed and the handler needs to be triggered before the command is executed. + this.finalizeComposition(false); + } + } + + if (ev.keyCode === 229) { + // If the "composition character" is used but gets to this point it means a non-composition + // character (eg. numbers and punctuation) was pressed when the IME was active. + this.handleAnyTextareaChanges(); + return false; + } + + return true; + } + + /** + * Finalizes the composition, resuming regular input actions. This is called when a composition + * is ending. + * @param waitForPropogation Whether to wait for events to propogate before sending + * the input. This should be false if a non-composition keystroke is entered before the + * compositionend event is triggered, such as enter, so that the composition is send before + * the command is executed. + */ + private finalizeComposition(waitForPropogation: boolean): void { + this.compositionView.classList.remove('active'); + this.isComposing = false; + this.clearTextareaPosition(); + + if (!waitForPropogation) { + // Cancel any delayed composition send requests and send the input immediately. + this.isSendingComposition = false; + const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end); + this.terminal.handler(input); + } else { + // Make a deep copy of the composition position here as a new compositionstart event may + // fire before the setTimeout executes. + const currentCompositionPosition = { + start: this.compositionPosition.start, + end: this.compositionPosition.end, + }; + + // Since composition* events happen before the changes take place in the textarea on most + // browsers, use a setTimeout with 0ms time to allow the native compositionend event to + // complete. This ensures the correct character is retrieved, this solution was used + // because: + // - The compositionend event's data property is unreliable, at least on Chromium + // - The last compositionupdate event's data property does not always accurately describe + // the character, a counter example being Korean where an ending consonsant can move to + // the following character if the following input is a vowel. + this.isSendingComposition = true; + setTimeout(() => { + // Ensure that the input has not already been sent + if (this.isSendingComposition) { + this.isSendingComposition = false; + let input; + if (this.isComposing) { + // Use the end position to get the string if a new composition has started. + input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end); + } else { + // Don't use the end position here in order to pick up any characters after the + // composition has finished, for example when typing a non-composition character + // (eg. 2) after a composition character. + input = this.textarea.value.substring(currentCompositionPosition.start); + } + this.terminal.handler(input); + } + }, 0); + } + } + + /** + * Apply any changes made to the textarea after the current event chain is allowed to complete. + * This should be called when not currently composing but a keydown event with the "composition + * character" (229) is triggered, in order to allow non-composition text to be entered when an + * IME is active. + */ + private handleAnyTextareaChanges(): void { + const oldValue = this.textarea.value; + setTimeout(() => { + // Ignore if a composition has started since the timeout + if (!this.isComposing) { + const newValue = this.textarea.value; + const diff = newValue.replace(oldValue, ''); + if (diff.length > 0) { + this.terminal.handler(diff); + } + } + }, 0); + } + + /** + * Positions the composition view on top of the cursor and the textarea just below it (so the + * IME helper dialog is positioned correctly). + * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is + * necessary as the IME events across browsers are not consistently triggered. + */ + public updateCompositionElements(dontRecurse?: boolean): void { + if (!this.isComposing) { + return; + } + + if (this.terminal.buffer.isCursorInViewport) { + const cellHeight = Math.ceil(this.terminal.charMeasure.height * this.terminal.options.lineHeight); + const cursorTop = this.terminal.buffer.y * cellHeight; + const cursorLeft = this.terminal.buffer.x * this.terminal.charMeasure.width; + + this.compositionView.style.left = cursorLeft + 'px'; + this.compositionView.style.top = cursorTop + 'px'; + this.compositionView.style.height = cellHeight + 'px'; + this.compositionView.style.lineHeight = cellHeight + 'px'; + // Sync the textarea to the exact position of the composition view so the IME knows where the + // text is. + const compositionViewBounds = this.compositionView.getBoundingClientRect(); + this.textarea.style.left = cursorLeft + 'px'; + this.textarea.style.top = cursorTop + 'px'; + this.textarea.style.width = compositionViewBounds.width + 'px'; + this.textarea.style.height = compositionViewBounds.height + 'px'; + this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; + } + + if (!dontRecurse) { + setTimeout(() => this.updateCompositionElements(true), 0); + } + }; + + /** + * Clears the textarea's position so that the cursor does not blink on IE. + * @private + */ + private clearTextareaPosition(): void { + this.textarea.style.left = ''; + this.textarea.style.top = ''; + }; +} diff --git a/xterm.js/src/EscapeSequences.ts b/xterm.js/src/EscapeSequences.ts new file mode 100644 index 0000000..cb97c36 --- /dev/null +++ b/xterm.js/src/EscapeSequences.ts @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +/** + * C0 control codes + * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes + */ +export namespace C0 { + /** Null (Caret = ^@, C = \0) */ + export const NUL = '\x00'; + /** Start of Heading (Caret = ^A) */ + export const SOH = '\x01'; + /** Start of Text (Caret = ^B) */ + export const STX = '\x02'; + /** End of Text (Caret = ^C) */ + export const ETX = '\x03'; + /** End of Transmission (Caret = ^D) */ + export const EOT = '\x04'; + /** Enquiry (Caret = ^E) */ + export const ENQ = '\x05'; + /** Acknowledge (Caret = ^F) */ + export const ACK = '\x06'; + /** Bell (Caret = ^G, C = \a) */ + export const BEL = '\x07'; + /** Backspace (Caret = ^H, C = \b) */ + export const BS = '\x08'; + /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \t) */ + export const HT = '\x09'; + /** Line Feed (Caret = ^J, C = \n) */ + export const LF = '\x0a'; + /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \v) */ + export const VT = '\x0b'; + /** Form Feed (Caret = ^L, C = \f) */ + export const FF = '\x0c'; + /** Carriage Return (Caret = ^M, C = \r) */ + export const CR = '\x0d'; + /** Shift Out (Caret = ^N) */ + export const SO = '\x0e'; + /** Shift In (Caret = ^O) */ + export const SI = '\x0f'; + /** Data Link Escape (Caret = ^P) */ + export const DLE = '\x10'; + /** Device Control One (XON) (Caret = ^Q) */ + export const DC1 = '\x11'; + /** Device Control Two (Caret = ^R) */ + export const DC2 = '\x12'; + /** Device Control Three (XOFF) (Caret = ^S) */ + export const DC3 = '\x13'; + /** Device Control Four (Caret = ^T) */ + export const DC4 = '\x14'; + /** Negative Acknowledge (Caret = ^U) */ + export const NAK = '\x15'; + /** Synchronous Idle (Caret = ^V) */ + export const SYN = '\x16'; + /** End of Transmission Block (Caret = ^W) */ + export const ETB = '\x17'; + /** Cancel (Caret = ^X) */ + export const CAN = '\x18'; + /** End of Medium (Caret = ^Y) */ + export const EM = '\x19'; + /** Substitute (Caret = ^Z) */ + export const SUB = '\x1a'; + /** Escape (Caret = ^[, C = \e) */ + export const ESC = '\x1b'; + /** File Separator (Caret = ^\) */ + export const FS = '\x1c'; + /** Group Separator (Caret = ^]) */ + export const GS = '\x1d'; + /** Record Separator (Caret = ^^) */ + export const RS = '\x1e'; + /** Unit Separator (Caret = ^_) */ + export const US = '\x1f'; + /** Space */ + export const SP = '\x20'; + /** Delete (Caret = ^?) */ + export const DEL = '\x7f'; +}; diff --git a/xterm.js/src/EventEmitter.test.ts b/xterm.js/src/EventEmitter.test.ts new file mode 100644 index 0000000..c1f0a0a --- /dev/null +++ b/xterm.js/src/EventEmitter.test.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { EventEmitter } from './EventEmitter'; + +describe('EventEmitter', () => { + let eventEmitter: EventEmitter; + + beforeEach(() => { + eventEmitter = new EventEmitter(); + }); + + describe('once', () => { + it('should trigger the listener only once', () => { + let count = 0; + const listener = () => count++; + eventEmitter.once('test', listener); + eventEmitter.emit('test'); + assert.equal(count, 1); + eventEmitter.emit('test'); + assert.equal(count, 1); + }); + }); + + describe('emit', () => { + it('should emit events to listeners', () => { + let count1 = 0; + let count2 = 0; + const listener1 = () => count1++; + const listener2 = () => count2++; + eventEmitter.on('test', listener1); + eventEmitter.on('test', listener2); + eventEmitter.emit('test'); + assert.equal(count1, 1); + assert.equal(count2, 1); + eventEmitter.emit('test'); + assert.equal(count1, 2); + assert.equal(count2, 2); + }); + + it('should manage multiple listener types', () => { + let count1 = 0; + let count2 = 0; + const listener1 = () => count1++; + const listener2 = () => count2++; + eventEmitter.on('test', listener1); + eventEmitter.on('foo', listener2); + eventEmitter.emit('test'); + assert.equal(count1, 1); + assert.equal(count2, 0); + eventEmitter.emit('foo'); + assert.equal(count1, 1); + assert.equal(count2, 1); + }); + }); + + describe('listeners', () => { + it('should return listeners for the type requested', () => { + assert.equal(eventEmitter.listeners('test').length, 0); + const listener = () => {}; + eventEmitter.on('test', listener); + assert.deepEqual(eventEmitter.listeners('test'), [listener]); + }); + }); + + describe('off', () => { + it('should remove the specific listener', () => { + const listener1 = () => {}; + const listener2 = () => {}; + eventEmitter.on('foo', listener1); + eventEmitter.on('foo', listener2); + assert.equal(eventEmitter.listeners('foo').length, 2); + eventEmitter.off('foo', listener1); + assert.deepEqual(eventEmitter.listeners('foo'), [listener2]); + }); + }); + + describe('removeAllListeners', () => { + it('should clear all listeners', () => { + eventEmitter.on('foo', () => {}); + assert.equal(eventEmitter.listeners('foo').length, 1); + eventEmitter.removeAllListeners('foo'); + assert.equal(eventEmitter.listeners('foo').length, 0); + }); + }); +}); diff --git a/xterm.js/src/EventEmitter.ts b/xterm.js/src/EventEmitter.ts new file mode 100644 index 0000000..414eac8 --- /dev/null +++ b/xterm.js/src/EventEmitter.ts @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IEventEmitter, IListenerType } from './Interfaces'; + +export class EventEmitter implements IEventEmitter { + private _events: {[type: string]: IListenerType[]}; + + constructor() { + // Restore the previous events if available, this will happen if the + // constructor is called multiple times on the same object (terminal reset). + this._events = this._events || {}; + } + + public on(type: string, listener: IListenerType): void { + this._events[type] = this._events[type] || []; + this._events[type].push(listener); + } + + public off(type: string, listener: IListenerType): void { + if (!this._events[type]) { + return; + } + + let obj = this._events[type]; + let i = obj.length; + + while (i--) { + if (obj[i] === listener || obj[i].listener === listener) { + obj.splice(i, 1); + return; + } + } + } + + public removeAllListeners(type: string): void { + if (this._events[type]) { + delete this._events[type]; + } + } + + public once(type: string, listener: IListenerType): void { + function on(): void { + let args = Array.prototype.slice.call(arguments); + this.off(type, on); + listener.apply(this, args); + } + (on).listener = listener; + this.on(type, on); + } + + public emit(type: string, ...args: any[]): void { + if (!this._events[type]) { + return; + } + let obj = this._events[type]; + for (let i = 0; i < obj.length; i++) { + obj[i].apply(this, args); + } + } + + public listeners(type: string): IListenerType[] { + return this._events[type] || []; + } + + protected destroy(): void { + this._events = {}; + } +} diff --git a/xterm.js/src/InputHandler.test.ts b/xterm.js/src/InputHandler.test.ts new file mode 100644 index 0000000..eb7b70d --- /dev/null +++ b/xterm.js/src/InputHandler.test.ts @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { InputHandler } from './InputHandler'; +import { MockInputHandlingTerminal } from './utils/TestUtils.test'; + +describe('InputHandler', () => { + describe('save and restore cursor', () => { + let terminal = new MockInputHandlingTerminal(); + terminal.buffer.x = 1; + terminal.buffer.y = 2; + let inputHandler = new InputHandler(terminal); + // Save cursor position + inputHandler.saveCursor([]); + assert.equal(terminal.buffer.x, 1); + assert.equal(terminal.buffer.y, 2); + // Change cursor position + terminal.buffer.x = 10; + terminal.buffer.y = 20; + // Restore cursor position + inputHandler.restoreCursor([]); + assert.equal(terminal.buffer.x, 1); + assert.equal(terminal.buffer.y, 2); + }); + describe('setCursorStyle', () => { + it('should call Terminal.setOption with correct params', () => { + let terminal = new MockInputHandlingTerminal(); + let inputHandler = new InputHandler(terminal); + + inputHandler.setCursorStyle([0]); + assert.equal(terminal.options['cursorStyle'], 'block'); + assert.equal(terminal.options['cursorBlink'], true); + + terminal.options = {}; + inputHandler.setCursorStyle([1]); + assert.equal(terminal.options['cursorStyle'], 'block'); + assert.equal(terminal.options['cursorBlink'], true); + + terminal.options = {}; + inputHandler.setCursorStyle([2]); + assert.equal(terminal.options['cursorStyle'], 'block'); + assert.equal(terminal.options['cursorBlink'], false); + + terminal.options = {}; + inputHandler.setCursorStyle([3]); + assert.equal(terminal.options['cursorStyle'], 'underline'); + assert.equal(terminal.options['cursorBlink'], true); + + terminal.options = {}; + inputHandler.setCursorStyle([4]); + assert.equal(terminal.options['cursorStyle'], 'underline'); + assert.equal(terminal.options['cursorBlink'], false); + + terminal.options = {}; + inputHandler.setCursorStyle([5]); + assert.equal(terminal.options['cursorStyle'], 'bar'); + assert.equal(terminal.options['cursorBlink'], true); + + terminal.options = {}; + inputHandler.setCursorStyle([6]); + assert.equal(terminal.options['cursorStyle'], 'bar'); + assert.equal(terminal.options['cursorBlink'], false); + }); + }); + describe('setMode', () => { + it('should toggle Terminal.bracketedPasteMode', () => { + let terminal = new MockInputHandlingTerminal(); + terminal.prefix = '?'; + terminal.bracketedPasteMode = false; + let inputHandler = new InputHandler(terminal); + // Set bracketed paste mode + inputHandler.setMode([2004]); + assert.equal(terminal.bracketedPasteMode, true); + // Reset bracketed paste mode + inputHandler.resetMode([2004]); + assert.equal(terminal.bracketedPasteMode, false); + }); + }); +}); diff --git a/xterm.js/src/InputHandler.ts b/xterm.js/src/InputHandler.ts new file mode 100644 index 0000000..1ba6dc7 --- /dev/null +++ b/xterm.js/src/InputHandler.ts @@ -0,0 +1,1455 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * @license MIT + */ + +import { IInputHandler, ITerminal, IInputHandlingTerminal } from './Interfaces'; +import { C0 } from './EscapeSequences'; +import { DEFAULT_CHARSET } from './Charsets'; +import { CharData } from './Types'; +import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer'; +import { FLAGS } from './renderer/Types'; +import { wcwidth } from './CharWidth'; + +/** + * The terminal's standard implementation of IInputHandler, this handles all + * input from the Parser. + * + * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand + * each function's header comment. + */ +export class InputHandler implements IInputHandler { + constructor(private _terminal: IInputHandlingTerminal) { } + + public addChar(char: string, code: number): void { + if (char >= ' ') { + // calculate print space + // expensive call, therefore we save width in line buffer + const ch_width = wcwidth(code); + + if (this._terminal.charset && this._terminal.charset[char]) { + char = this._terminal.charset[char]; + } + + let row = this._terminal.buffer.y + this._terminal.buffer.ybase; + + // insert combining char in last cell + // FIXME: needs handling after cursor jumps + if (!ch_width && this._terminal.buffer.x) { + // dont overflow left + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1]) { + if (!this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][CHAR_DATA_WIDTH_INDEX]) { + // found empty cell after fullwidth, need to go 2 cells back + if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2]) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][3] = char.charCodeAt(0); + } + } else { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][CHAR_DATA_CHAR_INDEX] += char; + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][3] = char.charCodeAt(0); + } + this._terminal.updateRange(this._terminal.buffer.y); + } + return; + } + + // goto next line if ch would overflow + // TODO: needs a global min terminal width of 2 + if (this._terminal.buffer.x + ch_width - 1 >= this._terminal.cols) { + // autowrap - DECAWM + if (this._terminal.wraparoundMode) { + this._terminal.buffer.x = 0; + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(true); + } else { + // The line already exists (eg. the initial viewport), mark it as a + // wrapped line + (this._terminal.buffer.lines.get(this._terminal.buffer.y)).isWrapped = true; + } + } else { + if (ch_width === 2) // FIXME: check for xterm behavior + return; + } + } + row = this._terminal.buffer.y + this._terminal.buffer.ybase; + + // insert mode: move characters to right + if (this._terminal.insertMode) { + // do this twice for a fullwidth char + for (let moves = 0; moves < ch_width; ++moves) { + // remove last cell, if it's width is 0 + // we have to adjust the second last cell as well + const removed = this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).pop(); + if (removed[CHAR_DATA_WIDTH_INDEX] === 0 + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] + && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2][CHAR_DATA_WIDTH_INDEX] === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]; + } + + // insert empty cell at cursor + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 0, [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]); + } + } + + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, ch_width, char.charCodeAt(0)]; + this._terminal.buffer.x++; + this._terminal.updateRange(this._terminal.buffer.y); + + // fullwidth char - set next cell width to zero and advance cursor + if (ch_width === 2) { + this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, '', 0, undefined]; + this._terminal.buffer.x++; + } + } + } + + /** + * BEL + * Bell (Ctrl-G). + */ + public bell(): void { + this._terminal.bell(); + } + + /** + * LF + * Line Feed or New Line (NL). (LF is Ctrl-J). + */ + public lineFeed(): void { + if (this._terminal.convertEol) { + this._terminal.buffer.x = 0; + } + this._terminal.buffer.y++; + if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) { + this._terminal.buffer.y--; + this._terminal.scroll(); + } + // If the end of the line is hit, prevent this action from wrapping around to the next line. + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + /** + * This event is emitted whenever the terminal outputs a LF or NL. + * + * @event linefeed + */ + this._terminal.emit('linefeed'); + } + + /** + * CR + * Carriage Return (Ctrl-M). + */ + public carriageReturn(): void { + this._terminal.buffer.x = 0; + } + + /** + * BS + * Backspace (Ctrl-H). + */ + public backspace(): void { + if (this._terminal.buffer.x > 0) { + this._terminal.buffer.x--; + } + } + + /** + * TAB + * Horizontal Tab (HT) (Ctrl-I). + */ + public tab(): void { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + } + + /** + * SO + * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the + * G1 character set. + */ + public shiftOut(): void { + this._terminal.setgLevel(1); + } + + /** + * SI + * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0 + * character set (the default). + */ + public shiftIn(): void { + this._terminal.setgLevel(0); + } + + /** + * CSI Ps @ + * Insert Ps (Blank) Character(s) (default = 1) (ICH). + */ + public insertChars(params: number[]): void { + let param = params[0]; + if (param < 1) param = 1; + + const row = this._terminal.buffer.y + this._terminal.buffer.ybase; + let j = this._terminal.buffer.x; + const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row).splice(j++, 0, ch); + this._terminal.buffer.lines.get(row).pop(); + } + } + + /** + * CSI Ps A + * Cursor Up Ps Times (default = 1) (CUU). + */ + public cursorUp(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + } + + /** + * CSI Ps B + * Cursor Down Ps Times (default = 1) (CUD). + */ + public cursorDown(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + // If the end of the line is hit, prevent this action from wrapping around to the next line. + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + } + + /** + * CSI Ps C + * Cursor Forward Ps Times (default = 1) (CUF). + */ + public cursorForward(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + } + + /** + * CSI Ps D + * Cursor Backward Ps Times (default = 1) (CUB). + */ + public cursorBackward(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + // If the end of the line is hit, prevent this action from wrapping around to the next line. + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + this._terminal.buffer.x -= param; + if (this._terminal.buffer.x < 0) { + this._terminal.buffer.x = 0; + } + } + + /** + * CSI Ps E + * Cursor Next Line Ps Times (default = 1) (CNL). + * same as CSI Ps B ? + */ + public cursorNextLine(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + this._terminal.buffer.x = 0; + } + + + /** + * CSI Ps F + * Cursor Preceding Line Ps Times (default = 1) (CNL). + * reuse CSI Ps A ? + */ + public cursorPrecedingLine(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y -= param; + if (this._terminal.buffer.y < 0) { + this._terminal.buffer.y = 0; + } + this._terminal.buffer.x = 0; + } + + + /** + * CSI Ps G + * Cursor Character Absolute [column] (default = [row,1]) (CHA). + */ + public cursorCharAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + } + + /** + * CSI Ps ; Ps H + * Cursor Position [row;column] (default = [1,1]) (CUP). + */ + public cursorPosition(params: number[]): void { + let col: number; + let row: number = params[0] - 1; + + if (params.length >= 2) { + col = params[1] - 1; + } else { + col = 0; + } + + if (row < 0) { + row = 0; + } else if (row >= this._terminal.rows) { + row = this._terminal.rows - 1; + } + + if (col < 0) { + col = 0; + } else if (col >= this._terminal.cols) { + col = this._terminal.cols - 1; + } + + this._terminal.buffer.x = col; + this._terminal.buffer.y = row; + } + + /** + * CSI Ps I + * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + */ + public cursorForwardTab(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.nextStop(); + } + } + + /** + * CSI Ps J Erase in Display (ED). + * Ps = 0 -> Erase Below (default). + * Ps = 1 -> Erase Above. + * Ps = 2 -> Erase All. + * Ps = 3 -> Erase Saved Lines (xterm). + * CSI ? Ps J + * Erase in Display (DECSED). + * Ps = 0 -> Selective Erase Below (default). + * Ps = 1 -> Selective Erase Above. + * Ps = 2 -> Selective Erase All. + */ + public eraseInDisplay(params: number[]): void { + let j; + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y + 1; + for (; j < this._terminal.rows; j++) { + this._terminal.eraseLine(j); + } + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + j = this._terminal.buffer.y; + while (j--) { + this._terminal.eraseLine(j); + } + break; + case 2: + j = this._terminal.rows; + while (j--) this._terminal.eraseLine(j); + break; + case 3: + // Clear scrollback (everything not in viewport) + const scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows; + if (scrollBackSize > 0) { + this._terminal.buffer.lines.trimStart(scrollBackSize); + this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0); + this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0); + // Force a scroll event to refresh viewport + this._terminal.emit('scroll', 0); + } + break; + } + } + + /** + * CSI Ps K Erase in Line (EL). + * Ps = 0 -> Erase to Right (default). + * Ps = 1 -> Erase to Left. + * Ps = 2 -> Erase All. + * CSI ? Ps K + * Erase in Line (DECSEL). + * Ps = 0 -> Selective Erase to Right (default). + * Ps = 1 -> Selective Erase to Left. + * Ps = 2 -> Selective Erase All. + */ + public eraseInLine(params: number[]): void { + switch (params[0]) { + case 0: + this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 1: + this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y); + break; + case 2: + this._terminal.eraseLine(this._terminal.buffer.y); + break; + } + } + + /** + * CSI Ps L + * Insert Ps Line(s) (default = 1) (IL). + */ + public insertLines(params: number[]): void { + let param: number = params[0]; + if (param < 1) { + param = 1; + } + let row: number = this._terminal.buffer.y + this._terminal.buffer.ybase; + + let scrollBottomRowsOffset = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + let scrollBottomAbsolute = this._terminal.rows - 1 + this._terminal.buffer.ybase - scrollBottomRowsOffset + 1; + while (param--) { + // test: echo -e '\e[44m\e[1L\e[0m' + // blankLine(true) - xterm/linux behavior + this._terminal.buffer.lines.splice(scrollBottomAbsolute - 1, 1); + this._terminal.buffer.lines.splice(row, 0, this._terminal.blankLine(true)); + } + + // this.maxRange(); + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + } + + /** + * CSI Ps M + * Delete Ps Line(s) (default = 1) (DL). + */ + public deleteLines(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + const row: number = this._terminal.buffer.y + this._terminal.buffer.ybase; + + let j: number; + j = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom; + j = this._terminal.rows - 1 + this._terminal.buffer.ybase - j; + while (param--) { + // test: echo -e '\e[44m\e[1M\e[0m' + // blankLine(true) - xterm/linux behavior + this._terminal.buffer.lines.splice(row, 1); + this._terminal.buffer.lines.splice(j, 0, this._terminal.blankLine(true)); + } + + // this.maxRange(); + this._terminal.updateRange(this._terminal.buffer.y); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + } + + /** + * CSI Ps P + * Delete Ps Character(s) (default = 1) (DCH). + */ + public deleteChars(params: number[]): void { + let param: number = params[0]; + if (param < 1) { + param = 1; + } + + const row = this._terminal.buffer.y + this._terminal.buffer.ybase; + const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + + while (param--) { + this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 1); + this._terminal.buffer.lines.get(row).push(ch); + } + this._terminal.updateRange(this._terminal.buffer.y); + } + + /** + * CSI Ps S Scroll up Ps lines (default = 1) (SU). + */ + public scrollUp(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 0, this._terminal.blankLine()); + } + // this.maxRange(); + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + } + + /** + * CSI Ps T Scroll down Ps lines (default = 1) (SD). + */ + public scrollDown(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 1); + this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 0, this._terminal.blankLine()); + } + // this.maxRange(); + this._terminal.updateRange(this._terminal.buffer.scrollTop); + this._terminal.updateRange(this._terminal.buffer.scrollBottom); + } + + /** + * CSI Ps X + * Erase Ps Character(s) (default = 1) (ECH). + */ + public eraseChars(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + + const row = this._terminal.buffer.y + this._terminal.buffer.ybase; + let j = this._terminal.buffer.x; + const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + + while (param-- && j < this._terminal.cols) { + this._terminal.buffer.lines.get(row)[j++] = ch; + } + } + + /** + * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + */ + public cursorBackwardTab(params: number[]): void { + let param = params[0] || 1; + while (param--) { + this._terminal.buffer.x = this._terminal.buffer.prevStop(); + } + } + + /** + * CSI Pm ` Character Position Absolute + * [column] (default = [row,1]) (HPA). + */ + public charPosAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x = param - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + } + + /** + * CSI Pm a Character Position Relative + * [columns] (default = [row,col+1]) (HPR) + * reuse CSI Ps C ? + */ + public HPositionRelative(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.x += param; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + } + + /** + * CSI Ps b Repeat the preceding graphic character Ps times (REP). + */ + public repeatPrecedingCharacter(params: number[]): void { + let param = params[0] || 1; + const line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + this._terminal.buffer.y); + const ch = line[this._terminal.buffer.x - 1] || [this._terminal.defAttr, ' ', 1, 32]; + + while (param--) { + line[this._terminal.buffer.x++] = ch; + } + } + + /** + * CSI Ps c Send Device Attributes (Primary DA). + * Ps = 0 or omitted -> request attributes from terminal. The + * response depends on the decTerminalID resource setting. + * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'') + * -> CSI ? 1 ; 0 c (``VT101 with No Options'') + * -> CSI ? 6 c (``VT102'') + * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'') + * The VT100-style response parameters do not mean anything by + * themselves. VT220 parameters do, telling the host what fea- + * tures the terminal supports: + * Ps = 1 -> 132-columns. + * Ps = 2 -> Printer. + * Ps = 6 -> Selective erase. + * Ps = 8 -> User-defined keys. + * Ps = 9 -> National replacement character sets. + * Ps = 1 5 -> Technical characters. + * Ps = 2 2 -> ANSI color, e.g., VT525. + * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). + * CSI > Ps c + * Send Device Attributes (Secondary DA). + * Ps = 0 or omitted -> request the terminal's identification + * code. The response depends on the decTerminalID resource set- + * ting. It should apply only to VT220 and up, but xterm extends + * this to VT100. + * -> CSI > Pp ; Pv ; Pc c + * where Pp denotes the terminal type + * Pp = 0 -> ``VT100''. + * Pp = 1 -> ``VT220''. + * and Pv is the firmware version (for xterm, this was originally + * the XFree86 patch number, starting with 95). In a DEC termi- + * nal, Pc indicates the ROM cartridge registration number and is + * always zero. + * More information: + * xterm/charproc.c - line 2012, for more information. + * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?) + */ + public sendDeviceAttributes(params: number[]): void { + if (params[0] > 0) { + return; + } + + if (!this._terminal.prefix) { + if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) { + this._terminal.send(C0.ESC + '[?1;2c'); + } else if (this._terminal.is('linux')) { + this._terminal.send(C0.ESC + '[?6c'); + } + } else if (this._terminal.prefix === '>') { + // xterm and urxvt + // seem to spit this + // out around ~370 times (?). + if (this._terminal.is('xterm')) { + this._terminal.send(C0.ESC + '[>0;276;0c'); + } else if (this._terminal.is('rxvt-unicode')) { + this._terminal.send(C0.ESC + '[>85;95;0c'); + } else if (this._terminal.is('linux')) { + // not supported by linux console. + // linux console echoes parameters. + this._terminal.send(params[0] + 'c'); + } else if (this._terminal.is('screen')) { + this._terminal.send(C0.ESC + '[>83;40003;0c'); + } + } + } + + /** + * CSI Pm d Vertical Position Absolute (VPA) + * [row] (default = [1,column]) + */ + public linePosAbsolute(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y = param - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + } + + /** + * CSI Pm e Vertical Position Relative (VPR) + * [rows] (default = [row+1,column]) + * reuse CSI Ps B ? + */ + public VPositionRelative(params: number[]): void { + let param = params[0]; + if (param < 1) { + param = 1; + } + this._terminal.buffer.y += param; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + // If the end of the line is hit, prevent this action from wrapping around to the next line. + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x--; + } + } + + /** + * CSI Ps ; Ps f + * Horizontal and Vertical Position [row;column] (default = + * [1,1]) (HVP). + */ + public HVPosition(params: number[]): void { + if (params[0] < 1) params[0] = 1; + if (params[1] < 1) params[1] = 1; + + this._terminal.buffer.y = params[0] - 1; + if (this._terminal.buffer.y >= this._terminal.rows) { + this._terminal.buffer.y = this._terminal.rows - 1; + } + + this._terminal.buffer.x = params[1] - 1; + if (this._terminal.buffer.x >= this._terminal.cols) { + this._terminal.buffer.x = this._terminal.cols - 1; + } + } + + /** + * CSI Ps g Tab Clear (TBC). + * Ps = 0 -> Clear Current Column (default). + * Ps = 3 -> Clear All. + * Potentially: + * Ps = 2 -> Clear Stops on Line. + * http://vt100.net/annarbor/aaa-ug/section6.html + */ + public tabClear(params: number[]): void { + let param = params[0]; + if (param <= 0) { + delete this._terminal.buffer.tabs[this._terminal.buffer.x]; + } else if (param === 3) { + this._terminal.buffer.tabs = {}; + } + } + + /** + * CSI Pm h Set Mode (SM). + * Ps = 2 -> Keyboard Action Mode (AM). + * Ps = 4 -> Insert Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Automatic Newline (LNM). + * CSI ? Pm h + * DEC Private Mode Set (DECSET). + * Ps = 1 -> Application Cursor Keys (DECCKM). + * Ps = 2 -> Designate USASCII for character sets G0-G3 + * (DECANM), and set VT100 mode. + * Ps = 3 -> 132 Column Mode (DECCOLM). + * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM). + * Ps = 5 -> Reverse Video (DECSCNM). + * Ps = 6 -> Origin Mode (DECOM). + * Ps = 7 -> Wraparound Mode (DECAWM). + * Ps = 8 -> Auto-repeat Keys (DECARM). + * Ps = 9 -> Send Mouse X & Y on button press. See the sec- + * tion Mouse Tracking. + * Ps = 1 0 -> Show toolbar (rxvt). + * Ps = 1 2 -> Start Blinking Cursor (att610). + * Ps = 1 8 -> Print form feed (DECPFF). + * Ps = 1 9 -> Set print extent to full screen (DECPEX). + * Ps = 2 5 -> Show Cursor (DECTCEM). + * Ps = 3 0 -> Show scrollbar (rxvt). + * Ps = 3 5 -> Enable font-shifting functions (rxvt). + * Ps = 3 8 -> Enter Tektronix Mode (DECTEK). + * Ps = 4 0 -> Allow 80 -> 132 Mode. + * Ps = 4 1 -> more(1) fix (see curses resource). + * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN- + * RCM). + * Ps = 4 4 -> Turn On Margin Bell. + * Ps = 4 5 -> Reverse-wraparound Mode. + * Ps = 4 6 -> Start Logging. This is normally disabled by a + * compile-time option. + * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 6 6 -> Application keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends backspace (DECBKM). + * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Enable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). + * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit. + * (enables the eightBitInput resource). + * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num- + * Lock keys. (This enables the numLock resource). + * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This + * enables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete + * key. + * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This + * enables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Keep selection even if not highlighted. + * (This enables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Enable Urgency window manager hint when + * Control-G is received. (This enables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Enable raising of the window when Control-G + * is received. (enables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate + * Screen Buffer, clearing it first. (This may be disabled by + * the titeInhibit resource). This combines the effects of the 1 + * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based + * applications rather than the 4 7 mode. + * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Set Sun function-key mode. + * Ps = 1 0 5 2 -> Set HP function-key mode. + * Ps = 1 0 5 3 -> Set SCO function-key mode. + * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Set VT220 keyboard emulation. + * Ps = 2 0 0 4 -> Set bracketed paste mode. + * Modes: + * http: *vt100.net/docs/vt220-rm/chapter4.html + */ + public setMode(params: number[]): void { + if (params.length > 1) { + for (let i = 0; i < params.length; i++) { + this.setMode([params[i]]); + } + + return; + } + + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = true; + break; + case 20: + // this._t.convertEol = true; + break; + } + } else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = true; + break; + case 2: + this._terminal.setgCharset(0, DEFAULT_CHARSET); + this._terminal.setgCharset(1, DEFAULT_CHARSET); + this._terminal.setgCharset(2, DEFAULT_CHARSET); + this._terminal.setgCharset(3, DEFAULT_CHARSET); + // set VT100 mode here + break; + case 3: // 132 col mode + this._terminal.savedCols = this._terminal.cols; + this._terminal.resize(132, this._terminal.rows); + break; + case 6: + this._terminal.originMode = true; + break; + case 7: + this._terminal.wraparoundMode = true; + break; + case 12: + // this.cursorBlink = true; + break; + case 66: + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + this._terminal.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + // no release, no motion, no wheel, no modifiers. + case 1000: // vt200 mouse + // no motion. + // no modifiers, except control on the wheel. + case 1002: // button event mouse + case 1003: // any event mouse + // any event - sends motion events, + // even if there is no button held down. + + // TODO: Why are params[0] compares nested within a switch for params[0]? + + this._terminal.x10Mouse = params[0] === 9; + this._terminal.vt200Mouse = params[0] === 1000; + this._terminal.normalMouse = params[0] > 1000; + this._terminal.mouseEvents = true; + this._terminal.element.classList.add('enable-mouse-events'); + this._terminal.selectionManager.disable(); + this._terminal.log('Binding to mouse events.'); + break; + case 1004: // send focusin/focusout events + // focusin: ^[[I + // focusout: ^[[O + this._terminal.sendFocus = true; + break; + case 1005: // utf8 ext mode mouse + this._terminal.utfMouse = true; + // for wide terminals + // simply encodes large values as utf8 characters + break; + case 1006: // sgr ext mode mouse + this._terminal.sgrMouse = true; + // for wide terminals + // does not add 32 to fields + // press: ^[[ Keyboard Action Mode (AM). + * Ps = 4 -> Replace Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Normal Linefeed (LNM). + * CSI ? Pm l + * DEC Private Mode Reset (DECRST). + * Ps = 1 -> Normal Cursor Keys (DECCKM). + * Ps = 2 -> Designate VT52 mode (DECANM). + * Ps = 3 -> 80 Column Mode (DECCOLM). + * Ps = 4 -> Jump (Fast) Scroll (DECSCLM). + * Ps = 5 -> Normal Video (DECSCNM). + * Ps = 6 -> Normal Cursor Mode (DECOM). + * Ps = 7 -> No Wraparound Mode (DECAWM). + * Ps = 8 -> No Auto-repeat Keys (DECARM). + * Ps = 9 -> Don't send Mouse X & Y on button press. + * Ps = 1 0 -> Hide toolbar (rxvt). + * Ps = 1 2 -> Stop Blinking Cursor (att610). + * Ps = 1 8 -> Don't print form feed (DECPFF). + * Ps = 1 9 -> Limit print to scrolling region (DECPEX). + * Ps = 2 5 -> Hide Cursor (DECTCEM). + * Ps = 3 0 -> Don't show scrollbar (rxvt). + * Ps = 3 5 -> Disable font-shifting functions (rxvt). + * Ps = 4 0 -> Disallow 80 -> 132 Mode. + * Ps = 4 1 -> No more(1) fix (see curses resource). + * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC- + * NRCM). + * Ps = 4 4 -> Turn Off Margin Bell. + * Ps = 4 5 -> No Reverse-wraparound Mode. + * Ps = 4 6 -> Stop Logging. (This is normally disabled by a + * compile-time option). + * Ps = 4 7 -> Use Normal Screen Buffer. + * Ps = 6 6 -> Numeric keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends delete (DECBKM). + * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Disable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output + * (rxvt). + * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables + * the eightBitInput resource). + * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num- + * Lock keys. (This disables the numLock resource). + * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key. + * (This disables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad + * Delete key. + * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key. + * (This disables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Do not keep selection when not highlighted. + * (This disables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Disable Urgency window manager hint when + * Control-G is received. (This disables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Disable raising of the window when Control- + * G is received. (This disables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen + * first if in the Alternate Screen. (This may be disabled by + * the titeInhibit resource). + * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor + * as in DECRC. (This may be disabled by the titeInhibit + * resource). This combines the effects of the 1 0 4 7 and 1 0 + * 4 8 modes. Use this with terminfo-based applications rather + * than the 4 7 mode. + * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Reset Sun function-key mode. + * Ps = 1 0 5 2 -> Reset HP function-key mode. + * Ps = 1 0 5 3 -> Reset SCO function-key mode. + * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style. + * Ps = 2 0 0 4 -> Reset bracketed paste mode. + */ + public resetMode(params: number[]): void { + if (params.length > 1) { + for (let i = 0; i < params.length; i++) { + this.resetMode([params[i]]); + } + + return; + } + + if (!this._terminal.prefix) { + switch (params[0]) { + case 4: + this._terminal.insertMode = false; + break; + case 20: + // this._t.convertEol = false; + break; + } + } else if (this._terminal.prefix === '?') { + switch (params[0]) { + case 1: + this._terminal.applicationCursor = false; + break; + case 3: + if (this._terminal.cols === 132 && this._terminal.savedCols) { + this._terminal.resize(this._terminal.savedCols, this._terminal.rows); + } + delete this._terminal.savedCols; + break; + case 6: + this._terminal.originMode = false; + break; + case 7: + this._terminal.wraparoundMode = false; + break; + case 12: + // this.cursorBlink = false; + break; + case 66: + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + this._terminal.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + case 1000: // vt200 mouse + case 1002: // button event mouse + case 1003: // any event mouse + this._terminal.x10Mouse = false; + this._terminal.vt200Mouse = false; + this._terminal.normalMouse = false; + this._terminal.mouseEvents = false; + this._terminal.element.classList.remove('enable-mouse-events'); + this._terminal.selectionManager.enable(); + break; + case 1004: // send focusin/focusout events + this._terminal.sendFocus = false; + break; + case 1005: // utf8 ext mode mouse + this._terminal.utfMouse = false; + break; + case 1006: // sgr ext mode mouse + this._terminal.sgrMouse = false; + break; + case 1015: // urxvt ext mode mouse + this._terminal.urxvtMouse = false; + break; + case 25: // hide cursor + this._terminal.cursorHidden = true; + break; + case 1049: // alt screen buffer cursor + // FALL-THROUGH + case 47: // normal screen buffer + case 1047: // normal screen buffer - clearing it first + // Ensure the selection manager has the correct buffer + this._terminal.buffers.activateNormalBuffer(); + // TODO: Not sure if we need to save/restore after switching the buffer + // if (params[0] === 1049) { + // this.restoreCursor(params); + // } + this._terminal.selectionManager.setBuffer(this._terminal.buffer); + this._terminal.refresh(0, this._terminal.rows - 1); + this._terminal.viewport.syncScrollArea(); + this._terminal.showCursor(); + break; + case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste) + this._terminal.bracketedPasteMode = false; + break; + } + } + } + + /** + * CSI Pm m Character Attributes (SGR). + * Ps = 0 -> Normal (default). + * Ps = 1 -> Bold. + * Ps = 2 -> Faint, decreased intensity (ISO 6429). + * Ps = 4 -> Underlined. + * Ps = 5 -> Blink (appears as Bold). + * Ps = 7 -> Inverse. + * Ps = 8 -> Invisible, i.e., hidden (VT300). + * Ps = 2 2 -> Normal (neither bold nor faint). + * Ps = 2 4 -> Not underlined. + * Ps = 2 5 -> Steady (not blinking). + * Ps = 2 7 -> Positive (not inverse). + * Ps = 2 8 -> Visible, i.e., not hidden (VT300). + * Ps = 3 0 -> Set foreground color to Black. + * Ps = 3 1 -> Set foreground color to Red. + * Ps = 3 2 -> Set foreground color to Green. + * Ps = 3 3 -> Set foreground color to Yellow. + * Ps = 3 4 -> Set foreground color to Blue. + * Ps = 3 5 -> Set foreground color to Magenta. + * Ps = 3 6 -> Set foreground color to Cyan. + * Ps = 3 7 -> Set foreground color to White. + * Ps = 3 9 -> Set foreground color to default (original). + * Ps = 4 0 -> Set background color to Black. + * Ps = 4 1 -> Set background color to Red. + * Ps = 4 2 -> Set background color to Green. + * Ps = 4 3 -> Set background color to Yellow. + * Ps = 4 4 -> Set background color to Blue. + * Ps = 4 5 -> Set background color to Magenta. + * Ps = 4 6 -> Set background color to Cyan. + * Ps = 4 7 -> Set background color to White. + * Ps = 4 9 -> Set background color to default (original). + * + * If 16-color support is compiled, the following apply. Assume + * that xterm's resources are set so that the ISO color codes are + * the first 8 of a set of 16. Then the aixterm colors are the + * bright versions of the ISO colors: + * Ps = 9 0 -> Set foreground color to Black. + * Ps = 9 1 -> Set foreground color to Red. + * Ps = 9 2 -> Set foreground color to Green. + * Ps = 9 3 -> Set foreground color to Yellow. + * Ps = 9 4 -> Set foreground color to Blue. + * Ps = 9 5 -> Set foreground color to Magenta. + * Ps = 9 6 -> Set foreground color to Cyan. + * Ps = 9 7 -> Set foreground color to White. + * Ps = 1 0 0 -> Set background color to Black. + * Ps = 1 0 1 -> Set background color to Red. + * Ps = 1 0 2 -> Set background color to Green. + * Ps = 1 0 3 -> Set background color to Yellow. + * Ps = 1 0 4 -> Set background color to Blue. + * Ps = 1 0 5 -> Set background color to Magenta. + * Ps = 1 0 6 -> Set background color to Cyan. + * Ps = 1 0 7 -> Set background color to White. + * + * If xterm is compiled with the 16-color support disabled, it + * supports the following, from rxvt: + * Ps = 1 0 0 -> Set foreground and background color to + * default. + * + * If 88- or 256-color support is compiled, the following apply. + * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second + * Ps. + * Ps = 4 8 ; 5 ; Ps -> Set background color to the second + * Ps. + */ + public charAttributes(params: number[]): void { + // Optimize a single SGR0. + if (params.length === 1 && params[0] === 0) { + this._terminal.curAttr = this._terminal.defAttr; + return; + } + + const l = params.length; + let flags = this._terminal.curAttr >> 18; + let fg = (this._terminal.curAttr >> 9) & 0x1ff; + let bg = this._terminal.curAttr & 0x1ff; + let p; + + for (let i = 0; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + // fg color 8 + fg = p - 30; + } else if (p >= 40 && p <= 47) { + // bg color 8 + bg = p - 40; + } else if (p >= 90 && p <= 97) { + // fg color 16 + p += 8; + fg = p - 90; + } else if (p >= 100 && p <= 107) { + // bg color 16 + p += 8; + bg = p - 100; + } else if (p === 0) { + // default + flags = this._terminal.defAttr >> 18; + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + // flags = 0; + // fg = 0x1ff; + // bg = 0x1ff; + } else if (p === 1) { + // bold text + flags |= FLAGS.BOLD; + } else if (p === 4) { + // underlined text + flags |= FLAGS.UNDERLINE; + } else if (p === 5) { + // blink + flags |= FLAGS.BLINK; + } else if (p === 7) { + // inverse and positive + // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m' + flags |= FLAGS.INVERSE; + } else if (p === 8) { + // invisible + flags |= FLAGS.INVISIBLE; + } else if (p === 2) { + // dimmed text + flags |= FLAGS.DIM; + } else if (p === 22) { + // not bold nor faint + flags &= ~FLAGS.BOLD; + flags &= ~FLAGS.DIM; + } else if (p === 24) { + // not underlined + flags &= ~FLAGS.UNDERLINE; + } else if (p === 25) { + // not blink + flags &= ~FLAGS.BLINK; + } else if (p === 27) { + // not inverse + flags &= ~FLAGS.INVERSE; + } else if (p === 28) { + // not invisible + flags &= ~FLAGS.INVISIBLE; + } else if (p === 39) { + // reset fg + fg = (this._terminal.defAttr >> 9) & 0x1ff; + } else if (p === 49) { + // reset bg + bg = this._terminal.defAttr & 0x1ff; + } else if (p === 38) { + // fg color 256 + if (params[i + 1] === 2) { + i += 2; + fg = this._terminal.matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (fg === -1) fg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } else if (p === 48) { + // bg color 256 + if (params[i + 1] === 2) { + i += 2; + bg = this._terminal.matchColor( + params[i] & 0xff, + params[i + 1] & 0xff, + params[i + 2] & 0xff); + if (bg === -1) bg = 0x1ff; + i += 2; + } else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } else if (p === 100) { + // reset fg/bg + fg = (this._terminal.defAttr >> 9) & 0x1ff; + bg = this._terminal.defAttr & 0x1ff; + } else { + this._terminal.error('Unknown SGR attribute: %d.', p); + } + } + + this._terminal.curAttr = (flags << 18) | (fg << 9) | bg; + } + + /** + * CSI Ps n Device Status Report (DSR). + * Ps = 5 -> Status Report. Result (``OK'') is + * CSI 0 n + * Ps = 6 -> Report Cursor Position (CPR) [row;column]. + * Result is + * CSI r ; c R + * CSI ? Ps n + * Device Status Report (DSR, DEC-specific). + * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI + * ? r ; c R (assumes page is zero). + * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready). + * or CSI ? 1 1 n (not ready). + * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked) + * or CSI ? 2 1 n (locked). + * Ps = 2 6 -> Report Keyboard status as + * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). + * The last two parameters apply to VT400 & up, and denote key- + * board ready and LK01 respectively. + * Ps = 5 3 -> Report Locator status as + * CSI ? 5 3 n Locator available, if compiled-in, or + * CSI ? 5 0 n No Locator, if not. + */ + public deviceStatus(params: number[]): void { + if (!this._terminal.prefix) { + switch (params[0]) { + case 5: + // status report + this._terminal.send(C0.ESC + '[0n'); + break; + case 6: + // cursor position + this._terminal.send(C0.ESC + '[' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + } + } else if (this._terminal.prefix === '?') { + // modern xterm doesnt seem to + // respond to any of these except ?6, 6, and 5 + switch (params[0]) { + case 6: + // cursor position + this._terminal.send(C0.ESC + '[?' + + (this._terminal.buffer.y + 1) + + ';' + + (this._terminal.buffer.x + 1) + + 'R'); + break; + case 15: + // no printer + // this.send(C0.ESC + '[?11n'); + break; + case 25: + // dont support user defined keys + // this.send(C0.ESC + '[?21n'); + break; + case 26: + // north american keyboard + // this.send(C0.ESC + '[?27;1;0;0n'); + break; + case 53: + // no dec locator/mouse + // this.send(C0.ESC + '[?50n'); + break; + } + } + } + + /** + * CSI ! p Soft terminal reset (DECSTR). + * http://vt100.net/docs/vt220-rm/table4-10.html + */ + public softReset(params: number[]): void { + this._terminal.cursorHidden = false; + this._terminal.insertMode = false; + this._terminal.originMode = false; + this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false + this._terminal.applicationKeypad = false; // ? + this._terminal.viewport.syncScrollArea(); + this._terminal.applicationCursor = false; + this._terminal.buffer.scrollTop = 0; + this._terminal.buffer.scrollBottom = this._terminal.rows - 1; + this._terminal.curAttr = this._terminal.defAttr; + this._terminal.buffer.x = this._terminal.buffer.y = 0; // ? + this._terminal.charset = null; + this._terminal.glevel = 0; // ?? + this._terminal.charsets = [null]; // ?? + } + + /** + * CSI Ps SP q Set cursor style (DECSCUSR, VT520). + * Ps = 0 -> blinking block. + * Ps = 1 -> blinking block (default). + * Ps = 2 -> steady block. + * Ps = 3 -> blinking underline. + * Ps = 4 -> steady underline. + * Ps = 5 -> blinking bar (xterm). + * Ps = 6 -> steady bar (xterm). + */ + public setCursorStyle(params?: number[]): void { + const param = params[0] < 1 ? 1 : params[0]; + switch (param) { + case 1: + case 2: + this._terminal.setOption('cursorStyle', 'block'); + break; + case 3: + case 4: + this._terminal.setOption('cursorStyle', 'underline'); + break; + case 5: + case 6: + this._terminal.setOption('cursorStyle', 'bar'); + break; + } + const isBlinking = param % 2 === 1; + this._terminal.setOption('cursorBlink', isBlinking); + } + + /** + * CSI Ps ; Ps r + * Set Scrolling Region [top;bottom] (default = full size of win- + * dow) (DECSTBM). + * CSI ? Pm r + */ + public setScrollRegion(params: number[]): void { + if (this._terminal.prefix) return; + this._terminal.buffer.scrollTop = (params[0] || 1) - 1; + this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1; + this._terminal.buffer.x = 0; + this._terminal.buffer.y = 0; + } + + + /** + * CSI s + * Save cursor (ANSI.SYS). + */ + public saveCursor(params: number[]): void { + this._terminal.buffer.savedX = this._terminal.buffer.x; + this._terminal.buffer.savedY = this._terminal.buffer.y; + } + + + /** + * CSI u + * Restore cursor (ANSI.SYS). + */ + public restoreCursor(params: number[]): void { + this._terminal.buffer.x = this._terminal.buffer.savedX || 0; + this._terminal.buffer.y = this._terminal.buffer.savedY || 0; + } +} diff --git a/xterm.js/src/Interfaces.ts b/xterm.js/src/Interfaces.ts new file mode 100644 index 0000000..9a37a09 --- /dev/null +++ b/xterm.js/src/Interfaces.ts @@ -0,0 +1,355 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ILinkMatcherOptions } from './Interfaces'; +import { LinkMatcherHandler, LinkMatcherValidationCallback, Charset, LineData } from './Types'; +import { IColorSet, IRenderer } from './renderer/Interfaces'; +import { IMouseZoneManager } from './input/Interfaces'; + +export interface IBrowser { + isNode: boolean; + userAgent: string; + platform: string; + isFirefox: boolean; + isMSIE: boolean; + isMac: boolean; + isIpad: boolean; + isIphone: boolean; + isMSWindows: boolean; +} + +export interface IBufferAccessor { + buffer: IBuffer; +} + +export interface IElementAccessor { + element: HTMLElement; +} + +export interface ILinkifierAccessor { + linkifier: ILinkifier; +} + +export interface ITerminal extends ILinkifierAccessor, IBufferAccessor, IElementAccessor, IEventEmitter { + selectionManager: ISelectionManager; + charMeasure: ICharMeasure; + textarea: HTMLTextAreaElement; + renderer: IRenderer; + rows: number; + cols: number; + browser: IBrowser; + writeBuffer: string[]; + cursorHidden: boolean; + cursorState: number; + defAttr: number; + options: ITerminalOptions; + buffers: IBufferSet; + isFocused: boolean; + mouseHelper: IMouseHelper; + bracketedPasteMode: boolean; + + /** + * Emit the 'data' event and populate the given data. + * @param data The data to populate in the event. + */ + handler(data: string): void; + scrollLines(disp: number, suppressScrollEvent?: boolean): void; + cancel(ev: Event, force?: boolean): boolean | void; + log(text: string): void; + reset(): void; + showCursor(): void; + blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData; + refresh(start: number, end: number): void; +} + +/** + * This interface encapsulates everything needed from the Terminal by the + * InputHandler. This cleanly separates the large amount of methods needed by + * InputHandler cleanly from the ITerminal interface. + */ +export interface IInputHandlingTerminal extends IEventEmitter { + element: HTMLElement; + options: ITerminalOptions; + cols: number; + rows: number; + charset: Charset; + gcharset: number; + glevel: number; + charsets: Charset[]; + applicationKeypad: boolean; + applicationCursor: boolean; + originMode: boolean; + insertMode: boolean; + wraparoundMode: boolean; + bracketedPasteMode: boolean; + defAttr: number; + curAttr: number; + prefix: string; + savedCols: number; + x10Mouse: boolean; + vt200Mouse: boolean; + normalMouse: boolean; + mouseEvents: boolean; + sendFocus: boolean; + utfMouse: boolean; + sgrMouse: boolean; + urxvtMouse: boolean; + cursorHidden: boolean; + + buffers: IBufferSet; + buffer: IBuffer; + viewport: IViewport; + selectionManager: ISelectionManager; + + bell(): void; + focus(): void; + convertEol: boolean; + updateRange(y: number): void; + scroll(isWrapped?: boolean): void; + setgLevel(g: number): void; + eraseAttr(): number; + eraseRight(x: number, y: number): void; + eraseLine(y: number): void; + eraseLeft(x: number, y: number): void; + blankLine(cur?: boolean, isWrapped?: boolean): LineData; + is(term: string): boolean; + send(data: string): void; + setgCharset(g: number, charset: Charset): void; + resize(x: number, y: number): void; + log(text: string, data?: any): void; + reset(): void; + showCursor(): void; + refresh(start: number, end: number): void; + matchColor(r1: number, g1: number, b1: number): number; + error(text: string, data?: any): void; + setOption(key: string, value: any): void; +} + +export interface ITerminalOptions { + bellSound?: string; + bellStyle?: string; + cancelEvents?: boolean; + cols?: number; + convertEol?: boolean; + cursorBlink?: boolean; + cursorStyle?: string; + debug?: boolean; + disableStdin?: boolean; + enableBold?: boolean; + fontSize?: number; + fontFamily?: string; + handler?: (data: string) => void; + letterSpacing?: number; + lineHeight?: number; + rows?: number; + screenKeys?: boolean; + scrollback?: number; + tabStopWidth?: number; + termName?: string; + theme?: ITheme; + useFlowControl?: boolean; + allowTransparency?: boolean; +} + +export interface IBuffer { + lines: ICircularList; + ydisp: number; + ybase: number; + y: number; + x: number; + tabs: any; + scrollBottom: number; + scrollTop: number; + savedY: number; + savedX: number; + isCursorInViewport: boolean; + translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; + nextStop(x?: number): number; + prevStop(x?: number): number; +} + +export interface IBufferSet { + alt: IBuffer; + normal: IBuffer; + active: IBuffer; + + activateNormalBuffer(): void; + activateAltBuffer(): void; +} + +export interface IMouseHelper { + getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number]; + getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number }; +} + +export interface IViewport { + syncScrollArea(): void; + onWheel(ev: WheelEvent): void; + onTouchStart(ev: TouchEvent): void; + onTouchMove(ev: TouchEvent): void; + onThemeChanged(colors: IColorSet): void; +} + +export interface ISelectionManager { + selectionText: string; + selectionStart: [number, number]; + selectionEnd: [number, number]; + + disable(): void; + enable(): void; + setBuffer(buffer: IBuffer): void; + setSelection(row: number, col: number, length: number): void; +} + +export interface ICompositionHelper { + compositionstart(): void; + compositionupdate(ev: CompositionEvent): void; + compositionend(): void; + updateCompositionElements(dontRecurse?: boolean): void; + keydown(ev: KeyboardEvent): boolean; +} + +export interface ICharMeasure { + width: number; + height: number; + measure(options: ITerminalOptions): void; +} + +export interface ILinkifier extends IEventEmitter { + attachToDom(mouseZoneManager: IMouseZoneManager): void; + linkifyRows(start: number, end: number): void; + setHypertextLinkHandler(handler: LinkMatcherHandler): void; + setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void; + registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; + deregisterLinkMatcher(matcherId: number): boolean; +} + +export interface ICircularList extends IEventEmitter { + length: number; + maxLength: number; + forEach: (callbackfn: (value: T, index: number) => void) => void; + + get(index: number): T; + set(index: number, value: T): void; + push(value: T): void; + pop(): T; + splice(start: number, deleteCount: number, ...items: T[]): void; + trimStart(count: number): void; + shiftElements(start: number, count: number, offset: number): void; +} + +export interface IEventEmitter { + on(type: string, listener: IListenerType): void; + off(type: string, listener: IListenerType): void; + emit(type: string, data?: any): void; +} + +export interface IListenerType { + (data?: any): void; + listener?: (data?: any) => void; +}; + +export interface ILinkMatcherOptions { + /** + * The index of the link from the regex.match(text) call. This defaults to 0 + * (for regular expressions without capture groups). + */ + matchIndex?: number; + /** + * A callback that validates an individual link, returning true if valid and + * false if invalid. + */ + validationCallback?: LinkMatcherValidationCallback; + /** + * A callback that fires when the mouse hovers over a link. + */ + tooltipCallback?: LinkMatcherHandler; + /** + * A callback that fires when the mouse leaves a link that was hovered. + */ + leaveCallback?: () => void; + /** + * The priority of the link matcher, this defines the order in which the link + * matcher is evaluated relative to others, from highest to lowest. The + * default value is 0. + */ + priority?: number; +} + +/** + * Handles actions generated by the parser. + */ +export interface IInputHandler { + addChar(char: string, code: number): void; + + /** C0 BEL */ bell(): void; + /** C0 LF */ lineFeed(): void; + /** C0 CR */ carriageReturn(): void; + /** C0 BS */ backspace(): void; + /** C0 HT */ tab(): void; + /** C0 SO */ shiftOut(): void; + /** C0 SI */ shiftIn(): void; + + /** CSI @ */ insertChars(params?: number[]): void; + /** CSI A */ cursorUp(params?: number[]): void; + /** CSI B */ cursorDown(params?: number[]): void; + /** CSI C */ cursorForward(params?: number[]): void; + /** CSI D */ cursorBackward(params?: number[]): void; + /** CSI E */ cursorNextLine(params?: number[]): void; + /** CSI F */ cursorPrecedingLine(params?: number[]): void; + /** CSI G */ cursorCharAbsolute(params?: number[]): void; + /** CSI H */ cursorPosition(params?: number[]): void; + /** CSI I */ cursorForwardTab(params?: number[]): void; + /** CSI J */ eraseInDisplay(params?: number[]): void; + /** CSI K */ eraseInLine(params?: number[]): void; + /** CSI L */ insertLines(params?: number[]): void; + /** CSI M */ deleteLines(params?: number[]): void; + /** CSI P */ deleteChars(params?: number[]): void; + /** CSI S */ scrollUp(params?: number[]): void; + /** CSI T */ scrollDown(params?: number[]): void; + /** CSI X */ eraseChars(params?: number[]): void; + /** CSI Z */ cursorBackwardTab(params?: number[]): void; + /** CSI ` */ charPosAbsolute(params?: number[]): void; + /** CSI a */ HPositionRelative(params?: number[]): void; + /** CSI b */ repeatPrecedingCharacter(params?: number[]): void; + /** CSI c */ sendDeviceAttributes(params?: number[]): void; + /** CSI d */ linePosAbsolute(params?: number[]): void; + /** CSI e */ VPositionRelative(params?: number[]): void; + /** CSI f */ HVPosition(params?: number[]): void; + /** CSI g */ tabClear(params?: number[]): void; + /** CSI h */ setMode(params?: number[]): void; + /** CSI l */ resetMode(params?: number[]): void; + /** CSI m */ charAttributes(params?: number[]): void; + /** CSI n */ deviceStatus(params?: number[]): void; + /** CSI p */ softReset(params?: number[]): void; + /** CSI q */ setCursorStyle(params?: number[]): void; + /** CSI r */ setScrollRegion(params?: number[]): void; + /** CSI s */ saveCursor(params?: number[]): void; + /** CSI u */ restoreCursor(params?: number[]): void; +} + +export interface ITheme { + foreground?: string; + background?: string; + cursor?: string; + cursorAccent?: string; + selection?: string; + black?: string; + red?: string; + green?: string; + yellow?: string; + blue?: string; + magenta?: string; + cyan?: string; + white?: string; + brightBlack?: string; + brightRed?: string; + brightGreen?: string; + brightYellow?: string; + brightBlue?: string; + brightMagenta?: string; + brightCyan?: string; + brightWhite?: string; +} diff --git a/xterm.js/src/Linkifier.test.ts b/xterm.js/src/Linkifier.test.ts new file mode 100644 index 0000000..0878aaf --- /dev/null +++ b/xterm.js/src/Linkifier.test.ts @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { ITerminal, ILinkifier, IBuffer, IBufferAccessor, IElementAccessor } from './Interfaces'; +import { Linkifier } from './Linkifier'; +import { LinkMatcher, LineData } from './Types'; +import { IMouseZoneManager, IMouseZone } from './input/Interfaces'; +import { MockBuffer } from './utils/TestUtils.test'; +import { CircularList } from './utils/CircularList'; + +class TestLinkifier extends Linkifier { + constructor(_terminal: IBufferAccessor & IElementAccessor) { + super(_terminal); + Linkifier.TIME_BEFORE_LINKIFY = 0; + } + + public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; } + public linkifyRows(): void { super.linkifyRows(0, this._terminal.buffer.lines.length - 1); } +} + +class TestMouseZoneManager implements IMouseZoneManager { + public clears: number = 0; + public zones: IMouseZone[] = []; + add(zone: IMouseZone): void { + this.zones.push(zone); + } + clearAll(): void { + this.clears++; + } +} + +describe('Linkifier', () => { + let terminal: IBufferAccessor & IElementAccessor; + let linkifier: TestLinkifier; + let mouseZoneManager: TestMouseZoneManager; + + beforeEach(() => { + terminal = { + buffer: new MockBuffer(), + element: {} + }; + terminal.buffer.lines = new CircularList(20); + terminal.buffer.ydisp = 0; + linkifier = new TestLinkifier(terminal); + mouseZoneManager = new TestMouseZoneManager(); + }); + + function stringToRow(text: string): LineData { + let result: LineData = []; + for (let i = 0; i < text.length; i++) { + result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); + } + return result; + } + + function addRow(text: string): void { + terminal.buffer.lines.push(stringToRow(text)); + } + + function assertLinkifiesEntireRow(uri: string, done: MochaDone): void { + addRow(uri); + linkifier.linkifyRows(); + setTimeout(() => { + assert.equal(mouseZoneManager.zones[0].x1, 1); + assert.equal(mouseZoneManager.zones[0].x2, uri.length + 1); + assert.equal(mouseZoneManager.zones[0].y, terminal.buffer.lines.length); + done(); + }, 0); + } + + function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, links: {x: number, length: number}[], done: MochaDone): void { + addRow(rowText); + linkifier.registerLinkMatcher(linkMatcherRegex, () => {}); + linkifier.linkifyRows(); + // Allow linkify to happen + setTimeout(() => { + assert.equal(mouseZoneManager.zones.length, links.length); + links.forEach((l, i) => { + assert.equal(mouseZoneManager.zones[i].x1, l.x + 1); + assert.equal(mouseZoneManager.zones[i].x2, l.x + l.length + 1); + assert.equal(mouseZoneManager.zones[i].y, terminal.buffer.lines.length); + }); + done(); + }, 0); + } + + describe('before attachToDom', () => { + it('should allow link matcher registration', done => { + assert.doesNotThrow(() => { + const linkMatcherId = linkifier.registerLinkMatcher(/foo/, () => {}); + assert.isTrue(linkifier.deregisterLinkMatcher(linkMatcherId)); + done(); + }); + }); + }); + + describe('after attachToDom', () => { + beforeEach(() => { + linkifier.attachToDom(mouseZoneManager); + }); + + describe('http links', () => { + it('should allow ~ character in URI path', (done) => { + assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done); + }); + }); + + describe('link matcher', () => { + it('should match a single link', done => { + assertLinkifiesRow('foo', /foo/, [{x: 0, length: 3}], done); + }); + it('should match a single link at the start of a text node', done => { + assertLinkifiesRow('foo bar', /foo/, [{x: 0, length: 3}], done); + }); + it('should match a single link in the middle of a text node', done => { + assertLinkifiesRow('foo bar baz', /bar/, [{x: 4, length: 3}], done); + }); + it('should match a single link at the end of a text node', done => { + assertLinkifiesRow('foo bar', /bar/, [{x: 4, length: 3}], done); + }); + it('should match a link after a link at the start of a text node', done => { + assertLinkifiesRow('foo bar', /foo|bar/, [{x: 0, length: 3}, {x: 4, length: 3}], done); + }); + it('should match a link after a link in the middle of a text node', done => { + assertLinkifiesRow('foo bar baz', /bar|baz/, [{x: 4, length: 3}, {x: 8, length: 3}], done); + }); + it('should match a link immediately after a link at the end of a text node', done => { + assertLinkifiesRow('foo barbaz', /bar|baz/, [{x: 4, length: 3}, {x: 7, length: 3}], done); + }); + it('should not duplicate text after a unicode character (wrapped in a span)', done => { + // This is a regression test for an issue that came about when using + // an oh-my-zsh theme that added the large blue diamond unicode + // character (U+1F537) which caused the path to be duplicated. See #642. + assertLinkifiesRow('echo \'🔷foo\'', /foo/, [{x: 8, length: 3}], done); + }); + }); + + describe('validationCallback', () => { + it('should enable link if true', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => done(), { + validationCallback: (url, cb) => { + assert.equal(mouseZoneManager.zones.length, 0); + cb(true); + assert.equal(mouseZoneManager.zones.length, 1); + assert.equal(mouseZoneManager.zones[0].x1, 1); + assert.equal(mouseZoneManager.zones[0].x2, 5); + assert.equal(mouseZoneManager.zones[0].y, 1); + // Fires done() + mouseZoneManager.zones[0].clickCallback({}); + } + }); + linkifier.linkifyRows(); + }); + + it('should validate the uri, not the row', done => { + addRow('abc test abc'); + linkifier.registerLinkMatcher(/test/, () => done(), { + validationCallback: (uri, cb) => { + assert.equal(uri, 'test'); + done(); + } + }); + linkifier.linkifyRows(); + }); + + it('should disable link if false', done => { + addRow('test'); + linkifier.registerLinkMatcher(/test/, () => assert.fail(), { + validationCallback: (url, cb) => { + assert.equal(mouseZoneManager.zones.length, 0); + cb(false); + assert.equal(mouseZoneManager.zones.length, 0); + } + }); + linkifier.linkifyRows(); + // Allow time for the validation callback to be performed + setTimeout(() => done(), 10); + }); + + it('should trigger for multiple link matches on one row', done => { + addRow('test test'); + let count = 0; + linkifier.registerLinkMatcher(/test/, () => assert.fail(), { + validationCallback: (url, cb) => { + count += 1; + if (count === 2) { + done(); + } + cb(false); + } + }); + linkifier.linkifyRows(); + }); + }); + + describe('priority', () => { + it('should order the list from highest priority to lowest #1', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]); + }); + + it('should order the list from highest priority to lowest #2', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]); + }); + + it('should order items of equal priority in the order they are added', () => { + const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 }); + const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 }); + assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]); + }); + }); + }); +}); diff --git a/xterm.js/src/Linkifier.ts b/xterm.js/src/Linkifier.ts new file mode 100644 index 0000000..e6a63b5 --- /dev/null +++ b/xterm.js/src/Linkifier.ts @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces'; +import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEvent, LinkHoverEventTypes } from './Types'; +import { IMouseZoneManager } from './input/Interfaces'; +import { MouseZone } from './input/MouseZoneManager'; +import { EventEmitter } from './EventEmitter'; + +const protocolClause = '(https?:\\/\\/)'; +const domainCharacterSet = '[\\da-z\\.-]+'; +const negatedDomainCharacterSet = '[^\\da-z\\.-]+'; +const domainBodyClause = '(' + domainCharacterSet + ')'; +const tldClause = '([a-z\\.]{2,6})'; +const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; +const localHostClause = '(localhost)'; +const portClause = '(:\\d{1,5})'; +const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; +const pathClause = '(\\/[\\/\\w\\.\\-%~]*)*'; +const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; +const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; +const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; +const negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+'; +const bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause; +const start = '(?:^|' + negatedDomainCharacterSet + ')('; +const end = ')($|' + negatedPathCharacterSet + ')'; +const strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end); + +/** + * The ID of the built in http(s) link matcher. + */ +const HYPERTEXT_LINK_MATCHER_ID = 0; + +/** + * The Linkifier applies links to rows shortly after they have been refreshed. + */ +export class Linkifier extends EventEmitter implements ILinkifier { + /** + * The time to wait after a row is changed before it is linkified. This prevents + * the costly operation of searching every row multiple times, potentially a + * huge amount of times. + */ + protected static TIME_BEFORE_LINKIFY = 200; + + protected _linkMatchers: LinkMatcher[] = []; + + private _mouseZoneManager: IMouseZoneManager; + private _rowsTimeoutId: number; + private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID; + private _rowsToLinkify: {start: number, end: number}; + + constructor( + protected _terminal: IBufferAccessor & IElementAccessor + ) { + super(); + this._rowsToLinkify = { + start: null, + end: null + }; + this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 }); + } + + /** + * Attaches the linkifier to the DOM, enabling linkification. + * @param mouseZoneManager The mouse zone manager to register link zones with. + */ + public attachToDom(mouseZoneManager: IMouseZoneManager): void { + this._mouseZoneManager = mouseZoneManager; + } + + /** + * Queue linkification on a set of rows. + * @param start The row to linkify from (inclusive). + * @param end The row to linkify to (inclusive). + */ + public linkifyRows(start: number, end: number): void { + // Don't attempt linkify if not yet attached to DOM + if (!this._mouseZoneManager) { + return; + } + + // Increase range to linkify + if (!this._rowsToLinkify.start) { + this._rowsToLinkify.start = start; + this._rowsToLinkify.end = end; + } else { + this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start; + this._rowsToLinkify.end = this._rowsToLinkify.end > end ? this._rowsToLinkify.end : end; + } + + // Clear out any existing links on this row range + this._mouseZoneManager.clearAll(start, end); + + // Restart timer + if (this._rowsTimeoutId) { + clearTimeout(this._rowsTimeoutId); + } + this._rowsTimeoutId = setTimeout(() => this._linkifyRows(), Linkifier.TIME_BEFORE_LINKIFY); + } + + /** + * Linkifies the rows requested. + */ + private _linkifyRows(): void { + this._rowsTimeoutId = null; + for (let i = this._rowsToLinkify.start; i <= this._rowsToLinkify.end; i++) { + this._linkifyRow(i); + } + this._rowsToLinkify.start = null; + this._rowsToLinkify.end = null; + } + + /** + * Attaches a handler for hypertext links, overriding default
    behavior for + * tandard http(s) links. + * @param handler The handler to use, this can be cleared with null. + */ + public setHypertextLinkHandler(handler: LinkMatcherHandler): void { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler; + } + + /** + * Attaches a validation callback for hypertext links. + * @param callback The callback to use, this can be cleared with null. + */ + public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void { + this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback; + } + + /** + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param regex The regular expression to search for. Specifically, this + * searches the textContent of the rows. You will want to use \s to match a + * space ' ' character for example. + * @param handler The callback when the link is called. + * @param options Options for the link matcher. + * @return The ID of the new matcher, this can be used to deregister. + */ + public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: ILinkMatcherOptions = {}): number { + if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { + throw new Error('handler must be defined'); + } + const matcher: LinkMatcher = { + id: this._nextLinkMatcherId++, + regex, + handler, + matchIndex: options.matchIndex, + validationCallback: options.validationCallback, + hoverTooltipCallback: options.tooltipCallback, + hoverLeaveCallback: options.leaveCallback, + priority: options.priority || 0 + }; + this._addLinkMatcherToList(matcher); + return matcher.id; + } + + /** + * Inserts a link matcher to the list in the correct position based on the + * priority of each link matcher. New link matchers of equal priority are + * considered after older link matchers. + * @param matcher The link matcher to be added. + */ + private _addLinkMatcherToList(matcher: LinkMatcher): void { + if (this._linkMatchers.length === 0) { + this._linkMatchers.push(matcher); + return; + } + + for (let i = this._linkMatchers.length - 1; i >= 0; i--) { + if (matcher.priority <= this._linkMatchers[i].priority) { + this._linkMatchers.splice(i + 1, 0, matcher); + return; + } + } + + this._linkMatchers.splice(0, 0, matcher); + } + + /** + * Deregisters a link matcher if it has been registered. + * @param matcherId The link matcher's ID (returned after register) + * @return Whether a link matcher was found and deregistered. + */ + public deregisterLinkMatcher(matcherId: number): boolean { + // ID 0 is the hypertext link matcher which cannot be deregistered + for (let i = 1; i < this._linkMatchers.length; i++) { + if (this._linkMatchers[i].id === matcherId) { + this._linkMatchers.splice(i, 1); + return true; + } + } + return false; + } + + /** + * Linkifies a row. + * @param rowIndex The index of the row to linkify. + */ + private _linkifyRow(rowIndex: number): void { + const absoluteRowIndex = this._terminal.buffer.ydisp + rowIndex; + if (absoluteRowIndex >= this._terminal.buffer.lines.length) { + return; + } + const text = this._terminal.buffer.translateBufferLineToString(absoluteRowIndex, false); + for (let i = 0; i < this._linkMatchers.length; i++) { + this._doLinkifyRow(rowIndex, text, this._linkMatchers[i]); + } + } + + /** + * Linkifies a row given a specific handler. + * @param rowIndex The row index to linkify. + * @param text The text of the row (excludes text in the row that's already + * linkified). + * @param matcher The link matcher for this line. + * @param offset The how much of the row has already been linkified. + * @return The link element(s) that were added. + */ + private _doLinkifyRow(rowIndex: number, text: string, matcher: LinkMatcher, offset: number = 0): void { + // Iterate over nodes as we want to consider text nodes + let result = []; + const isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID; + + // Find the first match + let match = text.match(matcher.regex); + if (!match || match.length === 0) { + return; + } + let uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + + // Get index, match.index is for the outer match which includes negated chars + const index = text.indexOf(uri); + + // Ensure the link is valid before registering + if (matcher.validationCallback) { + matcher.validationCallback(uri, isValid => { + // Discard link if the line has already changed + if (this._rowsTimeoutId) { + return; + } + if (isValid) { + this._addLink(offset + index, rowIndex, uri, matcher); + } + }); + } else { + this._addLink(offset + index, rowIndex, uri, matcher); + } + + // Recursively check for links in the rest of the text + const remainingStartIndex = index + uri.length; + const remainingText = text.substr(remainingStartIndex); + if (remainingText.length > 0) { + this._doLinkifyRow(rowIndex, remainingText, matcher, offset + remainingStartIndex); + } + } + + /** + * Registers a link to the mouse zone manager. + * @param x The column the link starts. + * @param y The row the link is on. + * @param uri The URI of the link. + * @param matcher The link matcher for the link. + */ + private _addLink(x: number, y: number, uri: string, matcher: LinkMatcher): void { + this._mouseZoneManager.add(new MouseZone( + x + 1, + x + 1 + uri.length, + y + 1, + e => { + if (matcher.handler) { + return matcher.handler(e, uri); + } + window.open(uri, '_blank'); + }, + e => { + this.emit(LinkHoverEventTypes.HOVER, { x, y, length: uri.length}); + this._terminal.element.style.cursor = 'pointer'; + }, + e => { + this.emit(LinkHoverEventTypes.TOOLTIP, { x, y, length: uri.length}); + if (matcher.hoverTooltipCallback) { + matcher.hoverTooltipCallback(e, uri); + } + }, + () => { + this.emit(LinkHoverEventTypes.LEAVE, { x, y, length: uri.length}); + this._terminal.element.style.cursor = ''; + if (matcher.hoverLeaveCallback) { + matcher.hoverLeaveCallback(); + } + } + )); + } +} diff --git a/xterm.js/src/Parser.ts b/xterm.js/src/Parser.ts new file mode 100644 index 0000000..6f4b093 --- /dev/null +++ b/xterm.js/src/Parser.ts @@ -0,0 +1,673 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * @license MIT + */ + +import { C0 } from './EscapeSequences'; +import { IInputHandler } from './Interfaces'; +import { CHARSETS, DEFAULT_CHARSET } from './Charsets'; + +const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {}; +normalStateHandler[C0.BEL] = (parser, handler) => handler.bell(); +normalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed(); +normalStateHandler[C0.VT] = normalStateHandler[C0.LF]; +normalStateHandler[C0.FF] = normalStateHandler[C0.LF]; +normalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn(); +normalStateHandler[C0.BS] = (parser, handler) => handler.backspace(); +normalStateHandler[C0.HT] = (parser, handler) => handler.tab(); +normalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut(); +normalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn(); +normalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED); + +// TODO: Remove terminal when parser owns params and currentParam +const escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {}; +escapedStateHandler['['] = (parser, terminal) => { + // ESC [ Control Sequence Introducer (CSI is 0x9b) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.CSI_PARAM); +}; +escapedStateHandler[']'] = (parser, terminal) => { + // ESC ] Operating System Command (OSC is 0x9d) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.OSC); +}; +escapedStateHandler['P'] = (parser, terminal) => { + // ESC P Device Control String (DCS is 0x90) + terminal.params = []; + terminal.currentParam = 0; + parser.setState(ParserState.DCS); +}; +escapedStateHandler['_'] = (parser, terminal) => { + // ESC _ Application Program Command ( APC is 0x9f). + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['^'] = (parser, terminal) => { + // ESC ^ Privacy Message ( PM is 0x9e). + parser.setState(ParserState.IGNORE); +}; +escapedStateHandler['c'] = (parser, terminal) => { + // ESC c Full Reset (RIS). + terminal.reset(); +}; +escapedStateHandler['E'] = (parser, terminal) => { + // ESC E Next Line ( NEL is 0x85). + terminal.buffer.x = 0; + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['D'] = (parser, terminal) => { + // ESC D Index ( IND is 0x84). + terminal.index(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['M'] = (parser, terminal) => { + // ESC M Reverse Index ( RI is 0x8d). + terminal.reverseIndex(); + parser.setState(ParserState.NORMAL); +}; +escapedStateHandler['%'] = (parser, terminal) => { + // ESC % Select default/utf-8 character set. + // @ = default, G = utf-8 + terminal.setgLevel(0); + terminal.setgCharset(0, DEFAULT_CHARSET); // US (default) + parser.setState(ParserState.NORMAL); + parser.skipNextChar(); +}; +escapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL); + +const csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {}; +csiParamStateHandler['?'] = (parser) => parser.setPrefix('?'); +csiParamStateHandler['>'] = (parser) => parser.setPrefix('>'); +csiParamStateHandler['!'] = (parser) => parser.setPrefix('!'); +csiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10); +csiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1); +csiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2); +csiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3); +csiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4); +csiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5); +csiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6); +csiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7); +csiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8); +csiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9); +csiParamStateHandler['$'] = (parser) => parser.setPostfix('$'); +csiParamStateHandler['"'] = (parser) => parser.setPostfix('"'); +csiParamStateHandler[' '] = (parser) => parser.setPostfix(' '); +csiParamStateHandler['\''] = (parser) => parser.setPostfix('\''); +csiParamStateHandler[';'] = (parser) => parser.finalizeParam(); +csiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL); + +const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {}; +csiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params); +csiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params); +csiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params); +csiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params); +csiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params); +csiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params); +csiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params); +csiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params); +csiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params); +csiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params); +csiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params); +csiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params); +csiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params); +csiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params); +csiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params); +csiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params); +csiStateHandler['T'] = (handler, params, prefix) => { + if (params.length < 2 && !prefix) { + handler.scrollDown(params); + } +}; +csiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params); +csiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params); +csiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params); +csiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params); +csiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params); +csiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params); +csiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params); +csiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params); +csiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params); +csiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params); +csiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params); +csiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params); +csiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params); +csiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params); +csiStateHandler['p'] = (handler, params, prefix) => { + switch (prefix) { + case '!': handler.softReset(params); break; + } +}; +csiStateHandler['q'] = (handler, params, prefix, postfix) => { + if (postfix === ' ') { + handler.setCursorStyle(params); + } +}; +csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params); +csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); +csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); +csiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL); + +export enum ParserState { + NORMAL = 0, + ESCAPED = 1, + CSI_PARAM = 2, + CSI = 3, + OSC = 4, + CHARSET = 5, + DCS = 6, + IGNORE = 7 +} + +/** + * The terminal's parser, all input into the terminal goes through the parser + * which parses and defers the actual input handling the the IInputHandler + * specified in the constructor. + */ +export class Parser { + private _state: ParserState; + private _position: number; + + // TODO: Remove terminal when handler can do everything + constructor( + private _inputHandler: IInputHandler, + private _terminal: any + ) { + this._state = ParserState.NORMAL; + } + + /** + * Parse and handle data. + * + * @param data The data to parse. + */ + public parse(data: string): ParserState { + const l = data.length; + let j; + let cs; + let ch; + let code; + let low; + + const cursorStartX = this._terminal.buffer.x; + const cursorStartY = this._terminal.buffer.y; + + if (this._terminal.debug) { + this._terminal.log('data: ' + data); + } + + this._position = 0; + // apply leftover surrogate high from last write + if (this._terminal.surrogate_high) { + data = this._terminal.surrogate_high + data; + this._terminal.surrogate_high = ''; + } + + for (; this._position < l; this._position++) { + ch = data[this._position]; + + // FIXME: higher chars than 0xa0 are not allowed in escape sequences + // --> maybe move to default + code = data.charCodeAt(this._position); + if (0xD800 <= code && code <= 0xDBFF) { + // we got a surrogate high + // get surrogate low (next 2 bytes) + low = data.charCodeAt(this._position + 1); + if (isNaN(low)) { + // end of data stream, save surrogate high + this._terminal.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(this._position + 1); + } + // surrogate low - already handled above + if (0xDC00 <= code && code <= 0xDFFF) + continue; + + switch (this._state) { + case ParserState.NORMAL: + if (ch in normalStateHandler) { + normalStateHandler[ch](this, this._inputHandler); + } else { + this._inputHandler.addChar(ch, code); + } + break; + case ParserState.ESCAPED: + if (ch in escapedStateHandler) { + escapedStateHandler[ch](this, this._terminal); + // Skip switch as it was just handled + break; + } + switch (ch) { + + // ESC (,),*,+,-,. Designate G0-G2 Character Set. + case '(': // <-- this seems to get all the attention + case ')': + case '*': + case '+': + case '-': + case '.': + switch (ch) { + case '(': + this._terminal.gcharset = 0; + break; + case ')': + this._terminal.gcharset = 1; + break; + case '*': + this._terminal.gcharset = 2; + break; + case '+': + this._terminal.gcharset = 3; + break; + case '-': + this._terminal.gcharset = 1; + break; + case '.': + this._terminal.gcharset = 2; + break; + } + this._state = ParserState.CHARSET; + break; + + // Designate G3 Character Set (VT300). + // A = ISO Latin-1 Supplemental. + // Not implemented. + case '/': + this._terminal.gcharset = 3; + this._state = ParserState.CHARSET; + this._position--; + break; + + // ESC N + // Single Shift Select of G2 Character Set + // ( SS2 is 0x8e). This affects next character only. + case 'N': + this._state = ParserState.NORMAL; + break; + // ESC O + // Single Shift Select of G3 Character Set + // ( SS3 is 0x8f). This affects next character only. + case 'O': + this._state = ParserState.NORMAL; + break; + // ESC n + // Invoke the G2 Character Set as GL (LS2). + case 'n': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + // ESC o + // Invoke the G3 Character Set as GL (LS3). + case 'o': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + // ESC | + // Invoke the G3 Character Set as GR (LS3R). + case '|': + this._terminal.setgLevel(3); + this._state = ParserState.NORMAL; + break; + // ESC } + // Invoke the G2 Character Set as GR (LS2R). + case '}': + this._terminal.setgLevel(2); + this._state = ParserState.NORMAL; + break; + // ESC ~ + // Invoke the G1 Character Set as GR (LS1R). + case '~': + this._terminal.setgLevel(1); + this._state = ParserState.NORMAL; + break; + + // ESC 7 Save Cursor (DECSC). + case '7': + this._inputHandler.saveCursor(); + this._state = ParserState.NORMAL; + break; + + // ESC 8 Restore Cursor (DECRC). + case '8': + this._inputHandler.restoreCursor(); + this._state = ParserState.NORMAL; + break; + + // ESC # 3 DEC line height/width + case '#': + this._state = ParserState.NORMAL; + this._position++; + break; + + // ESC H Tab Set (HTS is 0x88). + case 'H': + this._terminal.tabSet(); + this._state = ParserState.NORMAL; + break; + + // ESC = Application Keypad (DECKPAM). + case '=': + this._terminal.log('Serial port requested application keypad.'); + this._terminal.applicationKeypad = true; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + + // ESC > Normal Keypad (DECKPNM). + case '>': + this._terminal.log('Switching back to normal keypad.'); + this._terminal.applicationKeypad = false; + if (this._terminal.viewport) { + this._terminal.viewport.syncScrollArea(); + } + this._state = ParserState.NORMAL; + break; + + default: + this._state = ParserState.NORMAL; + this._terminal.error('Unknown ESC control: %s.', ch); + break; + } + break; + + case ParserState.CHARSET: + if (ch in CHARSETS) { + cs = CHARSETS[ch]; + if (ch === '/') { // ISOLatin is actually /A + this.skipNextChar(); + } + } else { + cs = DEFAULT_CHARSET; + } + this._terminal.setgCharset(this._terminal.gcharset, cs); + this._terminal.gcharset = null; + this._state = ParserState.NORMAL; + break; + + case ParserState.OSC: + // OSC Ps ; Pt ST + // OSC Ps ; Pt BEL + // Set Text Parameters. + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) this._position++; + + this._terminal.params.push(this._terminal.currentParam); + + switch (this._terminal.params[0]) { + case 0: + case 1: + case 2: + if (this._terminal.params[1]) { + this._terminal.title = this._terminal.params[1]; + this._terminal.handleTitle(this._terminal.title); + } + break; + case 3: + // set X property + break; + case 4: + case 5: + // change dynamic colors + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + // change dynamic ui colors + break; + case 46: + // change log file + break; + case 50: + // dynamic font + break; + case 51: + // emacs shell + break; + case 52: + // manipulate selection data + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + // reset colors + break; + } + + this._terminal.params = []; + this._terminal.currentParam = 0; + this._state = ParserState.NORMAL; + } else { + if (!this._terminal.params.length) { + if (ch >= '0' && ch <= '9') { + this._terminal.currentParam = + this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48; + } else if (ch === ';') { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = ''; + } + } else { + this._terminal.currentParam += ch; + } + } + break; + + case ParserState.CSI_PARAM: + if (ch in csiParamStateHandler) { + csiParamStateHandler[ch](this); + break; + } + this.finalizeParam(); + // Fall through the CSI as this character should be the CSI code. + this._state = ParserState.CSI; + + case ParserState.CSI: + if (ch in csiStateHandler) { + if (this._terminal.debug) { + this._terminal.log(`CSI ${this._terminal.prefix ? this._terminal.prefix : ''} ${this._terminal.params ? this._terminal.params.join(';') : ''} ${this._terminal.postfix ? this._terminal.postfix : ''} ${ch}`); + } + csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this); + } else { + this._terminal.error('Unknown CSI code: %s.', ch); + } + + this._state = ParserState.NORMAL; + this._terminal.prefix = ''; + this._terminal.postfix = ''; + break; + + case ParserState.DCS: + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) this._position++; + let pt; + let valid: boolean; + + switch (this._terminal.prefix) { + // User-Defined Keys (DECUDK). + case '': + break; + + // Request Status String (DECRQSS). + // test: echo -e '\eP$q"p\e\\' + case '$q': + pt = this._terminal.currentParam; + valid = false; + + switch (pt) { + // DECSCA + case '"q': + pt = '0"q'; + break; + + // DECSCL + case '"p': + pt = '61"p'; + break; + + // DECSTBM + case 'r': + pt = '' + + (this._terminal.buffer.scrollTop + 1) + + ';' + + (this._terminal.buffer.scrollBottom + 1) + + 'r'; + break; + + // SGR + case 'm': + pt = '0m'; + break; + + default: + this._terminal.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + + this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\'); + break; + + // Set Termcap/Terminfo Data (xterm, experimental). + case '+p': + break; + + // Request Termcap/Terminfo String (xterm, experimental) + // Regular xterm does not even respond to this sequence. + // This can cause a small glitch in vim. + // test: echo -ne '\eP+q6b64\e\\' + case '+q': + pt = this._terminal.currentParam; + valid = false; + + this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\'); + break; + + default: + this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix); + break; + } + + this._terminal.currentParam = 0; + this._terminal.prefix = ''; + this._state = ParserState.NORMAL; + } else if (!this._terminal.currentParam) { + if (!this._terminal.prefix && ch !== '$' && ch !== '+') { + this._terminal.currentParam = ch; + } else if (this._terminal.prefix.length === 2) { + this._terminal.currentParam = ch; + } else { + this._terminal.prefix += ch; + } + } else { + this._terminal.currentParam += ch; + } + break; + + case ParserState.IGNORE: + // For PM and APC. + if (ch === C0.ESC || ch === C0.BEL) { + if (ch === C0.ESC) this._position++; + this._state = ParserState.NORMAL; + } + break; + } + } + + // Fire the cursormove event if it's moved. This is done inside the parser + // as a render cannot happen in the middle of a parsing round. + if (this._terminal.buffer.x !== cursorStartX || this._terminal.buffer.y !== cursorStartY) { + this._terminal.emit('cursormove'); + } + + return this._state; + } + + /** + * Set the parser's current parsing state. + * + * @param state The new state. + */ + public setState(state: ParserState): void { + this._state = state; + } + + /** + * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>' + * or '!'. + * + * @param prefix The prefix. + */ + public setPrefix(prefix: string): void { + this._terminal.prefix = prefix; + } + + /** + * Sets the parsier's current prefix. CSI codes can have postfixes of '$', + * '"', ' ', '\''. + * + * @param postfix The postfix. + */ + public setPostfix(postfix: string): void { + this._terminal.postfix = postfix; + } + + /** + * Sets the parser's current parameter. + * + * @param param the parameter. + */ + public setParam(param: number): void { + this._terminal.currentParam = param; + } + + /** + * Gets the parser's current parameter. + */ + public getParam(): number { + return this._terminal.currentParam; + } + + /** + * Finalizes the parser's current parameter, adding it to the list of + * parameters and setting the new current parameter to 0. + */ + public finalizeParam(): void { + this._terminal.params.push(this._terminal.currentParam); + this._terminal.currentParam = 0; + } + + /** + * Tell the parser to skip the next character. + */ + public skipNextChar(): void { + this._position++; + } + + /** + * Tell the parser to repeat parsing the current character (for example if it + * needs parsing using a different state. + */ + // public repeatChar(): void { + // this._position--; + // } +} diff --git a/xterm.js/src/SelectionManager.test.ts b/xterm.js/src/SelectionManager.test.ts new file mode 100644 index 0000000..a10dc66 --- /dev/null +++ b/xterm.js/src/SelectionManager.test.ts @@ -0,0 +1,344 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import jsdom = require('jsdom'); +import { assert } from 'chai'; +import { ITerminal, ICircularList, IBuffer } from './Interfaces'; +import { CharMeasure } from './utils/CharMeasure'; +import { CircularList } from './utils/CircularList'; +import { SelectionManager } from './SelectionManager'; +import { SelectionModel } from './SelectionModel'; +import { BufferSet } from './BufferSet'; +import { MockTerminal } from './utils/TestUtils.test'; +import { LineData, CharData } from './Types'; + +class TestMockTerminal extends MockTerminal { + emit(event: string, data: any): void {} +} + +class TestSelectionManager extends SelectionManager { + constructor( + terminal: ITerminal, + buffer: IBuffer, + charMeasure: CharMeasure + ) { + super(terminal, buffer, charMeasure); + } + + public get model(): SelectionModel { return this._model; } + + public selectLineAt(line: number): void { this._selectLineAt(line); } + public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords); } + + // Disable DOM interaction + public enable(): void {} + public disable(): void {} + public refresh(): void {} +} + +describe('SelectionManager', () => { + let dom: jsdom.JSDOM; + let window: Window; + let document: Document; + + let terminal: ITerminal; + let buffer: IBuffer; + let rowContainer: HTMLElement; + let selectionManager: TestSelectionManager; + + beforeEach(() => { + dom = new jsdom.JSDOM(''); + window = dom.window; + document = window.document; + terminal = new TestMockTerminal(); + terminal.cols = 80; + terminal.rows = 2; + terminal.options.scrollback = 100; + terminal.buffers = new BufferSet(terminal); + terminal.buffer = terminal.buffers.active; + buffer = terminal.buffer; + selectionManager = new TestSelectionManager(terminal, buffer, null); + }); + + function stringToRow(text: string): LineData { + let result: LineData = []; + for (let i = 0; i < text.length; i++) { + result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); + } + return result; + } + + function stringArrayToRow(chars: string[]): LineData { + return chars.map(c => [0, c, 1, c.charCodeAt(0)]); + } + + describe('_selectWordAt', () => { + it('should expand selection for normal width chars', () => { + buffer.lines.set(0, stringToRow('foo bar')); + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, 'bar'); + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, 'bar'); + selectionManager.selectWordAt([6, 0]); + assert.equal(selectionManager.selectionText, 'bar'); + }); + it('should expand selection for whitespace', () => { + buffer.lines.set(0, stringToRow('a b')); + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, 'a'); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, 'b'); + }); + it('should expand selection for wide characters', () => { + // Wide characters use a special format + buffer.lines.set(0, [ + [null, '中', 2, '中'.charCodeAt(0)], + [null, '', 0, null], + [null, '文', 2, '文'.charCodeAt(0)], + [null, '', 0, null], + [null, ' ', 1, ' '.charCodeAt(0)], + [null, 'a', 1, 'a'.charCodeAt(0)], + [null, '中', 2, '中'.charCodeAt(0)], + [null, '', 0, null], + [null, '文', 2, '文'.charCodeAt(0)], + [null, '', 0, ''.charCodeAt(0)], + [null, 'b', 1, 'b'.charCodeAt(0)], + [null, ' ', 1, ' '.charCodeAt(0)], + [null, 'f', 1, 'f'.charCodeAt(0)], + [null, 'o', 1, 'o'.charCodeAt(0)], + [null, 'o', 1, 'o'.charCodeAt(0)] + ]); + // Ensure wide characters take up 2 columns + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, '中文'); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '中文'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, '中文'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, '中文'); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, ' '); + // Ensure wide characters work when wrapped in normal width characters + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([6, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([7, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([8, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([9, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([10, 0]); + assert.equal(selectionManager.selectionText, 'a中文b'); + selectionManager.selectWordAt([11, 0]); + assert.equal(selectionManager.selectionText, ' '); + // Ensure normal width characters work fine in a line containing wide characters + selectionManager.selectWordAt([12, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + selectionManager.selectWordAt([13, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + selectionManager.selectWordAt([14, 0]); + assert.equal(selectionManager.selectionText, 'foo'); + }); + it('should select up to non-path characters that are commonly adjacent to paths', () => { + buffer.lines.set(0, stringToRow('(cd)[ef]{gh}\'ij"')); + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, '(cd'); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, 'cd'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, 'cd'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, 'cd)'); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, '[ef'); + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, 'ef'); + selectionManager.selectWordAt([6, 0]); + assert.equal(selectionManager.selectionText, 'ef'); + selectionManager.selectWordAt([7, 0]); + assert.equal(selectionManager.selectionText, 'ef]'); + selectionManager.selectWordAt([8, 0]); + assert.equal(selectionManager.selectionText, '{gh'); + selectionManager.selectWordAt([9, 0]); + assert.equal(selectionManager.selectionText, 'gh'); + selectionManager.selectWordAt([10, 0]); + assert.equal(selectionManager.selectionText, 'gh'); + selectionManager.selectWordAt([11, 0]); + assert.equal(selectionManager.selectionText, 'gh}'); + selectionManager.selectWordAt([12, 0]); + assert.equal(selectionManager.selectionText, '\'ij'); + selectionManager.selectWordAt([13, 0]); + assert.equal(selectionManager.selectionText, 'ij'); + selectionManager.selectWordAt([14, 0]); + assert.equal(selectionManager.selectionText, 'ij'); + selectionManager.selectWordAt([15, 0]); + assert.equal(selectionManager.selectionText, 'ij"'); + }); + describe('emoji', () => { + it('should treat a single emoji as a word when wrapped in spaces', () => { + buffer.lines.set(0, stringToRow(' ⚽ a')); // The a is here to prevent the space being trimmed in selectionText + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '⚽'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, ' '); + }); + it('should treat multiple emojis as a word when wrapped in spaces', () => { + buffer.lines.set(0, stringToRow(' ⚽⚽ a')); // The a is here to prevent the space being trimmed in selectionText + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '⚽⚽'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, '⚽⚽'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, ' '); + }); + it('should treat emojis using the zero-width-joiner as a single word', () => { + // Note that the first 3 emojis include the invisible ZWJ char + buffer.lines.set(0, stringArrayToRow([ + ' ', '👨‍', '👩‍', '👧‍', '👦', ' ', 'a' + ])); // The a is here to prevent the space being trimmed in selectionText + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, ' '); + // ZWJ emojis do not combine in the terminal so the family emoji used here consumed 4 cells + // The selection text should retain ZWJ chars despite not combining on the terminal + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '👨‍👩‍👧‍👦'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, '👨‍👩‍👧‍👦'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, '👨‍👩‍👧‍👦'); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, '👨‍👩‍👧‍👦'); + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, ' '); + }); + it('should treat emojis and characters joined together as a word', () => { + buffer.lines.set(0, stringToRow(' ⚽ab cd⚽ ef⚽gh')); // The a is here to prevent the space being trimmed in selectionText + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '⚽ab'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, '⚽ab'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, '⚽ab'); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, 'cd⚽'); + selectionManager.selectWordAt([6, 0]); + assert.equal(selectionManager.selectionText, 'cd⚽'); + selectionManager.selectWordAt([7, 0]); + assert.equal(selectionManager.selectionText, 'cd⚽'); + selectionManager.selectWordAt([8, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([9, 0]); + assert.equal(selectionManager.selectionText, 'ef⚽gh'); + selectionManager.selectWordAt([10, 0]); + assert.equal(selectionManager.selectionText, 'ef⚽gh'); + selectionManager.selectWordAt([11, 0]); + assert.equal(selectionManager.selectionText, 'ef⚽gh'); + selectionManager.selectWordAt([12, 0]); + assert.equal(selectionManager.selectionText, 'ef⚽gh'); + selectionManager.selectWordAt([13, 0]); + assert.equal(selectionManager.selectionText, 'ef⚽gh'); + }); + it('should treat complex emojis and characters joined together as a word', () => { + // This emoji is the flag for England and is made up of: 1F3F4 E0067 E0062 E0065 E006E E0067 E007F + buffer.lines.set(0, stringArrayToRow([ + ' ', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', 'a', 'b', ' ', 'c', 'd', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', ' ', 'e', 'f', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', 'g', 'h', ' ', 'a' + ])); // The a is here to prevent the space being trimmed in selectionText + selectionManager.selectWordAt([0, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([1, 0]); + assert.equal(selectionManager.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab'); + selectionManager.selectWordAt([2, 0]); + assert.equal(selectionManager.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab'); + selectionManager.selectWordAt([3, 0]); + assert.equal(selectionManager.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab'); + selectionManager.selectWordAt([4, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([5, 0]); + assert.equal(selectionManager.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + selectionManager.selectWordAt([6, 0]); + assert.equal(selectionManager.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + selectionManager.selectWordAt([7, 0]); + assert.equal(selectionManager.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + selectionManager.selectWordAt([8, 0]); + assert.equal(selectionManager.selectionText, ' '); + selectionManager.selectWordAt([9, 0]); + assert.equal(selectionManager.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh'); + selectionManager.selectWordAt([10, 0]); + assert.equal(selectionManager.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh'); + selectionManager.selectWordAt([11, 0]); + assert.equal(selectionManager.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh'); + selectionManager.selectWordAt([12, 0]); + assert.equal(selectionManager.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh'); + selectionManager.selectWordAt([13, 0]); + assert.equal(selectionManager.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh'); + }); + }); + }); + + describe('_selectLineAt', () => { + it('should select the entire line', () => { + buffer.lines.set(0, stringToRow('foo bar')); + selectionManager.selectLineAt(0); + assert.equal(selectionManager.selectionText, 'foo bar', 'The selected text is correct'); + assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 0], 'The actual selection spans the entire column'); + }); + }); + + describe('selectAll', () => { + it('should select the entire buffer, beyond the viewport', () => { + buffer.lines.length = 5; + buffer.lines.set(0, stringToRow('1')); + buffer.lines.set(1, stringToRow('2')); + buffer.lines.set(2, stringToRow('3')); + buffer.lines.set(3, stringToRow('4')); + buffer.lines.set(4, stringToRow('5')); + selectionManager.selectAll(); + terminal.buffer.ybase = buffer.lines.length - terminal.rows; + assert.equal(selectionManager.selectionText, '1\n2\n3\n4\n5'); + }); + }); + + describe('hasSelection', () => { + it('should return whether there is a selection', () => { + selectionManager.model.selectionStart = [0, 0]; + selectionManager.model.selectionStartLength = 0; + assert.equal(selectionManager.hasSelection, false); + selectionManager.model.selectionEnd = [0, 0]; + assert.equal(selectionManager.hasSelection, false); + selectionManager.model.selectionEnd = [1, 0]; + assert.equal(selectionManager.hasSelection, true); + selectionManager.model.selectionEnd = [0, 1]; + assert.equal(selectionManager.hasSelection, true); + selectionManager.model.selectionEnd = [1, 1]; + assert.equal(selectionManager.hasSelection, true); + }); + }); +}); diff --git a/xterm.js/src/SelectionManager.ts b/xterm.js/src/SelectionManager.ts new file mode 100644 index 0000000..cd6fc99 --- /dev/null +++ b/xterm.js/src/SelectionManager.ts @@ -0,0 +1,739 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { MouseHelper } from './utils/MouseHelper'; +import * as Browser from './utils/Browser'; +import { CharMeasure } from './utils/CharMeasure'; +import { CircularList } from './utils/CircularList'; +import { EventEmitter } from './EventEmitter'; +import { ITerminal, ICircularList, ISelectionManager, IBuffer } from './Interfaces'; +import { SelectionModel } from './SelectionModel'; +import { LineData, CharData } from './Types'; +import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer'; + +/** + * The number of pixels the mouse needs to be above or below the viewport in + * order to scroll at the maximum speed. + */ +const DRAG_SCROLL_MAX_THRESHOLD = 50; + +/** + * The maximum scrolling speed + */ +const DRAG_SCROLL_MAX_SPEED = 15; + +/** + * The number of milliseconds between drag scroll updates. + */ +const DRAG_SCROLL_INTERVAL = 50; + +/** + * A string containing all characters that are considered word separated by the + * double click to select work logic. + */ +const WORD_SEPARATORS = ' ()[]{}\'"'; + +const NON_BREAKING_SPACE_CHAR = String.fromCharCode(160); +const ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g'); + +/** + * Represents a position of a word on a line. + */ +interface IWordPosition { + start: number; + length: number; +} + +/** + * A selection mode, this drives how the selection behaves on mouse move. + */ +enum SelectionMode { + NORMAL, + WORD, + LINE +} + +/** + * A class that manages the selection of the terminal. With help from + * SelectionModel, SelectionManager handles with all logic associated with + * dealing with the selection, including handling mouse interaction, wide + * characters and fetching the actual text within the selection. Rendering is + * not handled by the SelectionManager but a 'refresh' event is fired when the + * selection is ready to be redrawn. + */ +export class SelectionManager extends EventEmitter implements ISelectionManager { + protected _model: SelectionModel; + + /** + * The amount to scroll every drag scroll update (depends on how far the mouse + * drag is above or below the terminal). + */ + private _dragScrollAmount: number; + + /** + * The current selection mode. + */ + private _activeSelectionMode: SelectionMode; + + /** + * A setInterval timer that is active while the mouse is down whose callback + * scrolls the viewport when necessary. + */ + private _dragScrollIntervalTimer: NodeJS.Timer; + + /** + * The animation frame ID used for refreshing the selection. + */ + private _refreshAnimationFrame: number; + + /** + * Whether selection is enabled. + */ + private _enabled = true; + + private _mouseMoveListener: EventListener; + private _mouseUpListener: EventListener; + + constructor( + private _terminal: ITerminal, + private _buffer: IBuffer, + private _charMeasure: CharMeasure + ) { + super(); + this._initListeners(); + this.enable(); + + this._model = new SelectionModel(_terminal); + this._activeSelectionMode = SelectionMode.NORMAL; + } + + /** + * Initializes listener variables. + */ + private _initListeners(): void { + this._mouseMoveListener = event => this._onMouseMove(event); + this._mouseUpListener = event => this._onMouseUp(event); + + // Only adjust the selection on trim, shiftElements is rarely used (only in + // reverseIndex) and delete in a splice is only ever used when the same + // number of elements was just added. Given this is could actually be + // beneficial to leave the selection as is for these cases. + this._buffer.lines.on('trim', (amount: number) => this._onTrim(amount)); + } + + /** + * Disables the selection manager. This is useful for when terminal mouse + * are enabled. + */ + public disable(): void { + this.clearSelection(); + this._enabled = false; + } + + /** + * Enable the selection manager. + */ + public enable(): void { + this._enabled = true; + } + + /** + * Sets the active buffer, this should be called when the alt buffer is + * switched in or out. + * @param buffer The active buffer. + */ + public setBuffer(buffer: IBuffer): void { + this._buffer = buffer; + this.clearSelection(); + } + + public get selectionStart(): [number, number] { return this._model.finalSelectionStart; } + public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; } + + /** + * Gets whether there is an active text selection. + */ + public get hasSelection(): boolean { + const start = this._model.finalSelectionStart; + const end = this._model.finalSelectionEnd; + if (!start || !end) { + return false; + } + return start[0] !== end[0] || start[1] !== end[1]; + } + + /** + * Gets the text currently selected. + */ + public get selectionText(): string { + const start = this._model.finalSelectionStart; + const end = this._model.finalSelectionEnd; + if (!start || !end) { + return ''; + } + + // Get first row + const startRowEndCol = start[1] === end[1] ? end[0] : null; + let result: string[] = []; + result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol)); + + // Get middle rows + for (let i = start[1] + 1; i <= end[1] - 1; i++) { + const bufferLine = this._buffer.lines.get(i); + const lineText = this._buffer.translateBufferLineToString(i, true); + if ((bufferLine).isWrapped) { + result[result.length - 1] += lineText; + } else { + result.push(lineText); + } + } + + // Get final row + if (start[1] !== end[1]) { + const bufferLine = this._buffer.lines.get(end[1]); + const lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]); + if ((bufferLine).isWrapped) { + result[result.length - 1] += lineText; + } else { + result.push(lineText); + } + } + + // Format string by replacing non-breaking space chars with regular spaces + // and joining the array into a multi-line string. + const formattedResult = result.map(line => { + return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' '); + }).join(Browser.isMSWindows ? '\r\n' : '\n'); + + return formattedResult; + } + + /** + * Clears the current terminal selection. + */ + public clearSelection(): void { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this.refresh(); + } + + /** + * Queues a refresh, redrawing the selection on the next opportunity. + * @param isNewSelection Whether the selection should be registered as a new + * selection on Linux. + */ + public refresh(isNewSelection?: boolean): void { + // Queue the refresh for the renderer + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(() => this._refresh()); + } + + // If the platform is Linux and the refresh call comes from a mouse event, + // we need to update the selection for middle click to paste selection. + if (Browser.isLinux && isNewSelection) { + const selectionText = this.selectionText; + if (selectionText.length) { + this.emit('newselection', this.selectionText); + } + } + } + + /** + * Fires the refresh event, causing consumers to pick it up and redraw the + * selection state. + */ + private _refresh(): void { + this._refreshAnimationFrame = null; + this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd }); + } + + /** + * Selects all text within the terminal. + */ + public selectAll(): void { + this._model.isSelectAllActive = true; + this.refresh(); + this._terminal.emit('selection'); + } + + /** + * Handle the buffer being trimmed, adjust the selection position. + * @param amount The amount the buffer is being trimmed. + */ + private _onTrim(amount: number): void { + const needsRefresh = this._model.onTrim(amount); + if (needsRefresh) { + this.refresh(); + } + } + + /** + * Gets the 0-based [x, y] buffer coordinates of the current mouse event. + * @param event The mouse event. + */ + private _getMouseBufferCoords(event: MouseEvent): [number, number] { + const coords = this._terminal.mouseHelper.getCoords(event, this._terminal.element, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true); + if (!coords) { + return null; + } + + // Convert to 0-based + coords[0]--; + coords[1]--; + + // Convert viewport coords to buffer coords + coords[1] += this._terminal.buffer.ydisp; + return coords; + } + + /** + * Gets the amount the viewport should be scrolled based on how far out of the + * terminal the mouse is. + * @param event The mouse event. + */ + private _getMouseEventScrollAmount(event: MouseEvent): number { + let offset = MouseHelper.getCoordsRelativeToElement(event, this._terminal.element)[1]; + const terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight); + if (offset >= 0 && offset <= terminalHeight) { + return 0; + } + if (offset > terminalHeight) { + offset -= terminalHeight; + } + + offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD); + offset /= DRAG_SCROLL_MAX_THRESHOLD; + return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1)); + } + + /** + * Returns whether the selection manager should force selection, regardless of + * whether the terminal is in mouse events mode. + * @param event The mouse event. + */ + public shouldForceSelection(event: MouseEvent): boolean { + return Browser.isMac ? event.altKey : event.shiftKey; + } + + /** + * Handles te mousedown event, setting up for a new selection. + * @param event The mousedown event. + */ + public onMouseDown(event: MouseEvent): void { + // If we have selection, we want the context menu on right click even if the + // terminal is in mouse mode. + if (event.button === 2 && this.hasSelection) { + return; + } + + // Only action the primary button + if (event.button !== 0) { + return; + } + + // Allow selection when using a specific modifier key, even when disabled + if (!this._enabled) { + if (!this.shouldForceSelection(event)) { + return; + } + + // Don't send the mouse down event to the current process, we want to select + event.stopPropagation(); + } + + // Tell the browser not to start a regular selection + event.preventDefault(); + + // Reset drag scroll state + this._dragScrollAmount = 0; + + if (this._enabled && event.shiftKey) { + this._onIncrementalClick(event); + } else { + if (event.detail === 1) { + this._onSingleClick(event); + } else if (event.detail === 2) { + this._onDoubleClick(event); + } else if (event.detail === 3) { + this._onTripleClick(event); + } + } + + this._addMouseDownListeners(); + this.refresh(true); + } + + /** + * Adds listeners when mousedown is triggered. + */ + private _addMouseDownListeners(): void { + // Listen on the document so that dragging outside of viewport works + this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener); + this._dragScrollIntervalTimer = setInterval(() => this._dragScroll(), DRAG_SCROLL_INTERVAL); + } + + /** + * Removes the listeners that are registered when mousedown is triggered. + */ + private _removeMouseDownListeners(): void { + this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener); + clearInterval(this._dragScrollIntervalTimer); + this._dragScrollIntervalTimer = null; + } + + /** + * Performs an incremental click, setting the selection end position to the mouse + * position. + * @param event The mouse event. + */ + private _onIncrementalClick(event: MouseEvent): void { + if (this._model.selectionStart) { + this._model.selectionEnd = this._getMouseBufferCoords(event); + } + } + + /** + * Performs a single click, resetting relevant state and setting the selection + * start position. + * @param event The mouse event. + */ + private _onSingleClick(event: MouseEvent): void { + this._model.selectionStartLength = 0; + this._model.isSelectAllActive = false; + this._activeSelectionMode = SelectionMode.NORMAL; + + // Initialize the new selection + this._model.selectionStart = this._getMouseBufferCoords(event); + if (!this._model.selectionStart) { + return; + } + this._model.selectionEnd = null; + + // Ensure the line exists + const line = this._buffer.lines.get(this._model.selectionStart[1]); + if (!line) { + return; + } + + // Return early if the click event is not in the buffer (eg. in scroll bar) + if (line.length >= this._model.selectionStart[0]) { + return; + } + + // If the mouse is over the second half of a wide character, adjust the + // selection to cover the whole character + const char = line[this._model.selectionStart[0]]; + if (char[CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionStart[0]++; + } + } + + /** + * Performs a double click, selecting the current work. + * @param event The mouse event. + */ + private _onDoubleClick(event: MouseEvent): void { + const coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.WORD; + this._selectWordAt(coords); + } + } + + /** + * Performs a triple click, selecting the current line and activating line + * select mode. + * @param event The mouse event. + */ + private _onTripleClick(event: MouseEvent): void { + const coords = this._getMouseBufferCoords(event); + if (coords) { + this._activeSelectionMode = SelectionMode.LINE; + this._selectLineAt(coords[1]); + } + } + + /** + * Handles the mousemove event when the mouse button is down, recording the + * end of the selection and refreshing the selection. + * @param event The mousemove event. + */ + private _onMouseMove(event: MouseEvent): void { + // If the mousemove listener is active it means that a selection is + // currently being made, we should stop propogation to prevent mouse events + // to be sent to the pty. + event.stopImmediatePropagation(); + + // Record the previous position so we know whether to redraw the selection + // at the end. + const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null; + + // Set the initial selection end based on the mouse coordinates + this._model.selectionEnd = this._getMouseBufferCoords(event); + if (!this._model.selectionEnd) { + this.refresh(true); + return; + } + + // Select the entire line if line select mode is active. + if (this._activeSelectionMode === SelectionMode.LINE) { + if (this._model.selectionEnd[1] < this._model.selectionStart[1]) { + this._model.selectionEnd[0] = 0; + } else { + this._model.selectionEnd[0] = this._terminal.cols; + } + } else if (this._activeSelectionMode === SelectionMode.WORD) { + this._selectToWordAt(this._model.selectionEnd); + } + + // Determine the amount of scrolling that will happen. + this._dragScrollAmount = this._getMouseEventScrollAmount(event); + + // If the cursor was above or below the viewport, make sure it's at the + // start or end of the viewport respectively. + if (this._dragScrollAmount > 0) { + this._model.selectionEnd[0] = this._terminal.cols; + } else if (this._dragScrollAmount < 0) { + this._model.selectionEnd[0] = 0; + } + + // If the character is a wide character include the cell to the right in the + // selection. Note that selections at the very end of the line will never + // have a character. + if (this._model.selectionEnd[1] < this._buffer.lines.length) { + const char = this._buffer.lines.get(this._model.selectionEnd[1])[this._model.selectionEnd[0]]; + if (char && char[CHAR_DATA_WIDTH_INDEX] === 0) { + this._model.selectionEnd[0]++; + } + } + + // Only draw here if the selection changes. + if (!previousSelectionEnd || + previousSelectionEnd[0] !== this._model.selectionEnd[0] || + previousSelectionEnd[1] !== this._model.selectionEnd[1]) { + this.refresh(true); + } + } + + /** + * The callback that occurs every DRAG_SCROLL_INTERVAL ms that does the + * scrolling of the viewport. + */ + private _dragScroll(): void { + if (this._dragScrollAmount) { + this._terminal.scrollLines(this._dragScrollAmount, false); + // Re-evaluate selection + if (this._dragScrollAmount > 0) { + this._model.selectionEnd = [this._terminal.cols - 1, Math.min(this._terminal.buffer.ydisp + this._terminal.rows, this._terminal.buffer.lines.length - 1)]; + } else { + this._model.selectionEnd = [0, this._terminal.buffer.ydisp]; + } + this.refresh(); + } + } + + /** + * Handles the mouseup event, removing the mousedown listeners. + * @param event The mouseup event. + */ + private _onMouseUp(event: MouseEvent): void { + this._removeMouseDownListeners(); + + if (this.hasSelection) + this._terminal.emit('selection'); + } + + /** + * Converts a viewport column to the character index on the buffer line, the + * latter takes into account wide characters. + * @param coords The coordinates to find the 2 index for. + */ + private _convertViewportColToCharacterIndex(bufferLine: any, coords: [number, number]): number { + let charIndex = coords[0]; + for (let i = 0; coords[0] >= i; i++) { + const char = bufferLine[i]; + if (char[CHAR_DATA_WIDTH_INDEX] === 0) { + // Wide characters aren't included in the line string so decrement the + // index so the index is back on the wide character. + charIndex--; + } else if (char[CHAR_DATA_CHAR_INDEX].length > 1 && coords[0] !== i) { + // Emojis take up multiple characters, so adjust accordingly. For these + // we don't want ot include the character at the column as we're + // returning the start index in the string, not the end index. + charIndex += char[CHAR_DATA_CHAR_INDEX].length - 1; + } + } + return charIndex; + } + + public setSelection(col: number, row: number, length: number): void { + this._model.clearSelection(); + this._removeMouseDownListeners(); + this._model.selectionStart = [col, row]; + this._model.selectionStartLength = length; + this.refresh(); + } + + /** + * Gets positional information for the word at the coordinated specified. + * @param coords The coordinates to get the word at. + */ + private _getWordAt(coords: [number, number]): IWordPosition { + const bufferLine = this._buffer.lines.get(coords[1]); + if (!bufferLine) { + return null; + } + + const line = this._buffer.translateBufferLineToString(coords[1], false); + + // Get actual index, taking into consideration wide characters + let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords); + let endIndex = startIndex; + + // Record offset to be used later + const charOffset = coords[0] - startIndex; + let leftWideCharCount = 0; + let rightWideCharCount = 0; + let leftLongCharOffset = 0; + let rightLongCharOffset = 0; + + if (line.charAt(startIndex) === ' ') { + // Expand until non-whitespace is hit + while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') { + startIndex--; + } + while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') { + endIndex++; + } + } else { + // Expand until whitespace is hit. This algorithm works by scanning left + // and right from the starting position, keeping both the index format + // (line) and the column format (bufferLine) in sync. When a wide + // character is hit, it is recorded and the column index is adjusted. + let startCol = coords[0]; + let endCol = coords[0]; + + // Consider the initial position, skip it and increment the wide char + // variable + if (bufferLine[startCol][CHAR_DATA_WIDTH_INDEX] === 0) { + leftWideCharCount++; + startCol--; + } + if (bufferLine[endCol][CHAR_DATA_WIDTH_INDEX] === 2) { + rightWideCharCount++; + endCol++; + } + + // Adjust the end index for characters whose length are > 1 (emojis) + if (bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length > 1) { + rightLongCharOffset += bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length - 1; + } + + // Expand the string in both directions until a space is hit + while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine[startCol - 1])) { + const char = bufferLine[startCol - 1]; + if (char[CHAR_DATA_WIDTH_INDEX] === 0) { + // If the next character is a wide char, record it and skip the column + leftWideCharCount++; + startCol--; + } else if (char[CHAR_DATA_CHAR_INDEX].length > 1) { + // If the next character's string is longer than 1 char (eg. emoji), + // adjust the index + leftLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1; + startIndex -= char[CHAR_DATA_CHAR_INDEX].length - 1; + } + startIndex--; + startCol--; + } + while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine[endCol + 1])) { + const char = bufferLine[endCol + 1]; + if (char[CHAR_DATA_WIDTH_INDEX] === 2) { + // If the next character is a wide char, record it and skip the column + rightWideCharCount++; + endCol++; + } else if (char[CHAR_DATA_CHAR_INDEX].length > 1) { + // If the next character's string is longer than 1 char (eg. emoji), + // adjust the index + rightLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1; + endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1; + } + endIndex++; + endCol++; + } + } + + // Incremenet the end index so it is at the start of the next character + endIndex++; + + // Calculate the start _column_, converting the the string indexes back to + // column coordinates. + const start = + startIndex // The index of the selection's start char in the line string + + charOffset // The difference between the initial char's column and index + - leftWideCharCount // The number of wide chars left of the initial char + + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis) + + // Calculate the length in _columns_, converting the the string indexes back + // to column coordinates. + const length = Math.min(this._terminal.cols, // Disallow lengths larger than the terminal cols + endIndex // The index of the selection's end char in the line string + - startIndex // The index of the selection's start char in the line string + + leftWideCharCount // The number of wide chars left of the initial char + + rightWideCharCount // The number of wide chars right of the initial char (inclusive) + - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis) + - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis) + + return { start, length }; + } + + /** + * Selects the word at the coordinates specified. + * @param coords The coordinates to get the word at. + */ + protected _selectWordAt(coords: [number, number]): void { + const wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionStart = [wordPosition.start, coords[1]]; + this._model.selectionStartLength = wordPosition.length; + } + } + + /** + * Sets the selection end to the word at the coordinated specified. + * @param coords The coordinates to get the word at. + */ + private _selectToWordAt(coords: [number, number]): void { + const wordPosition = this._getWordAt(coords); + if (wordPosition) { + this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]]; + } + } + + /** + * Gets whether the character is considered a word separator by the select + * word logic. + * @param char The character to check. + */ + private _isCharWordSeparator(charData: CharData): boolean { + // Zero width characters are never separators as they are always to the + // right of wide characters + if (charData[CHAR_DATA_WIDTH_INDEX] === 0) { + return false; + } + return WORD_SEPARATORS.indexOf(charData[CHAR_DATA_CHAR_INDEX]) >= 0; + } + + /** + * Selects the line specified. + * @param line The line index. + */ + protected _selectLineAt(line: number): void { + this._model.selectionStart = [0, line]; + this._model.selectionStartLength = this._terminal.cols; + } +} diff --git a/xterm.js/src/SelectionModel.test.ts b/xterm.js/src/SelectionModel.test.ts new file mode 100644 index 0000000..e195d6b --- /dev/null +++ b/xterm.js/src/SelectionModel.test.ts @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { ITerminal } from './Interfaces'; +import { SelectionModel } from './SelectionModel'; +import {BufferSet} from './BufferSet'; +import { MockTerminal } from './utils/TestUtils.test'; + +class TestSelectionModel extends SelectionModel { + constructor( + terminal: ITerminal + ) { + super(terminal); + } +} + +describe('SelectionManager', () => { + let window: Window; + let document: Document; + + let terminal: ITerminal; + let model: TestSelectionModel; + + beforeEach(() => { + terminal = new MockTerminal(); + terminal.cols = 80; + terminal.rows = 2; + terminal.options.scrollback = 10; + terminal.buffers = new BufferSet(terminal); + terminal.buffer = terminal.buffers.active; + + model = new TestSelectionModel(terminal); + }); + + describe('clearSelection', () => { + it('should clear the final selection', () => { + model.selectionStart = [0, 0]; + model.selectionEnd = [10, 2]; + assert.deepEqual(model.finalSelectionStart, [0, 0]); + assert.deepEqual(model.finalSelectionEnd, [10, 2]); + model.clearSelection(); + assert.deepEqual(model.finalSelectionStart, null); + assert.deepEqual(model.finalSelectionEnd, null); + }); + }); + + describe('areSelectionValuesReversed', () => { + it('should return true when the selection end is before selection start', () => { + model.selectionStart = [1, 0]; + model.selectionEnd = [0, 0]; + assert.equal(model.areSelectionValuesReversed(), true); + model.selectionStart = [10, 2]; + model.selectionEnd = [0, 0]; + assert.equal(model.areSelectionValuesReversed(), true); + }); + it('should return false when the selection end is after selection start', () => { + model.selectionStart = [0, 0]; + model.selectionEnd = [1, 0]; + assert.equal(model.areSelectionValuesReversed(), false); + model.selectionStart = [0, 0]; + model.selectionEnd = [10, 2]; + assert.equal(model.areSelectionValuesReversed(), false); + }); + }); + + describe('onTrim', () => { + it('should trim a portion of the selection when a part of it is trimmed', () => { + model.selectionStart = [0, 0]; + model.selectionEnd = [10, 2]; + model.onTrim(1); + assert.deepEqual(model.finalSelectionStart, [0, 0]); + assert.deepEqual(model.finalSelectionEnd, [10, 1]); + model.onTrim(1); + assert.deepEqual(model.finalSelectionStart, [0, 0]); + assert.deepEqual(model.finalSelectionEnd, [10, 0]); + }); + it('should clear selection when it is trimmed in its entirety', () => { + model.selectionStart = [0, 0]; + model.selectionEnd = [10, 0]; + model.onTrim(1); + assert.deepEqual(model.finalSelectionStart, null); + assert.deepEqual(model.finalSelectionEnd, null); + }); + }); + + describe('finalSelectionStart', () => { + it('should return the start of the buffer if select all is active', () => { + model.isSelectAllActive = true; + assert.deepEqual(model.finalSelectionStart, [0, 0]); + }); + it('should return selection start if there is no selection end', () => { + model.selectionStart = [2, 2]; + assert.deepEqual(model.finalSelectionStart, [2, 2]); + }); + it('should return selection end if values are reversed', () => { + model.selectionStart = [2, 2]; + model.selectionEnd = [3, 2]; + assert.deepEqual(model.finalSelectionStart, [2, 2]); + model.selectionEnd = [1, 2]; + assert.deepEqual(model.finalSelectionStart, [1, 2]); + }); + }); + + describe('finalSelectionEnd', () => { + it('should return the end of the buffer if select all is active', () => { + model.isSelectAllActive = true; + assert.deepEqual(model.finalSelectionEnd, [80, 1]); + }); + it('should return null if there is no selection start', () => { + assert.equal(model.finalSelectionEnd, null); + model.selectionEnd = [1, 2]; + assert.equal(model.finalSelectionEnd, null); + }); + it('should return selection start + length if there is no selection end', () => { + model.selectionStart = [2, 2]; + model.selectionStartLength = 2; + assert.deepEqual(model.finalSelectionEnd, [4, 2]); + }); + it('should return selection start + length if values are reversed', () => { + model.selectionStart = [2, 2]; + model.selectionStartLength = 2; + model.selectionEnd = [2, 1]; + assert.deepEqual(model.finalSelectionEnd, [4, 2]); + }); + it('should return selection start + length if selection end is inside the start selection', () => { + model.selectionStart = [2, 2]; + model.selectionStartLength = 2; + model.selectionEnd = [3, 2]; + assert.deepEqual(model.finalSelectionEnd, [4, 2]); + }); + it('should return selection end if selection end is after selection start + length', () => { + model.selectionStart = [2, 2]; + model.selectionStartLength = 2; + model.selectionEnd = [5, 2]; + assert.deepEqual(model.finalSelectionEnd, [5, 2]); + }); + }); +}); diff --git a/xterm.js/src/SelectionModel.ts b/xterm.js/src/SelectionModel.ts new file mode 100644 index 0000000..5982b1e --- /dev/null +++ b/xterm.js/src/SelectionModel.ts @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal } from './Interfaces'; + +/** + * Represents a selection within the buffer. This model only cares about column + * and row coordinates, not wide characters. + */ +export class SelectionModel { + /** + * Whether select all is currently active. + */ + public isSelectAllActive: boolean; + + /** + * The [x, y] position the selection starts at. + */ + public selectionStart: [number, number]; + + /** + * The minimal length of the selection from the start position. When double + * clicking on a word, the word will be selected which makes the selection + * start at the start of the word and makes this variable the length. + */ + public selectionStartLength: number; + + /** + * The [x, y] position the selection ends at. + */ + public selectionEnd: [number, number]; + + constructor( + private _terminal: ITerminal + ) { + this.clearSelection(); + } + + /** + * Clears the current selection. + */ + public clearSelection(): void { + this.selectionStart = null; + this.selectionEnd = null; + this.isSelectAllActive = false; + this.selectionStartLength = 0; + } + + /** + * The final selection start, taking into consideration select all. + */ + public get finalSelectionStart(): [number, number] { + if (this.isSelectAllActive) { + return [0, 0]; + } + + if (!this.selectionEnd || !this.selectionStart) { + return this.selectionStart; + } + + return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart; + } + + /** + * The final selection end, taking into consideration select all, double click + * word selection and triple click line selection. + */ + public get finalSelectionEnd(): [number, number] { + if (this.isSelectAllActive) { + return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1]; + } + + if (!this.selectionStart) { + return null; + } + + // Use the selection start if the end doesn't exist or they're reversed + if (!this.selectionEnd || this.areSelectionValuesReversed()) { + return [this.selectionStart[0] + this.selectionStartLength, this.selectionStart[1]]; + } + + // Ensure the the word/line is selected after a double/triple click + if (this.selectionStartLength) { + // Select the larger of the two when start and end are on the same line + if (this.selectionEnd[1] === this.selectionStart[1]) { + return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]]; + } + } + return this.selectionEnd; + } + + /** + * Returns whether the selection start and end are reversed. + */ + public areSelectionValuesReversed(): boolean { + const start = this.selectionStart; + const end = this.selectionEnd; + if (!start || !end) { + return false; + } + return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]); + } + + /** + * Handle the buffer being trimmed, adjust the selection position. + * @param amount The amount the buffer is being trimmed. + * @return Whether a refresh is necessary. + */ + public onTrim(amount: number): boolean { + // Adjust the selection position based on the trimmed amount. + if (this.selectionStart) { + this.selectionStart[1] -= amount; + } + if (this.selectionEnd) { + this.selectionEnd[1] -= amount; + } + + // The selection has moved off the buffer, clear it. + if (this.selectionEnd && this.selectionEnd[1] < 0) { + this.clearSelection(); + return true; + } + + // If the selection start is trimmed, ensure the start column is 0. + if (this.selectionStart && this.selectionStart[1] < 0) { + this.selectionStart[1] = 0; + } + return false; + } +} diff --git a/xterm.js/src/Terminal.integration.ts b/xterm.js/src/Terminal.integration.ts new file mode 100644 index 0000000..00db4dd --- /dev/null +++ b/xterm.js/src/Terminal.integration.ts @@ -0,0 +1,163 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + * + * This file contains integration tests for xterm.js. + */ + +import * as cp from 'child_process'; +import * as glob from 'glob'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import * as pty from 'node-pty'; +import { assert } from 'chai'; +import { Terminal } from './Terminal'; +import { CHAR_DATA_CHAR_INDEX } from './Buffer'; + +let primitive_pty: any; + +// fake sychronous pty write - read +// we just pipe the data from slave to master as a child program would do +// pty.js opens pipe fds with O_NONBLOCK +// just wait 10ms instead of setting fds to blocking mode +function ptyWriteRead(data: string, cb: (result: string) => void): void { + fs.writeSync(primitive_pty.slave, data); + setTimeout(() => { + let b = new Buffer(64000); + let bytes = fs.readSync(primitive_pty.master, b, 0, 64000, null); + cb(b.toString('utf8', 0, bytes)); + }); +} + +// make sure raw pty is at x=0 and has no pending data +function ptyReset(cb: (result: string) => void): void { + ptyWriteRead('\r\n', cb); +} + +/* debug helpers */ +// generate colorful noisy output to compare xterm and emulator cell states +function formatError(in_: string, out_: string, expected: string): string { + function addLineNumber(start: number, color: string): (s: string) => string { + let counter = start || 0; + return function(s: string): string { + counter += 1; + return '\x1b[33m' + (' ' + counter).slice(-2) + color + s; + }; + } + let line80 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890'; + let s = ''; + s += '\n\x1b[34m' + JSON.stringify(in_); + s += '\n\x1b[33m ' + line80 + '\n'; + s += out_.split('\n').map(addLineNumber(0, '\x1b[31m')).join('\n'); + s += '\n\x1b[33m ' + line80 + '\n'; + s += expected.split('\n').map(addLineNumber(0, '\x1b[32m')).join('\n'); + return s; +} + +// simple debug output of terminal cells +function terminalToString(term: Terminal): string { + let result = ''; + let line_s = ''; + for (let line = term.buffer.ybase; line < term.buffer.ybase + term.rows; line++) { + line_s = ''; + for (let cell = 0; cell < term.cols; ++cell) { + line_s += term.buffer.lines.get(line)[cell][CHAR_DATA_CHAR_INDEX]; + } + // rtrim empty cells as xterm does + line_s = line_s.replace(/\s+$/, ''); + result += line_s; + result += '\n'; + } + return result; +} + +// Skip tests on Windows since pty.open isn't supported +if (os.platform() !== 'win32') { + let CONSOLE_LOG = console.log; + + // expect files need terminal at 80x25! + let COLS = 80; + let ROWS = 25; + + /** some helpers for pty interaction */ + // we need a pty in between to get the termios decorations + // for the basic test cases a raw pty device is enough + primitive_pty = pty.native.open(COLS, ROWS); + + /** tests */ + describe('xterm output comparison', () => { + let xterm; + + beforeEach(() => { + xterm = new Terminal({ cols: COLS, rows: ROWS }); + xterm.refresh = () => {}; + xterm.viewport = { + syncScrollArea: () => {} + }; + }); + + // omit stack trace for escape sequence files + Error.stackTraceLimit = 0; + let files = glob.sync('**/escape_sequence_files/*.in', { cwd: path.join(__dirname, '..')}); + // only successful tests for now + let skip = [ + 10, 16, 17, 19, 32, 33, 34, 35, 36, 39, + 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, + 63, 68 + ]; + if (os.platform() === 'darwin') { + // These are failing on macOS only + skip.push(3, 7, 11, 67); + } + for (let i = 0; i < files.length; i++) { + if (skip.indexOf(i) >= 0) { + continue; + } + ((filename: string) => { + it(filename.split('/').slice(-1)[0], done => { + ptyReset(() => { + let in_file = fs.readFileSync(filename, 'utf8'); + ptyWriteRead(in_file, from_pty => { + // uncomment this to get log from terminal + // console.log = function(){}; + + // Perform a synchronous .write(data) + xterm.writeBuffer.push(from_pty); + xterm.innerWrite(); + + let from_emulator = terminalToString(xterm); + console.log = CONSOLE_LOG; + let expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8'); + // Some of the tests have whitespace on the right of lines, we trim all the linex + // from xterm.js so ignore this for now at least. + let expectedRightTrimmed = expected.split('\n').map(l => l.replace(/\s+$/, '')).join('\n'); + if (from_emulator !== expectedRightTrimmed) { + // uncomment to get noisy output + throw new Error(formatError(in_file, from_emulator, expected)); + // throw new Error('mismatch'); + } + done(); + }); + }); + }); + })(files[i]); + } + }); +} + +describe('typings', () => { + it('should throw no compile errors', function (): void { + this.timeout(20000); + let tsc = path.join(__dirname, '..', 'node_modules', '.bin', 'tsc'); + if (process.platform === 'win32') { + tsc += '.cmd'; + } + const fixtureDir = path.join(__dirname, '..', 'fixtures', 'typings-test'); + let result = cp.spawnSync(tsc, { cwd: fixtureDir }); + assert.equal(result.status, 0, `build did not succeed:\nstdout: ${result.stdout.toString()}\nstderr: ${result.stderr.toString()}\n`); + // Clean up + fs.unlinkSync(path.join(fixtureDir, 'typings-test.js')); + }); +}); diff --git a/xterm.js/src/Terminal.test.ts b/xterm.js/src/Terminal.test.ts new file mode 100644 index 0000000..9cb0b75 --- /dev/null +++ b/xterm.js/src/Terminal.test.ts @@ -0,0 +1,1037 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; +import { Terminal } from './Terminal'; +import * as attach from './addons/attach/attach'; +import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test'; +import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer'; + +const INIT_COLS = 80; +const INIT_ROWS = 24; + +class TestTerminal extends Terminal { + public evaluateKeyEscapeSequence(ev: any): {cancel: boolean, key: string, scrollLines: number} { return this._evaluateKeyEscapeSequence(ev); } + public keyDown(ev: any): boolean { return this._keyDown(ev); } + public keyPress(ev: any): boolean { return this._keyPress(ev); } +} + +describe('term.js addons', () => { + let term: TestTerminal; + + beforeEach(() => { + term = new TestTerminal({ + cols: INIT_COLS, + rows: INIT_ROWS + }); + term.refresh = () => {}; + (term).renderer = new MockRenderer(); + term.viewport = new MockViewport(); + (term).compositionHelper = new MockCompositionHelper(); + // Force synchronous writes + term.write = (data) => { + term.writeBuffer.push(data); + (term).innerWrite(); + }; + (term).element = { + classList: { + toggle: () => {}, + remove: () => {} + } + }; + }); + + it('should apply addons with Terminal.applyAddon', () => { + Terminal.applyAddon(attach); + // Test that addon was applied successfully, adding attach to Terminal's + // prototype. + assert.equal(typeof (Terminal).prototype.attach, 'function'); + }); + + describe('getOption', () => { + it('should retrieve the option correctly', () => { + // In the `options` namespace. + term.options.cursorBlink = true; + assert.equal(term.getOption('cursorBlink'), true); + + // On the Terminal instance + delete term.options.cursorBlink; + term.options.cursorBlink = false; + assert.equal(term.getOption('cursorBlink'), false); + }); + it('should throw when retrieving a non-existant option', () => { + assert.throws(term.getOption.bind(term, 'fake', true)); + }); + }); + + describe('attachCustomKeyEventHandler', () => { + let evKeyDown = { + preventDefault: () => {}, + stopPropagation: () => {}, + type: 'keydown', + keyCode: 77 + }; + let evKeyPress = { + preventDefault: () => {}, + stopPropagation: () => {}, + type: 'keypress', + keyCode: 77 + }; + + beforeEach(() => { + term.handler = () => {}; + term.showCursor = () => {}; + term.clearSelection = () => {}; + }); + + it('should process the keydown/keypress event based on what the handler returns', () => { + assert.equal(term.keyDown(evKeyDown), true); + assert.equal(term.keyPress(evKeyPress), true); + term.attachCustomKeyEventHandler(ev => ev.keyCode === 77); + assert.equal(term.keyDown(evKeyDown), true); + assert.equal(term.keyPress(evKeyPress), true); + term.attachCustomKeyEventHandler(ev => ev.keyCode !== 77); + assert.equal(term.keyDown(evKeyDown), false); + assert.equal(term.keyPress(evKeyPress), false); + }); + + it('should alive after reset(ESC c Full Reset (RIS))', () => { + term.attachCustomKeyEventHandler(ev => ev.keyCode !== 77); + assert.equal(term.keyDown(evKeyDown), false); + assert.equal(term.keyPress(evKeyPress), false); + term.reset(); + assert.equal(term.keyDown(evKeyDown), false); + assert.equal(term.keyPress(evKeyPress), false); + }); + }); + + describe('setOption', () => { + it('should set the option correctly', () => { + term.setOption('cursorBlink', true); + assert.equal(term.options.cursorBlink, true); + term.setOption('cursorBlink', false); + assert.equal(term.options.cursorBlink, false); + }); + it('should throw when setting a non-existant option', () => { + assert.throws(term.setOption.bind(term, 'fake', true)); + }); + }); + + describe('clear', () => { + it('should clear a buffer equal to rows', () => { + let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + term.clear(); + assert.equal(term.buffer.y, 0); + assert.equal(term.buffer.ybase, 0); + assert.equal(term.buffer.ydisp, 0); + assert.equal(term.buffer.lines.length, term.rows); + assert.deepEqual(term.buffer.lines.get(0), promptLine); + for (let i = 1; i < term.rows; i++) { + assert.deepEqual(term.buffer.lines.get(i), term.blankLine()); + } + }); + it('should clear a buffer larger than rows', () => { + // Fill the buffer with dummy rows + for (let i = 0; i < term.rows * 2; i++) { + term.write('test\n'); + } + + let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + term.clear(); + assert.equal(term.buffer.y, 0); + assert.equal(term.buffer.ybase, 0); + assert.equal(term.buffer.ydisp, 0); + assert.equal(term.buffer.lines.length, term.rows); + assert.deepEqual(term.buffer.lines.get(0), promptLine); + for (let i = 1; i < term.rows; i++) { + assert.deepEqual(term.buffer.lines.get(i), term.blankLine()); + } + }); + it('should not break the prompt when cleared twice', () => { + let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + term.clear(); + term.clear(); + assert.equal(term.buffer.y, 0); + assert.equal(term.buffer.ybase, 0); + assert.equal(term.buffer.ydisp, 0); + assert.equal(term.buffer.lines.length, term.rows); + assert.deepEqual(term.buffer.lines.get(0), promptLine); + for (let i = 1; i < term.rows; i++) { + assert.deepEqual(term.buffer.lines.get(i), term.blankLine()); + } + }); + }); + + describe('scroll', () => { + describe('scrollLines', () => { + let startYDisp; + beforeEach(() => { + for (let i = 0; i < term.rows * 2; i++) { + term.writeln('test'); + } + startYDisp = term.rows + 1; + }); + it('should scroll a single line', () => { + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollLines(-1); + assert.equal(term.buffer.ydisp, startYDisp - 1); + term.scrollLines(1); + assert.equal(term.buffer.ydisp, startYDisp); + }); + it('should scroll multiple lines', () => { + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollLines(-5); + assert.equal(term.buffer.ydisp, startYDisp - 5); + term.scrollLines(5); + assert.equal(term.buffer.ydisp, startYDisp); + }); + it('should not scroll beyond the bounds of the buffer', () => { + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollLines(1); + assert.equal(term.buffer.ydisp, startYDisp); + for (let i = 0; i < startYDisp; i++) { + term.scrollLines(-1); + } + assert.equal(term.buffer.ydisp, 0); + term.scrollLines(-1); + assert.equal(term.buffer.ydisp, 0); + }); + }); + + describe('scrollPages', () => { + let startYDisp; + beforeEach(() => { + for (let i = 0; i < term.rows * 3; i++) { + term.writeln('test'); + } + startYDisp = (term.rows * 2) + 1; + }); + it('should scroll a single page', () => { + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollPages(-1); + assert.equal(term.buffer.ydisp, startYDisp - (term.rows - 1)); + term.scrollPages(1); + assert.equal(term.buffer.ydisp, startYDisp); + }); + it('should scroll a multiple pages', () => { + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollPages(-2); + assert.equal(term.buffer.ydisp, startYDisp - (term.rows - 1) * 2); + term.scrollPages(2); + assert.equal(term.buffer.ydisp, startYDisp); + }); + }); + + describe('scrollToTop', () => { + beforeEach(() => { + for (let i = 0; i < term.rows * 3; i++) { + term.writeln('test'); + } + }); + it('should scroll to the top', () => { + assert.notEqual(term.buffer.ydisp, 0); + term.scrollToTop(); + assert.equal(term.buffer.ydisp, 0); + }); + }); + + describe('scrollToBottom', () => { + let startYDisp; + beforeEach(() => { + for (let i = 0; i < term.rows * 3; i++) { + term.writeln('test'); + } + startYDisp = (term.rows * 2) + 1; + }); + it('should scroll to the bottom', () => { + term.scrollLines(-1); + term.scrollToBottom(); + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollPages(-1); + term.scrollToBottom(); + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollToTop(); + term.scrollToBottom(); + assert.equal(term.buffer.ydisp, startYDisp); + }); + }); + + describe('keyDown', () => { + it('should scroll down, when a key is pressed and terminal is scrolled up', () => { + // Override _evaluateKeyEscapeSequence to return cancel code + (term)._evaluateKeyEscapeSequence = () => { + return { key: 'a' }; + }; + let event = { + type: 'keydown', + keyCode: 0, + preventDefault: () => {}, + stopPropagation: () => {} + }; + + term.buffer.ydisp = 0; + term.buffer.ybase = 40; + term.keyDown(event); + + // Ensure that now the terminal is scrolled to bottom + assert.equal(term.buffer.ydisp, term.buffer.ybase); + }); + + it('should not scroll down, when a custom keydown handler prevents the event', () => { + // Add some output to the terminal + for (let i = 0; i < term.rows * 3; i++) { + term.writeln('test'); + } + let startYDisp = (term.rows * 2) + 1; + term.attachCustomKeyEventHandler(() => { + return false; + }); + + assert.equal(term.buffer.ydisp, startYDisp); + term.scrollLines(-1); + assert.equal(term.buffer.ydisp, startYDisp - 1); + term.keyDown({ keyCode: 0 }); + assert.equal(term.buffer.ydisp, startYDisp - 1); + }); + }); + + describe('scroll() function', () => { + describe('when scrollback > 0', () => { + it('should create a new line and scroll', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(INIT_ROWS - 1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS + 1); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a'); + assert.equal(term.buffer.lines.get(INIT_ROWS - 1)[0][CHAR_DATA_CHAR_INDEX], 'b'); + assert.equal(term.buffer.lines.get(INIT_ROWS)[0][CHAR_DATA_CHAR_INDEX], ' '); + }); + + it('should properly scroll inside a scroll region (scrollTop set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + term.buffer.scrollTop = 1; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'c'); + }); + + it('should properly scroll inside a scroll region (scrollBottom set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX] = 'd'; + term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX] = 'e'; + term.buffer.y = 3; + term.buffer.scrollBottom = 3; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS + 1); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a', '\'a\' should be pushed to the scrollback'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'b'); + assert.equal(term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX], 'c'); + assert.equal(term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX], 'd'); + assert.equal(term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index'); + assert.equal(term.buffer.lines.get(5)[0][CHAR_DATA_CHAR_INDEX], 'e'); + }); + + it('should properly scroll inside a scroll region (scrollTop and scrollBottom set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX] = 'd'; + term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX] = 'e'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + term.buffer.scrollTop = 1; + term.buffer.scrollBottom = 3; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'c', '\'b\' should be removed from the buffer'); + assert.equal(term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX], 'd'); + assert.equal(term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index'); + assert.equal(term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX], 'e'); + }); + }); + + describe('when scrollback === 0', () => { + beforeEach(() => { + term.setOption('scrollback', 0); + assert.equal(term.buffer.lines.maxLength, INIT_ROWS); + }); + + it('should create a new line and shift everything up', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(INIT_ROWS - 1)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + assert.equal(term.buffer.lines.length, INIT_ROWS); + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + // 'a' gets pushed out of buffer + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'b'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], ' '); + assert.equal(term.buffer.lines.get(INIT_ROWS - 2)[0][CHAR_DATA_CHAR_INDEX], 'c'); + assert.equal(term.buffer.lines.get(INIT_ROWS - 1)[0][CHAR_DATA_CHAR_INDEX], ' '); + }); + + it('should properly scroll inside a scroll region (scrollTop set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + term.buffer.scrollTop = 1; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'c'); + }); + + it('should properly scroll inside a scroll region (scrollBottom set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX] = 'd'; + term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX] = 'e'; + term.buffer.y = 3; + term.buffer.scrollBottom = 3; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'b'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'c'); + assert.equal(term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX], 'd'); + assert.equal(term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index'); + assert.equal(term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX], 'e'); + }); + + it('should properly scroll inside a scroll region (scrollTop and scrollBottom set)', () => { + term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX] = 'a'; + term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX] = 'b'; + term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX] = 'c'; + term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX] = 'd'; + term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX] = 'e'; + term.buffer.y = INIT_ROWS - 1; // Move cursor to last line + term.buffer.scrollTop = 1; + term.buffer.scrollBottom = 3; + term.scroll(); + assert.equal(term.buffer.lines.length, INIT_ROWS); + assert.equal(term.buffer.lines.get(0)[0][CHAR_DATA_CHAR_INDEX], 'a'); + assert.equal(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX], 'c', '\'b\' should be removed from the buffer'); + assert.equal(term.buffer.lines.get(2)[0][CHAR_DATA_CHAR_INDEX], 'd'); + assert.equal(term.buffer.lines.get(3)[0][CHAR_DATA_CHAR_INDEX], ' ', 'a blank line should be added at scrollBottom\'s index'); + assert.equal(term.buffer.lines.get(4)[0][CHAR_DATA_CHAR_INDEX], 'e'); + }); + }); + }); + }); + + describe('evaluateKeyEscapeSequence', () => { + it('should return the correct escape sequence for unmodified keys', () => { + // Backspace + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 8 }).key, '\x7f'); // ^? + // Tab + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 9 }).key, '\t'); + // Return/enter + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 13 }).key, '\r'); // CR + // Escape + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 27 }).key, '\x1b'); + // Page up, page down + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~ + // End, Home + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 35 }).key, '\x1b[F'); // SS3 F + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 36 }).key, '\x1b[H'); // SS3 H + // Left, up, right, down arrows + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 37 }).key, '\x1b[D'); // CSI D + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 38 }).key, '\x1b[A'); // CSI A + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 39 }).key, '\x1b[C'); // CSI C + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 40 }).key, '\x1b[B'); // CSI B + // Insert + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~ + // Delete + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~ + // F1-F12 + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 112 }).key, '\x1bOP'); // SS3 P + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 114 }).key, '\x1bOR'); // SS3 R + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 115 }).key, '\x1bOS'); // SS3 S + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~ + assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~ + }); + it('should return \\x1b[3;5~ for ctrl+delete', () => { + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~'); + }); + it('should return \\x1b[3;2~ for shift+delete', () => { + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~'); + }); + it('should return \\x1b[3;3~ for alt+delete', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); + }); + it('should return \\x1b[5D for ctrl+left', () => { + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D + }); + it('should return \\x1b[5C for ctrl+right', () => { + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C + }); + it('should return \\x1b[5A for ctrl+up', () => { + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for ctrl+down', () => { + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); + + describe('On non-macOS platforms', () => { + beforeEach(() => { + term.browser.isMac = false; + }); + // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100 + // http://unix.stackexchange.com/a/108106 + it('should return \\x1b[5D for alt+left', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D + }); + it('should return \\x1b[5C for alt+right', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C + }); + }); + + describe('On macOS platforms', () => { + beforeEach(() => { + term.browser.isMac = true; + }); + it('should return \\x1bb for alt+left', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1bb'); // CSI 5 D + }); + it('should return \\x1bf for alt+right', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C + }); + }); + + it('should return \\x1b[5A for alt+up', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for alt+down', () => { + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); + it('should return the correct escape sequence for modified F1-F12 keys', () => { + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~'); + assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~'); + + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~'); + assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~'); + }); + }); + + describe('Third level shift', () => { + let evKeyDown; + let evKeyPress; + + beforeEach(() => { + term.handler = () => {}; + term.showCursor = () => {}; + term.clearSelection = () => {}; + // term.compositionHelper = { + // isComposing: false, + // keydown: { + // bind: () => { + // return () => { return true; }; + // } + // } + // }; + evKeyDown = { + preventDefault: () => {}, + stopPropagation: () => {}, + type: 'keydown', + altKey: null, + keyCode: null + }; + evKeyPress = { + preventDefault: () => {}, + stopPropagation: () => {}, + type: 'keypress', + altKey: null, + charCode: null, + keyCode: null + }; + }); + + describe('On Mac OS', () => { + beforeEach(() => { + term.browser.isMac = true; + }); + + it('should not interfere with the alt key on keyDown', () => { + evKeyDown.altKey = true; + evKeyDown.keyCode = 81; + assert.equal(term.keyDown(evKeyDown), true); + evKeyDown.altKey = true; + evKeyDown.keyCode = 192; + assert.equal(term.keyDown(evKeyDown), true); + }); + + it('should interefere with the alt + arrow keys', () => { + evKeyDown.altKey = true; + evKeyDown.keyCode = 37; + assert.equal(term.keyDown(evKeyDown), false); + evKeyDown.altKey = true; + evKeyDown.keyCode = 39; + assert.equal(term.keyDown(evKeyDown), false); + }); + + it('should emit key with alt + key on keyPress', (done) => { + let keys = ['@', '@', '\\', '\\', '|', '|']; + + term.on('keypress', (key) => { + if (key) { + let index = keys.indexOf(key); + assert(index !== -1, 'Emitted wrong key: ' + key); + keys.splice(index, 1); + } + if (keys.length === 0) done(); + }); + + evKeyPress.altKey = true; + // @ + evKeyPress.charCode = null; + evKeyPress.keyCode = 64; + term.keyPress(evKeyPress); + // Firefox @ + evKeyPress.charCode = 64; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + // \ + evKeyPress.charCode = null; + evKeyPress.keyCode = 92; + term.keyPress(evKeyPress); + // Firefox \ + evKeyPress.charCode = 92; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + // | + evKeyPress.charCode = null; + evKeyPress.keyCode = 124; + term.keyPress(evKeyPress); + // Firefox | + evKeyPress.charCode = 124; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + }); + }); + + describe('On MS Windows', () => { + beforeEach(() => { + term.browser.isMSWindows = true; + }); + + it('should not interfere with the alt + ctrl key on keyDown', () => { + evKeyPress.altKey = true; + evKeyPress.ctrlKey = true; + evKeyPress.keyCode = 81; + assert.equal(term.keyDown(evKeyPress), true); + evKeyDown.altKey = true; + evKeyDown.ctrlKey = true; + evKeyDown.keyCode = 81; + assert.equal(term.keyDown(evKeyDown), true); + }); + + it('should interefere with the alt + ctrl + arrow keys', () => { + evKeyDown.altKey = true; + evKeyDown.ctrlKey = true; + + evKeyDown.keyCode = 37; + assert.equal(term.keyDown(evKeyDown), false); + evKeyDown.keyCode = 39; + assert.equal(term.keyDown(evKeyDown), false); + }); + + it('should emit key with alt + ctrl + key on keyPress', (done) => { + let keys = ['@', '@', '\\', '\\', '|', '|']; + + term.on('keypress', (key) => { + if (key) { + let index = keys.indexOf(key); + assert(index !== -1, 'Emitted wrong key: ' + key); + keys.splice(index, 1); + } + if (keys.length === 0) done(); + }); + + evKeyPress.altKey = true; + evKeyPress.ctrlKey = true; + + // @ + evKeyPress.charCode = null; + evKeyPress.keyCode = 64; + term.keyPress(evKeyPress); + // Firefox @ + evKeyPress.charCode = 64; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + // \ + evKeyPress.charCode = null; + evKeyPress.keyCode = 92; + term.keyPress(evKeyPress); + // Firefox \ + evKeyPress.charCode = 92; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + // | + evKeyPress.charCode = null; + evKeyPress.keyCode = 124; + term.keyPress(evKeyPress); + // Firefox | + evKeyPress.charCode = 124; + evKeyPress.keyCode = 0; + term.keyPress(evKeyPress); + }); + }); + }); + + describe('unicode - surrogates', () => { + it('2 characters per cell', function (): void { + this.timeout(10000); // This is needed because istanbul patches code and slows it down + let high = String.fromCharCode(0xD800); + for (let i = 0xDC00; i <= 0xDCFF; ++i) { + term.write(high + String.fromCharCode(i)); + let tchar = term.buffer.lines.get(0)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + expect(term.buffer.lines.get(0)[1][CHAR_DATA_CHAR_INDEX]).eql(' '); + term.reset(); + } + }); + it('2 characters at last cell', () => { + let high = String.fromCharCode(0xD800); + for (let i = 0xDC00; i <= 0xDCFF; ++i) { + term.buffer.x = term.cols - 1; + term.write(high + String.fromCharCode(i)); + expect(term.buffer.lines.get(0)[term.buffer.x - 1][CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); + expect(term.buffer.lines.get(0)[term.buffer.x - 1][CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX]).eql(' '); + term.reset(); + } + }); + it('2 characters per cell over line end with autowrap', () => { + let high = String.fromCharCode(0xD800); + for (let i = 0xDC00; i <= 0xDCFF; ++i) { + term.buffer.x = term.cols - 1; + term.wraparoundMode = true; + term.write('a' + high + String.fromCharCode(i)); + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_CHAR_INDEX]).eql('a'); + expect(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); + expect(term.buffer.lines.get(1)[0][CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(term.buffer.lines.get(1)[1][CHAR_DATA_CHAR_INDEX]).eql(' '); + term.reset(); + } + }); + it('2 characters per cell over line end without autowrap', () => { + let high = String.fromCharCode(0xD800); + for (let i = 0xDC00; i <= 0xDCFF; ++i) { + term.buffer.x = term.cols - 1; + term.wraparoundMode = false; + term.write('a' + high + String.fromCharCode(i)); + // auto wraparound mode should cut off the rest of the line + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_CHAR_INDEX]).eql('a'); + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(term.buffer.lines.get(1)[1][CHAR_DATA_CHAR_INDEX]).eql(' '); + term.reset(); + } + }); + it('splitted surrogates', () => { + let high = String.fromCharCode(0xD800); + for (let i = 0xDC00; i <= 0xDCFF; ++i) { + term.write(high); + term.write(String.fromCharCode(i)); + let tchar = term.buffer.lines.get(0)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + expect(term.buffer.lines.get(0)[1][CHAR_DATA_CHAR_INDEX]).eql(' '); + term.reset(); + } + }); + }); + + describe('unicode - combining characters', () => { + it('café', () => { + term.write('cafe\u0301'); + expect(term.buffer.lines.get(0)[3][CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); + expect(term.buffer.lines.get(0)[3][CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(term.buffer.lines.get(0)[3][CHAR_DATA_WIDTH_INDEX]).eql(1); + }); + it('café - end of line', () => { + term.buffer.x = term.cols - 1 - 3; + term.write('cafe\u0301'); + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(term.buffer.lines.get(0)[term.cols - 1][CHAR_DATA_WIDTH_INDEX]).eql(1); + expect(term.buffer.lines.get(0)[1][CHAR_DATA_CHAR_INDEX]).eql(' '); + expect(term.buffer.lines.get(0)[1][CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(term.buffer.lines.get(0)[1][CHAR_DATA_WIDTH_INDEX]).eql(1); + }); + it('multiple combined é', () => { + term.wraparoundMode = true; + term.write(Array(100).join('e\u0301')); + for (let i = 0; i < term.cols; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + } + let tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + }); + it('multiple surrogate with combined', () => { + term.wraparoundMode = true; + term.write(Array(100).join('\uD800\uDC00\u0301')); + for (let i = 0; i < term.cols; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\uD800\uDC00\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + } + let tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\uD800\uDC00\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + }); + }); + + describe('unicode - fullwidth characters', () => { + it('cursor movement even', () => { + expect(term.buffer.x).eql(0); + term.write('¥'); + expect(term.buffer.x).eql(2); + }); + it('cursor movement odd', () => { + term.buffer.x = 1; + expect(term.buffer.x).eql(1); + term.write('¥'); + expect(term.buffer.x).eql(3); + }); + it('line of ¥ even', () => { + term.wraparoundMode = true; + term.write(Array(50).join('¥')); + for (let i = 0; i < term.cols; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (i % 2) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + it('line of ¥ odd', () => { + term.wraparoundMode = true; + term.buffer.x = 1; + term.write(Array(50).join('¥')); + for (let i = 1; i < term.cols - 1; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (!(i % 2)) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(0)[term.cols - 1]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' '); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + it('line of ¥ with combining odd', () => { + term.wraparoundMode = true; + term.buffer.x = 1; + term.write(Array(50).join('¥\u0301')); + for (let i = 1; i < term.cols - 1; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (!(i % 2)) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(0)[term.cols - 1]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' '); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + it('line of ¥ with combining even', () => { + term.wraparoundMode = true; + term.write(Array(50).join('¥\u0301')); + for (let i = 0; i < term.cols; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (i % 2) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + it('line of surrogate fullwidth with combining odd', () => { + term.wraparoundMode = true; + term.buffer.x = 1; + term.write(Array(50).join('\ud843\ude6d\u0301')); + for (let i = 1; i < term.cols - 1; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (!(i % 2)) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(0)[term.cols - 1]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(' '); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); + tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + it('line of surrogate fullwidth with combining even', () => { + term.wraparoundMode = true; + term.write(Array(50).join('\ud843\ude6d\u0301')); + for (let i = 0; i < term.cols; ++i) { + let tchar = term.buffer.lines.get(0)[i]; + if (i % 2) { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(0); + } else { + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + } + } + let tchar = term.buffer.lines.get(1)[0]; + expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301'); + expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); + expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); + }); + }); + + describe('insert mode', () => { + it('halfwidth - all', () => { + term.write(Array(9).join('0123456789').slice(-80)); + term.buffer.x = 10; + term.buffer.y = 0; + term.insertMode = true; + term.write('abcde'); + expect(term.buffer.lines.get(0).length).eql(term.cols); + expect(term.buffer.lines.get(0)[10][CHAR_DATA_CHAR_INDEX]).eql('a'); + expect(term.buffer.lines.get(0)[14][CHAR_DATA_CHAR_INDEX]).eql('e'); + expect(term.buffer.lines.get(0)[15][CHAR_DATA_CHAR_INDEX]).eql('0'); + expect(term.buffer.lines.get(0)[79][CHAR_DATA_CHAR_INDEX]).eql('4'); + }); + it('fullwidth - insert', () => { + term.write(Array(9).join('0123456789').slice(-80)); + term.buffer.x = 10; + term.buffer.y = 0; + term.insertMode = true; + term.write('¥¥¥'); + expect(term.buffer.lines.get(0).length).eql(term.cols); + expect(term.buffer.lines.get(0)[10][CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(term.buffer.lines.get(0)[11][CHAR_DATA_CHAR_INDEX]).eql(''); + expect(term.buffer.lines.get(0)[14][CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(term.buffer.lines.get(0)[15][CHAR_DATA_CHAR_INDEX]).eql(''); + expect(term.buffer.lines.get(0)[79][CHAR_DATA_CHAR_INDEX]).eql('3'); + }); + it('fullwidth - right border', () => { + term.write(Array(41).join('¥')); + term.buffer.x = 10; + term.buffer.y = 0; + term.insertMode = true; + term.write('a'); + expect(term.buffer.lines.get(0).length).eql(term.cols); + expect(term.buffer.lines.get(0)[10][CHAR_DATA_CHAR_INDEX]).eql('a'); + expect(term.buffer.lines.get(0)[11][CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(term.buffer.lines.get(0)[79][CHAR_DATA_CHAR_INDEX]).eql(' '); // fullwidth char got replaced + term.write('b'); + expect(term.buffer.lines.get(0).length).eql(term.cols); + expect(term.buffer.lines.get(0)[11][CHAR_DATA_CHAR_INDEX]).eql('b'); + expect(term.buffer.lines.get(0)[12][CHAR_DATA_CHAR_INDEX]).eql('¥'); + expect(term.buffer.lines.get(0)[79][CHAR_DATA_CHAR_INDEX]).eql(''); // empty cell after fullwidth + }); + }); +}); diff --git a/xterm.js/src/Terminal.ts b/xterm.js/src/Terminal.ts new file mode 100644 index 0000000..b4bb377 --- /dev/null +++ b/xterm.js/src/Terminal.ts @@ -0,0 +1,2263 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * @license MIT + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + * + * Terminal Emulation References: + * http://vt100.net/ + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * http://invisible-island.net/vttest/ + * http://www.inwap.com/pdp10/ansicode.txt + * http://linux.die.net/man/4/console_codes + * http://linux.die.net/man/7/urxvt + */ + +import { BufferSet } from './BufferSet'; +import { Buffer, MAX_BUFFER_SIZE } from './Buffer'; +import { CompositionHelper } from './CompositionHelper'; +import { EventEmitter } from './EventEmitter'; +import { Viewport } from './Viewport'; +import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard'; +import { CircularList } from './utils/CircularList'; +import { C0 } from './EscapeSequences'; +import { InputHandler } from './InputHandler'; +import { Parser } from './Parser'; +import { Renderer } from './renderer/Renderer'; +import { Linkifier } from './Linkifier'; +import { SelectionManager } from './SelectionManager'; +import { CharMeasure } from './utils/CharMeasure'; +import * as Browser from './utils/Browser'; +import { MouseHelper } from './utils/MouseHelper'; +import { CHARSETS } from './Charsets'; +import { CustomKeyEventHandler, Charset, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types'; +import { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper, ITheme, ILinkifier } from './Interfaces'; +import { BellSound } from './utils/Sounds'; +import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager'; +import { IMouseZoneManager } from './input/Interfaces'; +import { MouseZoneManager } from './input/MouseZoneManager'; +import { initialize as initializeCharAtlas } from './renderer/CharAtlas'; +import { IRenderer } from './renderer/Interfaces'; + +// Let it work inside Node.js for automated testing purposes. +const document = (typeof window !== 'undefined') ? window.document : null; + +/** + * The amount of write requests to queue before sending an XOFF signal to the + * pty process. This number must be small in order for ^C and similar sequences + * to be responsive. + */ +const WRITE_BUFFER_PAUSE_THRESHOLD = 5; + +/** + * The number of writes to perform in a single batch before allowing the + * renderer to catch up with a 0ms setTimeout. + */ +const WRITE_BATCH_SIZE = 300; + +const DEFAULT_OPTIONS: ITerminalOptions = { + cols: 80, + rows: 24, + convertEol: false, + termName: 'xterm', + cursorBlink: false, + cursorStyle: 'block', + bellSound: BellSound, + bellStyle: 'none', + enableBold: true, + fontFamily: 'courier-new, courier, monospace', + fontSize: 15, + lineHeight: 1.0, + letterSpacing: 0, + scrollback: 1000, + screenKeys: false, + debug: false, + cancelEvents: false, + disableStdin: false, + useFlowControl: false, + allowTransparency: false, + tabStopWidth: 8, + theme: null + // programFeatures: false, + // focusKeys: false, +}; + +export class Terminal extends EventEmitter implements ITerminal, IInputHandlingTerminal { + public textarea: HTMLTextAreaElement; + public element: HTMLElement; + + /** + * The HTMLElement that the terminal is created in, set by Terminal.open. + */ + private parent: HTMLElement; + private context: Window; + private document: Document; + private body: HTMLBodyElement; + private viewportScrollArea: HTMLElement; + private viewportElement: HTMLElement; + private helperContainer: HTMLElement; + private compositionView: HTMLElement; + private charSizeStyleElement: HTMLStyleElement; + private bellAudioElement: HTMLAudioElement; + private visualBellTimer: number; + + public browser: IBrowser = Browser; + + public options: ITerminalOptions; + private colors: any; + + // TODO: This can be changed to an enum or boolean, 0 and 1 seem to be the only options + public cursorState: number; + public cursorHidden: boolean; + public convertEol: boolean; + + private sendDataQueue: string; + private customKeyEventHandler: CustomKeyEventHandler; + + // modes + public applicationKeypad: boolean; + public applicationCursor: boolean; + public originMode: boolean; + public insertMode: boolean; + public wraparoundMode: boolean; // defaults: xterm - true, vt100 - false + public bracketedPasteMode: boolean; + + // charset + // The current charset + public charset: Charset; + public gcharset: number; + public glevel: number; + public charsets: Charset[]; + + // mouse properties + private decLocator: boolean; // This is unstable and never set + public x10Mouse: boolean; + public vt200Mouse: boolean; + private vt300Mouse: boolean; // This is unstable and never set + public normalMouse: boolean; + public mouseEvents: boolean; + public sendFocus: boolean; + public utfMouse: boolean; + public sgrMouse: boolean; + public urxvtMouse: boolean; + + // misc + private refreshStart: number; + private refreshEnd: number; + public savedCols: number; + + // stream + private readable: boolean; + private writable: boolean; + + public defAttr: number; + public curAttr: number; + + public params: (string | number)[]; + public currentParam: string | number; + public prefix: string; + public postfix: string; + + // user input states + public writeBuffer: string[]; + private writeInProgress: boolean; + + /** + * Whether _xterm.js_ sent XOFF in order to catch up with the pty process. + * This is a distinct state from writeStopped so that if the user requested + * XOFF via ^S that it will not automatically resume when the writeBuffer goes + * below threshold. + */ + private xoffSentToCatchUp: boolean; + + /** Whether writing has been stopped as a result of XOFF */ + private writeStopped: boolean; + + // leftover surrogate high from previous write invocation + private surrogate_high: string; + + // Store if user went browsing history in scrollback + private userScrolling: boolean; + + private inputHandler: InputHandler; + private parser: Parser; + public renderer: IRenderer; + public selectionManager: SelectionManager; + public linkifier: ILinkifier; + public buffers: BufferSet; + public buffer: Buffer; + public viewport: IViewport; + private compositionHelper: ICompositionHelper; + public charMeasure: CharMeasure; + private _mouseZoneManager: IMouseZoneManager; + public mouseHelper: MouseHelper; + + public cols: number; + public rows: number; + + /** + * Creates a new `Terminal` object. + * + * @param {object} options An object containing a set of options, the available options are: + * - `cursorBlink` (boolean): Whether the terminal cursor blinks + * - `cols` (number): The number of columns of the terminal (horizontal size) + * - `rows` (number): The number of rows of the terminal (vertical size) + * + * @public + * @class Xterm Xterm + * @alias module:xterm/src/xterm + */ + constructor( + options: ITerminalOptions = {} + ) { + super(); + this.options = options; + this.setup(); + } + + private setup(): void { + Object.keys(DEFAULT_OPTIONS).forEach((key) => { + if (this.options[key] == null) { + this.options[key] = DEFAULT_OPTIONS[key]; + } + // TODO: We should move away from duplicate options on the Terminal object + this[key] = this.options[key]; + }); + + // this.context = options.context || window; + // this.document = options.document || document; + // TODO: WHy not document.body? + this.parent = document ? document.body : null; + + this.cols = this.options.cols; + this.rows = this.options.rows; + + if (this.options.handler) { + this.on('data', this.options.handler); + } + + this.cursorState = 0; + this.cursorHidden = false; + this.sendDataQueue = ''; + this.customKeyEventHandler = null; + + // modes + this.applicationKeypad = false; + this.applicationCursor = false; + this.originMode = false; + this.insertMode = false; + this.wraparoundMode = true; // defaults: xterm - true, vt100 - false + this.bracketedPasteMode = false; + + // charset + this.charset = null; + this.gcharset = null; + this.glevel = 0; + // TODO: Can this be just []? + this.charsets = [null]; + + this.readable = true; + this.writable = true; + + this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.curAttr = (0 << 18) | (257 << 9) | (256 << 0); + + this.params = []; + this.currentParam = 0; + this.prefix = ''; + this.postfix = ''; + + // user input states + this.writeBuffer = []; + this.writeInProgress = false; + + this.xoffSentToCatchUp = false; + this.writeStopped = false; + this.surrogate_high = ''; + this.userScrolling = false; + + this.inputHandler = new InputHandler(this); + this.parser = new Parser(this.inputHandler, this); + // Reuse renderer if the Terminal is being recreated via a reset call. + this.renderer = this.renderer || null; + this.selectionManager = this.selectionManager || null; + this.linkifier = this.linkifier || new Linkifier(this); + this._mouseZoneManager = this._mouseZoneManager || null; + + // Create the terminal's buffers and set the current buffer + this.buffers = new BufferSet(this); + this.buffer = this.buffers.active; // Convenience shortcut; + this.buffers.on('activate', (buffer: Buffer) => { + this.buffer = buffer; + }); + + // Ensure the selection manager has the correct buffer + if (this.selectionManager) { + this.selectionManager.setBuffer(this.buffer); + } + } + + /** + * back_color_erase feature for xterm. + */ + public eraseAttr(): number { + // if (this.is('screen')) return this.defAttr; + return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); + } + + /** + * Focus the terminal. Delegates focus handling to the terminal's DOM element. + */ + public focus(): void { + if (this.textarea) { + this.textarea.focus(); + } + } + + public get isFocused(): boolean { + return document.activeElement === this.textarea; + } + + /** + * Retrieves an option's value from the terminal. + * @param {string} key The option key. + */ + public getOption(key: string): any { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + + if (typeof this.options[key] !== 'undefined') { + return this.options[key]; + } + + return this[key]; + } + + /** + * Sets an option on the terminal. + * @param {string} key The option key. + * @param {any} value The option value. + */ + public setOption(key: string, value: any): void { + if (!(key in DEFAULT_OPTIONS)) { + throw new Error('No option with key "' + key + '"'); + } + switch (key) { + case 'bellStyle': + if (!value) { + value = 'none'; + } + break; + case 'cursorStyle': + if (!value) { + value = 'block'; + } + break; + case 'lineHeight': + if (value < 1) { + console.warn(`${key} cannot be less than 1, value: ${value}`); + return; + } + case 'tabStopWidth': + if (value < 1) { + console.warn(`${key} cannot be less than 1, value: ${value}`); + return; + } + break; + case 'theme': + // If open has been called we do not want to set options.theme as the + // source of truth is owned by the renderer. + if (this.renderer) { + this._setTheme(value); + return; + } + break; + case 'scrollback': + value = Math.min(value, MAX_BUFFER_SIZE); + + if (value < 0) { + console.warn(`${key} cannot be less than 0, value: ${value}`); + return; + } + if (this.options[key] !== value) { + const newBufferLength = this.rows + value; + if (this.buffer.lines.length > newBufferLength) { + const amountToTrim = this.buffer.lines.length - newBufferLength; + const needsRefresh = (this.buffer.ydisp - amountToTrim < 0); + this.buffer.lines.trimStart(amountToTrim); + this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0); + this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0); + if (needsRefresh) { + this.refresh(0, this.rows - 1); + } + } + } + break; + } + this[key] = value; + this.options[key] = value; + switch (key) { + case 'fontFamily': + case 'fontSize': + // When the font changes the size of the cells may change which requires a renderer clear + this.renderer.clear(); + this.charMeasure.measure(this.options); + break; + case 'enableBold': + case 'letterSpacing': + case 'lineHeight': + // When the font changes the size of the cells may change which requires a renderer clear + this.renderer.clear(); + this.renderer.onResize(this.cols, this.rows, false); + this.refresh(0, this.rows - 1); + // this.charMeasure.measure(this.options); + case 'scrollback': + this.buffers.resize(this.cols, this.rows); + this.viewport.syncScrollArea(); + break; + case 'tabStopWidth': this.buffers.setupTabStops(); break; + case 'bellSound': + case 'bellStyle': this.syncBellSound(); break; + } + // Inform renderer of changes + if (this.renderer) { + this.renderer.onOptionsChanged(); + } + } + + /** + * Binds the desired focus behavior on a given terminal object. + */ + private _onTextAreaFocus(): void { + if (this.sendFocus) { + this.send(C0.ESC + '[I'); + } + this.element.classList.add('focus'); + this.showCursor(); + this.emit('focus'); + }; + + /** + * Blur the terminal, calling the blur function on the terminal's underlying + * textarea. + */ + public blur(): void { + return this.textarea.blur(); + } + + /** + * Binds the desired blur behavior on a given terminal object. + */ + private _onTextAreaBlur(): void { + this.refresh(this.buffer.y, this.buffer.y); + if (this.sendFocus) { + this.send(C0.ESC + '[O'); + } + this.element.classList.remove('focus'); + this.emit('blur'); + } + + /** + * Initialize default behavior + */ + private initGlobal(): void { + this.bindKeys(); + + // Bind clipboard functionality + on(this.element, 'copy', (event: ClipboardEvent) => { + // If mouse events are active it means the selection manager is disabled and + // copy should be handled by the host program. + if (!this.hasSelection()) { + return; + } + copyHandler(event, this, this.selectionManager); + }); + const pasteHandlerWrapper = event => pasteHandler(event, this); + on(this.textarea, 'paste', pasteHandlerWrapper); + on(this.element, 'paste', pasteHandlerWrapper); + + // Handle right click context menus + if (Browser.isFirefox) { + // Firefox doesn't appear to fire the contextmenu event on right click + on(this.element, 'mousedown', (event: MouseEvent) => { + if (event.button === 2) { + rightClickHandler(event, this.textarea, this.selectionManager); + } + }); + } else { + on(this.element, 'contextmenu', (event: MouseEvent) => { + rightClickHandler(event, this.textarea, this.selectionManager); + }); + } + + // Move the textarea under the cursor when middle clicking on Linux to ensure + // middle click to paste selection works. This only appears to work in Chrome + // at the time is writing. + if (Browser.isLinux) { + // Use auxclick event over mousedown the latter doesn't seem to work. Note + // that the regular click event doesn't fire for the middle mouse button. + on(this.element, 'auxclick', (event: MouseEvent) => { + if (event.button === 1) { + moveTextAreaUnderMouseCursor(event, this.textarea); + } + }); + } + } + + /** + * Apply key handling to the terminal + */ + private bindKeys(): void { + const self = this; + on(this.element, 'keydown', function (ev: KeyboardEvent): void { + if (document.activeElement !== this) { + return; + } + self._keyDown(ev); + }, true); + + on(this.element, 'keypress', function (ev: KeyboardEvent): void { + if (document.activeElement !== this) { + return; + } + self._keyPress(ev); + }, true); + + on(this.element, 'keyup', (ev: KeyboardEvent) => { + if (!wasMondifierKeyOnlyEvent(ev)) { + this.focus(); + } + }, true); + + on(this.textarea, 'keydown', (ev: KeyboardEvent) => { + this._keyDown(ev); + }, true); + + on(this.textarea, 'keypress', (ev: KeyboardEvent) => { + this._keyPress(ev); + // Truncate the textarea's value, since it is not needed + this.textarea.value = ''; + }, true); + + on(this.textarea, 'compositionstart', () => this.compositionHelper.compositionstart()); + on(this.textarea, 'compositionupdate', (e: CompositionEvent) => this.compositionHelper.compositionupdate(e)); + on(this.textarea, 'compositionend', () => this.compositionHelper.compositionend()); + this.on('refresh', () => this.compositionHelper.updateCompositionElements()); + this.on('refresh', (data) => this.queueLinkification(data.start, data.end)); + } + + /** + * Opens the terminal within an element. + * + * @param {HTMLElement} parent The element to create the terminal within. + */ + public open(parent: HTMLElement): void { + let i = 0; + let div; + + this.parent = parent || this.parent; + + if (!this.parent) { + throw new Error('Terminal requires a parent element.'); + } + + // Grab global elements + this.context = this.parent.ownerDocument.defaultView; + this.document = this.parent.ownerDocument; + this.body = this.document.body; + + initializeCharAtlas(this.document, this.options.allowTransparency); + + // Create main element container + this.element = this.document.createElement('div'); + this.element.classList.add('terminal'); + this.element.classList.add('xterm'); + this.element.setAttribute('tabindex', '0'); + this.parent.appendChild(this.element); + + // Performance: Use a document fragment to build the terminal + // viewport and helper elements detached from the DOM + const fragment = document.createDocumentFragment(); + this.viewportElement = document.createElement('div'); + this.viewportElement.classList.add('xterm-viewport'); + fragment.appendChild(this.viewportElement); + this.viewportScrollArea = document.createElement('div'); + this.viewportScrollArea.classList.add('xterm-scroll-area'); + this.viewportElement.appendChild(this.viewportScrollArea); + + this._mouseZoneManager = new MouseZoneManager(this); + this.on('scroll', () => this._mouseZoneManager.clearAll()); + this.linkifier.attachToDom(this._mouseZoneManager); + + // Create the container that will hold helpers like the textarea for + // capturing DOM Events. Then produce the helpers. + this.helperContainer = document.createElement('div'); + this.helperContainer.classList.add('xterm-helpers'); + fragment.appendChild(this.helperContainer); + + this.textarea = document.createElement('textarea'); + this.textarea.classList.add('xterm-helper-textarea'); + this.textarea.setAttribute('autocorrect', 'off'); + this.textarea.setAttribute('autocapitalize', 'off'); + this.textarea.setAttribute('spellcheck', 'false'); + this.textarea.tabIndex = 0; + this.textarea.addEventListener('focus', () => this._onTextAreaFocus()); + this.textarea.addEventListener('blur', () => this._onTextAreaBlur()); + this.helperContainer.appendChild(this.textarea); + + this.compositionView = document.createElement('div'); + this.compositionView.classList.add('composition-view'); + this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this); + this.helperContainer.appendChild(this.compositionView); + + this.charSizeStyleElement = document.createElement('style'); + this.helperContainer.appendChild(this.charSizeStyleElement); + this.charMeasure = new CharMeasure(document, this.helperContainer); + + // Preload audio, this relied on helperContainer + this.syncBellSound(); + + // Performance: Add viewport and helper elements from the fragment + this.element.appendChild(fragment); + + this.renderer = new Renderer(this, this.options.theme); + this.options.theme = null; + this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); + this.viewport.onThemeChanged(this.renderer.colorManager.colors); + + this.on('cursormove', () => this.renderer.onCursorMove()); + this.on('resize', () => this.renderer.onResize(this.cols, this.rows, false)); + this.on('blur', () => this.renderer.onBlur()); + this.on('focus', () => this.renderer.onFocus()); + this.charMeasure.on('charsizechanged', () => this.renderer.onResize(this.cols, this.rows, true)); + this.renderer.on('resize', (dimensions) => this.viewport.syncScrollArea()); + + this.selectionManager = new SelectionManager(this, this.buffer, this.charMeasure); + this.element.addEventListener('mousedown', (e: MouseEvent) => this.selectionManager.onMouseDown(e)); + this.selectionManager.on('refresh', data => this.renderer.onSelectionChanged(data.start, data.end)); + this.selectionManager.on('newselection', text => { + // If there's a new selection, put it into the textarea, focus and select it + // in order to register it as a selection on the OS. This event is fired + // only on Linux to enable middle click to paste selection. + this.textarea.value = text; + this.textarea.focus(); + this.textarea.select(); + }); + this.on('scroll', () => { + this.viewport.syncScrollArea(); + this.selectionManager.refresh(); + }); + this.viewportElement.addEventListener('scroll', () => this.selectionManager.refresh()); + + this.mouseHelper = new MouseHelper(this.renderer); + + // Measure the character size + this.charMeasure.measure(this.options); + + // Setup loop that draws to screen + this.refresh(0, this.rows - 1); + + // Initialize global actions that need to be taken on the document. + this.initGlobal(); + + // Listen for mouse events and translate + // them into terminal mouse protocols. + this.bindMouse(); + + } + + /** + * Sets the theme on the renderer. The renderer must have been initialized. + * @param theme The theme to ste. + */ + private _setTheme(theme: ITheme): void { + const colors = this.renderer.setTheme(theme); + if (this.viewport) { + this.viewport.onThemeChanged(colors); + } + } + + /** + * Apply the provided addon on the `Terminal` class. + * @param addon The addon to apply. + */ + public static applyAddon(addon: any): void { + addon.apply(Terminal); + } + + /** + * XTerm mouse events + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking + * To better understand these + * the xterm code is very helpful: + * Relevant files: + * button.c, charproc.c, misc.c + * Relevant functions in xterm/button.c: + * BtnCode, EmitButtonCode, EditorButton, SendMousePosition + */ + public bindMouse(): void { + const el = this.element; + const self = this; + let pressed = 32; + + // mouseup, mousedown, wheel + // left click: ^[[M 3<^[[M#3< + // wheel up: ^[[M`3> + function sendButton(ev: MouseEvent | WheelEvent): void { + let button; + let pos; + + // get the xterm-style button + button = getButton(ev); + + // get mouse coordinates + pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) return; + + sendEvent(button, pos); + + switch ((ev).overrideType || ev.type) { + case 'mousedown': + pressed = button; + break; + case 'mouseup': + // keep it at the left + // button, just in case. + pressed = 32; + break; + case 'wheel': + // nothing. don't + // interfere with + // `pressed`. + break; + } + } + + // motion example of a left click: + // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< + function sendMove(ev: MouseEvent): void { + let button = pressed; + let pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + if (!pos) return; + + // buttons marked as motions + // are incremented by 32 + button += 32; + + sendEvent(button, pos); + } + + // encode button and + // position to characters + function encode(data: number[], ch: number): void { + if (!self.utfMouse) { + if (ch === 255) { + data.push(0); + return; + } + if (ch > 127) ch = 127; + data.push(ch); + } else { + if (ch === 2047) { + data.push(0); + return; + } + if (ch < 127) { + data.push(ch); + } else { + if (ch > 2047) ch = 2047; + data.push(0xC0 | (ch >> 6)); + data.push(0x80 | (ch & 0x3F)); + } + } + } + + // send a mouse event: + // regular/utf8: ^[[M Cb Cx Cy + // urxvt: ^[[ Cb ; Cx ; Cy M + // sgr: ^[[ Cb ; Cx ; Cy M/m + // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r + // locator: CSI P e ; P b ; P r ; P c ; P p & w + function sendEvent(button: number, pos: {x: number, y: number}): void { + // self.emit('mouse', { + // x: pos.x - 32, + // y: pos.x - 32, + // button: button + // }); + + if (self.vt300Mouse) { + // NOTE: Unstable. + // http://www.vt100.net/docs/vt3xx-gp/chapter15.html + button &= 3; + pos.x -= 32; + pos.y -= 32; + let data = C0.ESC + '[24'; + if (button === 0) data += '1'; + else if (button === 1) data += '3'; + else if (button === 2) data += '5'; + else if (button === 3) return; + else data += '0'; + data += '~[' + pos.x + ',' + pos.y + ']\r'; + self.send(data); + return; + } + + if (self.decLocator) { + // NOTE: Unstable. + button &= 3; + pos.x -= 32; + pos.y -= 32; + if (button === 0) button = 2; + else if (button === 1) button = 4; + else if (button === 2) button = 6; + else if (button === 3) button = 3; + self.send(C0.ESC + '[' + + button + + ';' + + (button === 3 ? 4 : 0) + + ';' + + pos.y + + ';' + + pos.x + + ';' + // Not sure what page is meant to be + + (pos).page || 0 + + '&w'); + return; + } + + if (self.urxvtMouse) { + pos.x -= 32; + pos.y -= 32; + pos.x++; + pos.y++; + self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M'); + return; + } + + if (self.sgrMouse) { + pos.x -= 32; + pos.y -= 32; + self.send(C0.ESC + '[<' + + (((button & 3) === 3 ? button & ~3 : button) - 32) + + ';' + + pos.x + + ';' + + pos.y + + ((button & 3) === 3 ? 'm' : 'M')); + return; + } + + let data: number[] = []; + + encode(data, button); + encode(data, pos.x); + encode(data, pos.y); + + self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data)); + } + + function getButton(ev: MouseEvent): number { + let button; + let shift; + let meta; + let ctrl; + let mod; + + // two low bits: + // 0 = left + // 1 = middle + // 2 = right + // 3 = release + // wheel up/down: + // 1, and 2 - with 64 added + switch ((ev).overrideType || ev.type) { + case 'mousedown': + button = ev.button != null + ? +ev.button + : ev.which != null + ? ev.which - 1 + : null; + + if (Browser.isMSIE) { + button = button === 1 ? 0 : button === 4 ? 1 : button; + } + break; + case 'mouseup': + button = 3; + break; + case 'DOMMouseScroll': + button = ev.detail < 0 + ? 64 + : 65; + break; + case 'wheel': + button = (ev).wheelDeltaY > 0 + ? 64 + : 65; + break; + } + + // next three bits are the modifiers: + // 4 = shift, 8 = meta, 16 = control + shift = ev.shiftKey ? 4 : 0; + meta = ev.metaKey ? 8 : 0; + ctrl = ev.ctrlKey ? 16 : 0; + mod = shift | meta | ctrl; + + // no mods + if (self.vt200Mouse) { + // ctrl only + mod &= ctrl; + } else if (!self.normalMouse) { + mod = 0; + } + + // increment to SP + button = (32 + (mod << 2)) + button; + + return button; + } + + on(el, 'mousedown', (ev: MouseEvent) => { + + // Prevent the focus on the textarea from getting lost + // and make sure we get focused on mousedown + ev.preventDefault(); + this.focus(); + + // Don't send the mouse button to the pty if mouse events are disabled or + // if the selection manager is having selection forced (ie. a modifier is + // held). + if (!this.mouseEvents || this.selectionManager.shouldForceSelection(ev)) { + return; + } + + // send the button + sendButton(ev); + + // fix for odd bug + // if (this.vt200Mouse && !this.normalMouse) { + if (this.vt200Mouse) { + (ev).overrideType = 'mouseup'; + sendButton(ev); + return this.cancel(ev); + } + + // bind events + if (this.normalMouse) on(this.document, 'mousemove', sendMove); + + // x10 compatibility mode can't send button releases + if (!this.x10Mouse) { + const handler = (ev: MouseEvent) => { + sendButton(ev); + // TODO: Seems dangerous calling this on document? + if (this.normalMouse) off(this.document, 'mousemove', sendMove); + off(this.document, 'mouseup', handler); + return this.cancel(ev); + }; + // TODO: Seems dangerous calling this on document? + on(this.document, 'mouseup', handler); + } + + return this.cancel(ev); + }); + + // if (this.normalMouse) { + // on(this.document, 'mousemove', sendMove); + // } + + on(el, 'wheel', (ev: WheelEvent) => { + if (!this.mouseEvents) return; + if (this.x10Mouse || this.vt300Mouse || this.decLocator) return; + sendButton(ev); + ev.preventDefault(); + }); + + // allow wheel scrolling in + // the shell for example + on(el, 'wheel', (ev: WheelEvent) => { + if (this.mouseEvents) return; + this.viewport.onWheel(ev); + return this.cancel(ev); + }); + + on(el, 'touchstart', (ev: TouchEvent) => { + if (this.mouseEvents) return; + this.viewport.onTouchStart(ev); + return this.cancel(ev); + }); + + on(el, 'touchmove', (ev: TouchEvent) => { + if (this.mouseEvents) return; + this.viewport.onTouchMove(ev); + return this.cancel(ev); + }); + } + + /** + * Destroys the terminal. + */ + public destroy(): void { + super.destroy(); + this.readable = false; + this.writable = false; + this.handler = () => {}; + this.write = () => {}; + if (this.element && this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } + // this.emit('close'); + } + + /** + * Tells the renderer to refresh terminal content between two rows (inclusive) at the next + * opportunity. + * @param {number} start The row to start from (between 0 and this.rows - 1). + * @param {number} end The row to end at (between start and this.rows - 1). + */ + public refresh(start: number, end: number): void { + if (this.renderer) { + this.renderer.queueRefresh(start, end); + } + } + + /** + * Queues linkification for the specified rows. + * @param {number} start The row to start from (between 0 and this.rows - 1). + * @param {number} end The row to end at (between start and this.rows - 1). + */ + private queueLinkification(start: number, end: number): void { + if (this.linkifier) { + this.linkifier.linkifyRows(start, end); + } + } + + /** + * Display the cursor element + */ + public showCursor(): void { + if (!this.cursorState) { + this.cursorState = 1; + this.refresh(this.buffer.y, this.buffer.y); + } + } + + /** + * Scroll the terminal down 1 row, creating a blank line. + * @param isWrapped Whether the new line is wrapped from the previous line. + */ + public scroll(isWrapped?: boolean): void { + const newLine = this.blankLine(undefined, isWrapped); + const topRow = this.buffer.ybase + this.buffer.scrollTop; + let bottomRow = this.buffer.ybase + this.buffer.scrollBottom; + + if (this.buffer.scrollTop === 0) { + // Determine whether the buffer is going to be trimmed after insertion. + const willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength; + + // Insert the line using the fastest method + if (bottomRow === this.buffer.lines.length - 1) { + this.buffer.lines.push(newLine); + } else { + this.buffer.lines.splice(bottomRow + 1, 0, newLine); + } + + // Only adjust ybase and ydisp when the buffer is not trimmed + if (!willBufferBeTrimmed) { + this.buffer.ybase++; + // Only scroll the ydisp with ybase if the user has not scrolled up + if (!this.userScrolling) { + this.buffer.ydisp++; + } + } else { + // When the buffer is full and the user has scrolled up, keep the text + // stable unless ydisp is right at the top + if (this.userScrolling) { + this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0); + } + } + } else { + // scrollTop is non-zero which means no line will be going to the + // scrollback, instead we can just shift them in-place. + const scrollRegionHeight = bottomRow - topRow + 1/*as it's zero-based*/; + this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1); + this.buffer.lines.set(bottomRow, newLine); + } + + // Move the viewport to the bottom of the buffer unless the user is + // scrolling. + if (!this.userScrolling) { + this.buffer.ydisp = this.buffer.ybase; + } + + // Flag rows that need updating + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + + /** + * This event is emitted whenever the terminal is scrolled. + * The one parameter passed is the new y display position. + * + * @event scroll + */ + this.emit('scroll', this.buffer.ydisp); + } + + /** + * Scroll the display of the terminal + * @param {number} disp The number of lines to scroll down (negative scroll up). + * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollLines. This is used + * to avoid unwanted events being handled by the viewport when the event was triggered from the + * viewport originally. + */ + public scrollLines(disp: number, suppressScrollEvent?: boolean): void { + if (disp < 0) { + if (this.buffer.ydisp === 0) { + return; + } + this.userScrolling = true; + } else if (disp + this.buffer.ydisp >= this.buffer.ybase) { + this.userScrolling = false; + } + + const oldYdisp = this.buffer.ydisp; + this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0); + + // No change occurred, don't trigger scroll/refresh + if (oldYdisp === this.buffer.ydisp) { + return; + } + + if (!suppressScrollEvent) { + this.emit('scroll', this.buffer.ydisp); + } + + this.refresh(0, this.rows - 1); + } + + /** + * Scroll the display of the terminal by a number of pages. + * @param {number} pageCount The number of pages to scroll (negative scrolls up). + */ + public scrollPages(pageCount: number): void { + this.scrollLines(pageCount * (this.rows - 1)); + } + + /** + * Scrolls the display of the terminal to the top. + */ + public scrollToTop(): void { + this.scrollLines(-this.buffer.ydisp); + } + + /** + * Scrolls the display of the terminal to the bottom. + */ + public scrollToBottom(): void { + this.scrollLines(this.buffer.ybase - this.buffer.ydisp); + } + + /** + * Writes text to the terminal. + * @param {string} data The text to write to the terminal. + */ + public write(data: string): void { + this.writeBuffer.push(data); + + // Send XOFF to pause the pty process if the write buffer becomes too large so + // xterm.js can catch up before more data is sent. This is necessary in order + // to keep signals such as ^C responsive. + if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) { + // XOFF - stop pty pipe + // XON will be triggered by emulator before processing data chunk + this.send(C0.DC3); + this.xoffSentToCatchUp = true; + } + + if (!this.writeInProgress && this.writeBuffer.length > 0) { + // Kick off a write which will write all data in sequence recursively + this.writeInProgress = true; + // Kick off an async innerWrite so more writes can come in while processing data + setTimeout(() => { + this.innerWrite(); + }); + } + } + + private innerWrite(): void { + const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); + while (writeBatch.length > 0) { + const data = writeBatch.shift(); + + // If XOFF was sent in order to catch up with the pty process, resume it if + // the writeBuffer is empty to allow more data to come in. + if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) { + this.send(C0.DC1); + this.xoffSentToCatchUp = false; + } + + this.refreshStart = this.buffer.y; + this.refreshEnd = this.buffer.y; + + // HACK: Set the parser state based on it's state at the time of return. + // This works around the bug #662 which saw the parser state reset in the + // middle of parsing escape sequence in two chunks. For some reason the + // state of the parser resets to 0 after exiting parser.parse. This change + // just sets the state back based on the correct return statement. + const state = this.parser.parse(data); + this.parser.setState(state); + + this.updateRange(this.buffer.y); + this.refresh(this.refreshStart, this.refreshEnd); + } + if (this.writeBuffer.length > 0) { + // Allow renderer to catch up before processing the next batch + setTimeout(() => this.innerWrite(), 0); + } else { + this.writeInProgress = false; + } + } + + /** + * Writes text to the terminal, followed by a break line character (\n). + * @param {string} data The text to write to the terminal. + */ + public writeln(data: string): void { + this.write(data + '\r\n'); + } + + /** + * Attaches a custom key event handler which is run before keys are processed, + * giving consumers of xterm.js ultimate control as to what keys should be + * processed by the terminal and what keys should not. + * @param customKeyEventHandler The custom KeyboardEvent handler to attach. + * This is a function that takes a KeyboardEvent, allowing consumers to stop + * propogation and/or prevent the default action. The function returns whether + * the event should be processed by xterm.js. + */ + public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void { + this.customKeyEventHandler = customKeyEventHandler; + } + + /** + * Attaches a http(s) link handler, forcing web links to behave differently to + * regular tags. This will trigger a refresh as links potentially need to be + * reconstructed. Calling this with null will remove the handler. + * @param handler The handler callback function. + */ + public setHypertextLinkHandler(handler: LinkMatcherHandler): void { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); + } + this.linkifier.setHypertextLinkHandler(handler); + // Refresh to force links to refresh + this.refresh(0, this.rows - 1); + } + + /** + * Attaches a validation callback for hypertext links. This is useful to use + * validation logic or to do something with the link's element and url. + * @param callback The callback to use, this can + * be cleared with null. + */ + public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void { + if (!this.linkifier) { + throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); + } + this.linkifier.setHypertextValidationCallback(callback); + // // Refresh to force links to refresh + this.refresh(0, this.rows - 1); + } + + /** + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param regex The regular expression to search for, specifically + * this searches the textContent of the rows. You will want to use \s to match + * a space ' ' character for example. + * @param handler The callback when the link is called. + * @param options Options for the link matcher. + * @return The ID of the new matcher, this can be used to deregister. + */ + public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number { + if (this.linkifier) { + const matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); + this.refresh(0, this.rows - 1); + return matcherId; + } + return 0; + } + + /** + * Deregisters a link matcher if it has been registered. + * @param matcherId The link matcher's ID (returned after register) + */ + public deregisterLinkMatcher(matcherId: number): void { + if (this.linkifier) { + if (this.linkifier.deregisterLinkMatcher(matcherId)) { + this.refresh(0, this.rows - 1); + } + } + } + + /** + * Gets whether the terminal has an active selection. + */ + public hasSelection(): boolean { + return this.selectionManager ? this.selectionManager.hasSelection : false; + } + + /** + * Gets the terminal's current selection, this is useful for implementing copy + * behavior outside of xterm.js. + */ + public getSelection(): string { + return this.selectionManager ? this.selectionManager.selectionText : ''; + } + + /** + * Clears the current terminal selection. + */ + public clearSelection(): void { + if (this.selectionManager) { + this.selectionManager.clearSelection(); + } + } + + /** + * Selects all text within the terminal. + */ + public selectAll(): void { + if (this.selectionManager) { + this.selectionManager.selectAll(); + } + } + + /** + * Handle a keydown event + * Key Resources: + * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent + * @param {KeyboardEvent} ev The keydown event to be handled. + */ + protected _keyDown(ev: KeyboardEvent): boolean { + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + + if (!this.compositionHelper.keydown(ev)) { + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + return false; + } + + const result = this._evaluateKeyEscapeSequence(ev); + + if (result.key === C0.DC3) { // XOFF + this.writeStopped = true; + } else if (result.key === C0.DC1) { // XON + this.writeStopped = false; + } + + if (result.scrollLines) { + this.scrollLines(result.scrollLines); + return this.cancel(ev, true); + } + + if (isThirdLevelShift(this.browser, ev)) { + return true; + } + + if (result.cancel) { + // The event is canceled at the end already, is this necessary? + this.cancel(ev, true); + } + + if (!result.key) { + return true; + } + + this.emit('keydown', ev); + this.emit('key', result.key, ev); + this.showCursor(); + this.handler(result.key); + + return this.cancel(ev, true); + } + + /** + * Returns an object that determines how a KeyboardEvent should be handled. The key of the + * returned value is the new key code to pass to the PTY. + * + * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * @param ev The keyboard event to be translated to key escape sequence. + */ + protected _evaluateKeyEscapeSequence(ev: KeyboardEvent): {cancel: boolean, key: string, scrollLines: number} { + const result: {cancel: boolean, key: string, scrollLines: number} = { + // Whether to cancel event propogation (NOTE: this may not be needed since the event is + // canceled at the end of keyDown + cancel: false, + // The new key even to emit + key: undefined, + // The number of characters to scroll, if this is defined it will cancel the event + scrollLines: undefined + }; + const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0); + switch (ev.keyCode) { + case 0: + if (ev.key === 'UIKeyInputUpArrow') { + if (this.applicationCursor) { + result.key = C0.ESC + 'OA'; + } else { + result.key = C0.ESC + '[A'; + } + } + else if (ev.key === 'UIKeyInputLeftArrow') { + if (this.applicationCursor) { + result.key = C0.ESC + 'OD'; + } else { + result.key = C0.ESC + '[D'; + } + } + else if (ev.key === 'UIKeyInputRightArrow') { + if (this.applicationCursor) { + result.key = C0.ESC + 'OC'; + } else { + result.key = C0.ESC + '[C'; + } + } + else if (ev.key === 'UIKeyInputDownArrow') { + if (this.applicationCursor) { + result.key = C0.ESC + 'OB'; + } else { + result.key = C0.ESC + '[B'; + } + } + break; + case 8: + // backspace + if (ev.shiftKey) { + result.key = C0.BS; // ^H + break; + } else if (ev.altKey) { + result.key = C0.ESC + C0.DEL; // \e ^? + break; + } + result.key = C0.DEL; // ^? + break; + case 9: + // tab + if (ev.shiftKey) { + result.key = C0.ESC + '[Z'; + break; + } + result.key = C0.HT; + result.cancel = true; + break; + case 13: + // return/enter + result.key = C0.CR; + result.cancel = true; + break; + case 27: + // escape + result.key = C0.ESC; + result.cancel = true; + break; + case 37: + // left-arrow + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D'; + // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards + // http://unix.stackexchange.com/a/108106 + // macOS uses different escape sequences than linux + if (result.key === C0.ESC + '[1;3D') { + result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D'; + } + } else if (this.applicationCursor) { + result.key = C0.ESC + 'OD'; + } else { + result.key = C0.ESC + '[D'; + } + break; + case 39: + // right-arrow + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C'; + // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward + // http://unix.stackexchange.com/a/108106 + // macOS uses different escape sequences than linux + if (result.key === C0.ESC + '[1;3C') { + result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C'; + } + } else if (this.applicationCursor) { + result.key = C0.ESC + 'OC'; + } else { + result.key = C0.ESC + '[C'; + } + break; + case 38: + // up-arrow + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A'; + // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key === C0.ESC + '[1;3A') { + result.key = C0.ESC + '[1;5A'; + } + } else if (this.applicationCursor) { + result.key = C0.ESC + 'OA'; + } else { + result.key = C0.ESC + '[A'; + } + break; + case 40: + // down-arrow + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B'; + // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key === C0.ESC + '[1;3B') { + result.key = C0.ESC + '[1;5B'; + } + } else if (this.applicationCursor) { + result.key = C0.ESC + 'OB'; + } else { + result.key = C0.ESC + '[B'; + } + break; + case 45: + // insert + if (!ev.shiftKey && !ev.ctrlKey) { + // or + are used to + // copy-paste on some systems. + result.key = C0.ESC + '[2~'; + } + break; + case 46: + // delete + if (modifiers) { + result.key = C0.ESC + '[3;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[3~'; + } + break; + case 36: + // home + if (modifiers) + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H'; + else if (this.applicationCursor) + result.key = C0.ESC + 'OH'; + else + result.key = C0.ESC + '[H'; + break; + case 35: + // end + if (modifiers) + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F'; + else if (this.applicationCursor) + result.key = C0.ESC + 'OF'; + else + result.key = C0.ESC + '[F'; + break; + case 33: + // page up + if (ev.shiftKey) { + result.scrollLines = -(this.rows - 1); + } else { + result.key = C0.ESC + '[5~'; + } + break; + case 34: + // page down + if (ev.shiftKey) { + result.scrollLines = this.rows - 1; + } else { + result.key = C0.ESC + '[6~'; + } + break; + case 112: + // F1-F12 + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P'; + } else { + result.key = C0.ESC + 'OP'; + } + break; + case 113: + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q'; + } else { + result.key = C0.ESC + 'OQ'; + } + break; + case 114: + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R'; + } else { + result.key = C0.ESC + 'OR'; + } + break; + case 115: + if (modifiers) { + result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S'; + } else { + result.key = C0.ESC + 'OS'; + } + break; + case 116: + if (modifiers) { + result.key = C0.ESC + '[15;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[15~'; + } + break; + case 117: + if (modifiers) { + result.key = C0.ESC + '[17;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[17~'; + } + break; + case 118: + if (modifiers) { + result.key = C0.ESC + '[18;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[18~'; + } + break; + case 119: + if (modifiers) { + result.key = C0.ESC + '[19;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[19~'; + } + break; + case 120: + if (modifiers) { + result.key = C0.ESC + '[20;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[20~'; + } + break; + case 121: + if (modifiers) { + result.key = C0.ESC + '[21;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[21~'; + } + break; + case 122: + if (modifiers) { + result.key = C0.ESC + '[23;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[23~'; + } + break; + case 123: + if (modifiers) { + result.key = C0.ESC + '[24;' + (modifiers + 1) + '~'; + } else { + result.key = C0.ESC + '[24~'; + } + break; + default: + // a-z and space + if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = String.fromCharCode(ev.keyCode - 64); + } else if (ev.keyCode === 32) { + // NUL + result.key = String.fromCharCode(0); + } else if (ev.keyCode >= 51 && ev.keyCode <= 55) { + // escape, file sep, group sep, record sep, unit sep + result.key = String.fromCharCode(ev.keyCode - 51 + 27); + } else if (ev.keyCode === 56) { + // delete + result.key = String.fromCharCode(127); + } else if (ev.keyCode === 219) { + // ^[ - Control Sequence Introducer (CSI) + result.key = String.fromCharCode(27); + } else if (ev.keyCode === 220) { + // ^\ - String Terminator (ST) + result.key = String.fromCharCode(28); + } else if (ev.keyCode === 221) { + // ^] - Operating System Command (OSC) + result.key = String.fromCharCode(29); + } + } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { + // On Mac this is a third level shift. Use instead. + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32); + } else if (ev.keyCode === 192) { + result.key = C0.ESC + '`'; + } else if (ev.keyCode >= 48 && ev.keyCode <= 57) { + result.key = C0.ESC + (ev.keyCode - 48); + } + } else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { + if (ev.keyCode === 65) { // cmd + a + this.selectAll(); + } + } + break; + } + + return result; + } + + /** + * Set the G level of the terminal + * @param g + */ + public setgLevel(g: number): void { + this.glevel = g; + this.charset = this.charsets[g]; + } + + /** + * Set the charset for the given G level of the terminal + * @param g + * @param charset + */ + public setgCharset(g: number, charset: Charset): void { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } + } + + /** + * Handle a keypress event. + * Key Resources: + * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent + * @param {KeyboardEvent} ev The keypress event to be handled. + */ + protected _keyPress(ev: KeyboardEvent): boolean { + let key; + + if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { + return false; + } + + this.cancel(ev); + + if (ev.charCode) { + key = ev.charCode; + } else if (ev.which == null) { + key = ev.keyCode; + } else if (ev.which !== 0 && ev.charCode !== 0) { + key = ev.which; + } else { + return false; + } + + if (!key || ( + (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this.browser, ev) + )) { + return false; + } + + key = String.fromCharCode(key); + + this.emit('keypress', key, ev); + this.emit('key', key, ev); + this.showCursor(); + this.handler(key); + + return true; + } + + /** + * Send data for handling to the terminal + * @param {string} data + */ + public send(data: string): void { + if (!this.sendDataQueue) { + setTimeout(() => { + this.handler(this.sendDataQueue); + this.sendDataQueue = ''; + }, 1); + } + + this.sendDataQueue += data; + } + + /** + * Ring the bell. + * Note: We could do sweet things with webaudio here + */ + public bell(): void { + this.emit('bell'); + if (this.soundBell()) this.bellAudioElement.play(); + + if (this.visualBell()) { + this.element.classList.add('visual-bell-active'); + clearTimeout(this.visualBellTimer); + this.visualBellTimer = window.setTimeout(() => { + this.element.classList.remove('visual-bell-active'); + }, 200); + } + } + + /** + * Log the current state to the console. + */ + public log(text: string, data?: any): void { + if (!this.options.debug) return; + if (!this.context.console || !this.context.console.log) return; + this.context.console.log(text, data); + } + + /** + * Log the current state as error to the console. + */ + public error(text: string, data?: any): void { + if (!this.options.debug) return; + if (!this.context.console || !this.context.console.error) return; + this.context.console.error(text, data); + } + + /** + * Resizes the terminal. + * + * @param {number} x The number of columns to resize to. + * @param {number} y The number of rows to resize to. + */ + public resize(x: number, y: number): void { + if (isNaN(x) || isNaN(y)) { + return; + } + + if (x === this.cols && y === this.rows) { + // Check if we still need to measure the char size (fixes #785). + if (!this.charMeasure.width || !this.charMeasure.height) { + this.charMeasure.measure(this.options); + } + return; + } + + if (x < 1) x = 1; + if (y < 1) y = 1; + + this.buffers.resize(x, y); + + this.cols = x; + this.rows = y; + this.buffers.setupTabStops(this.cols); + + this.charMeasure.measure(this.options); + + this.refresh(0, this.rows - 1); + this.emit('resize', {cols: x, rows: y}); + } + + /** + * Updates the range of rows to refresh + * @param {number} y The number of rows to refresh next. + */ + public updateRange(y: number): void { + if (y < this.refreshStart) this.refreshStart = y; + if (y > this.refreshEnd) this.refreshEnd = y; + // if (y > this.refreshEnd) { + // this.refreshEnd = y; + // if (y > this.rows - 1) { + // this.refreshEnd = this.rows - 1; + // } + // } + } + + /** + * Set the range of refreshing to the maximum value + */ + public maxRange(): void { + this.refreshStart = 0; + this.refreshEnd = this.rows - 1; + } + + /** + * Erase in the identified line everything from "x" to the end of the line (right). + * @param {number} x The column from which to start erasing to the end of the line. + * @param {number} y The line in which to operate. + */ + public eraseRight(x: number, y: number): void { + const line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm + for (; x < this.cols; x++) { + line[x] = ch; + } + this.updateRange(y); + } + + /** + * Erase in the identified line everything from "x" to the start of the line (left). + * @param {number} x The column from which to start erasing to the start of the line. + * @param {number} y The line in which to operate. + */ + public eraseLeft(x: number, y: number): void { + const line = this.buffer.lines.get(this.buffer.ybase + y); + if (!line) { + return; + } + const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm + x++; + while (x--) { + line[x] = ch; + } + this.updateRange(y); + } + + /** + * Clear the entire buffer, making the prompt line the new first line. + */ + public clear(): void { + if (this.buffer.ybase === 0 && this.buffer.y === 0) { + // Don't clear if it's already clear + return; + } + this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)); + this.buffer.lines.length = 1; + this.buffer.ydisp = 0; + this.buffer.ybase = 0; + this.buffer.y = 0; + for (let i = 1; i < this.rows; i++) { + this.buffer.lines.push(this.blankLine()); + } + this.refresh(0, this.rows - 1); + this.emit('scroll', this.buffer.ydisp); + } + + /** + * Erase all content in the given line + * @param {number} y The line to erase all of its contents. + */ + public eraseLine(y: number): void { + this.eraseRight(0, y); + } + + /** + * Return the data array of a blank line + * @param {boolean} cur First bunch of data for each "blank" character. + * @param {boolean} isWrapped Whether the new line is wrapped from the previous line. + * @param {boolean} cols The number of columns in the terminal, if this is not + * set, the terminal's current column count would be used. + */ + public blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData { + const attr = cur ? this.eraseAttr() : this.defAttr; + + const ch: CharData = [attr, ' ', 1, 32 /* ' '.charCodeAt(0) */]; // width defaults to 1 halfwidth character + const line: LineData = []; + + // TODO: It is not ideal that this is a property on an array, a buffer line + // class should be added that will hold this data and other useful functions. + if (isWrapped) { + (line).isWrapped = isWrapped; + } + + cols = cols || this.cols; + for (let i = 0; i < cols; i++) { + line[i] = ch; + } + + return line; + } + + /** + * If cur return the back color xterm feature attribute. Else return defAttr. + * @param cur + */ + public ch(cur?: boolean): CharData { + if (cur) { + return [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; + } + return [this.defAttr, ' ', 1, 32 /* ' '.charCodeAt(0) */]; + } + + /** + * Evaluate if the current terminal is the given argument. + * @param term The terminal name to evaluate + */ + public is(term: string): boolean { + return (this.options.termName + '').indexOf(term) === 0; + } + + /** + * Emit the 'data' event and populate the given data. + * @param {string} data The data to populate in the event. + */ + public handler(data: string): void { + // Prevents all events to pty process if stdin is disabled + if (this.options.disableStdin) { + return; + } + + // Clear the selection if the selection manager is available and has an active selection + if (this.selectionManager && this.selectionManager.hasSelection) { + this.selectionManager.clearSelection(); + } + + // Input is being sent to the terminal, the terminal should focus the prompt. + if (this.buffer.ybase !== this.buffer.ydisp) { + this.scrollToBottom(); + } + this.emit('data', data); + } + + /** + * Emit the 'title' event and populate the given title. + * @param {string} title The title to populate in the event. + */ + private handleTitle(title: string): void { + /** + * This event is emitted when the title of the terminal is changed + * from inside the terminal. The parameter is the new title. + * + * @event title + */ + this.emit('title', title); + } + + /** + * ESC + */ + + /** + * ESC D Index (IND is 0x84). + */ + public index(): void { + this.buffer.y++; + if (this.buffer.y > this.buffer.scrollBottom) { + this.buffer.y--; + this.scroll(); + } + // If the end of the line is hit, prevent this action from wrapping around to the next line. + if (this.buffer.x >= this.cols) { + this.buffer.x--; + } + } + + /** + * ESC M Reverse Index (RI is 0x8d). + * + * Move the cursor up one row, inserting a new blank line if necessary. + */ + public reverseIndex(): void { + if (this.buffer.y === this.buffer.scrollTop) { + // possibly move the code below to term.reverseScroll(); + // test: echo -ne '\e[1;1H\e[44m\eM\e[0m' + // blankLine(true) is xterm/linux behavior + const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop; + this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1); + this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true)); + this.updateRange(this.buffer.scrollTop); + this.updateRange(this.buffer.scrollBottom); + } else { + this.buffer.y--; + } + } + + /** + * ESC c Full Reset (RIS). + */ + public reset(): void { + this.options.rows = this.rows; + this.options.cols = this.cols; + const customKeyEventHandler = this.customKeyEventHandler; + const inputHandler = this.inputHandler; + const buffers = this.buffers; + this.setup(); + this.customKeyEventHandler = customKeyEventHandler; + this.inputHandler = inputHandler; + this.buffers = buffers; + this.refresh(0, this.rows - 1); + this.viewport.syncScrollArea(); + } + + + /** + * ESC H Tab Set (HTS is 0x88). + */ + private tabSet(): void { + this.buffer.tabs[this.buffer.x] = true; + } + + // TODO: Remove cancel function and cancelEvents option + public cancel(ev: Event, force?: boolean): boolean { + if (!this.options.cancelEvents && !force) { + return; + } + ev.preventDefault(); + ev.stopPropagation(); + return false; + } + + // TODO: Remove when true color is implemented + public matchColor(r1: number, g1: number, b1: number): number { + return matchColor_(r1, g1, b1); + } + + private visualBell(): boolean { + return this.options.bellStyle === 'visual' || + this.options.bellStyle === 'both'; + } + + private soundBell(): boolean { + return this.options.bellStyle === 'sound' || + this.options.bellStyle === 'both'; + } + + private syncBellSound(): void { + // Don't update anything if the terminal has not been opened yet + if (!this.element) { + return; + } + + if (this.soundBell() && this.bellAudioElement) { + this.bellAudioElement.setAttribute('src', this.options.bellSound); + } else if (this.soundBell()) { + this.bellAudioElement = document.createElement('audio'); + this.bellAudioElement.setAttribute('preload', 'auto'); + this.bellAudioElement.setAttribute('src', this.options.bellSound); + this.helperContainer.appendChild(this.bellAudioElement); + } else if (this.bellAudioElement) { + this.helperContainer.removeChild(this.bellAudioElement); + } + } +} + +/** + * Helpers + */ + +function globalOn(el: any, type: string, handler: (event: Event) => any, capture?: boolean): void { + if (!Array.isArray(el)) { + el = [el]; + } + el.forEach((element: HTMLElement) => { + element.addEventListener(type, handler, capture || false); + }); +} +// TODO: Remove once everything is typed +const on = globalOn; + +function off(el: any, type: string, handler: (event: Event) => any, capture: boolean = false): void { + el.removeEventListener(type, handler, capture); +} + +function isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean { + const thirdLevelKey = + (browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + + if (ev.type === 'keypress') { + return thirdLevelKey; + } + + // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events) + return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); +} + +function wasMondifierKeyOnlyEvent(ev: KeyboardEvent): boolean { + return ev.keyCode === 16 || // Shift + ev.keyCode === 17 || // Ctrl + ev.keyCode === 18; // Alt +} + +/** + * TODO: + * The below color-related code can be removed when true color is implemented. + * It's only purpose is to match true color requests with the closest matching + * ANSI color code. + */ + +// Colors 0-15 + 16-255 +// Much thanks to TooTallNate for writing this. +const vcolors: number[][] = (function(): number[][] { + const result = DEFAULT_ANSI_COLORS.map(c => { + c = c.substring(1); + return [ + parseInt(c.substring(0, 2), 16), + parseInt(c.substring(2, 4), 16), + parseInt(c.substring(4, 6), 16) + ]; + }); + const r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + + // 16-231 + for (let i = 0; i < 216; i++) { + result.push([ + r[(i / 36) % 6 | 0], + r[(i / 6) % 6 | 0], + r[i % 6] + ]); + } + + // 232-255 (grey) + let c: number; + for (let i = 0; i < 24; i++) { + c = 8 + i * 10; + result.push([c, c, c]); + } + + return result; +})(); + +const matchColorCache: {[colorRGBHash: number]: number} = {}; + +// http://stackoverflow.com/questions/1633828 +function matchColorDistance(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number): number { + return Math.pow(30 * (r1 - r2), 2) + + Math.pow(59 * (g1 - g2), 2) + + Math.pow(11 * (b1 - b2), 2); +}; + + +function matchColor_(r1: number, g1: number, b1: number): number { + const hash = (r1 << 16) | (g1 << 8) | b1; + + if (matchColorCache[hash] != null) { + return matchColorCache[hash]; + } + + let ldiff = Infinity; + let li = -1; + let i = 0; + let c: number[]; + let r2: number; + let g2: number; + let b2: number; + let diff: number; + + for (; i < vcolors.length; i++) { + c = vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + + diff = matchColorDistance(r1, g1, b1, r2, g2, b2); + + if (diff === 0) { + li = i; + break; + } + + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + + return matchColorCache[hash] = li; +} diff --git a/xterm.js/src/Types.ts b/xterm.js/src/Types.ts new file mode 100644 index 0000000..a0c03fd --- /dev/null +++ b/xterm.js/src/Types.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export type LinkMatcher = { + id: number, + regex: RegExp, + handler: LinkMatcherHandler, + hoverTooltipCallback?: LinkMatcherHandler, + hoverLeaveCallback?: () => void, + matchIndex?: number, + validationCallback?: LinkMatcherValidationCallback, + priority?: number +}; +export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void; +export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; + +export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean; +export type Charset = {[key: string]: string}; + +export type CharData = [number, string, number, number]; +export type LineData = CharData[]; + +export type LinkHoverEvent = { + x: number, + y: number, + length: number +}; + +export enum LinkHoverEventTypes { + HOVER = 'linkhover', + TOOLTIP = 'linktooltip', + LEAVE = 'linkleave' +}; diff --git a/xterm.js/src/Viewport.ts b/xterm.js/src/Viewport.ts new file mode 100644 index 0000000..1ea7fa0 --- /dev/null +++ b/xterm.js/src/Viewport.ts @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, IViewport } from './Interfaces'; +import { CharMeasure } from './utils/CharMeasure'; +import { IColorSet } from './renderer/Interfaces'; + +/** + * Represents the viewport of a terminal, the visible area within the larger buffer of output. + * Logic for the virtual scroll bar is included in this object. + */ +export class Viewport implements IViewport { + private currentRowHeight: number = 0; + private lastRecordedBufferLength: number = 0; + private lastRecordedViewportHeight: number = 0; + private lastRecordedBufferHeight: number = 0; + private lastTouchY: number; + + /** + * Creates a new Viewport. + * @param terminal The terminal this viewport belongs to. + * @param viewportElement The DOM element acting as the viewport. + * @param scrollArea The DOM element acting as the scroll area. + * @param charMeasure A DOM element used to measure the character size of. the terminal. + */ + constructor( + private terminal: ITerminal, + private viewportElement: HTMLElement, + private scrollArea: HTMLElement, + private charMeasure: CharMeasure + ) { + this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); + + // Perform this async to ensure the CharMeasure is ready. + setTimeout(() => this.syncScrollArea(), 0); + } + + public onThemeChanged(colors: IColorSet): void { + this.viewportElement.style.backgroundColor = colors.background; + } + + /** + * Refreshes row height, setting line-height, viewport height and scroll area height if + * necessary. + */ + private refresh(): void { + if (this.charMeasure.height > 0) { + this.currentRowHeight = this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio; + + if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) { + this.lastRecordedViewportHeight = this.terminal.renderer.dimensions.canvasHeight; + this.viewportElement.style.height = this.lastRecordedViewportHeight + 'px'; + } + + const newBufferHeight = Math.round(this.currentRowHeight * this.lastRecordedBufferLength); + if (this.lastRecordedBufferHeight !== newBufferHeight) { + this.lastRecordedBufferHeight = newBufferHeight; + this.scrollArea.style.height = this.lastRecordedBufferHeight + 'px'; + } + } + } + + /** + * Updates dimensions and synchronizes the scroll area if necessary. + */ + public syncScrollArea(): void { + if (this.lastRecordedBufferLength !== this.terminal.buffer.lines.length) { + // If buffer height changed + this.lastRecordedBufferLength = this.terminal.buffer.lines.length; + this.refresh(); + } else if (this.lastRecordedViewportHeight !== (this.terminal).renderer.dimensions.canvasHeight) { + // If viewport height changed + this.refresh(); + } else { + // If size has changed, refresh viewport + if (this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this.currentRowHeight) { + this.refresh(); + } + } + + // Sync scrollTop + const scrollTop = this.terminal.buffer.ydisp * this.currentRowHeight; + if (this.viewportElement.scrollTop !== scrollTop) { + this.viewportElement.scrollTop = scrollTop; + } + } + + /** + * Handles scroll events on the viewport, calculating the new viewport and requesting the + * terminal to scroll to it. + * @param ev The scroll event. + */ + private onScroll(ev: Event): void { + const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + const diff = newRow - this.terminal.buffer.ydisp; + this.terminal.scrollLines(diff, true); + } + + /** + * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual + * scrolling to `onScroll`, this event needs to be attached manually by the consumer of + * `Viewport`. + * @param ev The mouse wheel event. + */ + public onWheel(ev: WheelEvent): void { + if (ev.deltaY === 0) { + // Do nothing if it's not a vertical scroll event + return; + } + // Fallback to WheelEvent.DOM_DELTA_PIXEL + let multiplier = 1; + if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { + multiplier = this.currentRowHeight; + } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + multiplier = this.currentRowHeight * this.terminal.rows; + } + this.viewportElement.scrollTop += ev.deltaY * multiplier; + // Prevent the page from scrolling when the terminal scrolls + ev.preventDefault(); + }; + + /** + * Handles the touchstart event, recording the touch occurred. + * @param ev The touch event. + */ + public onTouchStart(ev: TouchEvent): void { + this.lastTouchY = ev.touches[0].pageY; + }; + + /** + * Handles the touchmove event, scrolling the viewport if the position shifted. + * @param ev The touch event. + */ + public onTouchMove(ev: TouchEvent): void { + let deltaY = this.lastTouchY - ev.touches[0].pageY; + this.lastTouchY = ev.touches[0].pageY; + if (deltaY === 0) { + return; + } + this.viewportElement.scrollTop += deltaY; + ev.preventDefault(); + }; +} diff --git a/xterm.js/src/addons/attach/attach.test.ts b/xterm.js/src/addons/attach/attach.test.ts new file mode 100644 index 0000000..9bf0e07 --- /dev/null +++ b/xterm.js/src/addons/attach/attach.test.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as attach from './attach' + +class MockTerminal {} + +describe('attach addon', () => { + describe('apply', () => { + it('should do register the `attach` and `detach` methods', () => { + attach.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.attach, 'function'); + assert.equal(typeof (MockTerminal).prototype.detach, 'function'); + }); + }); +}); diff --git a/xterm.js/src/addons/attach/attach.ts b/xterm.js/src/addons/attach/attach.ts new file mode 100644 index 0000000..4e0d594 --- /dev/null +++ b/xterm.js/src/addons/attach/attach.ts @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * @license MIT + * + * Implements the attach method, that attaches the terminal to a WebSocket stream. + */ + +/** + * Attaches the given terminal to the given socket. + * + * @param {Terminal} term - The terminal to be attached to the given socket. + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ +export function attach(term, socket, bidirectional, buffered) { + bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; + term.socket = socket; + + term._flushBuffer = function() { + term.write(term._attachSocketBuffer); + term._attachSocketBuffer = null; + }; + + term._pushToBuffer = function(data) { + if (term._attachSocketBuffer) { + term._attachSocketBuffer += data; + } else { + term._attachSocketBuffer = data; + setTimeout(term._flushBuffer, 10); + } + }; + + var myTextDecoder; + + term._getMessage = function(ev) { + var str; + if (typeof ev.data === "object") { + if (ev.data instanceof ArrayBuffer) { + if (!myTextDecoder) { + myTextDecoder = new TextDecoder(); + } + + str = myTextDecoder.decode( ev.data ); + } + else { + throw "TODO: handle Blob?"; + } + } + + if (buffered) { + term._pushToBuffer(str || ev.data); + } else { + term.write(str || ev.data); + } + }; + + term._sendData = function(data) { + if (socket.readyState !== 1) { + return; + } + socket.send(data); + }; + + socket.addEventListener('message', term._getMessage); + + if (bidirectional) { + term.on('data', term._sendData); + } + + socket.addEventListener('close', term.detach.bind(term, socket)); + socket.addEventListener('error', term.detach.bind(term, socket)); +}; + +/** + * Detaches the given terminal from the given socket + * + * @param {Terminal} term - The terminal to be detached from the given socket. + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ +export function detach(term, socket) { + term.off('data', term._sendData); + + socket = (typeof socket == 'undefined') ? term.socket : socket; + + if (socket) { + socket.removeEventListener('message', term._getMessage); + } + + delete term.socket; +}; + + +export function apply(terminalConstructor) { + /** + * Attaches the current terminal to the given socket + * + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ + terminalConstructor.prototype.attach = function(socket, bidirectional, buffered) { + return attach(this, socket, bidirectional, buffered); + }; + + /** + * Detaches the current terminal from the given socket. + * + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ + terminalConstructor.prototype.detach = function(socket) { + return detach(this, socket); + }; +} diff --git a/xterm.js/src/addons/attach/index.html b/xterm.js/src/addons/attach/index.html new file mode 100644 index 0000000..b6f853b --- /dev/null +++ b/xterm.js/src/addons/attach/index.html @@ -0,0 +1,93 @@ + + + + + + + + + + +
    + +

    + xterm.js: socket attach +

    +

    + Attach the terminal to a WebSocket terminal stream with ease. Perfect for attaching to your + Docker containers. +

    +

    + Socket information +

    +
    + + +
    +
    + +
    + + + \ No newline at end of file diff --git a/xterm.js/src/addons/attach/package.json b/xterm.js/src/addons/attach/package.json new file mode 100644 index 0000000..9e45068 --- /dev/null +++ b/xterm.js/src/addons/attach/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.attach", + "main": "attach.js", + "private": true +} diff --git a/xterm.js/src/addons/attach/tsconfig.json b/xterm.js/src/addons/attach/tsconfig.json new file mode 100644 index 0000000..9772232 --- /dev/null +++ b/xterm.js/src/addons/attach/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/attach/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/fit/fit.test.ts b/xterm.js/src/addons/fit/fit.test.ts new file mode 100644 index 0000000..159cc98 --- /dev/null +++ b/xterm.js/src/addons/fit/fit.test.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as fit from './fit' + +class MockTerminal {} + +describe('fit addon', () => { + describe('apply', () => { + it('should do register the `proposeGeometry` and `fit` methods', () => { + fit.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.proposeGeometry, 'function'); + assert.equal(typeof (MockTerminal).prototype.fit, 'function'); + }); + }); +}); diff --git a/xterm.js/src/addons/fit/fit.ts b/xterm.js/src/addons/fit/fit.ts new file mode 100644 index 0000000..b87ccc0 --- /dev/null +++ b/xterm.js/src/addons/fit/fit.ts @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * @license MIT + * + * Fit terminal columns and rows to the dimensions of its DOM element. + * + * ## Approach + * + * Rows: Truncate the division of the terminal parent element height by the + * terminal row height. + * Columns: Truncate the division of the terminal parent element width by the + * terminal character width (apply display: inline at the terminal + * row and truncate its width with the current number of columns). + */ + +export function proposeGeometry(term) { + if (!term.element.parentElement) { + return null; + } + var parentElementStyle = window.getComputedStyle(term.element.parentElement); + var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')); + var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17); + var elementStyle = window.getComputedStyle(term.element); + var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')); + var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')); + var availableHeight = parentElementHeight - elementPaddingVer; + var availableWidth = parentElementWidth - elementPaddingHor; + var geometry = { + cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth), + rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight) + }; + + return geometry; +}; + +export function fit(term) { + var geometry = proposeGeometry(term); + if (geometry) { + // Force a full render + if (term.rows !== geometry.rows || term.cols !== geometry.cols) { + term.renderer.clear(); + term.resize(geometry.cols, geometry.rows); + } + } +}; + +export function apply(terminalConstructor) { + terminalConstructor.prototype.proposeGeometry = function() { + return proposeGeometry(this); + } + + terminalConstructor.prototype.fit = function() { + return fit(this); + } +} diff --git a/xterm.js/src/addons/fit/package.json b/xterm.js/src/addons/fit/package.json new file mode 100644 index 0000000..f7cb5bc --- /dev/null +++ b/xterm.js/src/addons/fit/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.fit", + "main": "fit.js", + "private": true +} diff --git a/xterm.js/src/addons/fit/tsconfig.json b/xterm.js/src/addons/fit/tsconfig.json new file mode 100644 index 0000000..949f8b6 --- /dev/null +++ b/xterm.js/src/addons/fit/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/fit/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/fullscreen/fullscreen.css b/xterm.js/src/addons/fullscreen/fullscreen.css new file mode 100644 index 0000000..60e8c51 --- /dev/null +++ b/xterm.js/src/addons/fullscreen/fullscreen.css @@ -0,0 +1,10 @@ +.xterm.fullscreen { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: auto; + height: auto; + z-index: 255; +} diff --git a/xterm.js/src/addons/fullscreen/fullscreen.test.ts b/xterm.js/src/addons/fullscreen/fullscreen.test.ts new file mode 100644 index 0000000..c77ea75 --- /dev/null +++ b/xterm.js/src/addons/fullscreen/fullscreen.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as fullscreen from './fullscreen' + +class MockTerminal {} + +describe('fullscreen addon', () => { + describe('apply', () => { + it('should do register the `toggleFullscreen` method', () => { + fullscreen.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.toggleFullScreen, 'function'); + }); + }); +}); diff --git a/xterm.js/src/addons/fullscreen/fullscreen.ts b/xterm.js/src/addons/fullscreen/fullscreen.ts new file mode 100644 index 0000000..31ab518 --- /dev/null +++ b/xterm.js/src/addons/fullscreen/fullscreen.ts @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * @license MIT + */ + +/** + * Toggle the given terminal's fullscreen mode. + * @param {Terminal} term - The terminal to toggle full screen mode + * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false) + */ +export function toggleFullScreen(term, fullscreen) { + var fn; + + if (typeof fullscreen == 'undefined') { + fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add'; + } else if (!fullscreen) { + fn = 'remove'; + } else { + fn = 'add'; + } + + term.element.classList[fn]('fullscreen'); +}; + +export function apply(terminalConstructor) { + terminalConstructor.prototype.toggleFullScreen = function (fullscreen) { + return toggleFullScreen(this, fullscreen); + }; +} diff --git a/xterm.js/src/addons/fullscreen/package.json b/xterm.js/src/addons/fullscreen/package.json new file mode 100644 index 0000000..fdaf688 --- /dev/null +++ b/xterm.js/src/addons/fullscreen/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.fullscreen", + "main": "fullscreen.js", + "private": true +} diff --git a/xterm.js/src/addons/fullscreen/tsconfig.json b/xterm.js/src/addons/fullscreen/tsconfig.json new file mode 100644 index 0000000..b04144c --- /dev/null +++ b/xterm.js/src/addons/fullscreen/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/fullscreen/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/search/SearchHelper.ts b/xterm.js/src/addons/search/SearchHelper.ts new file mode 100644 index 0000000..5735dd4 --- /dev/null +++ b/xterm.js/src/addons/search/SearchHelper.ts @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +// import { ITerminal } from '../../Interfaces'; +// import { translateBufferLineToString } from '../../utils/BufferLine'; + +interface ISearchResult { + term: string; + col: number; + row: number; +} + +/** + * A class that knows how to search the terminal and how to display the results. + */ +export class SearchHelper { + constructor(private _terminal: any) { + // TODO: Search for multiple instances on 1 line + // TODO: Don't use the actual selection, instead use a "find selection" so multiple instances can be highlighted + // TODO: Highlight other instances in the viewport + // TODO: Support regex, case sensitivity, etc. + } + + /** + * Find the next instance of the term, then scroll to and select it. If it + * doesn't exist, do nothing. + * @param term Tne search term. + * @return Whether a result was found. + */ + public findNext(term: string): boolean { + if (!term || term.length === 0) { + return false; + } + + let result: ISearchResult; + + let startRow = this._terminal.buffer.ydisp; + if (this._terminal.selectionManager.selectionEnd) { + // Start from the selection end if there is a selection + startRow = this._terminal.selectionManager.selectionEnd[1]; + } + + // Search from ydisp + 1 to end + for (let y = startRow + 1; y < this._terminal.buffer.ybase + this._terminal.rows; y++) { + result = this._findInLine(term, y); + if (result) { + break; + } + } + + // Search from the top to the current ydisp + if (!result) { + for (let y = 0; y < startRow; y++) { + result = this._findInLine(term, y); + if (result) { + break; + } + } + } + + // Set selection and scroll if a result was found + return this._selectResult(result); + } + + /** + * Find the previous instance of the term, then scroll to and select it. If it + * doesn't exist, do nothing. + * @param term Tne search term. + * @return Whether a result was found. + */ + public findPrevious(term: string): boolean { + if (!term || term.length === 0) { + return false; + } + + let result: ISearchResult; + + let startRow = this._terminal.buffer.ydisp; + if (this._terminal.selectionManager.selectionStart) { + // Start from the selection end if there is a selection + startRow = this._terminal.selectionManager.selectionStart[1]; + } + + // Search from ydisp + 1 to end + for (let y = startRow - 1; y >= 0; y--) { + result = this._findInLine(term, y); + if (result) { + break; + } + } + + // Search from the top to the current ydisp + if (!result) { + for (let y = this._terminal.buffer.ybase + this._terminal.rows - 1; y > startRow; y--) { + result = this._findInLine(term, y); + if (result) { + break; + } + } + } + + // Set selection and scroll if a result was found + return this._selectResult(result); + } + + /** + * Searches a line for a search term. + * @param term Tne search term. + * @param y The line to search. + * @return The search result if it was found. + */ + private _findInLine(term: string, y: number): ISearchResult { + const lowerStringLine = this._terminal.buffer.translateBufferLineToString(y, true).toLowerCase(); + const lowerTerm = term.toLowerCase(); + const searchIndex = lowerStringLine.indexOf(lowerTerm); + if (searchIndex >= 0) { + return { + term, + col: searchIndex, + row: y + }; + } + } + + /** + * Selects and scrolls to a result. + * @param result The result to select. + * @return Whethera result was selected. + */ + private _selectResult(result: ISearchResult): boolean { + if (!result) { + return false; + } + this._terminal.selectionManager.setSelection(result.col, result.row, result.term.length); + this._terminal.scrollLines(result.row - this._terminal.buffer.ydisp, false); + return true; + } +} diff --git a/xterm.js/src/addons/search/package.json b/xterm.js/src/addons/search/package.json new file mode 100644 index 0000000..552e933 --- /dev/null +++ b/xterm.js/src/addons/search/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.search", + "main": "search.js", + "private": true +} diff --git a/xterm.js/src/addons/search/search.ts b/xterm.js/src/addons/search/search.ts new file mode 100644 index 0000000..480fea7 --- /dev/null +++ b/xterm.js/src/addons/search/search.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { SearchHelper } from './SearchHelper'; + + +/** + * Find the next instance of the term, then scroll to and select it. If it + * doesn't exist, do nothing. + * @param term Tne search term. + * @return Whether a result was found. + */ +export function findNext(terminal: any, term: string): boolean { + if (!terminal._searchHelper) { + terminal.searchHelper = new SearchHelper(terminal); + } + return (terminal.searchHelper).findNext(term); +}; + +/** + * Find the previous instance of the term, then scroll to and select it. If it + * doesn't exist, do nothing. + * @param term Tne search term. + * @return Whether a result was found. + */ +export function findPrevious(terminal: any, term: string): boolean { + if (!terminal._searchHelper) { + terminal.searchHelper = new SearchHelper(terminal); + } + return (terminal.searchHelper).findPrevious(term); +}; + +export function apply(terminalConstructor) { + terminalConstructor.prototype.findNext = function(term) { + return findNext(this, term); + } + + terminalConstructor.prototype.findPrevious = function(term) { + return findPrevious(this, term); + } +} diff --git a/xterm.js/src/addons/search/tsconfig.json b/xterm.js/src/addons/search/tsconfig.json new file mode 100644 index 0000000..7f72e47 --- /dev/null +++ b/xterm.js/src/addons/search/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/search/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/terminado/package.json b/xterm.js/src/addons/terminado/package.json new file mode 100644 index 0000000..d695959 --- /dev/null +++ b/xterm.js/src/addons/terminado/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.terminado", + "main": "terminado.js", + "private": true +} diff --git a/xterm.js/src/addons/terminado/terminado.test.ts b/xterm.js/src/addons/terminado/terminado.test.ts new file mode 100644 index 0000000..fe05989 --- /dev/null +++ b/xterm.js/src/addons/terminado/terminado.test.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as terminado from './terminado' + +class MockTerminal {} + +describe('terminado addon', () => { + describe('apply', () => { + it('should do register the `terminadoAttach` and `terminadoDetach` methods', () => { + terminado.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.terminadoAttach, 'function'); + assert.equal(typeof (MockTerminal).prototype.terminadoDetach, 'function'); + }); + }); +}); diff --git a/xterm.js/src/addons/terminado/terminado.ts b/xterm.js/src/addons/terminado/terminado.ts new file mode 100644 index 0000000..9a7c7ad --- /dev/null +++ b/xterm.js/src/addons/terminado/terminado.ts @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + * + * This module provides methods for attaching a terminal to a terminado + * WebSocket stream. + */ + +/** + * Attaches the given terminal to the given socket. + * + * @param {Terminal} term - The terminal to be attached to the given socket. + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ +export function terminadoAttach(term, socket, bidirectional, buffered) { + bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; + term.socket = socket; + + term._flushBuffer = function() { + term.write(term._attachSocketBuffer); + term._attachSocketBuffer = null; + }; + + term._pushToBuffer = function(data) { + if (term._attachSocketBuffer) { + term._attachSocketBuffer += data; + } else { + term._attachSocketBuffer = data; + setTimeout(term._flushBuffer, 10); + } + }; + + term._getMessage = function(ev) { + var data = JSON.parse(ev.data) + if( data[0] == "stdout" ) { + if (buffered) { + term._pushToBuffer(data[1]); + } else { + term.write(data[1]); + } + } + }; + + term._sendData = function(data) { + socket.send(JSON.stringify(['stdin', data])); + }; + + term._setSize = function(size) { + socket.send(JSON.stringify(['set_size', size.rows, size.cols])); + }; + + socket.addEventListener('message', term._getMessage); + + if (bidirectional) { + term.on('data', term._sendData); + } + term.on('resize', term._setSize); + + socket.addEventListener('close', term.terminadoDetach.bind(term, socket)); + socket.addEventListener('error', term.terminadoDetach.bind(term, socket)); +}; + +/** + * Detaches the given terminal from the given socket + * + * @param {Xterm} term - The terminal to be detached from the given socket. + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ +export function terminadoDetach(term, socket) { + term.off('data', term._sendData); + + socket = (typeof socket == 'undefined') ? term.socket : socket; + + if (socket) { + socket.removeEventListener('message', term._getMessage); + } + + delete term.socket; +}; + +export function apply(terminalConstructor) { + /** + * Attaches the current terminal to the given socket + * + * @param {WebSocket} socket - The socket to attach the current terminal. + * @param {boolean} bidirectional - Whether the terminal should send data + * to the socket as well. + * @param {boolean} buffered - Whether the rendering of incoming data + * should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. + */ + terminalConstructor.prototype.terminadoAttach = function(socket, bidirectional, buffered) { + return terminadoAttach(this, socket, bidirectional, buffered); + }; + + /** + * Detaches the current terminal from the given socket. + * + * @param {WebSocket} socket - The socket from which to detach the current + * terminal. + */ + terminalConstructor.prototype.terminadoDetach = function(socket) { + return terminadoDetach(this, socket); + }; +} diff --git a/xterm.js/src/addons/terminado/tsconfig.json b/xterm.js/src/addons/terminado/tsconfig.json new file mode 100644 index 0000000..775b20d --- /dev/null +++ b/xterm.js/src/addons/terminado/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/terminado/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/winptyCompat/package.json b/xterm.js/src/addons/winptyCompat/package.json new file mode 100644 index 0000000..2e9fc16 --- /dev/null +++ b/xterm.js/src/addons/winptyCompat/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.winptyCompat", + "main": "winptyCompat.js", + "private": true +} diff --git a/xterm.js/src/addons/winptyCompat/tsconfig.json b/xterm.js/src/addons/winptyCompat/tsconfig.json new file mode 100644 index 0000000..e15a09a --- /dev/null +++ b/xterm.js/src/addons/winptyCompat/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/winptyCompat/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/winptyCompat/winptyCompat.test.ts b/xterm.js/src/addons/winptyCompat/winptyCompat.test.ts new file mode 100644 index 0000000..21e54e5 --- /dev/null +++ b/xterm.js/src/addons/winptyCompat/winptyCompat.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as winptyCompat from './winptyCompat' + +class MockTerminal {} + +describe('winptyCompat addon', () => { + describe('apply', () => { + it('should do register the `winptyCompatInit` method', () => { + winptyCompat.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.winptyCompatInit, 'function'); + }); + }); +}); diff --git a/xterm.js/src/addons/winptyCompat/winptyCompat.ts b/xterm.js/src/addons/winptyCompat/winptyCompat.ts new file mode 100644 index 0000000..723bf01 --- /dev/null +++ b/xterm.js/src/addons/winptyCompat/winptyCompat.ts @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export function winptyCompatInit(terminal): void { + // Don't do anything when the platform is not Windows + const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0; + if (!isWindows) { + return; + } + + // Winpty does not support wraparound mode which means that lines will never + // be marked as wrapped. This causes issues for things like copying a line + // retaining the wrapped new line characters or if consumers are listening + // in on the data stream. + // + // The workaround for this is to listen to every incoming line feed and mark + // the line as wrapped if the last character in the previous line is not a + // space. This is certainly not without its problems, but generally on + // Windows when text reaches the end of the terminal it's likely going to be + // wrapped. + terminal.on('linefeed', () => { + const line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1); + const lastChar = line[terminal.cols - 1]; + + if (lastChar[3] !== 32 /* ' ' */) { + const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y); + (nextLine).isWrapped = true; + } + }); +} + +export function apply(terminalConstructor) { + terminalConstructor.prototype.winptyCompatInit = function(): void { + winptyCompatInit(this); + }; +} diff --git a/xterm.js/src/addons/zmodem/demo/app.js b/xterm.js/src/addons/zmodem/demo/app.js new file mode 100644 index 0000000..31ecd7d --- /dev/null +++ b/xterm.js/src/addons/zmodem/demo/app.js @@ -0,0 +1,87 @@ +var express = require('express'); +var app = express(); +var expressWs = require('express-ws')(app); +var os = require('os'); +var pty = require('node-pty'); + +var terminals = {}, + logs = {}; + +app.use('/build', express.static(__dirname + '/../../../../build')); +app.use('/demo', express.static(__dirname + '/../../../../demo')); +app.use('/zmodemjs', express.static(__dirname + '/../../../../node_modules/zmodem.js/dist')); + +app.get('/', function(req, res){ + res.sendFile(__dirname + '/index.html'); +}); + +app.get('/style.css', function(req, res){ + res.sendFile(__dirname + '/style.css'); +}); + +app.get('/main.js', function(req, res){ + res.sendFile(__dirname + '/main.js'); +}); + +app.post('/terminals', function (req, res) { + var cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], { + encoding: null, + name: 'xterm-color', + cols: cols || 80, + rows: rows || 24, + cwd: process.env.PWD, + env: process.env + }); + + console.log('Created terminal with PID: ' + term.pid); + terminals[term.pid] = term; + logs[term.pid] = ''; + term.on('data', function(data) { + logs[term.pid] += data; + }); + res.send(term.pid.toString()); + res.end(); +}); + +app.post('/terminals/:pid/size', function (req, res) { + var pid = parseInt(req.params.pid), + cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = terminals[pid]; + + term.resize(cols, rows); + console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.'); + res.end(); +}); + +app.ws('/terminals/:pid', function (ws, req) { + var term = terminals[parseInt(req.params.pid)]; + console.log('Connected to terminal ' + term.pid); + ws.send(logs[term.pid]); + + term.on('data', function(data) { + try { + ws.send(data); + } catch (ex) { + // The WebSocket is not open, ignore + } + }); + ws.on('message', function(msg) { + term.write(msg); + }); + ws.on('close', function () { + term.kill(); + console.log('Closed terminal ' + term.pid); + // Clean things up + delete terminals[term.pid]; + delete logs[term.pid]; + }); +}); + +var port = process.env.PORT || 3000, + host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0'; + +console.log('App listening to http://' + host + ':' + port); +app.listen(port, host); diff --git a/xterm.js/src/addons/zmodem/demo/index.html b/xterm.js/src/addons/zmodem/demo/index.html new file mode 100644 index 0000000..aee7742 --- /dev/null +++ b/xterm.js/src/addons/zmodem/demo/index.html @@ -0,0 +1,128 @@ + + + + xterm.js demo + + + + + + + + + + + + + + + + +

    xterm.js: xterm, in the browser

    + +
    + +
    + + + + + + + + + +
    + +
    +

    Actions

    +

    + + +

    +
    +
    +

    Options

    +

    + +

    +

    + +

    +

    + +

    +

    + +

    +

    + +

    +

    + +

    +
    +

    Size

    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +

    Attention: The demo is a barebones implementation and is designed for xterm.js evaluation purposes only. Exposing the demo to the public as is would introduce security risks for the host.

    +

    * ZMODEM file transfers are supported via an addon. To try it out, install lrzsz onto the remote peer, then run rz to send from your browser or sz <file> to send from the remote peer.

    + + + diff --git a/xterm.js/src/addons/zmodem/demo/main.js b/xterm.js/src/addons/zmodem/demo/main.js new file mode 100644 index 0000000..2a153fb --- /dev/null +++ b/xterm.js/src/addons/zmodem/demo/main.js @@ -0,0 +1,383 @@ +"use strict"; + +var term, + protocol, + socketURL, + socket, + pid; + +var terminalContainer = document.getElementById('terminal-container'), + actionElements = { + findNext: document.querySelector('#find-next'), + findPrevious: document.querySelector('#find-previous') + }, + optionElements = { + cursorBlink: document.querySelector('#option-cursor-blink'), + cursorStyle: document.querySelector('#option-cursor-style'), + scrollback: document.querySelector('#option-scrollback'), + tabstopwidth: document.querySelector('#option-tabstopwidth'), + bellStyle: document.querySelector('#option-bell-style') + }, + colsElement = document.getElementById('cols'), + rowsElement = document.getElementById('rows'); + +function setTerminalSize() { + var cols = parseInt(colsElement.value, 10); + var rows = parseInt(rowsElement.value, 10); + var viewportElement = document.querySelector('.xterm-viewport'); + var scrollBarWidth = viewportElement.offsetWidth - viewportElement.clientWidth; + var width = (cols * term.charMeasure.width + 20 /*room for scrollbar*/).toString() + 'px'; + var height = (rows * term.charMeasure.height).toString() + 'px'; + + terminalContainer.style.width = width; + terminalContainer.style.height = height; + term.resize(cols, rows); +} + +colsElement.addEventListener('change', setTerminalSize); +rowsElement.addEventListener('change', setTerminalSize); + +actionElements.findNext.addEventListener('keypress', function (e) { + if (e.key === "Enter") { + e.preventDefault(); + term.findNext(actionElements.findNext.value); + } +}); +actionElements.findPrevious.addEventListener('keypress', function (e) { + if (e.key === "Enter") { + e.preventDefault(); + term.findPrevious(actionElements.findPrevious.value); + } +}); + +optionElements.cursorBlink.addEventListener('change', function () { + term.setOption('cursorBlink', optionElements.cursorBlink.checked); +}); +optionElements.cursorStyle.addEventListener('change', function () { + term.setOption('cursorStyle', optionElements.cursorStyle.value); +}); +optionElements.bellStyle.addEventListener('change', function () { + term.setOption('bellStyle', optionElements.bellStyle.value); +}); +optionElements.scrollback.addEventListener('change', function () { + term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); +}); +optionElements.tabstopwidth.addEventListener('change', function () { + term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); +}); + +createTerminal(); + +function createTerminal() { + // Clean terminal + while (terminalContainer.children.length) { + terminalContainer.removeChild(terminalContainer.children[0]); + } + term = new Terminal({ + cursorBlink: optionElements.cursorBlink.checked, + scrollback: parseInt(optionElements.scrollback.value, 10), + tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10) + }); + term.on('resize', function (size) { + if (!pid) { + return; + } + var cols = size.cols, + rows = size.rows, + url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; + + fetch(url, {method: 'POST'}); + }); + protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; + socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/'; + + term.open(terminalContainer); + term.fit(); + + // fit is called within a setTimeout, cols and rows need this. + setTimeout(function () { + colsElement.value = term.cols; + rowsElement.value = term.rows; + + // Set terminal size again to set the specific dimensions on the demo + setTerminalSize(); + + fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { + + res.text().then(function (pid) { + window.pid = pid; + socketURL += pid; + socket = new WebSocket(socketURL); + socket.onopen = runRealTerminal; + socket.onclose = runFakeTerminal; + socket.onerror = runFakeTerminal; + + term.zmodemAttach(socket, { + noTerminalWriteOutsideSession: true, + } ); + + term.on("zmodemRetract", () => { + start_form.style.display = "none"; + start_form.onsubmit = null; + }); + + term.on("zmodemDetect", (detection) => { + function do_zmodem() { + term.detach(); + let zsession = detection.confirm(); + + var promise; + + if (zsession.type === "receive") { + promise = _handle_receive_session(zsession); + } + else { + promise = _handle_send_session(zsession); + } + + promise.catch( console.error.bind(console) ).then( () => { + term.attach(socket); + } ); + } + + if (_auto_zmodem()) { + do_zmodem(); + } + else { + start_form.style.display = ""; + start_form.onsubmit = function(e) { + start_form.style.display = "none"; + + if (document.getElementById("zmstart_yes").checked) { + do_zmodem(); + } + else { + detection.deny(); + } + }; + } + }); + }); + }); + }, 0); +} + +//---------------------------------------------------------------------- +// UI STUFF + +function _show_file_info(xfer) { + var file_info = xfer.get_details(); + + document.getElementById("name").textContent = file_info.name; + document.getElementById("size").textContent = file_info.size; + document.getElementById("mtime").textContent = file_info.mtime; + document.getElementById("files_remaining").textContent = file_info.files_remaining; + document.getElementById("bytes_remaining").textContent = file_info.bytes_remaining; + + document.getElementById("mode").textContent = "0" + file_info.mode.toString(8); + + var xfer_opts = xfer.get_options(); + ["conversion", "management", "transport", "sparse"].forEach( (lbl) => { + document.getElementById(`zfile_${lbl}`).textContent = xfer_opts[lbl]; + } ); + + document.getElementById("zm_file").style.display = ""; +} +function _hide_file_info() { + document.getElementById("zm_file").style.display = "none"; +} + +function _save_to_disk(xfer, buffer) { + return Zmodem.Browser.save_to_disk(buffer, xfer.get_details().name); +} + +var skipper_button = document.getElementById("zm_progress_skipper"); +var skipper_button_orig_text = skipper_button.textContent; + +function _show_progress() { + skipper_button.disabled = false; + skipper_button.textContent = skipper_button_orig_text; + + document.getElementById("bytes_received").textContent = 0; + document.getElementById("percent_received").textContent = 0; + + document.getElementById("zm_progress").style.display = ""; +} + +function _update_progress(xfer) { + var total_in = xfer.get_offset(); + + document.getElementById("bytes_received").textContent = total_in; + + var percent_received = 100 * total_in / xfer.get_details().size; + document.getElementById("percent_received").textContent = percent_received.toFixed(2); +} + +function _hide_progress() { + document.getElementById("zm_progress").style.display = "none"; +} + +var start_form = document.getElementById("zm_start"); + +function _auto_zmodem() { + return document.getElementById("zmodem-auto").checked; +} + +// END UI STUFF +//---------------------------------------------------------------------- + +function _handle_receive_session(zsession) { + zsession.on("offer", function(xfer) { + current_receive_xfer = xfer; + + _show_file_info(xfer); + + var offer_form = document.getElementById("zm_offer"); + + function on_form_submit() { + offer_form.style.display = "none"; + + //START + //if (offer_form.zmaccept.value) { + if (_auto_zmodem() || document.getElementById("zmaccept_yes").checked) { + _show_progress(); + + var FILE_BUFFER = []; + xfer.on("input", (payload) => { + _update_progress(xfer); + FILE_BUFFER.push( new Uint8Array(payload) ); + }); + xfer.accept().then( + () => { + _save_to_disk(xfer, FILE_BUFFER); + }, + console.error.bind(console) + ); + } + else { + xfer.skip(); + } + //END + } + + if (_auto_zmodem()) { + on_form_submit(); + } + else { + offer_form.onsubmit = on_form_submit; + offer_form.style.display = ""; + } + } ); + + var promise = new Promise( (res) => { + zsession.on("session_end", () => { + _hide_file_info(); + _hide_progress(); + res(); + } ); + } ); + + zsession.start(); + + return promise; +} + +function _handle_send_session(zsession) { + var choose_form = document.getElementById("zm_choose"); + choose_form.style.display = ""; + + var file_el = document.getElementById("zm_files"); + + var promise = new Promise( (res) => { + file_el.onchange = function(e) { + choose_form.style.display = "none"; + + var files_obj = file_el.files; + + Zmodem.Browser.send_files( + zsession, + files_obj, + { + on_offer_response(obj, xfer) { + if (xfer) _show_progress(); + //console.log("offer", xfer ? "accepted" : "skipped"); + }, + on_progress(obj, xfer) { + _update_progress(xfer); + }, + on_file_complete(obj) { + //console.log("COMPLETE", obj); + _hide_progress(); + }, + } + ).then(_hide_progress).then( + zsession.close.bind(zsession), + console.error.bind(console) + ).then( () => { + _hide_file_info(); + _hide_progress(); + res(); + } ); + }; + } ); + + return promise; +} + +//This is here to allow canceling of an in-progress ZMODEM transfer. +var current_receive_xfer; + +//Called from HTML directly. +function skip_current_file() { + current_receive_xfer.skip(); + + skipper_button.disabled = true; + skipper_button.textContent = "Waiting for server to acknowledge skip …"; +} + +function runRealTerminal() { + term.attach(socket); + + term._initialized = true; +} + +function runFakeTerminal() { + if (term._initialized) { + return; + } + + term._initialized = true; + + var shellprompt = '$ '; + + term.prompt = function () { + term.write('\r\n' + shellprompt); + }; + + term.writeln('Welcome to xterm.js'); + term.writeln('This is a local terminal emulation, without a real terminal in the back-end.'); + term.writeln('Type some keys and commands to play around.'); + term.writeln(''); + term.prompt(); + + term.on('key', function (key, ev) { + var printable = ( + !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey + ); + + if (ev.keyCode == 13) { + term.prompt(); + } else if (ev.keyCode == 8) { + // Do not delete the prompt + if (term.x > 2) { + term.write('\b \b'); + } + } else if (printable) { + term.write(key); + } + }); + + term.on('paste', function (data, ev) { + term.write(data); + }); +} diff --git a/xterm.js/src/addons/zmodem/package.json b/xterm.js/src/addons/zmodem/package.json new file mode 100644 index 0000000..218130a --- /dev/null +++ b/xterm.js/src/addons/zmodem/package.json @@ -0,0 +1,5 @@ +{ + "name": "xterm.zmodem", + "main": "zmodem.js", + "private": true +} diff --git a/xterm.js/src/addons/zmodem/tsconfig.json b/xterm.js/src/addons/zmodem/tsconfig.json new file mode 100644 index 0000000..9ded72e --- /dev/null +++ b/xterm.js/src/addons/zmodem/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": ".", + "outDir": "../../../lib/addons/zmodem/", + "sourceMap": true, + "removeComments": true + } +} diff --git a/xterm.js/src/addons/zmodem/zmodem.test.ts b/xterm.js/src/addons/zmodem/zmodem.test.ts new file mode 100644 index 0000000..3cb2831 --- /dev/null +++ b/xterm.js/src/addons/zmodem/zmodem.test.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; + +import * as zmodem from './zmodem' + +class MockTerminal {} + +describe('zmodem addon', () => { + describe('apply', () => { + it('should do register the `zmodemAttach` method and `zmodemBrowser` attribute', () => { + zmodem.apply(MockTerminal); + assert.equal(typeof (MockTerminal).prototype.zmodemAttach, 'function'); + assert.equal(typeof (MockTerminal).prototype.zmodemBrowser, 'object'); + }); + }); +}); diff --git a/xterm.js/src/addons/zmodem/zmodem.ts b/xterm.js/src/addons/zmodem/zmodem.ts new file mode 100644 index 0000000..57bdde3 --- /dev/null +++ b/xterm.js/src/addons/zmodem/zmodem.ts @@ -0,0 +1,90 @@ +/** + * + * Allow xterm.js to handle ZMODEM uploads and downloads. + * + * This addon is a wrapper around zmodem.js. It adds the following to the + * Terminal class: + * + * - function `zmodemAttach(, )` - creates a Zmodem.Sentry + * on the passed WebSocket object. The Object passed is optional and + * can contain: + * - noTerminalWriteOutsideSession: Suppress writes from the Sentry + * object to the Terminal while there is no active Session. This + * is necessary for compatibility with, for example, the + * `attach.js` addon. + * + * - event `zmodemDetect` - fired on Zmodem.Sentry’s `on_detect` callback. + * Passes the zmodem.js Detection object. + * + * - event `zmodemRetract` - fired on Zmodem.Sentry’s `on_retract` callback. + * + * You’ll need to provide logic to handle uploads and downloads. + * See zmodem.js’s documentation for more details. + * + * **IMPORTANT:** After you confirm() a zmodem.js Detection, if you have + * used the `attach` or `terminado` addons, you’ll need to suspend their + * operation for the duration of the ZMODEM session. (The demo does this + * via `detach()` and a re-`attach()`.) + */ + +let Zmodem; + +export function zmodemAttach(term, ws, opts) { + if (!opts) opts = {}; + + var senderFunc = function _ws_sender_func(octets) { + ws.send(new Uint8Array(octets)); + }; + + var zsentry; + + function _shouldWrite() { + return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession; + } + + zsentry = new Zmodem.Sentry( { + to_terminal: function _to_terminal(octets) { + if (_shouldWrite()) { + term.write( + String.fromCharCode.apply(String, octets) + ); + } + }, + + sender: senderFunc, + + on_retract: function _on_retract() { + term.emit('zmodemRetract'); + }, + + on_detect: function _on_detect(detection) { + term.emit('zmodemDetect', detection); + }, + } ); + + function handleWSMessage(evt) { + + //In testing with xterm.js’s demo the first message was + //always text even if the rest were binary. While that + //may be specific to xterm.js’s demo, ultimately we + //should reject anything that isn’t binary. + if (typeof evt.data === 'string') { + if (_shouldWrite()) { + term.write(evt.data); + } + } + else { + zsentry.consume(evt.data); + } + } + + ws.binaryType = 'arraybuffer'; + ws.addEventListener('message', handleWSMessage); +} + +export function apply(terminalConstructor) { + Zmodem = (typeof window == 'object') ? (window).ZModem : {Browser: null}; // Nullify browser for tests + + terminalConstructor.prototype.zmodemAttach = zmodemAttach.bind(this, this); + terminalConstructor.prototype.zmodemBrowser = Zmodem.Browser +} diff --git a/xterm.js/src/handlers/Clipboard.test.ts b/xterm.js/src/handlers/Clipboard.test.ts new file mode 100644 index 0000000..d35e5fa --- /dev/null +++ b/xterm.js/src/handlers/Clipboard.test.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import * as Terminal from '../Terminal'; +import * as Clipboard from './Clipboard'; + +describe('evaluatePastedTextProcessing', () => { + it('should replace carriage return + line feed with line feed on windows', () => { + const pastedText = 'foo\r\nbar\r\n'; + const processedText = Clipboard.prepareTextForTerminal(pastedText, false); + const windowsProcessedText = Clipboard.prepareTextForTerminal(pastedText, true); + + assert.equal(processedText, 'foo\r\nbar\r\n'); + assert.equal(windowsProcessedText, 'foo\rbar\r'); + }); + it('should bracket pasted text in bracketedPasteMode', () => { + const pastedText = 'foo bar'; + const unbracketedText = Clipboard.bracketTextForPaste(pastedText, false); + const bracketedText = Clipboard.bracketTextForPaste(pastedText, true); + + assert.equal(unbracketedText, 'foo bar'); + assert.equal(bracketedText, '\x1b[200~foo bar\x1b[201~'); + }); +}); diff --git a/xterm.js/src/handlers/Clipboard.ts b/xterm.js/src/handlers/Clipboard.ts new file mode 100644 index 0000000..cf6661f --- /dev/null +++ b/xterm.js/src/handlers/Clipboard.ts @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, ISelectionManager } from '../Interfaces'; + +interface IWindow extends Window { + clipboardData?: { + getData(format: string): string; + setData(format: string, data: string): void; + }; +} + +declare var window: IWindow; + +/** + * Prepares text to be pasted into the terminal by normalizing the line endings + * @param text The pasted text that needs processing before inserting into the terminal + */ +export function prepareTextForTerminal(text: string, isMSWindows: boolean): string { + if (isMSWindows) { + return text.replace(/\r?\n/g, '\r'); + } + return text; +} + +/** + * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste + * @param text The pasted text to bracket + */ +export function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string { + if (bracketedPasteMode) { + return '\x1b[200~' + text + '\x1b[201~'; + } + return text; +} + +/** + * Binds copy functionality to the given terminal. + * @param {ClipboardEvent} ev The original copy event to be handled + */ +export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager): void { + if (term.browser.isMSIE) { + window.clipboardData.setData('Text', selectionManager.selectionText); + } else { + ev.clipboardData.setData('text/plain', selectionManager.selectionText); + } + + // Prevent or the original text will be copied. + ev.preventDefault(); +} + +/** + * Redirect the clipboard's data to the terminal's input handler. + * @param {ClipboardEvent} ev The original paste event to be handled + * @param {Terminal} term The terminal on which to apply the handled paste event + */ +export function pasteHandler(ev: ClipboardEvent, term: ITerminal): void { + ev.stopPropagation(); + + let text: string; + + let dispatchPaste = function(text: string): void { + text = prepareTextForTerminal(text, term.browser.isMSWindows); + text = bracketTextForPaste(text, term.bracketedPasteMode); + term.handler(text); + term.textarea.value = ''; + term.emit('paste', text); + term.cancel(ev); + }; + + if (term.browser.isMSIE) { + if (window.clipboardData) { + text = window.clipboardData.getData('Text'); + dispatchPaste(text); + } + } else { + if (ev.clipboardData) { + text = ev.clipboardData.getData('text/plain'); + dispatchPaste(text); + } + } +} + +/** + * Moves the textarea under the mouse cursor and focuses it. + * @param ev The original right click event to be handled. + * @param textarea The terminal's textarea. + */ +export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement): void { + // Bring textarea at the cursor position + textarea.style.position = 'fixed'; + textarea.style.width = '20px'; + textarea.style.height = '20px'; + textarea.style.left = (ev.clientX - 10) + 'px'; + textarea.style.top = (ev.clientY - 10) + 'px'; + textarea.style.zIndex = '1000'; + + textarea.focus(); + + // Reset the terminal textarea's styling + setTimeout(() => { + textarea.style.position = null; + textarea.style.width = null; + textarea.style.height = null; + textarea.style.left = null; + textarea.style.top = null; + textarea.style.zIndex = null; + }, 4); +} + +/** + * Bind to right-click event and allow right-click copy and paste. + * @param ev The original right click event to be handled. + * @param textarea The terminal's textarea. + * @param selectionManager The terminal's selection manager. + */ +export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager): void { + moveTextAreaUnderMouseCursor(ev, textarea); + + // Get textarea ready to copy from the context menu + textarea.value = selectionManager.selectionText; + textarea.select(); +} diff --git a/xterm.js/src/input/Interfaces.ts b/xterm.js/src/input/Interfaces.ts new file mode 100644 index 0000000..21514a5 --- /dev/null +++ b/xterm.js/src/input/Interfaces.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export interface IMouseZoneManager { + add(zone: IMouseZone): void; + clearAll(start?: number, end?: number): void; +} + +export interface IMouseZone { + x1: number; + x2: number; + y: number; + clickCallback: (e: MouseEvent) => any; + hoverCallback?: (e: MouseEvent) => any; + tooltipCallback?: (e: MouseEvent) => any; + leaveCallback?: () => any; +} diff --git a/xterm.js/src/input/MouseZoneManager.ts b/xterm.js/src/input/MouseZoneManager.ts new file mode 100644 index 0000000..8fae317 --- /dev/null +++ b/xterm.js/src/input/MouseZoneManager.ts @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IMouseZoneManager, IMouseZone } from './Interfaces'; +import { ITerminal } from '../Interfaces'; + +const HOVER_DURATION = 500; + +/** + * The MouseZoneManager allows components to register zones within the terminal + * that trigger hover and click callbacks. + * + * This class was intentionally made not so robust initially as the only case it + * needed to support was single-line links which never overlap. Improvements can + * be made in the future. + */ +export class MouseZoneManager implements IMouseZoneManager { + private _zones: IMouseZone[] = []; + + private _areZonesActive: boolean = false; + private _mouseMoveListener: (e: MouseEvent) => any; + private _clickListener: (e: MouseEvent) => any; + + private _tooltipTimeout: number = null; + private _currentZone: IMouseZone = null; + private _lastHoverCoords: [number, number] = [null, null]; + + constructor( + private _terminal: ITerminal + ) { + this._terminal.element.addEventListener('mousedown', e => this._onMouseDown(e)); + + // These events are expensive, only listen to it when mouse zones are active + this._mouseMoveListener = e => this._onMouseMove(e); + this._clickListener = e => this._onClick(e); + } + + public add(zone: IMouseZone): void { + this._zones.push(zone); + if (this._zones.length === 1) { + this._activate(); + } + } + + public clearAll(start?: number, end?: number): void { + // Exit if there's nothing to clear + if (this._zones.length === 0) { + return; + } + + // Clear all if start/end weren't set + if (!end) { + start = 0; + end = this._terminal.rows - 1; + } + + // Iterate through zones and clear them out if they're within the range + for (let i = 0; i < this._zones.length; i++) { + const zone = this._zones[i]; + if (zone.y > start && zone.y <= end + 1) { + if (this._currentZone && this._currentZone === zone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + } + this._zones.splice(i--, 1); + } + } + + // Deactivate the mouse zone manager if all the zones have been removed + if (this._zones.length === 0) { + this._deactivate(); + } + } + + private _activate(): void { + if (!this._areZonesActive) { + this._areZonesActive = true; + this._terminal.element.addEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.addEventListener('click', this._clickListener); + } + } + + private _deactivate(): void { + if (this._areZonesActive) { + this._areZonesActive = false; + this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener); + this._terminal.element.removeEventListener('click', this._clickListener); + } + } + + private _onMouseMove(e: MouseEvent): void { + // TODO: Ideally this would only clear the hover state when the mouse moves + // outside of the mouse zone + if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) { + this._onHover(e); + // Record the current coordinates + this._lastHoverCoords = [e.pageX, e.pageY]; + } + } + + private _onHover(e: MouseEvent): void { + const zone = this._findZoneEventAt(e); + + // Do nothing if the zone is the same + if (zone === this._currentZone) { + return; + } + + // Fire the hover end callback and cancel any existing timer if a new zone + // is being hovered + if (this._currentZone) { + this._currentZone.leaveCallback(); + this._currentZone = null; + if (this._tooltipTimeout) { + clearTimeout(this._tooltipTimeout); + } + } + + // Exit if there is not zone + if (!zone) { + return; + } + this._currentZone = zone; + + // Trigger the hover callback + if (zone.hoverCallback) { + zone.hoverCallback(e); + } + + // Restart the tooltip timeout + this._tooltipTimeout = setTimeout(() => this._onTooltip(e), HOVER_DURATION); + } + + private _onTooltip(e: MouseEvent): void { + this._tooltipTimeout = null; + const zone = this._findZoneEventAt(e); + if (zone && zone.tooltipCallback) { + zone.tooltipCallback(e); + } + } + + private _onMouseDown(e: MouseEvent): void { + // Ignore the event if there are no zones active + if (!this._areZonesActive) { + return; + } + + // Find the active zone, prevent event propagation if found to prevent other + // components from handling the mouse event. + const zone = this._findZoneEventAt(e); + if (zone) { + // TODO: When link modifier support is added, the event should only be + // cancelled when the modifier is held (see #1021) + e.preventDefault(); + e.stopImmediatePropagation(); + } + } + + private _onClick(e: MouseEvent): void { + // Find the active zone and click it if found + const zone = this._findZoneEventAt(e); + if (zone) { + zone.clickCallback(e); + e.preventDefault(); + e.stopImmediatePropagation(); + } + } + + private _findZoneEventAt(e: MouseEvent): IMouseZone { + const coords = this._terminal.mouseHelper.getCoords(e, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows); + if (!coords) { + return null; + } + for (let i = 0; i < this._zones.length; i++) { + const zone = this._zones[i]; + if (zone.y === coords[1] && zone.x1 <= coords[0] && zone.x2 > coords[0]) { + return zone; + } + }; + return null; + } +} + +export class MouseZone implements IMouseZone { + constructor( + public x1: number, + public x2: number, + public y: number, + public clickCallback: (e: MouseEvent) => any, + public hoverCallback?: (e: MouseEvent) => any, + public tooltipCallback?: (e: MouseEvent) => any, + public leaveCallback?: () => void + ) { + } +} diff --git a/xterm.js/src/renderer/BaseRenderLayer.ts b/xterm.js/src/renderer/BaseRenderLayer.ts new file mode 100644 index 0000000..b4becbc --- /dev/null +++ b/xterm.js/src/renderer/BaseRenderLayer.ts @@ -0,0 +1,336 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IRenderLayer, IColorSet, IRenderDimensions } from './Interfaces'; +import { ITerminal, ITerminalOptions } from '../Interfaces'; +import { acquireCharAtlas, CHAR_ATLAS_CELL_SPACING } from './CharAtlas'; +import { CharData } from '../Types'; +import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; + +export const INVERTED_DEFAULT_COLOR = -1; +const DIM_OPACITY = 0.5; + +export abstract class BaseRenderLayer implements IRenderLayer { + private _canvas: HTMLCanvasElement; + protected _ctx: CanvasRenderingContext2D; + private _scaledCharWidth: number = 0; + private _scaledCharHeight: number = 0; + private _scaledCellWidth: number = 0; + private _scaledCellHeight: number = 0; + private _scaledCharLeft: number = 0; + private _scaledCharTop: number = 0; + + private _charAtlas: HTMLCanvasElement | ImageBitmap; + + constructor( + container: HTMLElement, + id: string, + zIndex: number, + private _alpha: boolean, + protected _colors: IColorSet + ) { + this._canvas = document.createElement('canvas'); + this._canvas.id = `xterm-${id}-layer`; + this._canvas.style.zIndex = zIndex.toString(); + this._ctx = this._canvas.getContext('2d', {alpha: _alpha}); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + // Draw the background if this is an opaque layer + if (!_alpha) { + this.clearAll(); + } + container.appendChild(this._canvas); + } + + public onOptionsChanged(terminal: ITerminal): void {} + public onBlur(terminal: ITerminal): void {} + public onFocus(terminal: ITerminal): void {} + public onCursorMove(terminal: ITerminal): void {} + public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {} + public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void {} + + public onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void { + this._refreshCharAtlas(terminal, colorSet); + } + + /** + * Refreshes the char atlas, aquiring a new one if necessary. + * @param terminal The terminal. + * @param colorSet The color set to use for the char atlas. + */ + private _refreshCharAtlas(terminal: ITerminal, colorSet: IColorSet): void { + if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) { + return; + } + this._charAtlas = null; + const result = acquireCharAtlas(terminal, this._colors, this._scaledCharWidth, this._scaledCharHeight); + if (result instanceof HTMLCanvasElement) { + this._charAtlas = result; + } else { + result.then(bitmap => this._charAtlas = bitmap); + } + } + + public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void { + this._scaledCellWidth = dim.scaledCellWidth; + this._scaledCellHeight = dim.scaledCellHeight; + this._scaledCharWidth = dim.scaledCharWidth; + this._scaledCharHeight = dim.scaledCharHeight; + this._scaledCharLeft = dim.scaledCharLeft; + this._scaledCharTop = dim.scaledCharTop; + this._canvas.width = dim.scaledCanvasWidth; + this._canvas.height = dim.scaledCanvasHeight; + this._canvas.style.width = `${dim.canvasWidth}px`; + this._canvas.style.height = `${dim.canvasHeight}px`; + + // Draw the background if this is an opaque layer + if (!this._alpha) { + this.clearAll(); + } + + if (charSizeChanged) { + this._refreshCharAtlas(terminal, this._colors); + } + } + + public abstract reset(terminal: ITerminal): void; + + /** + * Fills 1+ cells completely. This uses the existing fillStyle on the context. + * @param x The column to start at. + * @param y The row to start at + * @param width The number of columns to fill. + * @param height The number of rows to fill. + */ + protected fillCells(x: number, y: number, width: number, height: number): void { + this._ctx.fillRect( + x * this._scaledCellWidth, + y * this._scaledCellHeight, + width * this._scaledCellWidth, + height * this._scaledCellHeight); + } + + /** + * Fills a 1px line (2px on HDPI) at the bottom of the cell. This uses the + * existing fillStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected fillBottomLineAtCells(x: number, y: number, width: number = 1): void { + this._ctx.fillRect( + x * this._scaledCellWidth, + (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */, + width * this._scaledCellWidth, + window.devicePixelRatio); + } + + /** + * Fills a 1px line (2px on HDPI) at the left of the cell. This uses the + * existing fillStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected fillLeftLineAtCell(x: number, y: number): void { + this._ctx.fillRect( + x * this._scaledCellWidth, + y * this._scaledCellHeight, + window.devicePixelRatio, + this._scaledCellHeight); + } + + /** + * Strokes a 1px rectangle (2px on HDPI) around a cell. This uses the existing + * strokeStyle on the context. + * @param x The column to fill. + * @param y The row to fill. + */ + protected strokeRectAtCell(x: number, y: number, width: number, height: number): void { + this._ctx.lineWidth = window.devicePixelRatio; + this._ctx.strokeRect( + x * this._scaledCellWidth + window.devicePixelRatio / 2, + y * this._scaledCellHeight + (window.devicePixelRatio / 2), + width * this._scaledCellWidth - window.devicePixelRatio, + (height * this._scaledCellHeight) - window.devicePixelRatio); + } + + /** + * Clears the entire canvas. + */ + protected clearAll(): void { + if (this._alpha) { + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + } else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + } + } + + /** + * Clears 1+ cells completely. + * @param x The column to start at. + * @param y The row to start at. + * @param width The number of columns to clear. + * @param height The number of rows to clear. + */ + protected clearCells(x: number, y: number, width: number, height: number): void { + if (this._alpha) { + this._ctx.clearRect( + x * this._scaledCellWidth, + y * this._scaledCellHeight, + width * this._scaledCellWidth, + height * this._scaledCellHeight); + } else { + this._ctx.fillStyle = this._colors.background; + this._ctx.fillRect( + x * this._scaledCellWidth, + y * this._scaledCellHeight, + width * this._scaledCellWidth, + height * this._scaledCellHeight); + } + } + + /** + * Draws a truecolor character at the cell. The character will be clipped to + * ensure that it fits with the cell, including the cell to the right if it's + * a wide character. This uses the existing fillStyle on the context. + * @param terminal The terminal. + * @param charData The char data for the character to draw. + * @param x The column to draw at. + * @param y The row to draw at. + * @param color The color of the character. + */ + protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void { + this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + this._ctx.textBaseline = 'top'; + this._clipRow(terminal, y); + this._ctx.fillText( + charData[CHAR_DATA_CHAR_INDEX], + x * this._scaledCellWidth + this._scaledCharLeft, + y * this._scaledCellHeight + this._scaledCharTop); + } + + /** + * Draws a character at a cell. If possible this will draw using the character + * atlas to reduce draw time. + * @param terminal The terminal. + * @param char The character. + * @param code The character code. + * @param width The width of the character. + * @param x The column to draw at. + * @param y The row to draw at. + * @param fg The foreground color, in the format stored within the attributes. + * @param bg The background color, in the format stored within the attributes. + * This is used to validate whether a cached image can be used. + * @param bold Whether the text is bold. + */ + protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean): void { + let colorIndex = 0; + if (fg < 256) { + colorIndex = fg + 2; + } else { + // If default color and bold + if (bold && terminal.options.enableBold) { + colorIndex = 1; + } + } + const isAscii = code < 256; + // A color is basic if it is one of the standard normal or bold weight + // colors of the characters held in the char atlas. Note that this excludes + // the normal weight _light_ color characters. + const isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold); + const isDefaultColor = fg >= 256; + const isDefaultBackground = bg >= 256; + if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground) { + // ImageBitmap's draw about twice as fast as from a canvas + const charAtlasCellWidth = this._scaledCharWidth + CHAR_ATLAS_CELL_SPACING; + const charAtlasCellHeight = this._scaledCharHeight + CHAR_ATLAS_CELL_SPACING; + + // Apply alpha to dim the character + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + + // Draw the non-bold version of the same color if bold is not enabled + if (bold && !terminal.options.enableBold) { + // Ignore default color as it's not touched above + if (colorIndex > 1) { + colorIndex -= 8; + } + } + + this._ctx.drawImage(this._charAtlas, + code * charAtlasCellWidth, + colorIndex * charAtlasCellHeight, + charAtlasCellWidth, + this._scaledCharHeight, + x * this._scaledCellWidth + this._scaledCharLeft, + y * this._scaledCellHeight + this._scaledCharTop, + charAtlasCellWidth, + this._scaledCharHeight); + } else { + this._drawUncachedChar(terminal, char, width, fg, x, y, bold, dim); + } + // This draws the atlas (for debugging purposes) + // this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + // this._ctx.drawImage(this._charAtlas, 0, 0); + } + + /** + * Draws a character at a cell. The character will be clipped to + * ensure that it fits with the cell, including the cell to the right if it's + * a wide character. + * @param terminal The terminal. + * @param char The character. + * @param width The width of the character. + * @param fg The foreground color, in the format stored within the attributes. + * @param x The column to draw at. + * @param y The row to draw at. + */ + private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean): void { + this._ctx.save(); + this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + if (bold && terminal.options.enableBold) { + this._ctx.font = `bold ${this._ctx.font}`; + } + this._ctx.textBaseline = 'top'; + + if (fg === INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } else if (fg < 256) { + // 256 color support + this._ctx.fillStyle = this._colors.ansi[fg]; + } else { + this._ctx.fillStyle = this._colors.foreground; + } + + this._clipRow(terminal, y); + + // Apply alpha to dim the character + if (dim) { + this._ctx.globalAlpha = DIM_OPACITY; + } + // Draw the character + this._ctx.fillText( + char, + x * this._scaledCellWidth + this._scaledCharLeft, + y * this._scaledCellHeight + this._scaledCharTop); + this._ctx.restore(); + } + + /** + * Clips a row to ensure no pixels will be drawn outside the cells in the row. + * @param terminal The terminal. + * @param y The row to clip. + */ + private _clipRow(terminal: ITerminal, y: number): void { + this._ctx.beginPath(); + this._ctx.rect( + 0, + y * this._scaledCellHeight, + terminal.cols * this._scaledCellWidth, + this._scaledCellHeight); + this._ctx.clip(); + } +} + diff --git a/xterm.js/src/renderer/CharAtlas.ts b/xterm.js/src/renderer/CharAtlas.ts new file mode 100644 index 0000000..8cd0911 --- /dev/null +++ b/xterm.js/src/renderer/CharAtlas.ts @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, ITheme } from '../Interfaces'; +import { IColorSet } from '../renderer/Interfaces'; +import { isFirefox } from '../utils/Browser'; + +export const CHAR_ATLAS_CELL_SPACING = 1; + +interface ICharAtlasConfig { + fontSize: number; + fontFamily: string; + scaledCharWidth: number; + scaledCharHeight: number; + colors: IColorSet; +} + +interface ICharAtlasCacheEntry { + bitmap: HTMLCanvasElement | Promise; + config: ICharAtlasConfig; + ownedBy: ITerminal[]; +} + +let charAtlasCache: ICharAtlasCacheEntry[] = []; + +/** + * Acquires a char atlas, either generating a new one or returning an existing + * one that is in use by another terminal. + * @param terminal The terminal. + * @param colors The colors to use. + */ +export function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledCharWidth: number, scaledCharHeight: number): HTMLCanvasElement | Promise { + const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors); + + // Check to see if the terminal already owns this config + for (let i = 0; i < charAtlasCache.length; i++) { + const entry = charAtlasCache[i]; + const ownedByIndex = entry.ownedBy.indexOf(terminal); + if (ownedByIndex >= 0) { + if (configEquals(entry.config, newConfig)) { + return entry.bitmap; + } else { + // The configs differ, release the terminal from the entry + if (entry.ownedBy.length === 1) { + charAtlasCache.splice(i, 1); + } else { + entry.ownedBy.splice(ownedByIndex, 1); + } + break; + } + } + } + + // Try match a char atlas from the cache + for (let i = 0; i < charAtlasCache.length; i++) { + const entry = charAtlasCache[i]; + if (configEquals(entry.config, newConfig)) { + // Add the terminal to the cache entry and return + entry.ownedBy.push(terminal); + return entry.bitmap; + } + } + + const newEntry: ICharAtlasCacheEntry = { + bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, colors.background, colors.foreground, colors.ansi), + config: newConfig, + ownedBy: [terminal] + }; + charAtlasCache.push(newEntry); + return newEntry.bitmap; +} + +function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig { + const clonedColors = { + foreground: colors.foreground, + background: colors.background, + cursor: null, + cursorAccent: null, + selection: null, + ansi: colors.ansi.slice(0, 16) + }; + return { + scaledCharWidth, + scaledCharHeight, + fontFamily: terminal.options.fontFamily, + fontSize: terminal.options.fontSize, + colors: clonedColors + }; +} + +function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean { + for (let i = 0; i < a.colors.ansi.length; i++) { + if (a.colors.ansi[i] !== b.colors.ansi[i]) { + return false; + } + } + return a.fontFamily === b.fontFamily && + a.fontSize === b.fontSize && + a.scaledCharWidth === b.scaledCharWidth && + a.scaledCharHeight === b.scaledCharHeight && + a.colors.foreground === b.colors.foreground && + a.colors.background === b.colors.background; +} + +let generator: CharAtlasGenerator; + +/** + * Initializes the char atlas generator. + * @param document The document. + */ +export function initialize(document: Document, alpha: boolean): void { + if (!generator) { + generator = new CharAtlasGenerator(document, alpha); + } +} + +class CharAtlasGenerator { + private _canvas: HTMLCanvasElement; + private _ctx: CanvasRenderingContext2D; + + constructor(private _document: Document, alpha: boolean) { + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d', {alpha}); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + } + + public generate(scaledCharWidth: number, scaledCharHeight: number, fontSize: number, fontFamily: string, background: string, foreground: string, ansiColors: string[]): HTMLCanvasElement | Promise { + const cellWidth = scaledCharWidth + CHAR_ATLAS_CELL_SPACING; + const cellHeight = scaledCharHeight + CHAR_ATLAS_CELL_SPACING; + this._canvas.width = 255 * cellWidth; + this._canvas.height = (/*default+default bold*/2 + /*0-15*/16) * cellHeight; + + this._ctx.fillStyle = background; + this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); + + this._ctx.save(); + this._ctx.fillStyle = foreground; + this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`; + this._ctx.textBaseline = 'top'; + + // Default color + for (let i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, 0, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, 0); + this._ctx.restore(); + } + // Default color bold + this._ctx.save(); + this._ctx.font = `bold ${this._ctx.font}`; + for (let i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight); + this._ctx.restore(); + } + this._ctx.restore(); + + // Colors 0-15 + this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`; + for (let colorIndex = 0; colorIndex < 16; colorIndex++) { + // colors 8-15 are bold + if (colorIndex === 8) { + this._ctx.font = `bold ${this._ctx.font}`; + } + const y = (colorIndex + 2) * cellHeight; + // Draw ascii characters + for (let i = 0; i < 256; i++) { + this._ctx.save(); + this._ctx.beginPath(); + this._ctx.rect(i * cellWidth, y, cellWidth, cellHeight); + this._ctx.clip(); + this._ctx.fillStyle = ansiColors[colorIndex]; + this._ctx.fillText(String.fromCharCode(i), i * cellWidth, y); + this._ctx.restore(); + } + } + this._ctx.restore(); + + // Support is patchy for createImageBitmap at the moment, pass a canvas back + // if support is lacking as drawImage works there too. Firefox is also + // included here as ImageBitmap appears both buggy and has horrible + // performance (tested on v55). + if (!('createImageBitmap' in window) || isFirefox) { + // Regenerate canvas and context as they are now owned by the char atlas + const result = this._canvas; + this._canvas = this._document.createElement('canvas'); + this._ctx = this._canvas.getContext('2d'); + this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + return result; + } + + const charAtlasImageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height); + + // Remove the background color from the image so characters may overlap + const r = parseInt(background.substr(1, 2), 16); + const g = parseInt(background.substr(3, 2), 16); + const b = parseInt(background.substr(5, 2), 16); + this._clearColor(charAtlasImageData, r, g, b); + + const promise = window.createImageBitmap(charAtlasImageData); + // Clear the rect while the promise is in progress + this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); + return promise; + } + + private _clearColor(imageData: ImageData, r: number, g: number, b: number): void { + for (let offset = 0; offset < imageData.data.length; offset += 4) { + if (imageData.data[offset] === r && + imageData.data[offset + 1] === g && + imageData.data[offset + 2] === b) { + imageData.data[offset + 3] = 0; + } + } + } +} diff --git a/xterm.js/src/renderer/ColorManager.test.ts b/xterm.js/src/renderer/ColorManager.test.ts new file mode 100644 index 0000000..2240760 --- /dev/null +++ b/xterm.js/src/renderer/ColorManager.test.ts @@ -0,0 +1,295 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { ColorManager } from './ColorManager'; + +describe('ColorManager', () => { + let cm: ColorManager; + + beforeEach(() => { + cm = new ColorManager(); + }); + + describe('constructor', () => { + it('should fill all colors with values', () => { + for (let key in cm.colors) { + if (typeof key === 'string') { + // A #rrggbb or rgba(...) + assert.ok(cm.colors[key].length >= 7); + } + } + assert.equal(cm.colors.ansi.length, 256); + }); + + it('should fill 240 colors with expected values', () => { + assert.equal(cm.colors.ansi[16], '#000000'); + assert.equal(cm.colors.ansi[17], '#00005f'); + assert.equal(cm.colors.ansi[18], '#000087'); + assert.equal(cm.colors.ansi[19], '#0000af'); + assert.equal(cm.colors.ansi[20], '#0000d7'); + assert.equal(cm.colors.ansi[21], '#0000ff'); + assert.equal(cm.colors.ansi[22], '#005f00'); + assert.equal(cm.colors.ansi[23], '#005f5f'); + assert.equal(cm.colors.ansi[24], '#005f87'); + assert.equal(cm.colors.ansi[25], '#005faf'); + assert.equal(cm.colors.ansi[26], '#005fd7'); + assert.equal(cm.colors.ansi[27], '#005fff'); + assert.equal(cm.colors.ansi[28], '#008700'); + assert.equal(cm.colors.ansi[29], '#00875f'); + assert.equal(cm.colors.ansi[30], '#008787'); + assert.equal(cm.colors.ansi[31], '#0087af'); + assert.equal(cm.colors.ansi[32], '#0087d7'); + assert.equal(cm.colors.ansi[33], '#0087ff'); + assert.equal(cm.colors.ansi[34], '#00af00'); + assert.equal(cm.colors.ansi[35], '#00af5f'); + assert.equal(cm.colors.ansi[36], '#00af87'); + assert.equal(cm.colors.ansi[37], '#00afaf'); + assert.equal(cm.colors.ansi[38], '#00afd7'); + assert.equal(cm.colors.ansi[39], '#00afff'); + assert.equal(cm.colors.ansi[40], '#00d700'); + assert.equal(cm.colors.ansi[41], '#00d75f'); + assert.equal(cm.colors.ansi[42], '#00d787'); + assert.equal(cm.colors.ansi[43], '#00d7af'); + assert.equal(cm.colors.ansi[44], '#00d7d7'); + assert.equal(cm.colors.ansi[45], '#00d7ff'); + assert.equal(cm.colors.ansi[46], '#00ff00'); + assert.equal(cm.colors.ansi[47], '#00ff5f'); + assert.equal(cm.colors.ansi[48], '#00ff87'); + assert.equal(cm.colors.ansi[49], '#00ffaf'); + assert.equal(cm.colors.ansi[50], '#00ffd7'); + assert.equal(cm.colors.ansi[51], '#00ffff'); + assert.equal(cm.colors.ansi[52], '#5f0000'); + assert.equal(cm.colors.ansi[53], '#5f005f'); + assert.equal(cm.colors.ansi[54], '#5f0087'); + assert.equal(cm.colors.ansi[55], '#5f00af'); + assert.equal(cm.colors.ansi[56], '#5f00d7'); + assert.equal(cm.colors.ansi[57], '#5f00ff'); + assert.equal(cm.colors.ansi[58], '#5f5f00'); + assert.equal(cm.colors.ansi[59], '#5f5f5f'); + assert.equal(cm.colors.ansi[60], '#5f5f87'); + assert.equal(cm.colors.ansi[61], '#5f5faf'); + assert.equal(cm.colors.ansi[62], '#5f5fd7'); + assert.equal(cm.colors.ansi[63], '#5f5fff'); + assert.equal(cm.colors.ansi[64], '#5f8700'); + assert.equal(cm.colors.ansi[65], '#5f875f'); + assert.equal(cm.colors.ansi[66], '#5f8787'); + assert.equal(cm.colors.ansi[67], '#5f87af'); + assert.equal(cm.colors.ansi[68], '#5f87d7'); + assert.equal(cm.colors.ansi[69], '#5f87ff'); + assert.equal(cm.colors.ansi[70], '#5faf00'); + assert.equal(cm.colors.ansi[71], '#5faf5f'); + assert.equal(cm.colors.ansi[72], '#5faf87'); + assert.equal(cm.colors.ansi[73], '#5fafaf'); + assert.equal(cm.colors.ansi[74], '#5fafd7'); + assert.equal(cm.colors.ansi[75], '#5fafff'); + assert.equal(cm.colors.ansi[76], '#5fd700'); + assert.equal(cm.colors.ansi[77], '#5fd75f'); + assert.equal(cm.colors.ansi[78], '#5fd787'); + assert.equal(cm.colors.ansi[79], '#5fd7af'); + assert.equal(cm.colors.ansi[80], '#5fd7d7'); + assert.equal(cm.colors.ansi[81], '#5fd7ff'); + assert.equal(cm.colors.ansi[82], '#5fff00'); + assert.equal(cm.colors.ansi[83], '#5fff5f'); + assert.equal(cm.colors.ansi[84], '#5fff87'); + assert.equal(cm.colors.ansi[85], '#5fffaf'); + assert.equal(cm.colors.ansi[86], '#5fffd7'); + assert.equal(cm.colors.ansi[87], '#5fffff'); + assert.equal(cm.colors.ansi[88], '#870000'); + assert.equal(cm.colors.ansi[89], '#87005f'); + assert.equal(cm.colors.ansi[90], '#870087'); + assert.equal(cm.colors.ansi[91], '#8700af'); + assert.equal(cm.colors.ansi[92], '#8700d7'); + assert.equal(cm.colors.ansi[93], '#8700ff'); + assert.equal(cm.colors.ansi[94], '#875f00'); + assert.equal(cm.colors.ansi[95], '#875f5f'); + assert.equal(cm.colors.ansi[96], '#875f87'); + assert.equal(cm.colors.ansi[97], '#875faf'); + assert.equal(cm.colors.ansi[98], '#875fd7'); + assert.equal(cm.colors.ansi[99], '#875fff'); + assert.equal(cm.colors.ansi[100], '#878700'); + assert.equal(cm.colors.ansi[101], '#87875f'); + assert.equal(cm.colors.ansi[102], '#878787'); + assert.equal(cm.colors.ansi[103], '#8787af'); + assert.equal(cm.colors.ansi[104], '#8787d7'); + assert.equal(cm.colors.ansi[105], '#8787ff'); + assert.equal(cm.colors.ansi[106], '#87af00'); + assert.equal(cm.colors.ansi[107], '#87af5f'); + assert.equal(cm.colors.ansi[108], '#87af87'); + assert.equal(cm.colors.ansi[109], '#87afaf'); + assert.equal(cm.colors.ansi[110], '#87afd7'); + assert.equal(cm.colors.ansi[111], '#87afff'); + assert.equal(cm.colors.ansi[112], '#87d700'); + assert.equal(cm.colors.ansi[113], '#87d75f'); + assert.equal(cm.colors.ansi[114], '#87d787'); + assert.equal(cm.colors.ansi[115], '#87d7af'); + assert.equal(cm.colors.ansi[116], '#87d7d7'); + assert.equal(cm.colors.ansi[117], '#87d7ff'); + assert.equal(cm.colors.ansi[118], '#87ff00'); + assert.equal(cm.colors.ansi[119], '#87ff5f'); + assert.equal(cm.colors.ansi[120], '#87ff87'); + assert.equal(cm.colors.ansi[121], '#87ffaf'); + assert.equal(cm.colors.ansi[122], '#87ffd7'); + assert.equal(cm.colors.ansi[123], '#87ffff'); + assert.equal(cm.colors.ansi[124], '#af0000'); + assert.equal(cm.colors.ansi[125], '#af005f'); + assert.equal(cm.colors.ansi[126], '#af0087'); + assert.equal(cm.colors.ansi[127], '#af00af'); + assert.equal(cm.colors.ansi[128], '#af00d7'); + assert.equal(cm.colors.ansi[129], '#af00ff'); + assert.equal(cm.colors.ansi[130], '#af5f00'); + assert.equal(cm.colors.ansi[131], '#af5f5f'); + assert.equal(cm.colors.ansi[132], '#af5f87'); + assert.equal(cm.colors.ansi[133], '#af5faf'); + assert.equal(cm.colors.ansi[134], '#af5fd7'); + assert.equal(cm.colors.ansi[135], '#af5fff'); + assert.equal(cm.colors.ansi[136], '#af8700'); + assert.equal(cm.colors.ansi[137], '#af875f'); + assert.equal(cm.colors.ansi[138], '#af8787'); + assert.equal(cm.colors.ansi[139], '#af87af'); + assert.equal(cm.colors.ansi[140], '#af87d7'); + assert.equal(cm.colors.ansi[141], '#af87ff'); + assert.equal(cm.colors.ansi[142], '#afaf00'); + assert.equal(cm.colors.ansi[143], '#afaf5f'); + assert.equal(cm.colors.ansi[144], '#afaf87'); + assert.equal(cm.colors.ansi[145], '#afafaf'); + assert.equal(cm.colors.ansi[146], '#afafd7'); + assert.equal(cm.colors.ansi[147], '#afafff'); + assert.equal(cm.colors.ansi[148], '#afd700'); + assert.equal(cm.colors.ansi[149], '#afd75f'); + assert.equal(cm.colors.ansi[150], '#afd787'); + assert.equal(cm.colors.ansi[151], '#afd7af'); + assert.equal(cm.colors.ansi[152], '#afd7d7'); + assert.equal(cm.colors.ansi[153], '#afd7ff'); + assert.equal(cm.colors.ansi[154], '#afff00'); + assert.equal(cm.colors.ansi[155], '#afff5f'); + assert.equal(cm.colors.ansi[156], '#afff87'); + assert.equal(cm.colors.ansi[157], '#afffaf'); + assert.equal(cm.colors.ansi[158], '#afffd7'); + assert.equal(cm.colors.ansi[159], '#afffff'); + assert.equal(cm.colors.ansi[160], '#d70000'); + assert.equal(cm.colors.ansi[161], '#d7005f'); + assert.equal(cm.colors.ansi[162], '#d70087'); + assert.equal(cm.colors.ansi[163], '#d700af'); + assert.equal(cm.colors.ansi[164], '#d700d7'); + assert.equal(cm.colors.ansi[165], '#d700ff'); + assert.equal(cm.colors.ansi[166], '#d75f00'); + assert.equal(cm.colors.ansi[167], '#d75f5f'); + assert.equal(cm.colors.ansi[168], '#d75f87'); + assert.equal(cm.colors.ansi[169], '#d75faf'); + assert.equal(cm.colors.ansi[170], '#d75fd7'); + assert.equal(cm.colors.ansi[171], '#d75fff'); + assert.equal(cm.colors.ansi[172], '#d78700'); + assert.equal(cm.colors.ansi[173], '#d7875f'); + assert.equal(cm.colors.ansi[174], '#d78787'); + assert.equal(cm.colors.ansi[175], '#d787af'); + assert.equal(cm.colors.ansi[176], '#d787d7'); + assert.equal(cm.colors.ansi[177], '#d787ff'); + assert.equal(cm.colors.ansi[178], '#d7af00'); + assert.equal(cm.colors.ansi[179], '#d7af5f'); + assert.equal(cm.colors.ansi[180], '#d7af87'); + assert.equal(cm.colors.ansi[181], '#d7afaf'); + assert.equal(cm.colors.ansi[182], '#d7afd7'); + assert.equal(cm.colors.ansi[183], '#d7afff'); + assert.equal(cm.colors.ansi[184], '#d7d700'); + assert.equal(cm.colors.ansi[185], '#d7d75f'); + assert.equal(cm.colors.ansi[186], '#d7d787'); + assert.equal(cm.colors.ansi[187], '#d7d7af'); + assert.equal(cm.colors.ansi[188], '#d7d7d7'); + assert.equal(cm.colors.ansi[189], '#d7d7ff'); + assert.equal(cm.colors.ansi[190], '#d7ff00'); + assert.equal(cm.colors.ansi[191], '#d7ff5f'); + assert.equal(cm.colors.ansi[192], '#d7ff87'); + assert.equal(cm.colors.ansi[193], '#d7ffaf'); + assert.equal(cm.colors.ansi[194], '#d7ffd7'); + assert.equal(cm.colors.ansi[195], '#d7ffff'); + assert.equal(cm.colors.ansi[196], '#ff0000'); + assert.equal(cm.colors.ansi[197], '#ff005f'); + assert.equal(cm.colors.ansi[198], '#ff0087'); + assert.equal(cm.colors.ansi[199], '#ff00af'); + assert.equal(cm.colors.ansi[200], '#ff00d7'); + assert.equal(cm.colors.ansi[201], '#ff00ff'); + assert.equal(cm.colors.ansi[202], '#ff5f00'); + assert.equal(cm.colors.ansi[203], '#ff5f5f'); + assert.equal(cm.colors.ansi[204], '#ff5f87'); + assert.equal(cm.colors.ansi[205], '#ff5faf'); + assert.equal(cm.colors.ansi[206], '#ff5fd7'); + assert.equal(cm.colors.ansi[207], '#ff5fff'); + assert.equal(cm.colors.ansi[208], '#ff8700'); + assert.equal(cm.colors.ansi[209], '#ff875f'); + assert.equal(cm.colors.ansi[210], '#ff8787'); + assert.equal(cm.colors.ansi[211], '#ff87af'); + assert.equal(cm.colors.ansi[212], '#ff87d7'); + assert.equal(cm.colors.ansi[213], '#ff87ff'); + assert.equal(cm.colors.ansi[214], '#ffaf00'); + assert.equal(cm.colors.ansi[215], '#ffaf5f'); + assert.equal(cm.colors.ansi[216], '#ffaf87'); + assert.equal(cm.colors.ansi[217], '#ffafaf'); + assert.equal(cm.colors.ansi[218], '#ffafd7'); + assert.equal(cm.colors.ansi[219], '#ffafff'); + assert.equal(cm.colors.ansi[220], '#ffd700'); + assert.equal(cm.colors.ansi[221], '#ffd75f'); + assert.equal(cm.colors.ansi[222], '#ffd787'); + assert.equal(cm.colors.ansi[223], '#ffd7af'); + assert.equal(cm.colors.ansi[224], '#ffd7d7'); + assert.equal(cm.colors.ansi[225], '#ffd7ff'); + assert.equal(cm.colors.ansi[226], '#ffff00'); + assert.equal(cm.colors.ansi[227], '#ffff5f'); + assert.equal(cm.colors.ansi[228], '#ffff87'); + assert.equal(cm.colors.ansi[229], '#ffffaf'); + assert.equal(cm.colors.ansi[230], '#ffffd7'); + assert.equal(cm.colors.ansi[231], '#ffffff'); + assert.equal(cm.colors.ansi[232], '#080808'); + assert.equal(cm.colors.ansi[233], '#121212'); + assert.equal(cm.colors.ansi[234], '#1c1c1c'); + assert.equal(cm.colors.ansi[235], '#262626'); + assert.equal(cm.colors.ansi[236], '#303030'); + assert.equal(cm.colors.ansi[237], '#3a3a3a'); + assert.equal(cm.colors.ansi[238], '#444444'); + assert.equal(cm.colors.ansi[239], '#4e4e4e'); + assert.equal(cm.colors.ansi[240], '#585858'); + assert.equal(cm.colors.ansi[241], '#626262'); + assert.equal(cm.colors.ansi[242], '#6c6c6c'); + assert.equal(cm.colors.ansi[243], '#767676'); + assert.equal(cm.colors.ansi[244], '#808080'); + assert.equal(cm.colors.ansi[245], '#8a8a8a'); + assert.equal(cm.colors.ansi[246], '#949494'); + assert.equal(cm.colors.ansi[247], '#9e9e9e'); + assert.equal(cm.colors.ansi[248], '#a8a8a8'); + assert.equal(cm.colors.ansi[249], '#b2b2b2'); + assert.equal(cm.colors.ansi[250], '#bcbcbc'); + assert.equal(cm.colors.ansi[251], '#c6c6c6'); + assert.equal(cm.colors.ansi[252], '#d0d0d0'); + assert.equal(cm.colors.ansi[253], '#dadada'); + assert.equal(cm.colors.ansi[254], '#e4e4e4'); + assert.equal(cm.colors.ansi[255], '#eeeeee'); + }); + }); + + describe('setTheme', () => { + it('should not throw when not setting all colors', () => { + assert.doesNotThrow(() => { + cm.setTheme({}); + }); + }); + + it('should set a partial set of colors, using the default if not present', () => { + assert.equal(cm.colors.background, '#000000'); + assert.equal(cm.colors.foreground, '#ffffff'); + cm.setTheme({ + background: '#FF0000', + foreground: '#00FF00' + }); + assert.equal(cm.colors.background, '#FF0000'); + assert.equal(cm.colors.foreground, '#00FF00'); + cm.setTheme({ + background: '#0000FF' + }); + assert.equal(cm.colors.background, '#0000FF'); + // FG reverts back to default + assert.equal(cm.colors.foreground, '#ffffff'); + }); + }); +}); diff --git a/xterm.js/src/renderer/ColorManager.ts b/xterm.js/src/renderer/ColorManager.ts new file mode 100644 index 0000000..ea5f1cb --- /dev/null +++ b/xterm.js/src/renderer/ColorManager.ts @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IColorSet, IColorManager } from './Interfaces'; +import { ITheme } from '../Interfaces'; + +const DEFAULT_FOREGROUND = '#ffffff'; +const DEFAULT_BACKGROUND = '#000000'; +const DEFAULT_CURSOR = '#ffffff'; +const DEFAULT_CURSOR_ACCENT = '#000000'; +const DEFAULT_SELECTION = 'rgba(255, 255, 255, 0.3)'; +export const DEFAULT_ANSI_COLORS = [ + // dark: + '#2e3436', + '#cc0000', + '#4e9a06', + '#c4a000', + '#3465a4', + '#75507b', + '#06989a', + '#d3d7cf', + // bright: + '#555753', + '#ef2929', + '#8ae234', + '#fce94f', + '#729fcf', + '#ad7fa8', + '#34e2e2', + '#eeeeec' +]; + +/** + * Fills an existing 16 length string with the remaining 240 ANSI colors. + * @param first16Colors The first 16 ANSI colors. + */ +function generate256Colors(first16Colors: string[]): string[] { + let colors = first16Colors.slice(); + + // Generate colors (16-231) + let v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (let i = 0; i < 216; i++) { + const r = toPaddedHex(v[(i / 36) % 6 | 0]); + const g = toPaddedHex(v[(i / 6) % 6 | 0]); + const b = toPaddedHex(v[i % 6]); + colors.push(`#${r}${g}${b}`); + } + + // Generate greys (232-255) + for (let i = 0; i < 24; i++) { + const c = toPaddedHex(8 + i * 10); + colors.push(`#${c}${c}${c}`); + } + + return colors; +} + +function toPaddedHex(c: number): string { + let s = c.toString(16); + return s.length < 2 ? '0' + s : s; +} + +/** + * Manages the source of truth for a terminal's colors. + */ +export class ColorManager implements IColorManager { + public colors: IColorSet; + + constructor() { + this.colors = { + foreground: DEFAULT_FOREGROUND, + background: DEFAULT_BACKGROUND, + cursor: DEFAULT_CURSOR, + cursorAccent: DEFAULT_CURSOR_ACCENT, + selection: DEFAULT_SELECTION, + ansi: generate256Colors(DEFAULT_ANSI_COLORS) + }; + } + + /** + * Sets the terminal's theme. + * @param theme The theme to use. If a partial theme is provided then default + * colors will be used where colors are not defined. + */ + public setTheme(theme: ITheme): void { + this.colors.foreground = theme.foreground || DEFAULT_FOREGROUND; + this.colors.background = theme.background || DEFAULT_BACKGROUND; + this.colors.cursor = theme.cursor || DEFAULT_CURSOR; + this.colors.cursorAccent = theme.cursorAccent || DEFAULT_CURSOR_ACCENT; + this.colors.selection = theme.selection || DEFAULT_SELECTION; + this.colors.ansi[0] = theme.black || DEFAULT_ANSI_COLORS[0]; + this.colors.ansi[1] = theme.red || DEFAULT_ANSI_COLORS[1]; + this.colors.ansi[2] = theme.green || DEFAULT_ANSI_COLORS[2]; + this.colors.ansi[3] = theme.yellow || DEFAULT_ANSI_COLORS[3]; + this.colors.ansi[4] = theme.blue || DEFAULT_ANSI_COLORS[4]; + this.colors.ansi[5] = theme.magenta || DEFAULT_ANSI_COLORS[5]; + this.colors.ansi[6] = theme.cyan || DEFAULT_ANSI_COLORS[6]; + this.colors.ansi[7] = theme.white || DEFAULT_ANSI_COLORS[7]; + this.colors.ansi[8] = theme.brightBlack || DEFAULT_ANSI_COLORS[8]; + this.colors.ansi[9] = theme.brightRed || DEFAULT_ANSI_COLORS[9]; + this.colors.ansi[10] = theme.brightGreen || DEFAULT_ANSI_COLORS[10]; + this.colors.ansi[11] = theme.brightYellow || DEFAULT_ANSI_COLORS[11]; + this.colors.ansi[12] = theme.brightBlue || DEFAULT_ANSI_COLORS[12]; + this.colors.ansi[13] = theme.brightMagenta || DEFAULT_ANSI_COLORS[13]; + this.colors.ansi[14] = theme.brightCyan || DEFAULT_ANSI_COLORS[14]; + this.colors.ansi[15] = theme.brightWhite || DEFAULT_ANSI_COLORS[15]; + } +} diff --git a/xterm.js/src/renderer/CursorRenderLayer.ts b/xterm.js/src/renderer/CursorRenderLayer.ts new file mode 100644 index 0000000..689d691 --- /dev/null +++ b/xterm.js/src/renderer/CursorRenderLayer.ts @@ -0,0 +1,354 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IColorSet, IRenderDimensions } from './Interfaces'; +import { IBuffer, ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces'; +import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; +import { GridCache } from './GridCache'; +import { FLAGS } from './Types'; +import { BaseRenderLayer } from './BaseRenderLayer'; +import { CharData } from '../Types'; + +interface CursorState { + x: number; + y: number; + isFocused: boolean; + style: string; + width: number; +} + +/** + * The time between cursor blinks. + */ +const BLINK_INTERVAL = 600; + +export class CursorRenderLayer extends BaseRenderLayer { + private _state: CursorState; + private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, charData: CharData) => void}; + private _cursorBlinkStateManager: CursorBlinkStateManager; + private _isFocused: boolean; + + constructor(container: HTMLElement, zIndex: number, colors: IColorSet) { + super(container, 'cursor', zIndex, true, colors); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + this._cursorRenderers = { + 'bar': this._renderBarCursor.bind(this), + 'block': this._renderBlockCursor.bind(this), + 'underline': this._renderUnderlineCursor.bind(this) + }; + // TODO: Consider initial options? Maybe onOptionsChanged should be called at the end of open? + } + + public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void { + super.resize(terminal, dim, charSizeChanged); + // Resizing the canvas discards the contents of the canvas so clear state + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + } + + public reset(terminal: ITerminal): void { + this._clearCursor(); + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + this.onOptionsChanged(terminal); + } + } + + public onBlur(terminal: ITerminal): void { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.pause(); + } + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + + public onFocus(terminal: ITerminal): void { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.resume(terminal); + } else { + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + } + + public onOptionsChanged(terminal: ITerminal): void { + if (terminal.options.cursorBlink) { + if (!this._cursorBlinkStateManager) { + this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, () => { + this._render(terminal, true); + }); + } + } else { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = null; + } + // Request a refresh from the terminal as management of rendering is being + // moved back to the terminal + terminal.refresh(terminal.buffer.y, terminal.buffer.y); + } + } + + public onCursorMove(terminal: ITerminal): void { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.restartBlinkAnimation(terminal); + } + } + + public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void { + // Only render if the animation frame is not active + if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) { + this._render(terminal, false); + } + } + + private _render(terminal: ITerminal, triggeredByAnimationFrame: boolean): void { + // Don't draw the cursor if it's hidden + if (!terminal.cursorState || terminal.cursorHidden) { + this._clearCursor(); + return; + } + + const cursorY = terminal.buffer.ybase + terminal.buffer.y; + const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp; + + // Don't draw the cursor if it's off-screen + if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) { + this._clearCursor(); + return; + } + + const charData = terminal.buffer.lines.get(cursorY)[terminal.buffer.x]; + if (!charData) { + return; + } + + if (!terminal.isFocused) { + this._clearCursor(); + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[CHAR_DATA_WIDTH_INDEX]; + return; + } + + // Don't draw the cursor if it's blinking + if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) { + this._clearCursor(); + return; + } + + if (this._state) { + // The cursor is already in the correct spot, don't redraw + if (this._state.x === terminal.buffer.x && + this._state.y === viewportRelativeCursorY && + this._state.isFocused === terminal.isFocused && + this._state.style === terminal.options.cursorStyle && + this._state.width === charData[CHAR_DATA_WIDTH_INDEX]) { + return; + } + this._clearCursor(); + } + + this._ctx.save(); + this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, charData); + this._ctx.restore(); + + this._state.x = terminal.buffer.x; + this._state.y = viewportRelativeCursorY; + this._state.isFocused = false; + this._state.style = terminal.options.cursorStyle; + this._state.width = charData[CHAR_DATA_WIDTH_INDEX]; + } + + private _clearCursor(): void { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.width, 1); + this._state = { + x: null, + y: null, + isFocused: null, + style: null, + width: null, + }; + } + } + + private _renderBarCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillLeftLineAtCell(x, y); + this._ctx.restore(); + } + + private _renderBlockCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillCells(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.fillStyle = this._colors.cursorAccent; + this.fillCharTrueColor(terminal, charData, x, y); + this._ctx.restore(); + } + + private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { + this._ctx.save(); + this._ctx.fillStyle = this._colors.cursor; + this.fillBottomLineAtCells(x, y); + this._ctx.restore(); + } + + private _renderBlurCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void { + this._ctx.save(); + this._ctx.strokeStyle = this._colors.cursor; + this.strokeRectAtCell(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1); + this._ctx.restore(); + } +} + +class CursorBlinkStateManager { + public isCursorVisible: boolean; + + private _animationFrame: number; + private _blinkStartTimeout: number; + private _blinkInterval: number; + + /** + * The time at which the animation frame was restarted, this is used on the + * next render to restart the timers so they don't need to restart the timers + * multiple times over a short period. + */ + private _animationTimeRestarted: number; + + constructor( + terminal: ITerminal, + private renderCallback: () => void + ) { + this.isCursorVisible = true; + if (terminal.isFocused) { + this._restartInterval(); + } + } + + public get isPaused(): boolean { return !(this._blinkStartTimeout || this._blinkInterval); } + + public dispose(): void { + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + } + + public restartBlinkAnimation(terminal: ITerminal): void { + if (this.isPaused) { + return; + } + // Save a timestamp so that the restart can be done on the next interval + this._animationTimeRestarted = Date.now(); + // Force a cursor render to ensure it's visible and in the correct position + this.isCursorVisible = true; + if (!this._animationFrame) { + this._animationFrame = window.requestAnimationFrame(() => { + this.renderCallback(); + this._animationFrame = null; + }); + } + } + + private _restartInterval(timeToStart: number = BLINK_INTERVAL): void { + // Clear any existing interval + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + } + + // Setup the initial timeout which will hide the cursor, this is done before + // the regular interval is setup in order to support restarting the blink + // animation in a lightweight way (without thrashing clearInterval and + // setInterval). + this._blinkStartTimeout = setTimeout(() => { + // Check if another animation restart was requested while this was being + // started + if (this._animationTimeRestarted) { + const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); + this._animationTimeRestarted = null; + if (time > 0) { + this._restartInterval(time); + return; + } + } + + // Hide the cursor + this.isCursorVisible = false; + this._animationFrame = window.requestAnimationFrame(() => { + this.renderCallback(); + this._animationFrame = null; + }); + + // Setup the blink interval + this._blinkInterval = setInterval(() => { + // Adjust the animation time if it was restarted + if (this._animationTimeRestarted) { + // calc time diff + // Make restart interval do a setTimeout initially? + const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); + this._animationTimeRestarted = null; + this._restartInterval(time); + return; + } + + // Invert visibility and render + this.isCursorVisible = !this.isCursorVisible; + this._animationFrame = window.requestAnimationFrame(() => { + this.renderCallback(); + this._animationFrame = null; + }); + }, BLINK_INTERVAL); + }, timeToStart); + } + + public pause(): void { + this.isCursorVisible = true; + if (this._blinkInterval) { + window.clearInterval(this._blinkInterval); + this._blinkInterval = null; + } + if (this._blinkStartTimeout) { + window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = null; + } + if (this._animationFrame) { + window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = null; + } + } + + public resume(terminal: ITerminal): void { + this._animationTimeRestarted = null; + this._restartInterval(); + this.restartBlinkAnimation(terminal); + } +} diff --git a/xterm.js/src/renderer/GridCache.test.ts b/xterm.js/src/renderer/GridCache.test.ts new file mode 100644 index 0000000..c4b1c22 --- /dev/null +++ b/xterm.js/src/renderer/GridCache.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { GridCache } from './GridCache'; + +describe('GridCache', () => { + let grid: GridCache; + + beforeEach(() => { + grid = new GridCache(); + }); + + describe('constructor', () => { + it('should create an empty cache', () => { + assert.equal(grid.cache.length, 0); + }); + }); + + describe('resize', () => { + it('should fill all new elements with null', () => { + grid.resize(2, 2); + assert.equal(grid.cache.length, 2); + assert.equal(grid.cache[0].length, 2); + assert.equal(grid.cache[0][0], null); + assert.equal(grid.cache[0][1], null); + assert.equal(grid.cache[1].length, 2); + assert.equal(grid.cache[1][0], null); + assert.equal(grid.cache[1][1], null); + grid.resize(3, 2); + assert.equal(grid.cache.length, 3); + assert.equal(grid.cache[2][0], null); + assert.equal(grid.cache[2][1], null); + }); + + it('should remove rows/cols from the cache when reduced', () => { + grid.resize(2, 2); + grid.resize(1, 1); + assert.equal(grid.cache.length, 1); + assert.equal(grid.cache[0].length, 1); + }); + + it('should not touch existing cache entries if they fit in the new cache', () => { + grid.resize(1, 1); + assert.equal(grid.cache[0][0], null); + grid.cache[0][0] = 1; + grid.resize(2, 1); + assert.equal(grid.cache[0][0], 1); + }); + }); + + describe('clear', () => { + it('should make all entries null', () => { + grid.resize(1, 1); + grid.cache[0][0] = 1; + grid.clear(); + assert.equal(grid.cache[0][0], null); + }); + }); +}); diff --git a/xterm.js/src/renderer/GridCache.ts b/xterm.js/src/renderer/GridCache.ts new file mode 100644 index 0000000..dd188c6 --- /dev/null +++ b/xterm.js/src/renderer/GridCache.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export class GridCache { + public cache: T[][]; + + public constructor() { + this.cache = []; + } + + public resize(width: number, height: number): void { + for (let x = 0; x < width; x++) { + if (this.cache.length <= x) { + this.cache.push([]); + } + for (let y = this.cache[x].length; y < height; y++) { + this.cache[x].push(null); + } + this.cache[x].length = height; + } + this.cache.length = width; + } + + public clear(): void { + for (let x = 0; x < this.cache.length; x++) { + for (let y = 0; y < this.cache[x].length; y++) { + this.cache[x][y] = null; + } + } + } +} diff --git a/xterm.js/src/renderer/Interfaces.ts b/xterm.js/src/renderer/Interfaces.ts new file mode 100644 index 0000000..be1b39d --- /dev/null +++ b/xterm.js/src/renderer/Interfaces.ts @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, ITerminalOptions, ITheme, IEventEmitter } from '../Interfaces'; + +export interface IRenderer extends IEventEmitter { + dimensions: IRenderDimensions; + colorManager: IColorManager; + + setTheme(theme: ITheme): IColorSet; + onWindowResize(devicePixelRatio: number): void; + onResize(cols: number, rows: number, didCharSizeChange: boolean): void; + onCharSizeChanged(): void; + onBlur(): void; + onFocus(): void; + onSelectionChanged(start: [number, number], end: [number, number]): void; + onCursorMove(): void; + onOptionsChanged(): void; + clear(): void; + queueRefresh(start: number, end: number): void; +} + +export interface IRenderLayer { + /** + * Called when the terminal loses focus. + */ + onBlur(terminal: ITerminal): void; + + /** + * * Called when the terminal gets focus. + */ + onFocus(terminal: ITerminal): void; + + /** + * Called when the cursor is moved. + */ + onCursorMove(terminal: ITerminal): void; + + /** + * Called when options change. + */ + onOptionsChanged(terminal: ITerminal): void; + + /** + * Called when the theme changes. + */ + onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void; + + /** + * Called when the data in the grid has changed (or needs to be rendered + * again). + */ + onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void; + + /** + * Calls when the selection changes. + */ + onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void; + + /** + * Resize the render layer. + */ + resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void; + + /** + * Clear the state of the render layer. + */ + reset(terminal: ITerminal): void; +} + +export interface IColorManager { + colors: IColorSet; +} + +export interface IColorSet { + foreground: string; + background: string; + cursor: string; + cursorAccent: string; + selection: string; + ansi: string[]; +} + +export interface IRenderDimensions { + scaledCharWidth: number; + scaledCharHeight: number; + scaledCellWidth: number; + scaledCellHeight: number; + scaledCharLeft: number; + scaledCharTop: number; + scaledCanvasWidth: number; + scaledCanvasHeight: number; + canvasWidth: number; + canvasHeight: number; + actualCellWidth: number; + actualCellHeight: number; +} diff --git a/xterm.js/src/renderer/LinkRenderLayer.ts b/xterm.js/src/renderer/LinkRenderLayer.ts new file mode 100644 index 0000000..8f3b63a --- /dev/null +++ b/xterm.js/src/renderer/LinkRenderLayer.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IColorSet, IRenderDimensions } from './Interfaces'; +import { IBuffer, ICharMeasure, ITerminal, ILinkifierAccessor } from '../Interfaces'; +import { CHAR_DATA_ATTR_INDEX } from '../Buffer'; +import { GridCache } from './GridCache'; +import { FLAGS } from './Types'; +import { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer'; +import { LinkHoverEvent, LinkHoverEventTypes } from '../Types'; + +export class LinkRenderLayer extends BaseRenderLayer { + private _state: LinkHoverEvent = null; + + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ILinkifierAccessor) { + super(container, 'link', zIndex, true, colors); + terminal.linkifier.on(LinkHoverEventTypes.HOVER, (e: LinkHoverEvent) => this._onLinkHover(e)); + terminal.linkifier.on(LinkHoverEventTypes.LEAVE, (e: LinkHoverEvent) => this._onLinkLeave(e)); + } + + public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void { + super.resize(terminal, dim, charSizeChanged); + // Resizing the canvas discards the contents of the canvas so clear state + this._state = null; + } + + public reset(terminal: ITerminal): void { + this._clearCurrentLink(); + } + + private _clearCurrentLink(): void { + if (this._state) { + this.clearCells(this._state.x, this._state.y, this._state.length, 1); + this._state = null; + } + } + + private _onLinkHover(e: LinkHoverEvent): void { + this._ctx.fillStyle = this._colors.foreground; + this.fillBottomLineAtCells(e.x, e.y, e.length); + this._state = e; + } + + private _onLinkLeave(e: LinkHoverEvent): void { + this._clearCurrentLink(); + } +} diff --git a/xterm.js/src/renderer/Renderer.ts b/xterm.js/src/renderer/Renderer.ts new file mode 100644 index 0000000..6ba7b40 --- /dev/null +++ b/xterm.js/src/renderer/Renderer.ts @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, ITheme } from '../Interfaces'; +import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; +import { TextRenderLayer } from './TextRenderLayer'; +import { SelectionRenderLayer } from './SelectionRenderLayer'; +import { CursorRenderLayer } from './CursorRenderLayer'; +import { ColorManager } from './ColorManager'; +import { BaseRenderLayer } from './BaseRenderLayer'; +import { IRenderLayer, IColorSet, IRenderer, IRenderDimensions } from './Interfaces'; +import { LinkRenderLayer } from './LinkRenderLayer'; +import { EventEmitter } from '../EventEmitter'; +import { ScreenDprMonitor } from '../utils/ScreenDprMonitor'; + +export class Renderer extends EventEmitter implements IRenderer { + /** A queue of the rows to be refreshed */ + private _refreshRowsQueue: {start: number, end: number}[] = []; + private _refreshAnimationFrame = null; + + private _renderLayers: IRenderLayer[]; + private _devicePixelRatio: number; + private _screenDprMonitor: ScreenDprMonitor; + private _isPaused: boolean = false; + private _needsFullRefresh: boolean = false; + + public colorManager: ColorManager; + public dimensions: IRenderDimensions; + + constructor(private _terminal: ITerminal, theme: ITheme) { + super(); + this.colorManager = new ColorManager(); + if (theme) { + this.colorManager.setTheme(theme); + } + + this._renderLayers = [ + new TextRenderLayer(this._terminal.element, 0, this.colorManager.colors, + this._terminal.options.allowTransparency), + new SelectionRenderLayer(this._terminal.element, 1, this.colorManager.colors), + new LinkRenderLayer(this._terminal.element, 2, this.colorManager.colors, this._terminal), + new CursorRenderLayer(this._terminal.element, 3, this.colorManager.colors) + ]; + this.dimensions = { + scaledCharWidth: null, + scaledCharHeight: null, + scaledCellWidth: null, + scaledCellHeight: null, + scaledCharLeft: null, + scaledCharTop: null, + scaledCanvasWidth: null, + scaledCanvasHeight: null, + canvasWidth: null, + canvasHeight: null, + actualCellWidth: null, + actualCellHeight: null + }; + this._devicePixelRatio = window.devicePixelRatio; + this._updateDimensions(); + + this._screenDprMonitor = new ScreenDprMonitor(); + this._screenDprMonitor.setListener(() => this.onWindowResize(window.devicePixelRatio)); + + // Detect whether IntersectionObserver is detected and enable renderer pause + // and resume based on terminal visibility if so + if ('IntersectionObserver' in window) { + const observer = new IntersectionObserver(e => this.onIntersectionChange(e[0]), {threshold: 0}); + observer.observe(this._terminal.element); + } + } + + public onIntersectionChange(entry: IntersectionObserverEntry): void { + this._isPaused = entry.intersectionRatio === 0; + if (!this._isPaused && this._needsFullRefresh) { + this._terminal.refresh(0, this._terminal.rows - 1); + } + } + + public onWindowResize(devicePixelRatio: number): void { + // If the device pixel ratio changed, the char atlas needs to be regenerated + // and the terminal needs to refreshed + if (this._devicePixelRatio !== devicePixelRatio) { + this._devicePixelRatio = devicePixelRatio; + this.onResize(this._terminal.cols, this._terminal.rows, true); + } + } + + public setTheme(theme: ITheme): IColorSet { + this.colorManager.setTheme(theme); + + // Clear layers and force a full render + this._renderLayers.forEach(l => { + l.onThemeChanged(this._terminal, this.colorManager.colors); + l.reset(this._terminal); + }); + + if (this._isPaused) { + this._needsFullRefresh = true; + } else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + + return this.colorManager.colors; + } + + public onResize(cols: number, rows: number, didCharSizeChange: boolean): void { + // Update character and canvas dimensions + this._updateDimensions(); + + // Resize all render layers + this._renderLayers.forEach(l => l.resize(this._terminal, this.dimensions, didCharSizeChange)); + + // Force a refresh + if (this._isPaused) { + this._needsFullRefresh = true; + } else { + this._terminal.refresh(0, this._terminal.rows - 1); + } + + this.emit('resize', { + width: this.dimensions.canvasWidth, + height: this.dimensions.canvasHeight + }); + } + + public onCharSizeChanged(): void { + this.onResize(this._terminal.cols, this._terminal.rows, true); + } + + public onBlur(): void { + this._runOperation(l => l.onBlur(this._terminal)); + } + + public onFocus(): void { + this._runOperation(l => l.onFocus(this._terminal)); + } + + public onSelectionChanged(start: [number, number], end: [number, number]): void { + this._runOperation(l => l.onSelectionChanged(this._terminal, start, end)); + } + + public onCursorMove(): void { + this._runOperation(l => l.onCursorMove(this._terminal)); + } + + public onOptionsChanged(): void { + this._runOperation(l => l.onOptionsChanged(this._terminal)); + } + + public clear(): void { + this._runOperation(l => l.reset(this._terminal)); + } + + private _runOperation(operation: (layer: IRenderLayer) => void): void { + if (this._isPaused) { + this._needsFullRefresh = true; + } else { + this._renderLayers.forEach(l => operation(l)); + } + } + + /** + * Queues a refresh between two rows (inclusive), to be done on next animation + * frame. + * @param {number} start The start row. + * @param {number} end The end row. + */ + public queueRefresh(start: number, end: number): void { + if (this._isPaused) { + this._needsFullRefresh = true; + return; + } + this._refreshRowsQueue.push({ start: start, end: end }); + if (!this._refreshAnimationFrame) { + this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this)); + } + } + + /** + * Performs the refresh loop callback, calling refresh only if a refresh is + * necessary before queueing up the next one. + */ + private _refreshLoop(): void { + let start; + let end; + if (this._refreshRowsQueue.length > 4) { + // Just do a full refresh when 5+ refreshes are queued + start = 0; + end = this._terminal.rows - 1; + } else { + // Get start and end rows that need refreshing + start = this._refreshRowsQueue[0].start; + end = this._refreshRowsQueue[0].end; + for (let i = 1; i < this._refreshRowsQueue.length; i++) { + if (this._refreshRowsQueue[i].start < start) { + start = this._refreshRowsQueue[i].start; + } + if (this._refreshRowsQueue[i].end > end) { + end = this._refreshRowsQueue[i].end; + } + } + } + this._refreshRowsQueue = []; + this._refreshAnimationFrame = null; + + // Render + start = Math.max(start, 0); + end = Math.min(end, this._terminal.rows - 1); + this._renderLayers.forEach(l => l.onGridChanged(this._terminal, start, end)); + this._terminal.emit('refresh', {start, end}); + } + + /** + * Recalculates the character and canvas dimensions. + */ + private _updateDimensions(): void { + // Perform a new measure if the CharMeasure dimensions are not yet available + if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) { + return; + } + + // Calculate the scaled character width. Width is floored as it must be + // drawn to an integer grid in order for the CharAtlas "stamps" to not be + // blurry. When text is drawn to the grid not using the CharAtlas, it is + // clipped to ensure there is no overlap with the next cell. + this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio); + + // Calculate the scaled character height. Height is ceiled in case + // devicePixelRatio is a floating point number in order to ensure there is + // enough space to draw the character to the cell. + this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio); + + // Calculate the scaled cell height, if lineHeight is not 1 then the value + // will be floored because since lineHeight can never be lower then 1, there + // is a guarentee that the scaled line height will always be larger than + // scaled char height. + this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight); + + // Calculate the y coordinate within a cell that text should draw from in + // order to draw in the center of a cell. + this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2); + + // Calculate the scaled cell width, taking the letterSpacing into account. + this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing); + + // Calculate the x coordinate with a cell that text should draw from in + // order to draw in the center of a cell. + this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2); + + // Recalculate the canvas dimensions; scaled* define the actual number of + // pixel in the canvas + this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight; + this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth; + + // The the size of the canvas on the page. It's very important that this + // rounds to nearest integer and not ceils as browsers often set + // window.devicePixelRatio as something like 1.100000023841858, when it's + // actually 1.1. Ceiling causes blurriness as the backing canvas image is 1 + // pixel too large for the canvas element size. + this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio); + this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio); + + // Get the _actual_ dimensions of an individual cell. This needs to be + // derived from the canvasWidth/Height calculated above which takes into + // account window.devicePixelRatio. CharMeasure.width/height by itself is + // insufficient when the page is not at 100% zoom level as CharMeasure is + // measured in CSS pixels, but the actual char size on the canvas can + // differ. + this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows; + this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols; + + } + +} diff --git a/xterm.js/src/renderer/SelectionRenderLayer.ts b/xterm.js/src/renderer/SelectionRenderLayer.ts new file mode 100644 index 0000000..9740bb9 --- /dev/null +++ b/xterm.js/src/renderer/SelectionRenderLayer.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IColorSet, IRenderDimensions } from './Interfaces'; +import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces'; +import { CHAR_DATA_ATTR_INDEX } from '../Buffer'; +import { GridCache } from './GridCache'; +import { FLAGS } from './Types'; +import { BaseRenderLayer } from './BaseRenderLayer'; + +export class SelectionRenderLayer extends BaseRenderLayer { + private _state: {start: [number, number], end: [number, number]}; + + constructor(container: HTMLElement, zIndex: number, colors: IColorSet) { + super(container, 'selection', zIndex, true, colors); + this._state = { + start: null, + end: null + }; + } + + public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void { + super.resize(terminal, dim, charSizeChanged); + // Resizing the canvas discards the contents of the canvas so clear state + this._state = { + start: null, + end: null + }; + } + + public reset(terminal: ITerminal): void { + if (this._state.start && this._state.end) { + this._state = { + start: null, + end: null + }; + this.clearAll(); + } + } + + public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void { + // Selection has not changed + if (this._state.start === start || this._state.end === end) { + return; + } + + // Remove all selections + this.clearAll(); + + // Selection does not exist + if (!start || !end) { + return; + } + + // Translate from buffer position to viewport position + const viewportStartRow = start[1] - terminal.buffer.ydisp; + const viewportEndRow = end[1] - terminal.buffer.ydisp; + const viewportCappedStartRow = Math.max(viewportStartRow, 0); + const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1); + + // No need to draw the selection + if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) { + return; + } + + // Draw first row + const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0; + const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols; + this._ctx.fillStyle = this._colors.selection; + this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); + + // Draw middle rows + const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0); + this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); + + // Draw final row + if (viewportCappedStartRow !== viewportCappedEndRow) { + // Only draw viewportEndRow if it's not the same as viewportStartRow + const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols; + this.fillCells(0, viewportCappedEndRow, endCol, 1); + } + + // Save state for next render + this._state.start = [start[0], start[1]]; + this._state.end = [end[0], end[1]]; + } +} diff --git a/xterm.js/src/renderer/TextRenderLayer.ts b/xterm.js/src/renderer/TextRenderLayer.ts new file mode 100644 index 0000000..145b205 --- /dev/null +++ b/xterm.js/src/renderer/TextRenderLayer.ts @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { IColorSet, IRenderDimensions } from './Interfaces'; +import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces'; +import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../Buffer'; +import { FLAGS } from './Types'; +import { GridCache } from './GridCache'; +import { CharData } from '../Types'; +import { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer'; + +/** + * This CharData looks like a null character, which will forc a clear and render + * when the character changes (a regular space ' ' character may not as it's + * drawn state is a cleared cell). + */ +const OVERLAP_OWNED_CHAR_DATA: CharData = [null, '', 0, -1]; + +export class TextRenderLayer extends BaseRenderLayer { + private _state: GridCache; + private _characterWidth: number; + private _characterFont: string; + private _characterOverlapCache: { [key: string]: boolean } = {}; + + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, alpha: + boolean) { + super(container, 'text', zIndex, alpha, colors); + this._state = new GridCache(); + } + + public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void { + super.resize(terminal, dim, charSizeChanged); + + // Clear the character width cache if the font or width has changed + const terminalFont = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { + this._characterWidth = dim.scaledCharWidth; + this._characterFont = terminalFont; + this._characterOverlapCache = {}; + } + // Resizing the canvas discards the contents of the canvas so clear state + this._state.clear(); + this._state.resize(terminal.cols, terminal.rows); + } + + public reset(terminal: ITerminal): void { + this._state.clear(); + this.clearAll(); + } + + public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void { + // Resize has not been called yet + if (this._state.cache.length === 0) { + return; + } + + for (let y = startRow; y <= endRow; y++) { + const row = y + terminal.buffer.ydisp; + const line = terminal.buffer.lines.get(row); + + this.clearCells(0, y, terminal.cols, 1); + // for (let x = 0; x < terminal.cols; x++) { + // this._state.cache[x][y] = null; + // } + + for (let x = 0; x < terminal.cols; x++) { + const charData = line[x]; + const code: number = charData[CHAR_DATA_CODE_INDEX]; + const char: string = charData[CHAR_DATA_CHAR_INDEX]; + const attr: number = charData[CHAR_DATA_ATTR_INDEX]; + let width: number = charData[CHAR_DATA_WIDTH_INDEX]; + + // The character to the left is a wide character, drawing is owned by + // the char at x-1 + if (width === 0) { + // this._state.cache[x][y] = null; + continue; + } + + // If the character is a space and the character to the left is an + // overlapping character, skip the character and allow the overlapping + // char to take full control over this character's cell. + if (code === 32 /*' '*/) { + if (x > 0) { + const previousChar: CharData = line[x - 1]; + if (this._isOverlapping(previousChar)) { + continue; + } + } + } + + // Skip rendering if the character is identical + // const state = this._state.cache[x][y]; + // if (state && state[CHAR_DATA_CHAR_INDEX] === char && state[CHAR_DATA_ATTR_INDEX] === attr) { + // // Skip render, contents are identical + // this._state.cache[x][y] = charData; + // continue; + // } + + // Clear the old character was not a space with the default background + // const wasInverted = !!(state && state[CHAR_DATA_ATTR_INDEX] && state[CHAR_DATA_ATTR_INDEX] >> 18 & FLAGS.INVERSE); + // if (state && !(state[CHAR_DATA_CODE_INDEX] === 32 /*' '*/ && (state[CHAR_DATA_ATTR_INDEX] & 0x1ff) >= 256 && !wasInverted)) { + // this._clearChar(x, y); + // } + // this._state.cache[x][y] = charData; + + const flags = attr >> 18; + let bg = attr & 0x1ff; + + // Skip rendering if the character is invisible + const isDefaultBackground = bg >= 256; + const isInvisible = flags & FLAGS.INVISIBLE; + const isInverted = flags & FLAGS.INVERSE; + if (!code || (code === 32 /*' '*/ && isDefaultBackground && !isInverted) || isInvisible) { + continue; + } + + // If the character is an overlapping char and the character to the right is a + // space, take ownership of the cell to the right. + if (width !== 0 && this._isOverlapping(charData)) { + // If the character is overlapping, we want to force a re-render on every + // frame. This is specifically to work around the case where two + // overlaping chars `a` and `b` are adjacent, the cursor is moved to b and a + // space is added. Without this, the first half of `b` would never + // get removed, and `a` would not re-render because it thinks it's + // already in the correct state. + // this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA; + if (x < line.length - 1 && line[x + 1][CHAR_DATA_CODE_INDEX] === 32 /*' '*/) { + width = 2; + // this._clearChar(x + 1, y); + // The overlapping char's char data will force a clear and render when the + // overlapping char is no longer to the left of the character and also when + // the space changes to another character. + // this._state.cache[x + 1][y] = OVERLAP_OWNED_CHAR_DATA; + } + } + + let fg = (attr >> 9) & 0x1ff; + + // If inverse flag is on, the foreground should become the background. + if (isInverted) { + const temp = bg; + bg = fg; + fg = temp; + if (fg === 256) { + fg = INVERTED_DEFAULT_COLOR; + } + if (bg === 257) { + bg = INVERTED_DEFAULT_COLOR; + } + } + + // Clear the cell next to this character if it's wide + if (width === 2) { + // this.clearCells(x + 1, y, 1, 1); + } + + // Draw background + if (bg < 256) { + this._ctx.save(); + this._ctx.fillStyle = (bg === INVERTED_DEFAULT_COLOR ? this._colors.foreground : this._colors.ansi[bg]); + this.fillCells(x, y, width, 1); + this._ctx.restore(); + } + + this._ctx.save(); + if (flags & FLAGS.BOLD) { + this._ctx.font = `bold ${this._ctx.font}`; + // Convert the FG color to the bold variant + if (fg < 8) { + fg += 8; + } + } + + if (flags & FLAGS.UNDERLINE) { + if (fg === INVERTED_DEFAULT_COLOR) { + this._ctx.fillStyle = this._colors.background; + } else if (fg < 256) { + // 256 color support + this._ctx.fillStyle = this._colors.ansi[fg]; + } else { + this._ctx.fillStyle = this._colors.foreground; + } + this.fillBottomLineAtCells(x, y); + } + + this.drawChar(terminal, char, code, width, x, y, fg, bg, !!(flags & FLAGS.BOLD), !!(flags & FLAGS.DIM)); + + this._ctx.restore(); + } + } + } + + /** + * Whether a character is overlapping to the next cell. + */ + private _isOverlapping(charData: CharData): boolean { + // Only single cell characters can be overlapping, rendering issues can + // occur without this check + if (charData[CHAR_DATA_WIDTH_INDEX] !== 1) { + return false; + } + + // We assume that any ascii character will not overlap + const code = charData[CHAR_DATA_CODE_INDEX]; + if (code < 256) { + return false; + } + + // Deliver from cache if available + const char = charData[CHAR_DATA_CHAR_INDEX]; + if (this._characterOverlapCache.hasOwnProperty(char)) { + return this._characterOverlapCache[char]; + } + + // Setup the font + this._ctx.save(); + this._ctx.font = this._characterFont; + + // Measure the width of the character, but Math.floor it + // because that is what the renderer does when it calculates + // the character dimensions we are comparing against + const overlaps = Math.floor(this._ctx.measureText(char).width) > this._characterWidth; + + // Restore the original context + this._ctx.restore(); + + // Cache and return + this._characterOverlapCache[char] = overlaps; + return overlaps; + } + + /** + * Clear the charcater at the cell specified. + * @param x The column of the char. + * @param y The row of the char. + */ + private _clearChar(x: number, y: number): void { + let colsToClear = 1; + // Clear the adjacent character if it was wide + const state = this._state.cache[x][y]; + if (state && state[CHAR_DATA_WIDTH_INDEX] === 2) { + colsToClear = 2; + } + this.clearCells(x, y, colsToClear, 1); + } +} diff --git a/xterm.js/src/renderer/Types.ts b/xterm.js/src/renderer/Types.ts new file mode 100644 index 0000000..31705a3 --- /dev/null +++ b/xterm.js/src/renderer/Types.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + + /** + * Flags used to render terminal text properly. + */ +export enum FLAGS { + BOLD = 1, + UNDERLINE = 2, + BLINK = 4, + INVERSE = 8, + INVISIBLE = 16, + DIM = 32 +}; diff --git a/xterm.js/src/utils/Browser.ts b/xterm.js/src/utils/Browser.ts new file mode 100644 index 0000000..48c0c37 --- /dev/null +++ b/xterm.js/src/utils/Browser.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { contains } from './Generic'; + +const isNode = (typeof navigator === 'undefined') ? true : false; +const userAgent = (isNode) ? 'node' : navigator.userAgent; +const platform = (isNode) ? 'node' : navigator.platform; + +export const isFirefox = !!~userAgent.indexOf('Firefox'); +export const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); + +// Find the users platform. We use this to interpret the meta key +// and ISO third level shifts. +// http://stackoverflow.com/q/19877924/577598 +export const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); +export const isIpad = platform === 'iPad'; +export const isIphone = platform === 'iPhone'; +export const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); +export const isLinux = platform.indexOf('Linux') >= 0; diff --git a/xterm.js/src/utils/CharMeasure.test.ts b/xterm.js/src/utils/CharMeasure.test.ts new file mode 100644 index 0000000..f50ce96 --- /dev/null +++ b/xterm.js/src/utils/CharMeasure.test.ts @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import jsdom = require('jsdom'); +import { assert } from 'chai'; +import { ICharMeasure, ITerminal } from '../Interfaces'; +import { CharMeasure } from './CharMeasure'; + +describe('CharMeasure', () => { + let dom: jsdom.JSDOM; + let window: Window; + let document: Document; + let container: HTMLElement; + let charMeasure: ICharMeasure; + + beforeEach(() => { + dom = new jsdom.JSDOM(''); + window = dom.window; + document = window.document; + container = document.createElement('div'); + document.body.appendChild(container); + charMeasure = new CharMeasure(document, container); + }); + + describe('measure', () => { + it('should have _measureElement', () => { + assert.isDefined((charMeasure)._measureElement, 'new CharMeasure() should have created _measureElement'); + }); + + it('should be performed sync', () => { + // Mock getBoundingClientRect since jsdom doesn't have a layout engine + (charMeasure)._measureElement.getBoundingClientRect = () => { + return { width: 1, height: 1 }; + }; + charMeasure.measure({}); + assert.equal(charMeasure.height, 1); + assert.equal(charMeasure.width, 1); + }); + + it('should NOT do a measure when the parent is hidden', done => { + charMeasure.measure({}); + setTimeout(() => { + const firstWidth = charMeasure.width; + container.style.display = 'none'; + container.style.fontSize = '2em'; + charMeasure.measure({}); + assert.equal(charMeasure.width, firstWidth); + done(); + }, 0); + }); + }); +}); diff --git a/xterm.js/src/utils/CharMeasure.ts b/xterm.js/src/utils/CharMeasure.ts new file mode 100644 index 0000000..62291ab --- /dev/null +++ b/xterm.js/src/utils/CharMeasure.ts @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { EventEmitter } from '../EventEmitter'; +import { ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces'; + +/** + * Utility class that measures the size of a character. Measurements are done in + * the DOM rather than with a canvas context because support for extracting the + * height of characters is patchy across browsers. + */ +export class CharMeasure extends EventEmitter implements ICharMeasure { + private _document: Document; + private _parentElement: HTMLElement; + private _measureElement: HTMLElement; + private _width: number; + private _height: number; + + constructor(document: Document, parentElement: HTMLElement) { + super(); + this._document = document; + this._parentElement = parentElement; + this._measureElement = this._document.createElement('span'); + this._measureElement.style.position = 'absolute'; + this._measureElement.style.top = '0'; + this._measureElement.style.left = '-9999em'; + this._measureElement.style.lineHeight = 'normal'; + this._measureElement.textContent = 'W'; + this._measureElement.setAttribute('aria-hidden', 'true'); + this._parentElement.appendChild(this._measureElement); + } + + public get width(): number { + return this._width; + } + + public get height(): number { + return this._height; + } + + public measure(options: ITerminalOptions): void { + this._measureElement.style.fontFamily = options.fontFamily; + this._measureElement.style.fontSize = `${options.fontSize}px`; + const geometry = this._measureElement.getBoundingClientRect(); + // The element is likely currently display:none, we should retain the + // previous value. + if (geometry.width === 0 || geometry.height === 0) { + return; + } + if (this._width !== geometry.width || this._height !== geometry.height) { + this._width = geometry.width; + this._height = Math.ceil(geometry.height); + this.emit('charsizechanged'); + } + } + +} diff --git a/xterm.js/src/utils/CircularList.test.ts b/xterm.js/src/utils/CircularList.test.ts new file mode 100644 index 0000000..6bb3511 --- /dev/null +++ b/xterm.js/src/utils/CircularList.test.ts @@ -0,0 +1,264 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert } from 'chai'; +import { CircularList } from './CircularList'; + +class TestCircularList extends CircularList { + public get array(): T[] { return this._array; } +} + +describe('CircularList', () => { + describe('push', () => { + it('should push values onto the array', () => { + const list = new CircularList(5); + list.push('1'); + list.push('2'); + list.push('3'); + list.push('4'); + list.push('5'); + assert.equal(list.get(0), '1'); + assert.equal(list.get(1), '2'); + assert.equal(list.get(2), '3'); + assert.equal(list.get(3), '4'); + assert.equal(list.get(4), '5'); + }); + + it('should push old values from the start out of the array when max length is reached', () => { + const list = new CircularList(2); + list.push('1'); + list.push('2'); + assert.equal(list.get(0), '1'); + assert.equal(list.get(1), '2'); + list.push('3'); + assert.equal(list.get(0), '2'); + assert.equal(list.get(1), '3'); + list.push('4'); + assert.equal(list.get(0), '3'); + assert.equal(list.get(1), '4'); + }); + }); + + describe('maxLength', () => { + it('should increase the size of the list', () => { + const list = new CircularList(2); + list.push('1'); + list.push('2'); + assert.equal(list.get(0), '1'); + assert.equal(list.get(1), '2'); + list.maxLength = 4; + list.push('3'); + list.push('4'); + assert.equal(list.get(0), '1'); + assert.equal(list.get(1), '2'); + assert.equal(list.get(2), '3'); + assert.equal(list.get(3), '4'); + list.push('wrapped'); + assert.equal(list.get(0), '2'); + assert.equal(list.get(1), '3'); + assert.equal(list.get(2), '4'); + assert.equal(list.get(3), 'wrapped'); + }); + + it('should return the maximum length of the list', () => { + const list = new CircularList(2); + assert.equal(list.maxLength, 2); + list.push('1'); + list.push('2'); + assert.equal(list.maxLength, 2); + list.push('3'); + assert.equal(list.maxLength, 2); + list.maxLength = 4; + assert.equal(list.maxLength, 4); + }); + }); + + describe('length', () => { + it('should return the current length of the list, capped at the maximum length', () => { + const list = new CircularList(2); + assert.equal(list.length, 0); + list.push('1'); + assert.equal(list.length, 1); + list.push('2'); + assert.equal(list.length, 2); + list.push('3'); + assert.equal(list.length, 2); + }); + }); + + describe('splice', () => { + it('should delete items', () => { + const list = new CircularList(2); + list.push('1'); + list.push('2'); + list.splice(0, 1); + assert.equal(list.length, 1); + assert.equal(list.get(0), '2'); + list.push('3'); + list.splice(1, 1); + assert.equal(list.length, 1); + assert.equal(list.get(0), '2'); + }); + + it('should insert items', () => { + const list = new CircularList(2); + list.push('1'); + list.splice(0, 0, '2'); + assert.equal(list.length, 2); + assert.equal(list.get(0), '2'); + assert.equal(list.get(1), '1'); + list.splice(1, 0, '3'); + assert.equal(list.length, 2); + assert.equal(list.get(0), '3'); + assert.equal(list.get(1), '1'); + }); + + it('should delete items then insert items', () => { + const list = new CircularList(3); + list.push('1'); + list.push('2'); + list.splice(0, 1, '3', '4'); + assert.equal(list.length, 3); + assert.equal(list.get(0), '3'); + assert.equal(list.get(1), '4'); + assert.equal(list.get(2), '2'); + }); + + it('should wrap the array correctly when more items are inserted than deleted', () => { + const list = new CircularList(3); + list.push('1'); + list.push('2'); + list.splice(1, 0, '3', '4'); + assert.equal(list.length, 3); + assert.equal(list.get(0), '3'); + assert.equal(list.get(1), '4'); + assert.equal(list.get(2), '2'); + }); + }); + + describe('trimStart', () => { + it('should remove items from the beginning of the list', () => { + const list = new CircularList(5); + list.push('1'); + list.push('2'); + list.push('3'); + list.push('4'); + list.push('5'); + list.trimStart(1); + assert.equal(list.length, 4); + assert.deepEqual(list.get(0), '2'); + assert.deepEqual(list.get(1), '3'); + assert.deepEqual(list.get(2), '4'); + assert.deepEqual(list.get(3), '5'); + list.trimStart(2); + assert.equal(list.length, 2); + assert.deepEqual(list.get(0), '4'); + assert.deepEqual(list.get(1), '5'); + }); + + it('should remove all items if the requested trim amount is larger than the list\'s length', () => { + const list = new CircularList(5); + list.push('1'); + list.trimStart(2); + assert.equal(list.length, 0); + }); + }); + + describe('shiftElements', () => { + it('should not mutate the list when count is 0', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.shiftElements(0, 0, 1); + assert.equal(list.length, 2); + assert.equal(list.get(0), 1); + assert.equal(list.get(1), 2); + }); + + it('should throw for invalid args', () => { + const list = new CircularList(5); + list.push(1); + assert.throws(() => list.shiftElements(-1, 1, 1), 'start argument out of range'); + assert.throws(() => list.shiftElements(1, 1, 1), 'start argument out of range'); + assert.throws(() => list.shiftElements(0, 1, -1), 'Cannot shift elements in list beyond index 0'); + }); + + it('should shift an element forward', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.shiftElements(0, 1, 1); + assert.equal(list.length, 2); + assert.equal(list.get(0), 1); + assert.equal(list.get(1), 1); + }); + + it('should shift elements forward', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.push(3); + list.push(4); + list.shiftElements(0, 2, 2); + assert.equal(list.length, 4); + assert.equal(list.get(0), 1); + assert.equal(list.get(1), 2); + assert.equal(list.get(2), 1); + assert.equal(list.get(3), 2); + }); + + it('should shift elements forward, expanding the list if needed', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.shiftElements(0, 2, 2); + assert.equal(list.length, 4); + assert.equal(list.get(0), 1); + assert.equal(list.get(1), 2); + assert.equal(list.get(2), 1); + assert.equal(list.get(3), 2); + }); + + it('should shift elements forward, wrapping the list if needed', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.push(3); + list.push(4); + list.push(5); + list.shiftElements(2, 2, 3); + assert.equal(list.length, 5); + assert.equal(list.get(0), 3); + assert.equal(list.get(1), 4); + assert.equal(list.get(2), 5); + assert.equal(list.get(3), 3); + assert.equal(list.get(4), 4); + }); + + it('should shift an element backwards', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.shiftElements(1, 1, -1); + assert.equal(list.length, 2); + assert.equal(list.get(0), 2); + assert.equal(list.get(1), 2); + }); + + it('should shift elements backwards', () => { + const list = new CircularList(5); + list.push(1); + list.push(2); + list.push(3); + list.push(4); + list.shiftElements(2, 2, -2); + assert.equal(list.length, 4); + assert.equal(list.get(0), 3); + assert.equal(list.get(1), 4); + assert.equal(list.get(2), 3); + assert.equal(list.get(3), 4); + }); + }); +}); diff --git a/xterm.js/src/utils/CircularList.ts b/xterm.js/src/utils/CircularList.ts new file mode 100644 index 0000000..97a32b7 --- /dev/null +++ b/xterm.js/src/utils/CircularList.ts @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { EventEmitter } from '../EventEmitter'; +import { ICircularList } from '../Interfaces'; + +/** + * Represents a circular list; a list with a maximum size that wraps around when push is called, + * overriding values at the start of the list. + */ +export class CircularList extends EventEmitter implements ICircularList { + protected _array: T[]; + private _startIndex: number; + private _length: number; + + constructor( + private _maxLength: number + ) { + super(); + this._array = new Array(this._maxLength); + this._startIndex = 0; + this._length = 0; + } + + public get maxLength(): number { + return this._maxLength; + } + + public set maxLength(newMaxLength: number) { + // There was no change in maxLength, return early. + if (this._maxLength === newMaxLength) { + return; + } + + // Reconstruct array, starting at index 0. Only transfer values from the + // indexes 0 to length. + let newArray = new Array(newMaxLength); + for (let i = 0; i < Math.min(newMaxLength, this.length); i++) { + newArray[i] = this._array[this._getCyclicIndex(i)]; + } + this._array = newArray; + this._maxLength = newMaxLength; + this._startIndex = 0; + } + + public get length(): number { + return this._length; + } + + public set length(newLength: number) { + if (newLength > this._length) { + for (let i = this._length; i < newLength; i++) { + this._array[i] = undefined; + } + } + this._length = newLength; + } + + public get forEach(): (callbackfn: (value: T, index: number) => void) => void { + return (callbackfn: (value: T, index: number) => void) => { + let i = 0; + let length = this.length; + for (let i = 0; i < length; i++) { + callbackfn(this.get(i), i); + } + }; + } + + /** + * Gets the value at an index. + * + * Note that for performance reasons there is no bounds checking here, the index reference is + * circular so this should always return a value and never throw. + * @param index The index of the value to get. + * @return The value corresponding to the index. + */ + public get(index: number): T { + return this._array[this._getCyclicIndex(index)]; + } + + /** + * Sets the value at an index. + * + * Note that for performance reasons there is no bounds checking here, the index reference is + * circular so this should always return a value and never throw. + * @param index The index to set. + * @param value The value to set. + */ + public set(index: number, value: T): void { + this._array[this._getCyclicIndex(index)] = value; + } + + /** + * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0 + * if the maximum length is reached. + * @param value The value to push onto the list. + */ + public push(value: T): void { + this._array[this._getCyclicIndex(this._length)] = value; + if (this._length === this._maxLength) { + this._startIndex++; + if (this._startIndex === this._maxLength) { + this._startIndex = 0; + } + this.emit('trim', 1); + } else { + this._length++; + } + } + + /** + * Removes and returns the last value on the list. + * @return The popped value. + */ + public pop(): T { + return this._array[this._getCyclicIndex(this._length-- - 1)]; + } + + /** + * Deletes and/or inserts items at a particular index (in that order). Unlike + * Array.prototype.splice, this operation does not return the deleted items as a new array in + * order to save creating a new array. Note that this operation may shift all values in the list + * in the worst case. + * @param start The index to delete and/or insert. + * @param deleteCount The number of elements to delete. + * @param items The items to insert. + */ + public splice(start: number, deleteCount: number, ...items: T[]): void { + // Delete items + if (deleteCount) { + for (let i = start; i < this._length - deleteCount; i++) { + this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)]; + } + this._length -= deleteCount; + } + + if (items && items.length) { + // Add items + for (let i = this._length - 1; i >= start; i--) { + this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)]; + } + for (let i = 0; i < items.length; i++) { + this._array[this._getCyclicIndex(start + i)] = items[i]; + } + + // Adjust length as needed + if (this._length + items.length > this.maxLength) { + const countToTrim = (this._length + items.length) - this.maxLength; + this._startIndex += countToTrim; + this._length = this.maxLength; + this.emit('trim', countToTrim); + } else { + this._length += items.length; + } + } + } + + /** + * Trims a number of items from the start of the list. + * @param count The number of items to remove. + */ + public trimStart(count: number): void { + if (count > this._length) { + count = this._length; + } + this._startIndex += count; + this._length -= count; + this.emit('trim', count); + } + + public shiftElements(start: number, count: number, offset: number): void { + if (count <= 0) { + return; + } + if (start < 0 || start >= this._length) { + throw new Error('start argument out of range'); + } + if (start + offset < 0) { + throw new Error('Cannot shift elements in list beyond index 0'); + } + + if (offset > 0) { + for (let i = count - 1; i >= 0; i--) { + this.set(start + i + offset, this.get(start + i)); + } + const expandListBy = (start + count + offset) - this._length; + if (expandListBy > 0) { + this._length += expandListBy; + while (this._length > this.maxLength) { + this._length--; + this._startIndex++; + this.emit('trim', 1); + } + } + } else { + for (let i = 0; i < count; i++) { + this.set(start + i + offset, this.get(start + i)); + } + } + } + + /** + * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the + * backing array to get the element associated with the regular index. + * @param index The regular index. + * @returns The cyclic index. + */ + private _getCyclicIndex(index: number): number { + return (this._startIndex + index) % this.maxLength; + } +} diff --git a/xterm.js/src/utils/Generic.ts b/xterm.js/src/utils/Generic.ts new file mode 100644 index 0000000..8237361 --- /dev/null +++ b/xterm.js/src/utils/Generic.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2016 The xterm.js authors. All rights reserved. + * @license MIT + */ + +/** + * Return if the given array contains the given element + * @param {Array} array The array to search for the given element. + * @param {Object} el The element to look for into the array + */ +export function contains(arr: any[], el: any): boolean { + return arr.indexOf(el) >= 0; +}; diff --git a/xterm.js/src/utils/MouseHelper.test.ts b/xterm.js/src/utils/MouseHelper.test.ts new file mode 100644 index 0000000..ac3137f --- /dev/null +++ b/xterm.js/src/utils/MouseHelper.test.ts @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import jsdom = require('jsdom'); +import { assert } from 'chai'; +import { MouseHelper } from './MouseHelper'; +import { MockCharMeasure, MockRenderer } from './TestUtils.test'; + +const CHAR_WIDTH = 10; +const CHAR_HEIGHT = 20; + +describe('MouseHelper.getCoords', () => { + let dom: jsdom.JSDOM; + let window: Window; + let document: Document; + let mouseHelper: MouseHelper; + + let charMeasure: MockCharMeasure; + + beforeEach(() => { + dom = new jsdom.JSDOM(''); + window = dom.window; + document = window.document; + charMeasure = new MockCharMeasure(); + charMeasure.width = CHAR_WIDTH; + charMeasure.height = CHAR_HEIGHT; + const renderer = new MockRenderer(); + renderer.dimensions = { + actualCellWidth: CHAR_WIDTH, + actualCellHeight: CHAR_HEIGHT + }; + mouseHelper = new MouseHelper(renderer); + }); + + describe('when charMeasure is not initialized', () => { + it('should return null', () => { + charMeasure = new MockCharMeasure(); + assert.equal(mouseHelper.getCoords({ pageX: 0, pageY: 0 }, document.createElement('div'), charMeasure, 1, 10, 10), null); + }); + }); + + describe('when pageX/pageY are not supported', () => { + it('should return null', () => { + assert.equal(mouseHelper.getCoords({ pageX: undefined, pageY: undefined }, document.createElement('div'), charMeasure, 1, 10, 10), null); + }); + }); + + it('should return the cell that was clicked', () => { + let coords: [number, number]; + coords = mouseHelper.getCoords({ pageX: CHAR_WIDTH / 2, pageY: CHAR_HEIGHT / 2 }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [1, 1]); + coords = mouseHelper.getCoords({ pageX: CHAR_WIDTH, pageY: CHAR_HEIGHT }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [1, 1]); + coords = mouseHelper.getCoords({ pageX: CHAR_WIDTH, pageY: CHAR_HEIGHT + 1 }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [1, 2]); + coords = mouseHelper.getCoords({ pageX: CHAR_WIDTH + 1, pageY: CHAR_HEIGHT }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [2, 1]); + }); + + it('should ensure the coordinates are returned within the terminal bounds', () => { + let coords: [number, number]; + coords = mouseHelper.getCoords({ pageX: -1, pageY: -1 }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [1, 1]); + // Event are double the cols/rows + coords = mouseHelper.getCoords({ pageX: CHAR_WIDTH * 20, pageY: CHAR_HEIGHT * 20 }, document.createElement('div'), charMeasure, 1, 10, 10); + assert.deepEqual(coords, [10, 10], 'coordinates should never come back as larger than the terminal'); + }); +}); diff --git a/xterm.js/src/utils/MouseHelper.ts b/xterm.js/src/utils/MouseHelper.ts new file mode 100644 index 0000000..d7d8f69 --- /dev/null +++ b/xterm.js/src/utils/MouseHelper.ts @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ICharMeasure } from '../Interfaces'; +import { IRenderer } from '../renderer/Interfaces'; + +export class MouseHelper { + constructor(private _renderer: IRenderer) {} + + public static getCoordsRelativeToElement(event: {pageX: number, pageY: number}, element: HTMLElement): [number, number] { + // Ignore browsers that don't support MouseEvent.pageX + if (event.pageX == null) { + return null; + } + + const originalElement = element; + let x = event.pageX; + let y = event.pageY; + + // Converts the coordinates from being relative to the document to being + // relative to the terminal. + while (element) { + x -= element.offsetLeft; + y -= element.offsetTop; + element = 'offsetParent' in element ? element.offsetParent : element.parentElement; + } + element = originalElement; + while (element && element !== element.ownerDocument.body) { + x += element.scrollLeft; + y += element.scrollTop; + element = element.parentElement; + } + return [x, y]; + } + + /** + * Gets coordinates within the terminal for a particular mouse event. The result + * is returned as an array in the form [x, y] instead of an object as it's a + * little faster and this function is used in some low level code. + * @param event The mouse event. + * @param element The terminal's container element. + * @param charMeasure The char measure object used to determine character sizes. + * @param colCount The number of columns in the terminal. + * @param rowCount The number of rows n the terminal. + * @param isSelection Whether the request is for the selection or not. This will + * apply an offset to the x value such that the left half of the cell will + * select that cell and the right half will select the next cell. + */ + public getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number] { + // Coordinates cannot be measured if charMeasure has not been initialized + if (!charMeasure.width || !charMeasure.height) { + return null; + } + + const coords = MouseHelper.getCoordsRelativeToElement(event, element); + if (!coords) { + return null; + } + + coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth); + coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight); + + // Ensure coordinates are within the terminal viewport. Note that selections + // need an addition point of precision to cover the end point (as characters + // cover half of one char and half of the next). + coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0)); + coords[1] = Math.min(Math.max(coords[1], 1), rowCount); + + return coords; + } + + /** + * Gets coordinates within the terminal for a particular mouse event, wrapping + * them to the bounds of the terminal and adding 32 to both the x and y values + * as expected by xterm. + * @param event The mouse event. + * @param element The terminal's container element. + * @param charMeasure The char measure object used to determine character sizes. + * @param colCount The number of columns in the terminal. + * @param rowCount The number of rows in the terminal. + */ + public getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number } { + const coords = this.getCoords(event, element, charMeasure, lineHeight, colCount, rowCount); + let x = coords[0]; + let y = coords[1]; + + // xterm sends raw bytes and starts at 32 (SP) for each. + x += 32; + y += 32; + + return { x, y }; + } +} diff --git a/xterm.js/src/utils/ScreenDprMonitor.ts b/xterm.js/src/utils/ScreenDprMonitor.ts new file mode 100644 index 0000000..15f3ac0 --- /dev/null +++ b/xterm.js/src/utils/ScreenDprMonitor.ts @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export type ScreenDprListener = (newDevicePixelRatio?: number, oldDevicePixelRatio?: number) => void; + +/** + * The screen device pixel ratio monitor allows listening for when the + * window.devicePixelRatio value changes. This is done not with polling but with + * the use of window.matchMedia to watch media queries. When the event fires, + * the listener will be reattached using a different media query to ensure that + * any further changes will register. + * + * The listener should fire on both window zoom changes and switching to a + * monitor with a different DPI. + */ +export class ScreenDprMonitor { + private _currentDevicePixelRatio: number; + private _outerListener: MediaQueryListListener; + private _listener: ScreenDprListener; + private _resolutionMediaMatchList: MediaQueryList; + + public setListener(listener: ScreenDprListener): void { + if (this._listener) { + this.clearListener(); + } + this._listener = listener; + this._outerListener = () => { + this._listener(window.devicePixelRatio, this._currentDevicePixelRatio); + this._updateDpr(); + }; + this._updateDpr(); + } + + private _updateDpr(): void { + // Clear listeners for old DPR + if (this._resolutionMediaMatchList) { + this._resolutionMediaMatchList.removeListener(this._outerListener); + } + // Add listeners for new DPR + this._currentDevicePixelRatio = window.devicePixelRatio; + this._resolutionMediaMatchList = window.matchMedia(`screen and (resolution: ${window.devicePixelRatio}dppx)`); + this._resolutionMediaMatchList.addListener(this._outerListener); + } + + public clearListener(): void { + if (!this._listener) { + return; + } + this._resolutionMediaMatchList.removeListener(this._outerListener); + this._listener = null; + this._outerListener = null; + } +} diff --git a/xterm.js/src/utils/Sounds.ts b/xterm.js/src/utils/Sounds.ts new file mode 100644 index 0000000..03f36f4 --- /dev/null +++ b/xterm.js/src/utils/Sounds.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +// Source: https://freesound.org/people/altemark/sounds/45759/ +// This sound is released under the Creative Commons Attribution 3.0 Unported +// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been +// made, apart from the conversion to base64. +export const BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg=='; diff --git a/xterm.js/src/utils/TestUtils.test.ts b/xterm.js/src/utils/TestUtils.test.ts new file mode 100644 index 0000000..80e2527 --- /dev/null +++ b/xterm.js/src/utils/TestUtils.test.ts @@ -0,0 +1,278 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, IListenerType, IInputHandlingTerminal, IViewport, ICircularList, ICompositionHelper, ITheme, ILinkifier, IMouseHelper } from '../Interfaces'; +import { LineData } from '../Types'; +import { Buffer } from '../Buffer'; +import * as Browser from './Browser'; +import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Interfaces'; + +export class MockTerminal implements ITerminal { + bracketedPasteMode: boolean; + mouseHelper: IMouseHelper; + renderer: IRenderer; + linkifier: ILinkifier; + isFocused: boolean; + options: ITerminalOptions = {}; + element: HTMLElement; + rowContainer: HTMLElement; + selectionContainer: HTMLElement; + selectionManager: ISelectionManager; + charMeasure: ICharMeasure; + textarea: HTMLTextAreaElement; + rows: number; + cols: number; + browser: IBrowser = Browser; + writeBuffer: string[]; + children: HTMLElement[]; + cursorHidden: boolean; + cursorState: number; + defAttr: number; + scrollback: number; + buffers: IBufferSet; + buffer: IBuffer; + handler(data: string): void { + throw new Error('Method not implemented.'); + } + on(event: string, callback: () => void): void { + throw new Error('Method not implemented.'); + } + off(type: string, listener: IListenerType): void { + throw new Error('Method not implemented.'); + } + scrollLines(disp: number, suppressScrollEvent: boolean): void { + throw new Error('Method not implemented.'); + } + cancel(ev: Event, force?: boolean): void { + throw new Error('Method not implemented.'); + } + log(text: string): void { + throw new Error('Method not implemented.'); + } + emit(event: string, data: any): void { + throw new Error('Method not implemented.'); + } + reset(): void { + throw new Error('Method not implemented.'); + } + showCursor(): void { + throw new Error('Method not implemented.'); + } + refresh(start: number, end: number): void { + throw new Error('Method not implemented.'); + } + blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData { + const line: LineData = []; + cols = cols || this.cols; + for (let i = 0; i < cols; i++) { + line.push([0, ' ', 1, 32]); + } + return line; + } +} + +export class MockCharMeasure implements ICharMeasure { + width: number; + height: number; + measure(options: ITerminalOptions): void { + throw new Error('Method not implemented.'); + } +} + +export class MockInputHandlingTerminal implements IInputHandlingTerminal { + element: HTMLElement; + options: ITerminalOptions = {}; + cols: number; + rows: number; + charset: { [key: string]: string; }; + gcharset: number; + glevel: number; + charsets: { [key: string]: string; }[]; + applicationKeypad: boolean; + applicationCursor: boolean; + originMode: boolean; + insertMode: boolean; + wraparoundMode: boolean; + bracketedPasteMode: boolean; + defAttr: number; + curAttr: number; + prefix: string; + savedCols: number; + x10Mouse: boolean; + vt200Mouse: boolean; + normalMouse: boolean; + mouseEvents: boolean; + sendFocus: boolean; + utfMouse: boolean; + sgrMouse: boolean; + urxvtMouse: boolean; + cursorHidden: boolean; + buffers: IBufferSet; + buffer: IBuffer = new MockBuffer(); + viewport: IViewport; + selectionManager: ISelectionManager; + focus(): void { + throw new Error('Method not implemented.'); + } + convertEol: boolean; + bell(): void { + throw new Error('Method not implemented.'); + } + + updateRange(y: number): void { + throw new Error('Method not implemented.'); + } + scroll(isWrapped?: boolean): void { + throw new Error('Method not implemented.'); + } + nextStop(x?: number): number { + throw new Error('Method not implemented.'); + } + setgLevel(g: number): void { + throw new Error('Method not implemented.'); + } + eraseAttr(): number { + throw new Error('Method not implemented.'); + } + eraseRight(x: number, y: number): void { + throw new Error('Method not implemented.'); + } + eraseLine(y: number): void { + throw new Error('Method not implemented.'); + } + eraseLeft(x: number, y: number): void { + throw new Error('Method not implemented.'); + } + blankLine(cur?: boolean, isWrapped?: boolean): [number, string, number, number][] { + throw new Error('Method not implemented.'); + } + prevStop(x?: number): number { + throw new Error('Method not implemented.'); + } + is(term: string): boolean { + throw new Error('Method not implemented.'); + } + send(data: string): void { + throw new Error('Method not implemented.'); + } + setgCharset(g: number, charset: { [key: string]: string; }): void { + throw new Error('Method not implemented.'); + } + resize(x: number, y: number): void { + throw new Error('Method not implemented.'); + } + log(text: string, data?: any): void { + throw new Error('Method not implemented.'); + } + reset(): void { + throw new Error('Method not implemented.'); + } + showCursor(): void { + throw new Error('Method not implemented.'); + } + refresh(start: number, end: number): void { + throw new Error('Method not implemented.'); + } + matchColor(r1: number, g1: number, b1: number): number { + throw new Error('Method not implemented.'); + } + error(text: string, data?: any): void { + throw new Error('Method not implemented.'); + } + setOption(key: string, value: any): void { + this.options[key] = value; + } + on(type: string, listener: IListenerType): void { + throw new Error('Method not implemented.'); + } + off(type: string, listener: IListenerType): void { + throw new Error('Method not implemented.'); + } + emit(type: string, data?: any): void { + throw new Error('Method not implemented.'); + } +} + +export class MockBuffer implements IBuffer { + isCursorInViewport: boolean; + lines: ICircularList<[number, string, number, number][]>; + ydisp: number; + ybase: number; + y: number; + x: number; + tabs: any; + scrollBottom: number; + scrollTop: number; + savedY: number; + savedX: number; + translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string { + return Buffer.prototype.translateBufferLineToString.apply(this, arguments); + } + nextStop(x?: number): number { + throw new Error('Method not implemented.'); + } + prevStop(x?: number): number { + throw new Error('Method not implemented.'); + } +} + +export class MockRenderer implements IRenderer { + colorManager: IColorManager; + on(type: string, listener: IListenerType): void { + throw new Error('Method not implemented.'); + } + off(type: string, listener: IListenerType): void { + throw new Error('Method not implemented.'); + } + emit(type: string, data?: any): void { + throw new Error('Method not implemented.'); + } + dimensions: IRenderDimensions; + setTheme(theme: ITheme): IColorSet { return {}; } + onResize(cols: number, rows: number, didCharSizeChange: boolean): void {} + onCharSizeChanged(): void {} + onBlur(): void {} + onFocus(): void {} + onSelectionChanged(start: [number, number], end: [number, number]): void {} + onCursorMove(): void {} + onOptionsChanged(): void {} + onWindowResize(devicePixelRatio: number): void {} + clear(): void {} + queueRefresh(start: number, end: number): void {} +} + +export class MockViewport implements IViewport { + onThemeChanged(colors: IColorSet): void { + throw new Error('Method not implemented.'); + } + onWheel(ev: WheelEvent): void { + throw new Error('Method not implemented.'); + } + onTouchStart(ev: TouchEvent): void { + throw new Error('Method not implemented.'); + } + onTouchMove(ev: TouchEvent): void { + throw new Error('Method not implemented.'); + } + syncScrollArea(): void { } +} + +export class MockCompositionHelper implements ICompositionHelper { + compositionstart(): void { + throw new Error('Method not implemented.'); + } + compositionupdate(ev: CompositionEvent): void { + throw new Error('Method not implemented.'); + } + compositionend(): void { + throw new Error('Method not implemented.'); + } + updateCompositionElements(dontRecurse?: boolean): void { + throw new Error('Method not implemented.'); + } + keydown(ev: KeyboardEvent): boolean { + return true; + } +} diff --git a/xterm.js/src/xterm.css b/xterm.js/src/xterm.css new file mode 100644 index 0000000..b3ee50f --- /dev/null +++ b/xterm.js/src/xterm.css @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2014 The xterm.js authors. All rights reserved. + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/term.js + * @license MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + */ + +/** + * Default styles for xterm.js + */ + +.xterm { + font-family: courier-new, courier, monospace; + font-feature-settings: "liga" 0; + position: relative; + user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.xterm.focus, +.xterm:focus { + outline: none; +} + +.xterm .xterm-helpers { + position: absolute; + top: 0; + /** + * The z-index of the helpers must be higher than the canvases in order for + * IMEs to appear on top. + */ + z-index: 10; +} + +.xterm .xterm-helper-textarea { + /* + * HACK: to fix IE's blinking cursor + * Move textarea out of the screen to the far left, so that the cursor is not visible. + */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -10; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.xterm .composition-view { + /* TODO: Composition position got messed up somewhere */ + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.xterm .composition-view.active { + display: block; +} + +.xterm .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; + cursor: default; +} + +.xterm canvas { + position: absolute; + left: 0; + top: 0; +} + +.xterm .xterm-scroll-area { + visibility: hidden; +} + +.xterm .xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + left: -9999em; +} + +.xterm.enable-mouse-events { + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ + cursor: default; +} + +.xterm:not(.enable-mouse-events) { + cursor: text; +} diff --git a/xterm.js/src/xterm.ts b/xterm.js/src/xterm.ts new file mode 100644 index 0000000..6df3a4c --- /dev/null +++ b/xterm.js/src/xterm.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + * + * This file is the entry point for browserify. + */ + +import { Terminal } from './Terminal'; + +module.exports = Terminal; diff --git a/xterm.js/tsconfig.json b/xterm.js/tsconfig.json new file mode 100644 index 0000000..38bfd2f --- /dev/null +++ b/xterm.js/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "rootDir": "src", + "outDir": "lib", + "sourceMap": true, + "removeComments": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "src/addons/**/*" + ] +} diff --git a/xterm.js/tslint.json b/xterm.js/tslint.json new file mode 100644 index 0000000..4d4d4aa --- /dev/null +++ b/xterm.js/tslint.json @@ -0,0 +1,62 @@ +{ + "rules": { + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "indent": [ + true, + "spaces" + ], + "typedef": [ + true, + "call-signature", + "parameter" + ], + "eofline": true, + "no-eval": true, + "no-internal-module": true, + "no-trailing-whitespace": true, + "one-variable-per-declaration": [ + true, + true + ], + "no-unsafe-finally": true, + "no-var-keyword": true, + "quotemark": [ + true, + "single" + ], + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": [ + true, + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} diff --git a/xterm.js/webpack.config.js b/xterm.js/webpack.config.js new file mode 100644 index 0000000..0c39626 --- /dev/null +++ b/xterm.js/webpack.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + entry: './demo/main.js', + output: { + path: path.resolve(__dirname, 'demo/dist'), + filename: 'bundle.js' + }, + devtool: 'source-map' +};