// Path: x-gwt-essential/src/main/java/com/github/spirylics/xgwt/essential/Element.java
// @JsType(isNative = true)
// public interface Element {
// 
//     @JsOverlay
//     static <E extends Element> E create(String tag) {
//         return (E) DOM.createElement(tag);
//     }
// 
//     @JsOverlay
//     static <E extends Element> E create(String tag, Map<String, Object> attributes) {
//         return (E) GQuery.$("<" + tag + " "
//                 + attributes.entrySet().stream()
//                 .map(e -> e.getKey() + "=\"" + XMapper.get().write(e.getValue()) + "\"")
//                 .collect(Collectors.joining(" "))
//                 + "></" + tag + ">").get(0);
//     }
// 
//     void addEventListener(String event, Fn.Arg<Event> function, boolean useCapture);
// 
//     void addEventListener(String event, Fn.Arg<Event> function);
// 
//     void removeEventListener(String event, Fn.Arg<Event> function, boolean useCapture);
// 
//     void removeEventListener(String event, Fn.Arg<Event> function);
// 
//     String getAttribute(String attribute);
// 
//     void setAttribute(String attribute, Object value);
// 
//     void removeAttribute(String attribute);
// 
//     <E extends Element> E querySelector(String selector);
// 
//     <E extends Element> E[] querySelectorAll(String selector);
// 
//     void focus();
// 
//     void blur();
// 
//     void appendChild(Element element);
// 
//     @JsOverlay
//     default <E extends Element> Stream<E> querySelectorStream(String selector) {
//         return Arrays.stream(querySelectorAll(selector));
//     }
// 
//     @JsOverlay
//     default void appendChild(Widget widget) {
//         appendChild((Element) widget.getElement());
//     }
// 
// 
//     @JsOverlay
//     default <E extends Element> E focus(boolean focused) {
//         if (focused) {
//             focus();
//         } else {
//             blur();
//         }
//         return (E) this;
//     }
// 
//     @JsOverlay
//     default <E extends Element> E hidden(boolean hidden) {
//         return attribute("hidden", hidden);
//     }
// 
//     @JsOverlay
//     default <E extends Element> E attribute(String attribute, Object value) {
//         if (value == null || Boolean.FALSE.equals(value)) {
//             removeAttribute(attribute);
//         } else {
//             setAttribute(attribute, XMapper.get().write(value));
//         }
//         return (E) this;
//     }
// 
//     @JsOverlay
//     default <V> V attribute(String attribute, Class<V> clazz) {
//         return XMapper.get().read(getAttribute(attribute), clazz);
//     }
// 
// }


import com.github.spirylics.xgwt.essential.Element;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.Promise;
import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
import jsinterop.annotations.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.gwt.query.client.GQuery.$;
import static com.google.gwt.query.client.GQuery.body;
    @JsMethod
    public static native DomApi dom(com.google.gwt.dom.client.Element element);

    @JsOverlay
    public static Promise googleMapsApiPromise() {
        return new PromiseFunction() {
            @Override
            public void f(final Deferred deferred) {
                if ($("google-maps-api").isEmpty()) {
                    $(body).append("<google-maps-api></google-maps-api>");
                }
                GQuery gMapsApi = $("google-maps-api");
                if (gMapsApi.prop("libraryLoaded", Boolean.class)) {
                    deferred.resolve();
                } else {
                    gMapsApi.on("api-load", new Function() {
                        @Override
                        public void f() {
                            deferred.resolve();
                        }
                    });
                }
            }
        };
    }

    @JsOverlay
    public static String toCamelCase(String text) {
        String bactrianCamel = Stream.of(text.split("[^a-zA-Z0-9]"))
                .map(v -> v.substring(0, 1).toUpperCase() + v.substring(1).toLowerCase())
// Path: x-gwt-essential/src/main/java/com/github/spirylics/xgwt/essential/Element.java
// @JsType(isNative = true)
// public interface Element {
// 
//     @JsOverlay
//     static <E extends Element> E create(String tag) {
//         return (E) DOM.createElement(tag);
//     }
// 
//     @JsOverlay
//     static <E extends Element> E create(String tag, Map<String, Object> attributes) {
//         return (E) GQuery.$("<" + tag + " "
//                 + attributes.entrySet().stream()
//                 .map(e -> e.getKey() + "=\"" + XMapper.get().write(e.getValue()) + "\"")
//                 .collect(Collectors.joining(" "))
//                 + "></" + tag + ">").get(0);
//     }
// 
//     void addEventListener(String event, Fn.Arg<Event> function, boolean useCapture);
// 
//     void addEventListener(String event, Fn.Arg<Event> function);
// 
//     void removeEventListener(String event, Fn.Arg<Event> function, boolean useCapture);
// 
//     void removeEventListener(String event, Fn.Arg<Event> function);
// 
//     String getAttribute(String attribute);
// 
//     void setAttribute(String attribute, Object value);
// 
//     void removeAttribute(String attribute);
// 
//     <E extends Element> E querySelector(String selector);
// 
//     <E extends Element> E[] querySelectorAll(String selector);
// 
//     void focus();
// 
//     void blur();
// 
//     void appendChild(Element element);
// 
//     @JsOverlay
//     default <E extends Element> Stream<E> querySelectorStream(String selector) {
//         return Arrays.stream(querySelectorAll(selector));
//     }
// 
//     @JsOverlay
//     default void appendChild(Widget widget) {
//         appendChild((Element) widget.getElement());
//     }
// 
// 
//     @JsOverlay
//     default <E extends Element> E focus(boolean focused) {
//         if (focused) {
//             focus();
//         } else {
//             blur();
//         }
//         return (E) this;
//     }
// 
//     @JsOverlay
//     default <E extends Element> E hidden(boolean hidden) {
//         return attribute("hidden", hidden);
//     }
// 
//     @JsOverlay
//     default <E extends Element> E attribute(String attribute, Object value) {
//         if (value == null || Boolean.FALSE.equals(value)) {
//             removeAttribute(attribute);
//         } else {
//             setAttribute(attribute, XMapper.get().write(value));
//         }
//         return (E) this;
//     }
// 
//     @JsOverlay
//     default <V> V attribute(String attribute, Class<V> clazz) {
//         return XMapper.get().read(getAttribute(attribute), clazz);
//     }
// 
// }


// Path: x-gwt-polymer/src/main/java/com/github/spirylics/xgwt/polymer/Polymer.java
import com.github.spirylics.xgwt.essential.Element;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.Promise;
import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
import jsinterop.annotations.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.gwt.query.client.GQuery.$;
import static com.google.gwt.query.client.GQuery.body;

    @JsMethod
    public static native DomApi dom(com.google.gwt.dom.client.Element element);

    @JsOverlay
    public static Promise googleMapsApiPromise() {
        return new PromiseFunction() {
            @Override
            public void f(final Deferred deferred) {
                if ($("google-maps-api").isEmpty()) {
                    $(body).append("<google-maps-api></google-maps-api>");
                }
                GQuery gMapsApi = $("google-maps-api");
                if (gMapsApi.prop("libraryLoaded", Boolean.class)) {
                    deferred.resolve();
                } else {
                    gMapsApi.on("api-load", new Function() {
                        @Override
                        public void f() {
                            deferred.resolve();
                        }
                    });
                }
            }
        };
    }

    @JsOverlay
    public static String toCamelCase(String text) {
        String bactrianCamel = Stream.of(text.split("[^a-zA-Z0-9]"))
                .map(v -> v.substring(0, 1).toUpperCase() + v.substring(1).toLowerCase())
                .collect(Collectors.joining());