@JsFunction
@FunctionalInterface
public interface Accumulator<T> {

    T call(T acc, T value);
} @JsFunction
@FunctionalInterface
public interface AccumulatorWithIndex<T> {

    T call(T acc, T value, int index);
} @JsFunction
@FunctionalInterface
public interface Action0 {
    void call();
} @JsFunction
@FunctionalInterface
public interface Action1<T> {
    void call(T t);
}
 @JsFunction
@FunctionalInterface
public interface Comparator<T> {

    int compare(T i1, T i2);
}
 @JsFunction
@FunctionalInterface
public interface ConditionFunc<S> {
    boolean call(S state);
}
 @JsFunction
@FunctionalInterface
public interface DeferProducer<T> {
    Observable<T> call();
}
 @JsFunction
@FunctionalInterface
public interface ElementSelector<T, R> {

    R selectElement(T element);
}
 @JsFunction
@FunctionalInterface
public interface ErrorCatcher<T, R> {
    Observable<R> call(Object t1, Observable<T> t2);
}
 @JsFunction
@FunctionalInterface
public interface Factory<T> {

    T call();
}
 @JsFunction
@FunctionalInterface
public interface Func0<T> {
    T call();
} @JsFunction
@FunctionalInterface
public interface Func1<T, R> {
    R call(T t);
}
 @JsFunction
@FunctionalInterface
public interface Func2<T1, T2, R> {
    R call(T1 t1, T2 t2);
}
 @JsFunction
@FunctionalInterface
public interface Func3<T1, T2, T3, R> {
    R call(T1 t1, T2 t2, T3 t3);
}
 @JsFunction
@FunctionalInterface
public interface Func4<T1, T2, T3, T4, R> {
    R call(T1 t1, T2 t2, T3 t3, T4 t4);
}
 @JsFunction
@FunctionalInterface
public interface Func5<T1, T2, T3, T4, T5, R> {
    R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
} @JsFunction
@FunctionalInterface
public interface Func6<T1, T2, T3, T4, T5, T6, R> {
    R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6);
} @JsFunction
@FunctionalInterface
public interface IterateFunc<S> {
    S call(S state);
}
 @JsFunction
@FunctionalInterface
public interface KeySelector<T, K> {

    K selectKey(T item);
}
 @JsFunction
@FunctionalInterface
public interface LetFunction<T, R> {
    Observable<R> call(Observable<T> t);
}
 @JsFunction
@FunctionalInterface
public interface ObservableFactoryFromResource<T> {
    Observable<T> call(AnonymousSubscription anonymousSubscription);
}
 @JsFunction
@FunctionalInterface
public interface OperatorFunction<T, R> {
    Observable<R> call(Observable<T> t);
}
 @JsFunction
@FunctionalInterface
public interface Predicate<T> {

    boolean test(T value);
}
 @JsFunction
@FunctionalInterface
public interface Predicate2<T> {
    boolean call(T t1, T t2);
}
 @JsFunction
@FunctionalInterface
public interface PredicateWithIndex<T> {

    boolean test(T value, int index);
} @JsFunction
@FunctionalInterface
public interface PredicateWithSourceIndex<T> {

    boolean test(T value, int index, Observable<T> source);
}
 @JsFunction
@FunctionalInterface
public interface ResultFunc<S, T> {
    T call(S state);
}
 @JsFunction
@FunctionalInterface
public interface ResultSelector<T, I, R> {

    R selectResult(T outerValue, I innerValue, int outerIndex, int innerIndex);
} @JsFunction
@FunctionalInterface
public interface ResultSelectorWithIndex<T, R> {

    R selectResult(T value, int index);
}
 @JsFunction
@FunctionalInterface
public interface Scanner<R, T> {

    Observable<R> scan(R acc, T item);
} @JsFunction
@FunctionalInterface
public interface TransformingAccumulator<T, R> {

    R call(R acc, T value, int index);
} @JsFunction
@FunctionalInterface
public interface TransformingAccumulatorWithIndex<T, R> {

    R call(R acc, T value, int index);
}
 @JsFunction
