public class CefSettings {
    /**
     * Log severity levels.
     */
    public enum LogSeverity {
        /**
         * Default logging (currently INFO logging).
         */
        LOGSEVERITY_DEFAULT,

        /**
         * Verbose logging.
         */
        LOGSEVERITY_VERBOSE,

        /**
         * INFO logging.
         */
        LOGSEVERITY_INFO,

        /**
         * WARNING logging.
         */
        LOGSEVERITY_WARNING,

        /**
         * ERROR logging.
         */
        LOGSEVERITY_ERROR,

        /**
         * FATAL logging.
         */
        LOGSEVERITY_FATAL,

        /**
         * Completely disable logging.
         */
        LOGSEVERITY_DISABLE
    }

    /**
     * 32-bit ARGB color value, not premultiplied. The color components are always
     * in a known order. Equivalent to the SkColor type.
     */
    public class ColorType {
        private long color_value = 0;

        private ColorType() {}

        public ColorType(int alpha, int red, int green, int blue) {
            color_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
        }

        public long getColor() {
            return color_value;
        }

        @Override
        public ColorType clone() {
            ColorType res = new ColorType();
            res.color_value = this.color_value;
            return res;
        }
    }

    /**
     * The path to a separate executable that will be launched for sub-processes.
     * By default the browser process executable is used. See the comments on
     * CefExecuteProcess() for details. Also configurable using the
     * "browser-subprocess-path" command-line switch.
     */
    public String browser_subprocess_path = null;

    /**
     * Set to true to enable windowless (off-screen) rendering support. Do not
     * enable this value if the application does not use windowless rendering as
     * it may reduce rendering performance on some systems.
     */
    public boolean windowless_rendering_enabled = true;

    /**
     * Set to true to disable configuration of browser process features using
     * standard CEF and Chromium command-line arguments. Configuration can still
     * be specified using CEF data structures or via the
     * CefApp::OnBeforeCommandLineProcessing() method.
     */
    public boolean command_line_args_disabled = false;

    /**
     * The location where cache data will be stored on disk. If empty an in-memory
     * cache will be used for some features and a temporary disk cache for others.
     * HTML5 databases such as localStorage will only persist across sessions if a
     * cache path is specified.
     */
    public String cache_path = null;

    /**
     * To persist session cookies (cookies without an expiry date or validity
     * interval) by default when using the global cookie manager set this value to
     * true. Session cookies are generally intended to be transient and most Web
     * browsers do not persist them. A |cache_path| value must also be specified to
     * enable this feature. Also configurable using the "persist-session-cookies"
     * command-line switch.
     */
    public boolean persist_session_cookies = false;

    /**
     * Value that will be returned as the User-Agent HTTP header. If empty the
     * default User-Agent string will be used. Also configurable using the
     * "user-agent" command-line switch.
     */
    public String user_agent = null;

    /**
     * Value that will be inserted as the product portion of the default
     * User-Agent string. If empty the Chromium product version will be used. If
     * |userAgent| is specified this value will be ignored. Also configurable
     * using the "product-version" command-line switch.
     */
    public String product_version = null;

    /**
     * The locale string that will be passed to Blink. If empty the default
     * locale of "en-US" will be used. This value is ignored on Linux where locale
     * is determined using environment variable parsing with the precedence order:
     * LANGUAGE, LC_ALL, LC_MESSAGES and LANG. Also configurable using the "lang"
     * command-line switch.
     */
    public String locale = null;

    /**
     * The directory and file name to use for the debug log. If empty, the
     * default name of "debug.log" will be used and the file will be written
     * to the application directory. Also configurable using the "log-file"
     * command-line switch.
     */
    public String log_file = null;

    /**
     * The log severity. Only messages of this severity level or higher will be
     * logged. Also configurable using the "log-severity" command-line switch with
     * a value of "verbose", "info", "warning", "error", "error-report" or
     * "disable".
     */
    public LogSeverity log_severity = LogSeverity.LOGSEVERITY_DEFAULT;

    /**
     * Custom flags that will be used when initializing the V8 JavaScript engine.
     * The consequences of using custom flags may not be well tested. Also
     * configurable using the "js-flags" command-line switch.
     */
    public String javascript_flags = null;

    /**
     * The fully qualified path for the resources directory. If this value is
     * empty the cef.pak and/or devtools_resources.pak files must be located in
     * the module directory on Windows/Linux or the app bundle Resources directory
     * on Mac OS X. Also configurable using the "resources-dir-path" command-line
     * switch.
     */
    public String resources_dir_path = null;

