UNPKG

vibetunnel

Version:

Terminal sharing server with web interface - supports macOS, Linux, and headless environments

162 lines 19.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createTmuxRoutes = createTmuxRoutes; const express_1 = require("express"); const tmux_manager_js_1 = require("../services/tmux-manager.js"); const logger_js_1 = require("../utils/logger.js"); const logger = (0, logger_js_1.createLogger)('tmux-routes'); function createTmuxRoutes(options) { const { ptyManager } = options; const router = (0, express_1.Router)(); const tmuxManager = tmux_manager_js_1.TmuxManager.getInstance(ptyManager); /** * Check if tmux is available */ router.get('/available', async (_req, res) => { try { const available = await tmuxManager.isAvailable(); res.json({ available }); } catch (error) { logger.error('Failed to check tmux availability', { error }); res.status(500).json({ error: 'Failed to check tmux availability' }); } }); /** * List all tmux sessions */ router.get('/sessions', async (_req, res) => { try { const sessions = await tmuxManager.listSessions(); res.json({ sessions }); } catch (error) { logger.error('Failed to list tmux sessions', { error }); res.status(500).json({ error: 'Failed to list tmux sessions' }); } }); /** * List windows in a tmux session */ router.get('/sessions/:sessionName/windows', async (req, res) => { try { const { sessionName } = req.params; const windows = await tmuxManager.listWindows(sessionName); res.json({ windows }); } catch (error) { logger.error('Failed to list tmux windows', { error }); res.status(500).json({ error: 'Failed to list tmux windows' }); } }); /** * List panes in a tmux session or window */ router.get('/sessions/:sessionName/panes', async (req, res) => { try { const { sessionName } = req.params; const windowIndex = req.query.window ? Number.parseInt(req.query.window, 10) : undefined; const panes = await tmuxManager.listPanes(sessionName, windowIndex); res.json({ panes }); } catch (error) { logger.error('Failed to list tmux panes', { error }); res.status(500).json({ error: 'Failed to list tmux panes' }); } }); /** * Create a new tmux session */ router.post('/sessions', async (req, res) => { try { const { name, command } = req.body; if (!name) { return res.status(400).json({ error: 'Session name is required' }); } await tmuxManager.createSession(name, command); res.json({ success: true, name }); } catch (error) { logger.error('Failed to create tmux session', { error }); res.status(500).json({ error: 'Failed to create tmux session' }); } }); /** * Attach to a tmux session/window/pane */ router.post('/attach', async (req, res) => { try { const { sessionName, windowIndex, paneIndex, cols, rows, workingDir, titleMode } = req.body; if (!sessionName) { return res.status(400).json({ error: 'Session name is required' }); } const options = { cols, rows, workingDir, titleMode, }; const sessionId = await tmuxManager.attachToTmux(sessionName, windowIndex, paneIndex, options); res.json({ success: true, sessionId, target: { session: sessionName, window: windowIndex, pane: paneIndex, }, }); } catch (error) { logger.error('Failed to attach to tmux session', { error }); res.status(500).json({ error: 'Failed to attach to tmux session' }); } }); /** * Send command to a tmux pane */ router.post('/sessions/:sessionName/send', async (req, res) => { try { const { sessionName } = req.params; const { command, windowIndex, paneIndex } = req.body; if (!command) { return res.status(400).json({ error: 'Command is required' }); } await tmuxManager.sendToPane(sessionName, command, windowIndex, paneIndex); res.json({ success: true }); } catch (error) { logger.error('Failed to send command to tmux pane', { error }); res.status(500).json({ error: 'Failed to send command to tmux pane' }); } }); /** * Kill a tmux session */ router.delete('/sessions/:sessionName', async (req, res) => { try { const { sessionName } = req.params; await tmuxManager.killSession(sessionName); res.json({ success: true }); } catch (error) { logger.error('Failed to kill tmux session', { error }); res.status(500).json({ error: 'Failed to kill tmux session' }); } }); /** * Get current tmux context (if inside tmux) */ router.get('/context', (_req, res) => { const insideTmux = tmuxManager.isInsideTmux(); const currentSession = tmuxManager.getCurrentSession(); res.json({ insideTmux, currentSession, }); }); return router; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG11eC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2ZXIvcm91dGVzL3RtdXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFRQSw0Q0F1S0M7QUEvS0QscUNBQWlDO0FBR2pDLGlFQUEwRDtBQUMxRCxrREFBa0Q7QUFFbEQsTUFBTSxNQUFNLEdBQUcsSUFBQSx3QkFBWSxFQUFDLGFBQWEsQ0FBQyxDQUFDO0FBRTNDLFNBQWdCLGdCQUFnQixDQUFDLE9BQW1DO0lBQ2xFLE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDL0IsTUFBTSxNQUFNLEdBQUcsSUFBQSxnQkFBTSxHQUFFLENBQUM7SUFDeEIsTUFBTSxXQUFXLEdBQUcsNkJBQVcsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFeEQ7O09BRUc7SUFDSCxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQzNDLElBQUksQ0FBQztZQUNILE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2xELEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsbUNBQW1DLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVIOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUMxQyxJQUFJ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LEVBQUUsS0FBSyxFQUFFLHFDQUFxQyxFQUFFLENBQUMsQ0FBQztRQUN6RSxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSDs7T0FFRztJQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN6RCxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUNuQyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDM0MsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDdkQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsNkJBQTZCLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVIOztPQUVHO0lBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7UUFDbkMsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzlDLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRXZELEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxVQUFVO1lBQ1YsY0FBYztTQUNmLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJvdXRlciB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHR5cGUgeyBTZXNzaW9uQ3JlYXRlT3B0aW9ucyB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFB0eU1hbmFnZXIgfSBmcm9tICcuLi9wdHkvcHR5LW1hbmFnZXIuanMnO1xuaW1wb3J0IHsgVG11eE1hbmFnZXIgfSBmcm9tICcuLi9zZXJ2aWNlcy90bXV4LW1hbmFnZXIuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0bXV4LXJvdXRlcycpO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVG11eFJvdXRlcyhvcHRpb25zOiB7IHB0eU1hbmFnZXI6IFB0eU1hbmFnZXIgfSk6IFJvdXRlciB7XG4gIGNvbnN0IHsgcHR5TWFuYWdlciB9ID0gb3B0aW9ucztcbiAgY29uc3Qgcm91dGVyID0gUm91dGVyKCk7XG4gIGNvbnN0IHRtdXhNYW5hZ2VyID0gVG11eE1hbmFnZXIuZ2V0SW5zdGFuY2UocHR5TWFuYWdlcik7XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRtdXggaXMgYXZhaWxhYmxlXG4gICAqL1xuICByb3V0ZXIuZ2V0KCcvYXZhaWxhYmxlJywgYXN5bmMgKF9yZXEsIHJlcykgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhdmFpbGFibGUgPSBhd2FpdCB0bXV4TWFuYWdlci5pc0F2YWlsYWJsZSgpO1xuICAgICAgcmVzLmpzb24oeyBhdmFpbGFibGUgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIGNoZWNrIHRtdXggYXZhaWxhYmlsaXR5JywgeyBlcnJvciB9KTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6ICdGYWlsZWQgdG8gY2hlY2sgdG11eCBhdmFpbGFiaWxpdHknIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIExpc3QgYWxsIHRtdXggc2Vzc2lvbnNcbiAgICovXG4gIHJvdXRlci5nZXQoJy9zZXNzaW9ucycsIGFzeW5jIChfcmVxLCByZXMpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCB0bXV4TWFuYWdlci5saXN0U2Vzc2lvbnMoKTtcbiAgICAgIHJlcy5qc29uKHsgc2Vzc2lvbnMgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIGxpc3QgdG11eCBzZXNzaW9ucycsIHsgZXJyb3IgfSk7XG4gICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7IGVycm9yOiAnRmFpbGVkIHRvIGxpc3QgdG11eCBzZXNzaW9ucycgfSk7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogTGlzdCB3aW5kb3dzIGluIGEgdG11eCBzZXNzaW9uXG4gICAqL1xuICByb3V0ZXIuZ2V0KCcvc2Vzc2lvbnMvOnNlc3Npb25OYW1lL3dpbmRvd3MnLCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBzZXNzaW9uTmFtZSB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHdpbmRvd3MgPSBhd2FpdCB0bXV4TWFuYWdlci5saXN0V2luZG93cyhzZXNzaW9uTmFtZSk7XG4gICAgICByZXMuanNvbih7IHdpbmRvd3MgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIGxpc3QgdG11eCB3aW5kb3dzJywgeyBlcnJvciB9KTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6ICdGYWlsZWQgdG8gbGlzdCB0bXV4IHdpbmRvd3MnIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIExpc3QgcGFuZXMgaW4gYSB0bXV4IHNlc3Npb24gb3Igd2luZG93XG4gICAqL1xuICByb3V0ZXIuZ2V0KCcvc2Vzc2lvbnMvOnNlc3Npb25OYW1lL3BhbmVzJywgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgc2Vzc2lvbk5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB3aW5kb3dJbmRleCA9IHJlcS5xdWVyeS53aW5kb3dcbiAgICAgICAgPyBOdW1iZXIucGFyc2VJbnQocmVxLnF1ZXJ5LndpbmRvdyBhcyBzdHJpbmcsIDEwKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHBhbmVzID0gYXdhaXQgdG11eE1hbmFnZXIubGlzdFBhbmVzKHNlc3Npb25OYW1lLCB3aW5kb3dJbmRleCk7XG4gICAgICByZXMuanNvbih7IHBhbmVzIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ZhaWxlZCB0byBsaXN0IHRtdXggcGFuZXMnLCB7IGVycm9yIH0pO1xuICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oeyBlcnJvcjogJ0ZhaWxlZCB0byBsaXN0IHRtdXggcGFuZXMnIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyB0bXV4IHNlc3Npb25cbiAgICovXG4gIHJvdXRlci5wb3N0KCcvc2Vzc2lvbnMnLCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBuYW1lLCBjb21tYW5kIH0gPSByZXEuYm9keTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oeyBlcnJvcjogJ1Nlc3Npb24gbmFtZSBpcyByZXF1aXJlZCcgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0bXV4TWFuYWdlci5jcmVhdGVTZXNzaW9uKG5hbWUsIGNvbW1hbmQpO1xuICAgICAgcmVzLmpzb24oeyBzdWNjZXNzOiB0cnVlLCBuYW1lIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ZhaWxlZCB0byBjcmVhdGUgdG11eCBzZXNzaW9uJywgeyBlcnJvciB9KTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6ICdGYWlsZWQgdG8gY3JlYXRlIHRtdXggc2Vzc2lvbicgfSk7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogQXR0YWNoIHRvIGEgdG11eCBzZXNzaW9uL3dpbmRvdy9wYW5lXG4gICAqL1xuICByb3V0ZXIucG9zdCgnL2F0dGFjaCcsIGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IHNlc3Npb25OYW1lLCB3aW5kb3dJbmRleCwgcGFuZUluZGV4LCBjb2xzLCByb3dzLCB3b3JraW5nRGlyLCB0aXRsZU1vZGUgfSA9IHJlcS5ib2R5O1xuXG4gICAgICBpZiAoIXNlc3Npb25OYW1lKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7IGVycm9yOiAnU2Vzc2lvbiBuYW1lIGlzIHJlcXVpcmVkJyB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3B0aW9uczogUGFydGlhbDxTZXNzaW9uQ3JlYXRlT3B0aW9ucz4gPSB7XG4gICAgICAgIGNvbHMsXG4gICAgICAgIHJvd3MsXG4gICAgICAgIHdvcmtpbmdEaXIsXG4gICAgICAgIHRpdGxlTW9kZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNlc3Npb25JZCA9IGF3YWl0IHRtdXhNYW5hZ2VyLmF0dGFjaFRvVG11eChcbiAgICAgICAgc2Vzc2lvbk5hbWUsXG4gICAgICAgIHdpbmRvd0luZGV4LFxuICAgICAgICBwYW5lSW5kZXgsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgICk7XG5cbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICB0YXJnZXQ6IHtcbiAgICAgICAgICBzZXNzaW9uOiBzZXNzaW9uTmFtZSxcbiAgICAgICAgICB3aW5kb3c6IHdpbmRvd0luZGV4LFxuICAgICAgICAgIHBhbmU6IHBhbmVJbmRleCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ZhaWxlZCB0byBhdHRhY2ggdG8gdG11eCBzZXNzaW9uJywgeyBlcnJvciB9KTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6ICdGYWlsZWQgdG8gYXR0YWNoIHRvIHRtdXggc2Vzc2lvbicgfSk7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogU2VuZCBjb21tYW5kIHRvIGEgdG11eCBwYW5lXG4gICAqL1xuICByb3V0ZXIucG9zdCgnL3Nlc3Npb25zLzpzZXNzaW9uTmFtZS9zZW5kJywgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgc2Vzc2lvbk5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB7IGNvbW1hbmQsIHdpbmRvd0luZGV4LCBwYW5lSW5kZXggfSA9IHJlcS5ib2R5O1xuXG4gICAgICBpZiAoIWNvbW1hbmQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHsgZXJyb3I6ICdDb21tYW5kIGlzIHJlcXVpcmVkJyB9KTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdG11eE1hbmFnZXIuc2VuZFRvUGFuZShzZXNzaW9uTmFtZSwgY29tbWFuZCwgd2luZG93SW5kZXgsIHBhbmVJbmRleCk7XG4gICAgICByZXMuanNvbih7IHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIHNlbmQgY29tbWFuZCB0byB0bXV4IHBhbmUnLCB7IGVycm9yIH0pO1xuICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oeyBlcnJvcjogJ0ZhaWxlZCB0byBzZW5kIGNvbW1hbmQgdG8gdG11eCBwYW5lJyB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBLaWxsIGEgdG11eCBzZXNzaW9uXG4gICAqL1xuICByb3V0ZXIuZGVsZXRlKCcvc2Vzc2lvbnMvOnNlc3Npb25OYW1lJywgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgc2Vzc2lvbk5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBhd2FpdCB0bXV4TWFuYWdlci5raWxsU2Vzc2lvbihzZXNzaW9uTmFtZSk7XG4gICAgICByZXMuanNvbih7IHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIGtpbGwgdG11eCBzZXNzaW9uJywgeyBlcnJvciB9KTtcbiAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6ICdGYWlsZWQgdG8ga2lsbCB0bXV4IHNlc3Npb24nIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHRtdXggY29udGV4dCAoaWYgaW5zaWRlIHRtdXgpXG4gICAqL1xuICByb3V0ZXIuZ2V0KCcvY29udGV4dCcsIChfcmVxLCByZXMpID0+IHtcbiAgICBjb25zdCBpbnNpZGVUbXV4ID0gdG11eE1hbmFnZXIuaXNJbnNpZGVUbXV4KCk7XG4gICAgY29uc3QgY3VycmVudFNlc3Npb24gPSB0bXV4TWFuYWdlci5nZXRDdXJyZW50U2Vzc2lvbigpO1xuXG4gICAgcmVzLmpzb24oe1xuICAgICAgaW5zaWRlVG11eCxcbiAgICAgIGN1cnJlbnRTZXNzaW9uLFxuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gcm91dGVyO1xufVxuIl19