@FunctionalInterface
public interface UnaryArrayFunction<T, R> {
    Observable<R>[] call(Observable<T> t);
} @JsFunction
@FunctionalInterface
public interface UnaryFunction<T, R> {
    R call(T t);
}
 @JsType(namespace = "Rx", isNative = true)
public class Scheduler {
    @JsProperty
    public static Scheduler async;
    @JsProperty
    public static Scheduler asap;
    @JsProperty
    public static Scheduler queue;
    @JsProperty
    public static Scheduler animationFrame;
} @JsType(isNative = true, namespace = "Rx")
public class Subject<T> extends Observable<T> implements Observer<T> {
    @Override
    public native void error(Object error);

    @Override
    public native void next(T value);

    @Override
    public native void complete();

    public native Observable<T> asObservable();
} @JsType(isNative = true)
public interface AnonymousSubscription {
    void unsubscribe();
}
 @JsType(isNative = true, namespace = "Rx")
public class Subscription implements ISubscription {

    @JsConstructor
    public Subscription(Action0 unsubscribe) {

    }

    @JsConstructor
    public Subscription() {

    }

    @JsProperty(name = "closed")
    @Override
    public native boolean isClosed();

    @Override
    public native void unsubscribe();

    public native Subscription add(TearDownSubscription tearDownLogic);

    public native void remove(Subscription subscription);
}
import com.github.timofeevda.gwt.rxjs.interop.functions.Accumulator;
import com.github.timofeevda.gwt.rxjs.interop.functions.AccumulatorWithIndex;
import com.github.timofeevda.gwt.rxjs.interop.functions.Action0;
import com.github.timofeevda.gwt.rxjs.interop.functions.Action1;
import com.github.timofeevda.gwt.rxjs.interop.functions.Comparator;
import com.github.timofeevda.gwt.rxjs.interop.functions.ConditionFunc;
import com.github.timofeevda.gwt.rxjs.interop.functions.DeferProducer;
import com.github.timofeevda.gwt.rxjs.interop.functions.ElementSelector;
import com.github.timofeevda.gwt.rxjs.interop.functions.ErrorCatcher;
import com.github.timofeevda.gwt.rxjs.interop.functions.Factory;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func0;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func1;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func2;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func3;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func4;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func5;
import com.github.timofeevda.gwt.rxjs.interop.functions.Func6;
import com.github.timofeevda.gwt.rxjs.interop.functions.IterateFunc;
import com.github.timofeevda.gwt.rxjs.interop.functions.KeySelector;
import com.github.timofeevda.gwt.rxjs.interop.functions.LetFunction;
import com.github.timofeevda.gwt.rxjs.interop.functions.ObservableFactoryFromResource;
import com.github.timofeevda.gwt.rxjs.interop.functions.OperatorFunction;
import com.github.timofeevda.gwt.rxjs.interop.functions.Predicate;
import com.github.timofeevda.gwt.rxjs.interop.functions.Predicate2;
import com.github.timofeevda.gwt.rxjs.interop.functions.PredicateWithIndex;
import com.github.timofeevda.gwt.rxjs.interop.functions.PredicateWithSourceIndex;
import com.github.timofeevda.gwt.rxjs.interop.functions.ResultFunc;
import com.github.timofeevda.gwt.rxjs.interop.functions.ResultSelector;
import com.github.timofeevda.gwt.rxjs.interop.functions.ResultSelectorWithIndex;
import com.github.timofeevda.gwt.rxjs.interop.functions.Scanner;
import com.github.timofeevda.gwt.rxjs.interop.functions.TransformingAccumulator;
import com.github.timofeevda.gwt.rxjs.interop.functions.TransformingAccumulatorWithIndex;
import com.github.timofeevda.gwt.rxjs.interop.functions.UnaryArrayFunction;
import com.github.timofeevda.gwt.rxjs.interop.functions.UnaryFunction;
import com.github.timofeevda.gwt.rxjs.interop.scheduler.Scheduler;
import com.github.timofeevda.gwt.rxjs.interop.subject.Subject;
import com.github.timofeevda.gwt.rxjs.interop.subscription.AnonymousSubscription;
import com.github.timofeevda.gwt.rxjs.interop.subscription.Subscription;
import com.google.gwt.dom.client.Element;
import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsType;

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Denis Timofeev <timofeevda@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 */
package com.github.timofeevda.gwt.rxjs.interop.observable;