    /**
     * The fully qualified path for the locales directory. If this value is empty
     * the locales directory must be located in the module directory. This value
     * is ignored on Mac OS X where pack files are always loaded from the app
     * bundle Resources directory. Also configurable using the "locales-dir-path"
     * command-line switch.
     */
    public String locales_dir_path = null;

    /**
     * Set to true to disable loading of pack files for resources and locales.
     * A resource bundle handler must be provided for the browser and render
     * processes via CefApp::GetResourceBundleHandler() if loading of pack files
     * is disabled. Also configurable using the "disable-pack-loading" command-
     * line switch.
     */
    public boolean pack_loading_disabled = false;

    /**
     * Set to a value between 1024 and 65535 to enable remote debugging on the
     * specified port. For example, if 8080 is specified the remote debugging URL
     * will be http: *localhost:8080. CEF can be remotely debugged from any CEF or
     * Chrome browser window. Also configurable using the "remote-debugging-port"
     * command-line switch.
     */
    public int remote_debugging_port = 0;

    /**
     * The number of stack trace frames to capture for uncaught exceptions.
     * Specify a positive value to enable the CefV8ContextHandler::
     * OnUncaughtException() callback. Specify 0 (default value) and
     * OnUncaughtException() will not be called. Also configurable using the
     * "uncaught-exception-stack-size" command-line switch.
     */
    public int uncaught_exception_stack_size = 0;

    /**
     * Set to true to ignore errors related to invalid SSL certificates.
     * Enabling this setting can lead to potential security vulnerabilities like
     * "man in the middle" attacks. Applications that load content from the
     * internet should not enable this setting. Also configurable using the
     * "ignore-certificate-errors" command-line switch.
     */
    public boolean ignore_certificate_errors = false;

    /**
     * Opaque background color used for accelerated content. By default the
     * background color will be white. Only the RGB compontents of the specified
     * value will be used. The alpha component must greater than 0 to enable use
     * of the background color but will be otherwise ignored.
     */
    public ColorType background_color = null;

    public CefSettings() {}

    @Override
    public CefSettings clone() {
        CefSettings tmp = new CefSettings();
        tmp.browser_subprocess_path = browser_subprocess_path;
        tmp.windowless_rendering_enabled = windowless_rendering_enabled;
        tmp.command_line_args_disabled = command_line_args_disabled;
        tmp.cache_path = cache_path;
        tmp.persist_session_cookies = persist_session_cookies;
        tmp.user_agent = user_agent;
        tmp.product_version = product_version;
        tmp.locale = locale;
        tmp.log_file = log_file;
        tmp.log_severity = log_severity;
        tmp.javascript_flags = javascript_flags;
        tmp.resources_dir_path = resources_dir_path;
        tmp.locales_dir_path = locales_dir_path;
        tmp.pack_loading_disabled = pack_loading_disabled;
        tmp.remote_debugging_port = remote_debugging_port;
        tmp.uncaught_exception_stack_size = uncaught_exception_stack_size;
        tmp.ignore_certificate_errors = ignore_certificate_errors;
        if (background_color != null) tmp.background_color = background_color.clone();
        return tmp;
    }
} @SuppressWarnings("unchecked")
public class Browser {

    private BrowserType type;
    private CefWebview cef;

    @SuppressWarnings("rawtypes")
    private HashMap<Class<?>, List> listeners;

    public String title;

    public Browser(BrowserType type, String url) {
        this.type = type;
        this.listeners = new HashMap<>();

        if (!NativeHelper.loaded) {
            NativeHelper.setupNatives(NativeHelper.getPlatform());
            NativeHelper.blockTillDownloaded();
        }
        CefWebview.setupNatives();

        this.cef = new CefWebview(this, url);
        cef.createCef();
    }

    public Browser() {
        this(BrowserType.LIGHTWEIGHT, "about:blank");
    }

    public Browser(String url) {
        this(BrowserType.LIGHTWEIGHT, url);
    }

    public static void shutdown() {
        for (GLJPanel n : CefWebview.uis) {
            n.removeAll();
            n = null;
        }
        for (CefBrowser b : CefWebview.browsers.keySet()) {
            b.stopLoad();
            b.close(true);
            CefWebview.client.doClose(b);
        }
        CefWebview.client.dispose();
        CefWebview.app.dispose();
        CefWebview.app = null;
    }

    public static boolean isInitialized() {
        return null != CefWebview.app;
    }

