// Path: api/java-api/src/main/java/com/aggregate/api/Pattern.java
// public class Pattern {
//     public static final String TEXT = "Text";
//     public static final String NUMBER = "Number";
//     public static final String DATE = "Date";
//     public static final String TIME = "Time";
// }
// 
// Path: api/java-api/src/main/java/com/aggregate/api/Request.java
// public class Request {
//     /**
//      * Markup of input speech
//      * @see Markup
//      */
//     public final Markup markup;
// 
//     public Request(Markup markup) {
//         this.markup = markup;
//     }
// 
//     /**
//      * Converts this instance to Json object
//      * @return JsonObject instance
//      */
//     public JsonObject toJson() {
//         JsonObject json = new JsonObject();
//         if (markup != null) {
//             json.put("markup", markup.toJson());
//         }
//         return json;
//     }
// 
// 
//     /**
//      * Converts Json object to Request instance
//      * @param json JsonObject
//      * @return Request instance
//      */
//     public static Request fromJson(JsonObject json) {
//         return new Request(Markup.fromJson(json.getJsonObject("markup")));
//     }
// 
//     /**
//      * Converts Vertx's event message to Request instance
//      * @param msg - Vertx's event message
//      * @return Request instance
//      * @see Message
//      */
//     public static Request fromMessage(Message msg) {
//         Object body = msg.body();
//         if (body instanceof JsonObject) {
//             return fromJson((JsonObject) body);
//         }
//         return null;
//     }
// }
// 
// Path: api/java-api/src/main/java/com/aggregate/api/Response.java
// public class Response extends JsonObject {
//     /**
//      * List of output speech strings (could be empty)
//      */
//     public final List<String> speeches;
// 
//     /**
//      * Dialog's context (optional)
//      */
//     public final String context;
// 
//     /**
//      * If switching context is modal or not
//      */
//     public final boolean modal;
// 
//     public Response(String speech) {
//         this(singletonList(speech));
//     }
// 
//     public Response(List<String> speeches) {
//         this(speeches, null, false);
//     }
// 
//     public Response(String speech, String context, boolean modal) {
//         this(singletonList(speech), context, modal);
//     }
// 
//     public Response(String context, boolean modal) {
//         this(emptyList(), context, modal);
//     }
// 
//     public Response(List<String> speeches, String context, boolean modal) {
//         this.speeches = unmodifiableList(speeches);
//         this.context = context;
//         this.modal = modal;
//         JsonArray array = new JsonArray();
//         speeches.forEach(s -> {
//             if (s != null && !s.isEmpty()) array.add(s);
//         });
//         put("context", context);
//         put("modal", modal);
//         put("speeches", array);
//     }
// 
// 
//     /**
//      * Converts Json object to Response instance
//      * @param json JsonObject
//      * @return Response instance
//      */
//     public static Response fromJson(JsonObject json) {
//         JsonArray array = json.getJsonArray("speeches", new JsonArray());
//         List<String> speeches = new ArrayList<>(array.size());
//         array.forEach(s -> speeches.add(s.toString()));
//         if (speeches.isEmpty()) {
//             String speech = json.getString("speech");
//             if (speech != null) speeches.add(speech);
//         }
//         String context = json.getString("context", json.getString("module"));
//         Boolean modal = json.getBoolean("modal", false);
//         return new Response(speeches, context, modal);
//     }
// }