/**
 * Contains bindings for the native Rx.Observable instance
 * <p/>
 * Methods which accept {@link Iterable} instances assume that {@link Iterable} implementor is backed by native JavaScript array
 * <p/>
 * Due to limitations of GWT's {@link JsFunction} annotation, pipe method can't be implemented using hierarchy of function
 * definitions, so certain amount of different combinations between {@link UnaryFunction} and {@link OperatorFunction}
 * is implemented
 *
 * @param <T> - observable value
 * @author dtimofeev since 20.12.2016.
 */
@JsType(namespace = "Rx", isNative = true)
@SuppressWarnings("unused")
public class Observable<T> {

    @SafeVarargs
    public native static <T> Observable<T> of(T... args);

    public native static <T> Observable<T> of(T[] args, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1);

    public native static <T> Observable<T> of(T item1, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1, T item2);

    public native static <T> Observable<T> of(T item1, T item2, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1, T item2, T item3);

    public native static <T> Observable<T> of(T item1, T item2, T item3, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4, T item5);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4, T item5, Scheduler scheduler);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4, T item5, T item6);

    public native static <T> Observable<T> of(T item1, T item2, T item3, T item4, T item5, T item6, Scheduler scheduler);

    public native static <T> Observable<T[]> forkJoin(Observable<? extends T> v1,
                                                      Observable<? extends T> v2);

    public native static <T> Observable<T[]> forkJoin(Observable<? extends T> v1,
                                                      Observable<? extends T> v2,
                                                      Observable<? extends T> v3);

    public native static <T> Observable<T[]> forkJoin(Observable<? extends T> v1,
                                                      Observable<? extends T> v2,
                                                      Observable<? extends T> v3,
                                                      Observable<? extends T> v4);

    public native static <T> Observable<T[]> forkJoin(Observable<? extends T> v1,
                                                      Observable<? extends T> v2,
                                                      Observable<? extends T> v3,
                                                      Observable<? extends T> v4,
                                                      Observable<? extends T> v5);

    public native static <T> Observable<T[]> forkJoin(Observable<? extends T> v1,
                                                      Observable<? extends T> v2,
                                                      Observable<? extends T> v3,
                                                      Observable<? extends T> v4,
                                                      Observable<? extends T> v5,
                                                      Observable<? extends T> v6);

    public native static <T, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                       Func1<? super T, ? extends R> mapper);

    public native static <T, T2, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                           Observable<? extends T2> v2,
                                                           Func2<? super T, ? super T2, ? extends R> mapper);

    public native static <T, T2, T3, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                               Observable<? extends T2> v2,
                                                               Observable<? extends T3> v3,
                                                               Func3<? super T, ? super T2, ? super T3, ? extends R> mapper);

    public native static <T, T2, T3, T4, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                                   Observable<? extends T2> v2,
                                                                   Observable<? extends T3> v3,
                                                                   Observable<? extends T4> v4,
                                                                   Func4<? super T, ? super T2, ? super T3, ? super T4, ? extends R> mapper);

    public native static <T, T2, T3, T4, T5, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                                       Observable<? extends T2> v2,
                                                                       Observable<? extends T3> v3,
                                                                       Observable<? extends T4> v4,
                                                                       Observable<? extends T5> v5,
                                                                       Func5<? super T, ? super T2, ? super T3, ? super T4, ? super T5, ? extends R> mapper);

    public native static <T, T2, T3, T4, T5, T6, R> Observable<R> forkJoin(Observable<? extends T> v1,
                                                                           Observable<? extends T2> v2,
                                                                           Observable<? extends T3> v3,
                                                                           Observable<? extends T4> v4,
                                                                           Observable<? extends T5> v5,
                                                                           Observable<? extends T6> v6,

                                                                           Func6<? super T, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? extends R> mapper);