    public CefWebview getCef() {
        return cef;
    }

    public BrowserType getType() {
        return type;
    }

    public void loadURL(String url) {
        cef.getCefBrowser().loadURL(url);
    }

    public void loadHTML(String html) {
        cef.getCefBrowser().loadURL(DataUri_create("text/html", html));
    }

    private static String DataUri_create(String mimeType, String contents) {
        return "data:" + mimeType + ";base64," + java.util.Base64.getEncoder().encodeToString(contents.getBytes());
    }

    public String getTitle() {
        return null == title ? getURL() : title;
    }

    public String getURL() {
        return cef.getCefBrowser().getURL();
    }

    /**
     * @deprecated To be replaced with history manager
     */
    @Deprecated
    public void goBack() {
        cef.getCefBrowser().goBack();
    }

    /**
     * @deprecated To be replaced with history manager
     */
    @Deprecated
    public void goForward() {
        cef.getCefBrowser().goForward();
    }

    /**
     * @deprecated To be replaced with history manager
     */
    @Deprecated
    public boolean canGoBack() {
        return cef.getCefBrowser().canGoBack();
    }

    /**
     * @deprecated To be replaced with history manager
     */
    @Deprecated
    public boolean canGoForward() {
        return cef.getCefBrowser().canGoForward();
    }

    public boolean isLoading() {
        return cef.getCefBrowser().isLoading();
    }

    public void stop() {
        cef.getCefBrowser().stopLoad();
    }

    public <T> List<? extends BrowserListener> getListeners(T type) {
        List<? extends BrowserListener> list  = this.listeners.getOrDefault(type, new ArrayList<>());
        return list;
    }

    public <T> void addListener(BrowserListener listener) {
        List<BrowserListener> list = this.listeners.getOrDefault(listener.getType(), new ArrayList<>());
        if (!list.contains(listener)) {
            list.add(listener);
            this.listeners.put(listener.getType(), list);
        }
    }

