// Path: src/main/java/com/redcanari/js/wrappers/TextEditorWrapper.java
// public class TextEditorWrapper implements ITextEditor {
// 
//     final ITextEditor textEditor;
//     byte[] text = null;
// 
//     public TextEditorWrapper(ITextEditor textEditor) {
//         this.textEditor = textEditor;
//         textEditor.getComponent().addHierarchyListener(e -> {
//             text = textEditor.getText();
//         });
//     }
// 
//     @Override
//     public Component getComponent() {
//         return textEditor.getComponent();
//     }
// 
//     @Override
//     public void setEditable(boolean b) {
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setEditable(b));
//         else
//             textEditor.setEditable(b);
//     }
// 
//     @Override
//     public void setText(byte[] bytes) {
//         text = bytes;
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setText(bytes));
//         else
//             textEditor.setText(bytes);
//     }
// 
//     @Override
//     public byte[] getText() {
//         if (Platform.isFxApplicationThread())
//             return text;
//         return textEditor.getText();
//     }
// 
//     @Override
//     public boolean isTextModified() {
//         return textEditor.isTextModified();
//     }
// 
//     @Override
//     public byte[] getSelectedText() {
//         return textEditor.getSelectedText();
//     }
// 
//     @Override
//     public int[] getSelectionBounds() {
//         return textEditor.getSelectionBounds();
//     }
// 
//     @Override
//     public void setSearchExpression(String s) {
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setSearchExpression(s));
//         else
//             textEditor.setSearchExpression(s);
//     }
// }
// 
// Path: src/main/java/com/redcanari/swing/SwingFXUtilities.java
// public class SwingFXUtilities {
// 
//     public static <T> void invokeLater(Callable<T> callable, JSObject callback) {
//         SwingUtilities.invokeLater(() -> {
//             try {
//                 final T result = callable.call();
//                 if (callback != null) {
//                     Platform.runLater(() -> callback.call("call", null, result));
//                 }
//             } catch (Exception e) {
//                 e.printStackTrace();
//             }
//         });
//     }
// 
//     public static <T> T invokeAndWait(Callable<T> callable) throws TimeoutException, ExecutionException, InterruptedException {
//         //blocks until future returns
//         FutureTask<T> task = new FutureTask<>(callable);
//         SwingUtilities.invokeLater(task);
//         return task.get();
//     }
// 
// 
// 
// }