import com.aggregate.api.Pattern;
import com.aggregate.api.Request;
import com.aggregate.api.Response;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
            if (m.body().toString().matches("(.*)key-detector")){
                vertx.eventBus().send("key.addKeyAction", config);
            }
        });
    }

    private void type(Request request) {
        String text = request.markup.get(Pattern.TEXT).source;
        if (!text.isEmpty()) {
            type(text);
        }
    }

    private void type(String text) {
        try {
            Robot robot = new Robot();
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            StringSelection stringSelection = new StringSelection(text);
            clipboard.setContents(stringSelection, stringSelection);

            int ctrl = osName.contains("mac") ? KeyEvent.VK_META : KeyEvent.VK_CONTROL;
            robot.keyPress(ctrl);
            robot.keyPress(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_V);
            robot.keyRelease(ctrl);
        } catch (Exception e) {
            log.error("Cannot type", e);
        }
    }
    private void startAction(){
// Path: api/java-api/src/main/java/com/aggregate/api/Pattern.java
// public class Pattern {
//     public static final String TEXT = "Text";
//     public static final String NUMBER = "Number";
//     public static final String DATE = "Date";
//     public static final String TIME = "Time";
// }
// 
// Path: api/java-api/src/main/java/com/aggregate/api/Request.java
// public class Request {
//     /**
//      * Markup of input speech
//      * @see Markup
//      */
//     public final Markup markup;
// 
//     public Request(Markup markup) {
//         this.markup = markup;
//     }
// 
//     /**
//      * Converts this instance to Json object
//      * @return JsonObject instance
//      */
//     public JsonObject toJson() {
//         JsonObject json = new JsonObject();
//         if (markup != null) {
//             json.put("markup", markup.toJson());
//         }
//         return json;
//     }
// 
// 
//     /**
//      * Converts Json object to Request instance
//      * @param json JsonObject
//      * @return Request instance
//      */
//     public static Request fromJson(JsonObject json) {
//         return new Request(Markup.fromJson(json.getJsonObject("markup")));
//     }
// 
//     /**
//      * Converts Vertx's event message to Request instance
//      * @param msg - Vertx's event message
//      * @return Request instance
//      * @see Message
//      */
//     public static Request fromMessage(Message msg) {
//         Object body = msg.body();
//         if (body instanceof JsonObject) {
//             return fromJson((JsonObject) body);
//         }
//         return null;
//     }
// }
// 
// Path: api/java-api/src/main/java/com/aggregate/api/Response.java
// public class Response extends JsonObject {
//     /**
//      * List of output speech strings (could be empty)
//      */
//     public final List<String> speeches;
// 
//     /**
//      * Dialog's context (optional)
//      */
//     public final String context;
// 
//     /**
//      * If switching context is modal or not
//      */
//     public final boolean modal;
// 
//     public Response(String speech) {
//         this(singletonList(speech));
//     }
// 
//     public Response(List<String> speeches) {
//         this(speeches, null, false);
//     }
// 
//     public Response(String speech, String context, boolean modal) {
//         this(singletonList(speech), context, modal);
//     }
// 
//     public Response(String context, boolean modal) {
//         this(emptyList(), context, modal);
//     }
// 
//     public Response(List<String> speeches, String context, boolean modal) {
//         this.speeches = unmodifiableList(speeches);
//         this.context = context;
//         this.modal = modal;
//         JsonArray array = new JsonArray();
//         speeches.forEach(s -> {
//             if (s != null && !s.isEmpty()) array.add(s);
//         });
//         put("context", context);
//         put("modal", modal);
//         put("speeches", array);
//     }
// 
// 
//     /**
//      * Converts Json object to Response instance
//      * @param json JsonObject
//      * @return Response instance
//      */
//     public static Response fromJson(JsonObject json) {
//         JsonArray array = json.getJsonArray("speeches", new JsonArray());
//         List<String> speeches = new ArrayList<>(array.size());
//         array.forEach(s -> speeches.add(s.toString()));
//         if (speeches.isEmpty()) {
//             String speech = json.getString("speech");
//             if (speech != null) speeches.add(speech);
//         }
//         String context = json.getString("context", json.getString("module"));
//         Boolean modal = json.getBoolean("modal", false);
//         return new Response(speeches, context, modal);
//     }
// }


// Path: modules/dictation/src/main/java/com/aggregate/dictation/Dictation.java
import com.aggregate.api.Pattern;
import com.aggregate.api.Request;
import com.aggregate.api.Response;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;

            if (m.body().toString().matches("(.*)key-detector")){
                vertx.eventBus().send("key.addKeyAction", config);
            }
        });
    }

    private void type(Request request) {
        String text = request.markup.get(Pattern.TEXT).source;
        if (!text.isEmpty()) {
            type(text);
        }
    }

    private void type(String text) {
        try {
            Robot robot = new Robot();
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            StringSelection stringSelection = new StringSelection(text);
            clipboard.setContents(stringSelection, stringSelection);

            int ctrl = osName.contains("mac") ? KeyEvent.VK_META : KeyEvent.VK_CONTROL;
            robot.keyPress(ctrl);
            robot.keyPress(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_V);
            robot.keyRelease(ctrl);
        } catch (Exception e) {
            log.error("Cannot type", e);
        }
    }
    private void startAction(){
        vertx.eventBus().publish("asr.start", null);