    public void removeListener(Class<? extends BrowserListener> type, BrowserListener listener) {
        List<BrowserListener> list  = this.listeners.getOrDefault(type, new ArrayList<>());
        if (list.contains(listener)) {
            list.remove(listener);
            this.listeners.put(type, list);
        }
    }

} public class BrowserPreferences {

    public static CefSettings settings = new CefSettings();
    private static String brand = "ZunoZap";
    public static boolean showNHgui = true;
    private static boolean blockRemoteFonts = false;
    private static boolean blockRemoteJS = false;
    private static ArrayList<String> switches = new ArrayList<>();

    public static void initDefault() {
        if (null == BrowserPreferences.settings.cache_path) {
            BrowserPreferences.settings.cache_path = new File(NativeHelper.lib.getParentFile(), "cache").getAbsolutePath();
        }
        settings.persist_session_cookies = true;
        settings.log_severity = CefSettings.LogSeverity.LOGSEVERITY_INFO;
        settings.user_agent = getUserAgent();
        System.out.println("BrowserPreferences init");
    }

    public static void addSwitch(String... toAdd) {
        switches.addAll(Arrays.asList(toAdd));
    }

    public static String[] getSwitches() {
        return switches.toArray(new String[switches.size()]);
    }

    public static String getBrand() {
        return brand;
    }

    public static void setBrand(String str) {
        brand = str;
    }

    /**
     * Blocks all resources with the type "RT_FONT_RESOURCE"
     */
    public static void setBlockRemoteFonts(boolean b) {
        blockRemoteFonts = b;
    }

    public static boolean shouldBlockRemoteFonts() {
        return blockRemoteFonts;
    }

    public static String getChromiumDir() {
        return NativeHelper.fold.getAbsolutePath();
    }

    public static String getDefaultChromiumDir() {
        return NativeHelper.fold.getAbsolutePath();
    }

    public static void setUserAgent(String userAgent) {
        settings.user_agent = userAgent;
    }

    public static String getUserAgent() {
        if (null == settings.user_agent) {
            // As of 2021, Google has blocked sign-in for CEF browsers
            // Now requiring us to report we are Firefox instead of Chrome.

            String spoof = NativeHelper.getPlatform().VER.split("chromium-")[1].split("[.]")[0] + ".0";
            int spoof_gecko = 20100101;

            String ua = "Mozilla/5.0 (%s) Gecko/" + spoof_gecko + " Firefox/%s";
            String os = System.getProperty("os.name");
            if (os.startsWith("Win")) os = "Windows NT 10.0"; 
            String arch = System.getProperty("os.arch");
            if (os.indexOf("Win") != -1) os = os + "; Win64; x64";
            else if (os.indexOf("Mac") != -1) os = os + "; Mac";
            else os = "X11; Linux x86_64" + arch;
            os += "; rv:84.0";

            return String.format(ua, os, spoof);
        }
        return settings.user_agent;
    }

    @Deprecated
    public static boolean isJavaScriptEnabled() {
        return !blockRemoteJS;
    }

    /**
     * @deprecated
     */
    @Deprecated
    public static void setJavaScriptEnabled(boolean b) {
        BrowserPreferences.blockRemoteJS = !b;
    }

} public class NativeHelper {

    public static String CEF_PATH;

    public enum NativePlatform {
        LINUX32 ("84.3.8+gc8a556f",  "84.0.4147.105"),
        LINUX64 ("84.3.8+gc8a556f",  "84.0.4147.105"),
        WIN32   ("84.3.8+gc8a556f",  "84.0.4147.105"),
        WIN64   ("84.3.8+gc8a556f",  "84.0.4147.105"),
        //WIN64 ("87.1.12+g03f9336", "87.0.4280.88"),
        MACOSX64("84.3.8+gc8a556f",  "84.0.4147.105");

        public String VER;
        public String GHD;
        private NativePlatform(String a, String b) {
            VER = "v1.0.10-" + a + "+chromium-" + b;
            GHD = "https://github.com/jcefbuild/jcefbuild/releases/download/" + VER;
        }
    }

    public static NativePlatform getPlatform() {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.indexOf("win") >= 0)
            return System.getProperty("os.arch").indexOf("64") != -1 ? NativePlatform.WIN64 : NativePlatform.WIN32;
        if (os.indexOf("mac") >= 0) return NativePlatform.MACOSX64;
        return System.getProperty("os.arch").indexOf("64") != -1 ? NativePlatform.LINUX64 : NativePlatform.LINUX32;
    }

    public static final File lib = new File(new File(System.getProperty("java.io.tmpdir"), "zunozap"), "cef");
    public static File fold;
    public static boolean loaded;
    private static int i = 0;

    private static JProgressBar pb;
    private static JFrame f;
    private static JLabel z;
    private static Download d;

    public static Download getDownload() {
        return d;
    }

    public static void setupNatives(NativePlatform platform) {
        String url = platform.GHD + "/" + platform.name().toLowerCase() + ".zip";
        String arch = System.getProperty("sun.arch.data.model");
        if (arch.equals("32") && platform.name().contains("64")) {
            System.out.println("Can not load 64-bit natives on 32-bit JVM");
            System.exit(1);
        }

        lib.mkdirs();

        File file = new File(lib, platform.name().toLowerCase() + platform.VER + ".zip");
        fold = new File(lib, platform.name().toLowerCase() + platform.VER);

        if (fold.exists()) {
            setNativePath(fold, platform);
            i = 1;
            return;
        } else if (lib.listFiles() != null && lib.listFiles().length > 0) for (File fi : lib.listFiles()) delete(fi);

        d = new Download(url, file);

        boolean showGui = BrowserPreferences.showNHgui;
        if (showGui) {
            pb = new JProgressBar(0, 101);
            f = new JFrame("ZunoZap");
            z = new JLabel(BrowserPreferences.getBrand()) {
                private static final long serialVersionUID = 1L;
    
                @Override
                public void paint(Graphics g) {
                    super.paint(g);
                    int k = (int)(getWidth()*(pb.getValue()/100.0f));
                    g.setFont(new Font("Dialog", 0, 12));
                    g.setColor(Color.ORANGE);
                    g.fillRect(0, getHeight() - 5, k, 5);
                    g.setColor(Color.WHITE);
                    String str = formatSize(d.downloaded - 1) + 
                            " / " + formatSize(d.size) + " [Status=" + d.status + "]";
                    g.drawString("Updating libraries, Please wait.", (getWidth() / 2) - (3 * 32), 24);
                    g.drawString(str, (getWidth() / 2) - (3 * str.length()), getHeight() - 15);
                    pb.setValue((int)(((float)d.downloaded / (float)d.size) * 100));
                    repaint();
                }
            };
            z.setFont(new Font("Dialog", Font.BOLD, 56));
            z.setForeground(Color.WHITE);
            z.setBorder(new EmptyBorder(30,65,30,65));
            f.setUndecorated(true);
            f.setBackground(new Color(0,0,0,235));
            f.setContentPane(z);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            f.setVisible(true);
        }

        new Thread(() -> { 
            Timer t = new Timer();
            t.schedule(new TimerTask() { 
                @Override public void run() {
                    if (showGui) {
                        pb.setValue((int)((float) d.downloaded / d.size) * 100);
                        z.repaint();
                    }
        
                    if (d.status == 2 && i == 0) {
                        Unzip unzip = new Unzip(file, fold);
                        try {
                            unzip.execute();
                        } catch (IOException e) {e.printStackTrace();}
                        setNativePath(fold, platform);
        
                        i = 1;
                        t.cancel();
                        if (showGui) f.dispose();
                    }
        }}, 20, 500);}).start();
    }

    private static void setNativePath(File f, NativePlatform plat) {
        System.out.println("SET N");
        File bin = new File(new File(f, "java-cef-build-bin"), "bin");
        File lib = new File(bin, "lib");
        File natives = new File(lib, plat.name().toLowerCase());
        System.out.println(natives);
        if (natives.exists()) CEF_PATH = natives.getAbsolutePath();
        try {
            System.out.println(CEF_PATH);
            addLibraryDir(CEF_PATH);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        for (File file : bin.listFiles()) {
            if (!file.getName().endsWith(".jar")) continue;
            try {
                ClassLoadingUtil.appendToURLClassPath(file.toURI().toURL());
            } catch (MalformedURLException e) {e.printStackTrace();}
        }
        loaded = true;
    }

    private static void addLibraryDir(String libraryPath) throws Exception {
        Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths");
        userPathsField.setAccessible(true);
        String[] paths = (String[]) userPathsField.get(null);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < paths.length; i++) {
            if (libraryPath.equals(paths[i])) continue;
            sb.append(paths[i]).append(File.pathSeparatorChar);
        }
        sb.append(libraryPath);
        System.setProperty("java.library.path", sb.toString());
        final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
        sysPathsField.setAccessible(true);
        sysPathsField.set(null, null);
    }

    private static void delete(File f) {
        if (null != f.listFiles())
        for (File fi : f.listFiles())
            if (fi.isDirectory()) delete(fi); else fi.delete();
        f.delete();
    }

    public static void blockTillDownloaded() {
        while (i == 0)
            try {Thread.sleep(1000);} catch (InterruptedException e){}
    }

    private static String formatSize(long v) {
        if (v < 1024) return (v > 0 ? v : 0) + " B";
        int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
        return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
    }

} public final class FinishLoadingEvent extends LoadEvent {

    private long frameId;
    private boolean isFrameMain;
    private String url;

    public FinishLoadingEvent(Browser browser, long frameId, boolean mainFrame, String validatedURL) {
        super(browser);

        this.frameId = frameId;
        this.isFrameMain = mainFrame;
        this.url = validatedURL;
    }

    public long getFrameId() {
        return frameId;
    }

    public boolean isMainFrame() {
        return isFrameMain;
    }

    public String getValidatedURL() {
        return url;
    }

} public class ResourceRequestEvent extends BrowserEvent {

    private CefRequest request;

    public ResourceRequestEvent(Browser browser, CefRequest request) {
        super(browser);
        this.request = request;
    }

    public void setUrl(String url) {
        request.setURL(url);
    }

    public String getReferrer() {
        return request.getReferrerURL();
    }

    public String getResourceType() {
        return request.getResourceType().name();
    }

    public CefRequest getCefRequest() {
        return request;
    }

    public String getUrl() {
        return request.getURL();
    }

    public boolean isCanceled() {
        return request.getURL().contains("adblock_block-sdjd");
    }

    public void cancel() {
        request.setURL("https://adblock_block-sdjdjfbskdfb.com/");
    }

} public class StartLoadingEvent extends LoadEvent {

    private long frameId;
    private long parentId;
    private boolean isFrameMain;
    private String url;
    private boolean isError;
    private boolean sameDoc;

    public StartLoadingEvent(Browser browser, long frameId, long parentFrameId, boolean mainFrame, String validatedURL, boolean errorPage) {
        this(browser, frameId, parentFrameId, mainFrame, validatedURL, errorPage, false);
    }

    public StartLoadingEvent(Browser browser, long frameId, long parentFrameId, boolean mainFrame, String validatedURL, boolean errorPage, boolean sameDocument) {
        super(browser);

        this.frameId = frameId;
        this.parentId = parentFrameId;
        this.isFrameMain = mainFrame;
        this.url = validatedURL;
        this.isError = errorPage;
        this.sameDoc = sameDocument;
    }

    public long getFrameId() {
        return frameId;
    }

    public long getParentFrameId() {
        return parentId;
    }

    public boolean isMainFrame() {
        return isFrameMain;
    }

    public String getValidatedURL() {
        return url;
    }

    public boolean isErrorPage() {
        return isError;
    }

    public boolean isSameDocument() {
        return sameDoc;
    }

} public final class TitleEvent extends BrowserEvent {

    public String title;

    public TitleEvent(Browser browser, String title) {
        super(browser);
        this.title = title;
    }

    public String getTitle() {
        return this.title;
    }

} public interface BrowserListener extends EventListener {

    public Class<?> getType();

} public interface LoadListener extends BrowserListener {

    public void onStartLoadingFrame(StartLoadingEvent e);

    public void onFinishLoadingFrame(FinishLoadingEvent e);

    public void onFailLoadingFrame(FailLoadingEvent e);

    public void onDocumentLoadedInFrame(FrameLoadEvent e);

    public void onDocumentLoadedInMainFrame(LoadEvent e);

    @Override
    public default Class<?> getType() {
        return LoadListener.class;
    }

} public interface ResourceRequestListener extends BrowserListener {

    public void onBeforeResourceLoad(ResourceRequestEvent event);

    @Override
    public default Class<?> getType() {
        return ResourceRequestListener.class;
    }

} public interface TitleListener extends BrowserListener {

    public void onTitleChange(TitleEvent event);

    @Override
    public default Class<?> getType() {
        return TitleListener.class;
    }

}
import java.awt.BorderLayout;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.JPanel;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefBeforeDownloadCallback;
import org.cef.callback.CefDownloadItem;
import org.cef.callback.CefDownloadItemCallback;
import org.cef.handler.CefDisplayHandlerAdapter;
import org.cef.handler.CefDownloadHandler;
import org.cef.handler.CefLoadHandler;
import org.cef.handler.CefRequestHandlerAdapter;
import org.cef.handler.CefResourceRequestHandler;
import org.cef.handler.CefResourceRequestHandlerAdapter;
import org.cef.misc.BoolRef;
import org.cef.network.CefRequest;
import org.cef.network.CefRequest.ResourceType;
import com.javazilla.chromium.Browser;
import com.javazilla.chromium.BrowserPreferences;
import com.javazilla.chromium.NativeHelper;
import com.javazilla.chromium.events.FinishLoadingEvent;
import com.javazilla.chromium.events.ResourceRequestEvent;
import com.javazilla.chromium.events.StartLoadingEvent;
import com.javazilla.chromium.events.TitleEvent;
import com.javazilla.chromium.listeners.BrowserListener;
import com.javazilla.chromium.listeners.LoadListener;
import com.javazilla.chromium.listeners.ResourceRequestListener;
import com.javazilla.chromium.listeners.TitleListener;
import com.jogamp.opengl.awt.GLJPanel;
import javafx.scene.Parent;
import javafx.scene.layout.AnchorPane;
package com.javazilla.chromium.internal;






public class CefWebview {

    public Parent root;
    public CefBrowser browser;
    private Browser jx;

    public static CefSettings settings;
    public static CefApp app;
    public static CefClient client;
    public static HashMap<CefBrowser, Browser> browsers = new HashMap<>();
    public static List<GLJPanel> uis = new ArrayList<>();
    private String url;

    public static List<String> ADBLOCK = new ArrayList<>();

    public CefWebview(Browser jx, String url) {
        this.jx = jx;
        this.url = url;
    }

    static {
        ADBLOCK.add("doubleclick.net");
        ADBLOCK.add("pagead2.googlesyndication.com");
        ADBLOCK.add("p.adsymptotic.com");
        ADBLOCK.add("pixel.advertising.com");
        ADBLOCK.add("s.amazon-adsystem.com");
        ADBLOCK.add("adblockanalytics.com");
        ADBLOCK.add("adgrowmedia.com");
    }

    public static void setupNatives() {
        try {
            String libPath = System.getProperty("java.library.path");
            if (!libPath.contains(NativeHelper.CEF_PATH))
                addLibraryDir(NativeHelper.CEF_PATH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public CefBrowser getCefBrowser() {
        return browser;
    }

    public void createCef() {
        if (client == null) {
            BrowserPreferences.initDefault();