import burp.*;
import com.redcanari.js.proxies.*;
import com.redcanari.js.wrappers.TextEditorWrapper;
import com.redcanari.swing.SwingFXUtilities;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.CookieHandler;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;


    /**
     * This method is used to customize UI components in line with Burp's UI style, including font size, colors, table
     * line spacing, etc. The action is performed recursively on any child components of the passed-in component.
     *
     * @param component The UI component to be customized.
     */
    public void customizeUiComponent(Component component) {
        SwingUtilities.invokeLater(() -> burpExtenderCallbacks.customizeUiComponent(component));
    }


    /**
     * This method is used to create a new instance of Burp's HTTP message editor, for the extension to use in its own
     * UI.
     *
     * @param controller An object created by the extension that implements the {@link burp.IMessageEditorController}
     *                   interface. This parameter is optional and may be {@code null}. If it is provided, then the
     *                   message editor will query the controller when required to obtain details about the currently
     *                   displayed message, including the {@link burp.IHttpService} for the message, and the associated
     *                   request or response message. If a controller is not provided, then the message editor will not
     *                   support context menu actions, such as sending requests to other Burp tools.
     * @param editable   Indicates whether the editor created should be editable, or used only for message viewing.
     * @param callback   A JavaScript callback function that will be called once the {@link burp.IMessageEditor}
     *                   instance is created. The instance of {@link burp.IMessageEditor} will be passed to the callback
     *                   function as the first parameter.
     */
    public void createMessageEditor(Object controller, boolean editable, JSObject callback) {
        final IMessageEditorController c = Helpers.<IMessageEditorController>wrapInterface(controller, MessageEditorControllerJSProxy.class);
// Path: src/main/java/com/redcanari/js/wrappers/TextEditorWrapper.java
// public class TextEditorWrapper implements ITextEditor {
// 
//     final ITextEditor textEditor;
//     byte[] text = null;
// 
//     public TextEditorWrapper(ITextEditor textEditor) {
//         this.textEditor = textEditor;
//         textEditor.getComponent().addHierarchyListener(e -> {
//             text = textEditor.getText();
//         });
//     }
// 
//     @Override
//     public Component getComponent() {
//         return textEditor.getComponent();
//     }
// 
//     @Override
//     public void setEditable(boolean b) {
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setEditable(b));
//         else
//             textEditor.setEditable(b);
//     }
// 
//     @Override
//     public void setText(byte[] bytes) {
//         text = bytes;
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setText(bytes));
//         else
//             textEditor.setText(bytes);
//     }
// 
//     @Override
//     public byte[] getText() {
//         if (Platform.isFxApplicationThread())
//             return text;
//         return textEditor.getText();
//     }
// 
//     @Override
//     public boolean isTextModified() {
//         return textEditor.isTextModified();
//     }
// 
//     @Override
//     public byte[] getSelectedText() {
//         return textEditor.getSelectedText();
//     }
// 
//     @Override
//     public int[] getSelectionBounds() {
//         return textEditor.getSelectionBounds();
//     }
// 
//     @Override
//     public void setSearchExpression(String s) {
//         if (Platform.isFxApplicationThread())
//             SwingUtilities.invokeLater(() -> textEditor.setSearchExpression(s));
//         else
//             textEditor.setSearchExpression(s);
//     }
// }
// 
// Path: src/main/java/com/redcanari/swing/SwingFXUtilities.java
// public class SwingFXUtilities {
// 
//     public static <T> void invokeLater(Callable<T> callable, JSObject callback) {
//         SwingUtilities.invokeLater(() -> {
//             try {
//                 final T result = callable.call();
//                 if (callback != null) {
//                     Platform.runLater(() -> callback.call("call", null, result));
//                 }
//             } catch (Exception e) {
//                 e.printStackTrace();
//             }
//         });
//     }
// 
//     public static <T> T invokeAndWait(Callable<T> callable) throws TimeoutException, ExecutionException, InterruptedException {
//         //blocks until future returns
//         FutureTask<T> task = new FutureTask<>(callable);
//         SwingUtilities.invokeLater(task);
//         return task.get();
//     }
// 
// 
// 
// }


// Path: src/main/java/com/redcanari/js/BurpExtenderCallbacksBridge.java
import burp.*;
import com.redcanari.js.proxies.*;
import com.redcanari.js.wrappers.TextEditorWrapper;
import com.redcanari.swing.SwingFXUtilities;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.CookieHandler;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;



    /**
     * This method is used to customize UI components in line with Burp's UI style, including font size, colors, table
     * line spacing, etc. The action is performed recursively on any child components of the passed-in component.
     *
     * @param component The UI component to be customized.
     */
    public void customizeUiComponent(Component component) {
        SwingUtilities.invokeLater(() -> burpExtenderCallbacks.customizeUiComponent(component));
    }


    /**
     * This method is used to create a new instance of Burp's HTTP message editor, for the extension to use in its own
     * UI.
     *
     * @param controller An object created by the extension that implements the {@link burp.IMessageEditorController}
     *                   interface. This parameter is optional and may be {@code null}. If it is provided, then the
     *                   message editor will query the controller when required to obtain details about the currently
     *                   displayed message, including the {@link burp.IHttpService} for the message, and the associated
     *                   request or response message. If a controller is not provided, then the message editor will not
     *                   support context menu actions, such as sending requests to other Burp tools.
     * @param editable   Indicates whether the editor created should be editable, or used only for message viewing.
     * @param callback   A JavaScript callback function that will be called once the {@link burp.IMessageEditor}
     *                   instance is created. The instance of {@link burp.IMessageEditor} will be passed to the callback
     *                   function as the first parameter.
     */
    public void createMessageEditor(Object controller, boolean editable, JSObject callback) {
        final IMessageEditorController c = Helpers.<IMessageEditorController>wrapInterface(controller, MessageEditorControllerJSProxy.class);
        SwingFXUtilities.invokeLater(