text:
package org.jgroups.perf;

import org.HdrHistogram.AbstractHistogram;
import org.HdrHistogram.Histogram;
import org.jgroups.*;
import org.jgroups.annotations.Property;
import org.jgroups.blocks.MethodCall;
import org.jgroups.blocks.RequestOptions;
import org.jgroups.blocks.ResponseMode;
import org.jgroups.blocks.RpcDispatcher;
import org.jgroups.blocks.atomic.SyncCounter;
import org.jgroups.conf.ClassConfigurator;
import org.jgroups.protocols.TP;
import org.jgroups.raft.blocks.CounterService;
import org.jgroups.tests.perf.PerfUtil;
import org.jgroups.tests.perf.PerfUtil.Config;
import org.jgroups.util.*;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * Tests performance of {@link org.jgroups.raft.blocks.CounterService}
 * @author Bela Ban
 * @version 1.0.5
 */
public class CounterPerf implements Receiver {
    private JChannel               channel;
    private Address                local_addr;
    private RpcDispatcher          disp;
    static final String            groupname="counter-perf";
    protected final List<Address>  members=new ArrayList<>();
    protected volatile View        view;
    protected volatile boolean     looping=true;
    protected ThreadFactory        thread_factory;
    protected CounterService       counter_service;
    protected SyncCounter          counter;
    private volatile String        histogramPath;

    // ============ configurable properties ==================
    @Property protected int     num_threads=100;
    @Property protected int     time=30; // in seconds
    @Property protected boolean print_updaters;
    @Property protected boolean print_details;
    @Property protected long    timeout=60000; // ms
    @Property protected int     range=10;
    @Property protected String  benchmark="sync";
    // ... add your own here, just don't forget to annotate them with @Property
    // =======================================================

    private static final Method[] METHODS=new Method[4];
    private static final short START                 =  0;
    private static final short GET_CONFIG            =  1;
    private static final short SET                   =  2;
    private static final short QUIT_ALL              =  3;

    protected static final Field NUM_THREADS, TIME, TIMEOUT, PRINT_INVOKERS, PRINT_DETAILS, RANGE, BENCHMARK;
    protected static final String COUNTER="counter";

    protected static final String format=
      "[1] Start test [2] View [4] Threads (%d) [6] Time (%s) [r] Range (%d)" +
        "\n[t] incr timeout (%s) [d] details (%b)  [i] print updaters (%b)" +
        "\n[b] benchmark mode (%s)" +
        "\n[v] Version [x] Exit [X] Exit all %s";

    private static final Map<String, Supplier<CounterBenchmark>> BENCHMARKS_MODES=new HashMap<>();

    static {
        try {
            METHODS[START]      = CounterPerf.class.getMethod("startTest");
            METHODS[GET_CONFIG] = CounterPerf.class.getMethod("getConfig");
            METHODS[SET]        = CounterPerf.class.getMethod("set", String.class, Object.class);
            METHODS[QUIT_ALL]   = CounterPerf.class.getMethod("quitAll");

            NUM_THREADS=Util.getField(CounterPerf.class, "num_threads", true);
            TIME=Util.getField(CounterPerf.class, "time", true);
            TIMEOUT=Util.getField(CounterPerf.class, "timeout", true);
            PRINT_INVOKERS=Util.getField(CounterPerf.class, "print_updaters", true);
            PRINT_DETAILS=Util.getField(CounterPerf.class, "print_details", true);
            RANGE=Util.getField(CounterPerf.class, "range", true);
            BENCHMARK = Util.getField(CounterPerf.class, "benchmark", true);
            PerfUtil.init();
            ClassConfigurator.addIfAbsent((short)1050, UpdateResult.class);

            BENCHMARKS_MODES.put("sync", SyncBenchmark::new);
            BENCHMARKS_MODES.put("async", AsyncCounterBenchmark::new);
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void init(String props, String name, int bind_port, boolean use_fibers, String histogram_path) throws Throwable {
        histogramPath = histogram_path;
        if (histogramPath != null) {
            System.out.println("Histogram enabled! Will be stored into " + histogramPath);
        }
        thread_factory=new DefaultThreadFactory("updater", false, true)
          .useFibers(use_fibers);
        if(use_fibers && Util.fibersAvailable())
            System.out.println("-- using fibers instead of threads");

        channel=new JChannel(props).setName(name);
        if(bind_port > 0) {
            TP transport=channel.getProtocolStack().getTransport();
            transport.setBindPort(bind_port);
        }

        disp=new RpcDispatcher(channel, this).setReceiver(this).setMethodLookup(id -> METHODS[id]);
        counter_service=new CounterService(channel).raftId(name).replTimeout(this.timeout);
        channel.connect(groupname);
        local_addr=channel.getAddress();

        if(members.size() < 2)
            return;
        Address coord=members.get(0);
        Config config=disp.callRemoteMethod(coord, new MethodCall(GET_CONFIG), new RequestOptions(ResponseMode.GET_ALL, 5000));
        if(config != null) {
            applyConfig(config);
            System.out.println("Fetched config from " + coord + ": " + config + "\n");
        }
        else
            System.err.println("failed to fetch config from " + coord);
    }

    void stop() {
        Util.close(disp, channel);
    }

    protected void stopEventLoop() {
        looping=false;
        Util.close(channel);
    }

    public void viewAccepted(View new_view) {
        this.view=new_view;
        System.out.println("** view: " + new_view);
        members.clear();
        members.addAll(new_view.getMembers());
    }

    // =================================== callbacks ======================================

    public UpdateResult startTest() throws Throwable {
        System.out.printf("running for %d seconds\n", time);

        Supplier<CounterBenchmark> benchmarkSupplier = BENCHMARKS_MODES.get(benchmark.toLowerCase());
        if (benchmarkSupplier == null) {
            String msg = String.format("Benchmark %s not found!", benchmark);
            System.out.println(msg);
            throw new IllegalArgumentException(msg);
        }

        try (CounterBenchmark bm = benchmarkSupplier.get()) {
            bm.init(num_threads, thread_factory, this::getDelta, counter);

            long start = System.currentTimeMillis();
            bm.start();

            long interval = (long) ((time * 1000.0) / 10.0);
            for (int i = 1; i <= 10; i++) {
                Util.sleep(interval);
                System.out.printf("%d: %s\n", i, printAverage(start, bm));
            }

            bm.stop();
            bm.join();
            long total_time = System.currentTimeMillis() - start;

            System.out.println();
            Histogram avg_incrs = bm.getResults(print_updaters, avgMinMax -> print(avgMinMax, print_details));
            if (print_updaters)
                System.out.printf("\navg over all updaters: %s\n", print(avg_incrs, print_details));

            System.out.printf("\ndone (in %s ms)\n", total_time);

            if (histogramPath != null) {
                String fileName = String.format("histogram_%s_%s.hgrm", counter_service.raftId(), this.benchmark);
                Path filePath = Path.of(histogramPath, fileName);
                System.out.println("Storing histogram to " + filePath.toAbsolutePath());
                try {
                    HistogramUtil.writeTo(avg_incrs, filePath.toFile());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return new UpdateResult(bm.getTotalUpdates(), total_time, avg_incrs);
        }
    }

    public void quitAll() {
        System.out.println("-- received quitAll(): shutting down");
        stopEventLoop();
        System.exit(0);
    }

    protected static String printAverage(long start_time, CounterBenchmark benchmark) {
        long tmp_time=System.currentTimeMillis() - start_time;
        long incrs=benchmark.getTotalUpdates();
        double incrs_sec=incrs / (tmp_time / 1000.0);
        return String.format("%,.0f updates/sec (%,d updates)", incrs_sec, incrs);
    }

    public void set(String field_name, Object value) {
        Field field=Util.getField(this.getClass(),field_name);
        if(field == null)
            System.err.println("Field " + field_name + " not found");
        else {
            Util.setField(field, this, value);
            System.out.println(field.getName() + "=" + value);
        }
    }

    public Config getConfig() {
        Config config=new Config();
        for(Field field: Util.getAllDeclaredFieldsWithAnnotations(CounterPerf.class, Property.class)) {
            if(field.isAnnotationPresent(Property.class)) {
                config.add(field.getName(), Util.getField(field, this));
            }
        }
        return config;
    }

    protected void applyConfig(Config config) {
        for(Map.Entry<String,Object> entry: config.values().entrySet()) {
            Field field=Util.getField(getClass(), entry.getKey());
            Util.setField(field, this, entry.getValue());
        }
    }

    // ================================= end of callbacks =====================================

    public void eventLoop() {
        boolean counter_available;
        long cnt=0;
        while(looping) {
            try {
                try {
                    cnt=getCounter();
                    counter_available=true;
                }
                catch(Throwable t) {
                    counter_available=false;
                }

                int c=Util.keyPress(String.format(format, num_threads, Util.printTime(time, TimeUnit.MILLISECONDS),
                                                  range, Util.printTime(timeout, TimeUnit.MILLISECONDS),
                                                  print_details, print_updaters, benchmark,
                                                  counter_available? String.format(" (counter=%d)\n", cnt) : "\n"));
                switch(c) {
                    case '1':
                        startBenchmark();
                        break;
                    case '2':
                        printView();
                        break;
                    case '4':
                        changeFieldAcrossCluster(NUM_THREADS, Util.readIntFromStdin("Number of updater threads: "));
                        break;
                    case '6':
                        changeFieldAcrossCluster(TIME, Util.readIntFromStdin("Time (secs): "));
                        break;
                    case 'd':
                        changeFieldAcrossCluster(PRINT_DETAILS, !print_details);
                        break;
                    case 'i':
                        changeFieldAcrossCluster(PRINT_INVOKERS, !print_updaters);
                        break;
                    case 't':
                        changeFieldAcrossCluster(TIMEOUT, Util.readIntFromStdin("update timeout (ms): "));
                        break;
                    case 'r':
                        changeFieldAcrossCluster(RANGE, Util.readIntFromStdin("range: "));
                        break;
                    case 'b':
                        changeFieldAcrossCluster(BENCHMARK, Util.readStringFromStdin("benchmark mode: "));
                        break;
                    case 'v':
                        System.out.printf("Version: %s, Java version: %s\n", Version.printVersion(),
                                          System.getProperty("java.vm.version", "n/a"));
                        break;
                    case 'x':
                    case -1:
                        looping=false;
                        break;
                    case 'X':
                        try {
                            RequestOptions options=new RequestOptions(ResponseMode.GET_NONE, 0)
                              .flags(Message.Flag.OOB, Message.Flag.DONT_BUNDLE, Message.Flag.NO_FC);
                            disp.callRemoteMethods(null, new MethodCall(QUIT_ALL), options);
                            break;
                        }
                        catch(Throwable t) {
                            System.err.println("Calling quitAll() failed: " + t);
                        }
                        break;
                    default:
                        break;
                }
            }
            catch(Throwable t) {
                t.printStackTrace();
            }
        }
        stop();
    }

    /** Kicks off the benchmark on all cluster nodes */
    void startBenchmark() {
        RspList<UpdateResult> responses;
        try {
            RequestOptions options=new RequestOptions(ResponseMode.GET_ALL, 0)
              .flags(Message.Flag.OOB, Message.Flag.DONT_BUNDLE, Message.Flag.NO_FC);
            responses=disp.callRemoteMethods(null, new MethodCall(START), options);
        }
        catch(Throwable t) {
            System.err.println("starting the benchmark failed: " + t);
            return;
        }

        long total_incrs=0;
        long total_time=0;
        Histogram globalHistogram=null;

        System.out.println("\n======================= Results: ===========================");
        for(Map.Entry<Address,Rsp<UpdateResult>> entry: responses.entrySet()) {
            Address mbr=entry.getKey();
            Rsp<UpdateResult> rsp=entry.getValue();
            UpdateResult result=rsp.getValue();
            if(result != null) {
                total_incrs+=result.num_updates;
                total_time+=result.total_time;
                if(globalHistogram == null)
                    globalHistogram=result.histogram;
                else
                    globalHistogram.add(result.histogram);
            }
            System.out.println(mbr + ": " + result);
        }
        double total_reqs_sec=total_incrs / ( total_time/ 1000.0);
        System.out.println("\n");
        System.out.println(Util.bold(String.format("Throughput: %,.2f updates/sec/node\n" +
                                                   "Time:       %s / update\n",
                                                   total_reqs_sec, print(globalHistogram, print_details))));
        System.out.println("\n\n");
    }

    protected void changeFieldAcrossCluster(Field field, Object value) throws Exception {
        disp.callRemoteMethods(null, new MethodCall(SET, field.getName(), value), RequestOptions.SYNC());
    }

    protected void printView() {
        System.out.printf("\n-- local: %s, view: %s\n", local_addr, view);
        try {
            System.in.skip(System.in.available());
        }
        catch(Exception ignored) {
        }
    }

    protected static String print(AbstractHistogram histogram, boolean details) {
        double avg = histogram.getMean();
        return details? String.format("min/avg/max = %d/%f/%s", histogram.getMinValue(), avg, histogram.getMaxValue()) :
          String.format("%s", Util.printTime(avg, TimeUnit.NANOSECONDS));
    }

    protected long getCounter() throws Exception {
        if(counter == null)
            counter=counter_service.getOrCreateCounter(COUNTER, 0);
        return counter.get();
    }

    protected int getDelta() {
        long random=Util.random(range);
        int retval=(int)(tossWeightedCoin(.5)? -random : random);
        if(retval < 0 && counter.getLocal() < 0)
            retval=-retval;
        return retval;
    }

    public static boolean tossWeightedCoin(double probability) {
        if(probability >= 1)
            return true;
        if(probability <= 0)
            return false;
        long r=Util.random(1000);
        long cutoff=(long)(probability * 1000);
        return r <= cutoff;
    }

    protected static class UpdateResult implements Streamable {
        protected long          num_updates;
        protected long          total_time;     // in ms
        protected Histogram     histogram; // in ns

        public UpdateResult() {
        }

        public UpdateResult(long num_updates, long total_time, Histogram histogram) {
            this.num_updates=num_updates;
            this.total_time=total_time;
            this.histogram=histogram;
        }

        @Override
        public void writeTo(DataOutput out) throws IOException {
            Bits.writeLongCompressed(num_updates, out);
            Bits.writeLongCompressed(total_time, out);
            Util.objectToStream(histogram, out);
        }

        @Override
        public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
            num_updates=Bits.readLongCompressed(in);
            total_time=Bits.readLongCompressed(in);
            histogram = Util.objectFromStream(in);
        }

        public String toString() {
            double total_reqs_per_sec=num_updates / (total_time / 1000.0);
            return String.format("%,.2f updates/sec (%,d updates, %s / update)", total_reqs_per_sec, num_updates,
                                 Util.printTime(histogram.getMean(), TimeUnit.NANOSECONDS));
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String  props=null, name=null, histogram_path = null;
        boolean run_event_loop=true, use_fibers=true;
        int port=0;

        for(int i=0; i < args.length; i++) {
            if("-props".equals(args[i])) {
                props=args[++i];
                continue;
            }
            if("-name".equals(args[i])) {
                name=args[++i];
                continue;
            }
            if("-nohup".equals(args[i])) {
                run_event_loop=false;
                continue;
            }
            if("-port".equals(args[i])) {
                port=Integer.parseInt(args[++i]);
                continue;
            }
            if("-use_fibers".equals(args[i])) {
                use_fibers=Boolean.parseBoolean(args[++i]);
                continue;
            }
            if ("-histogram".equals(args[i])) {
                histogram_path = args[++i];
                continue;
            }
            help();
            return;
        }

        if(name == null)
            throw new IllegalArgumentException("name (raft-id) must be set");

        CounterPerf test=null;
        try {
            test=new CounterPerf();
            test.init(props, name, port, use_fibers, histogram_path);
            if(run_event_loop)
                test.eventLoop();
            else {
                for(;;)
                    Util.sleep(60000);
            }
        }
        catch(Throwable ex) {
            ex.printStackTrace();
            if(test != null)
                test.stop();
        }
    }

    static void help() {
        System.out.println("CounterPerf [-props <props>] [-name name] [-nohup] [-port <bind port>] " +
                             "[-use_fibers <true|false>] [-histogram /path/to/write/log]");
    }

}


text:
(function () {
    'use strict';

    /* Directives */

    var directives = angular.module('tasks.directives', []);

    directives.directive('taskHistoryGrid', function($compile, $http) {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                try {
                    if (typeof($('#outsideTaskHistoryTable')[0].grid) !== 'undefined') {
                        return;
                    }
                }
                catch (e) {
                    return;
                }

                var elem = angular.element(element), k, rows, activity, message, date, stackTraceElement;

                elem.jqGrid({
                    url: '../tasks/api/activity/' + scope.taskId,
                    datatype: 'json',
                    jsonReader:{
                        repeatitems:false
                    },
                    colModel: [{
                        name: 'activityType',
                        index: 'activityType',
                        sortable: false,
                        width: 50
                    }, {
                        name: 'message',
                        index: 'message',
                        sortable: false,
                        width: 220
                    }, {
                        name: 'date',
                        formatter: function (value) {
                            return moment(parseInt(value, 10)).fromNow();
                        },
                        index: 'date',
                        sortable: false,
                        width: 80
                    }, {
                       name: 'stackTraceElement',
                       index: 'stackTraceElement',
                       sortable: false,
                       hidden: true
                   }],
                    pager: '#' + attrs.taskHistoryGrid,
                    viewrecords: true,
                    gridComplete: function () {
                        elem.jqGrid('setLabel', 'activityType', scope.msg('task.subsection.status'));
                        elem.jqGrid('setLabel', 'message', scope.msg('task.subsection.message'));
                        elem.jqGrid('setLabel', 'date', scope.msg('task.subsection.information'));

                        $('#outsideTaskHistoryTable').children('div').width('100%');
                        $('.ui-jqgrid-htable').addClass("table-lightblue");
                        $('.ui-jqgrid-btable').addClass("table-lightblue");
                        $('.ui-jqgrid-htable').width('100%');
                        $('.ui-jqgrid-bdiv').width('100%');
                        $('.ui-jqgrid-hdiv').width('100%');
                        $('.ui-jqgrid-view').width('100%');
                        $('#t_taskHistoryTable').width('auto');
                        $('.ui-jqgrid-pager').width('100%');
                        $('.ui-jqgrid-hbox').css({'padding-right':'0'});
                        $('.ui-jqgrid-hbox').width('100%');
                        $('#outsideTaskHistoryTable').children('div').each(function() {
                            $(this).find('table').width('100%');
                        });
                        rows = $("#taskHistoryTable").getDataIDs();
                        for (k = 0; k < rows.length; k+=1) {
                            activity = $("#taskHistoryTable").getCell(rows[k],"activityType").toLowerCase();
                            message = $("#taskHistoryTable").getCell(rows[k],"message");
                            if (activity !== undefined) {
                                if (activity === 'success') {
                                    $("#taskHistoryTable").jqGrid('setCell',rows[k],'activityType','','ok',{ },'');
                                } else if (activity === 'warning') {
                                    $("#taskHistoryTable").jqGrid('setCell',rows[k],'activityType','','ok',{ },'');
                                } else if (activity === 'error') {
                                    $("#taskHistoryTable").jqGrid('setCell',rows[k],'activityType','','ok',{ },'');
                                }
                            }

                            stackTraceElement = $("#taskHistoryTable").getCell(rows[k],"stackTraceElement");
                            if (message !== undefined && activity === 'error' && stackTraceElement !== undefined && stackTraceElement !== null) {
                                $("#taskHistoryTable").jqGrid('setCell',rows[k],'message',
                                    '
' + scope.msg(message) +
                                    '  ' +
                                    scope.msg('task.button.showStackTrace') + '
' +
                                    '
' + stackTraceElement + '
'
                                    ,'ok',{ },'');
                            } else if (message !== undefined) {
                                $("#taskHistoryTable").jqGrid('setCell',rows[k],'message',scope.msg(message),'ok',{ },'');
                            }
                        }
                    }
                });
            }
        };
    });

    directives.directive('taskPanelsResize', function ($window, $timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var windowDimensions = angular.element($window), setTableSize, setListSize, widthList, widthTBody, widthTaskPanel, widthTdRecentInfo, widthListHistory;

                setTableSize = function () {
                    widthTBody = $('#table-activity').width();
                    widthTdRecentInfo = Math.floor(widthTBody - (36 * 4));
                    $('.table-recent-activity  tbody td.recent-info').css({'text-overflow':'ellipsis', 'max-width': widthTdRecentInfo, 'min-width': 30});
                };

                setListSize = function () {
                    widthList = $('#task-list').width();
                    widthTaskPanel = Math.floor(widthList - 388);
                    $('#task-list .task-element.task-long-name').css({'text-overflow':'ellipsis', 'max-width': widthTaskPanel, 'min-width': 100});
                    widthListHistory = $('.history').width();
                    widthTaskPanel = Math.floor(widthListHistory - 300);
                    $('.history .task-element.task-long-name').css({'text-overflow':'ellipsis', 'max-width': widthTaskPanel, 'min-width': 100});
                };

                scope.getWindowDimensions = function () {
                    return {
                        'h': windowDimensions.height(),
                        'w': windowDimensions.width()
                    };
                };

                scope.$watch(scope.getWindowDimensions, function () {
                     $timeout(function() {
                         setTableSize();
                         setListSize();
                     }, 500);
                }, true);

                windowDimensions.on('resize', function () {
                    scope.$apply();
                });

                $('#inner-center').on('change', function() {
                    $timeout(function() {
                        setTableSize();
                        setListSize();
                    }, 250);
                });

                $('#inner-center').trigger("change");
            }
        };
    });

    directives.directive('overflowChange', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                $(element).find('.overflowChange').livequery(function () {
                    $(this).on({
                        shown: function (e) {
                            if (!e.target.classList.contains("help-inline")) {
                                $(this).css('overflow', 'visible');
                            }
                        },
                        hide: function (e) {
                            if (!e.target.classList.contains("help-inline")) {
                                $(this).css('overflow', 'hidden');
                            }
                        }
                    });
                });
            }
        };
    });

    directives.directive('expandAccordion', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                $('.panel-group').on('show.bs.collapse', function (e) {
                    $(e.target).siblings('.panel-heading').find('.accordion-toggle i.fa-caret-right').removeClass('fa-caret-right').addClass('fa-caret-down');
                });

                $('.tasks-list').on('show.bs.collapse', function (e) {
                    $(e.target).siblings('.panel-heading').find('.accordion-toggle i.fa-caret-right').removeClass('fa-caret-right').addClass('fa-caret-down');
                });

                $('.panel-group').on('hide.bs.collapse', function (e) {
                    $(e.target).siblings('.panel-heading').find('.accordion-toggle i.fa-caret-down').removeClass('fa-caret-down').addClass('fa-caret-right');
                });

                $('.tasks-list').on('hide.bs.collapse', function (e) {
                    $(e.target).siblings('.panel-heading').find('.accordion-toggle i.fa-caret-down').removeClass('fa-caret-down').addClass('fa-caret-right');
                });
            }
        };
    });

    directives.directive('draggable', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.draggable({
                    revert: true,
                    start: function () {
                        if (element.hasClass('draggable')) {
                            element.find("div:first-child").popover('hide');
                        }
                    }
                });
            }
        };
    });

    directives.directive('droppable', function (ManageTaskUtils, $compile) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.droppable({
                    drop: function (event, ui) {
                        var parent = scope, value, eventKey, dragElement, browser, emText, dataSource,
                            position = function (dropElement, dragElement) {
                                var sel, range, space = document.createTextNode(''), el, frag, node, lastNode, rangeInDropElem;

                                if (window.getSelection) {
                                    sel = window.getSelection();

                                    if (sel.getRangeAt && sel.rangeCount && sel.anchorNode.parentNode.tagName.toLowerCase() !== 'span') {
                                        range = sel.getRangeAt(0);
                                        rangeInDropElem = range.commonAncestorContainer.parentNode === dropElement[0] || range.commonAncestorContainer === dropElement[0] || range.commonAncestorContainer.parentNode.parentNode === dropElement[0];
                                    } else {
                                        rangeInDropElem = false;
                                    }

                                    if (rangeInDropElem) {
                                        el = document.createElement("div");
                                        el.innerHTML = dragElement[0].outerHTML;

                                        frag = document.createDocumentFragment();

                                        while ((node = el.firstChild) !== null) {
                                            lastNode = frag.appendChild(node);
                                        }

                                        $compile(frag)(scope);
                                        range.insertNode(frag);
                                        range.insertNode(space);

                                        if (lastNode) {
                                            range = range.cloneRange();
                                            range.setStartAfter(lastNode);
                                            range.collapse(true);
                                            sel.removeAllRanges();
                                            sel.addRange(range);
                                        }
                                    } else {
                                        $compile(dragElement)(scope);
                                        dropElement.append(dragElement);
                                        dropElement.append(space);
                                    }
                                } else if (document.selection && document.selection.type !== "Control") {
                                    document.selection.createRange().pasteHTML($compile(dragElement[0].outerHTML)(scope));
                                }
                            };

                        while (parent.task === undefined) {
                            parent = parent.$parent;
                        }

                        dragElement = angular.element(ui.draggable);
                        browser = parent.BrowserDetect.browser;

                        if (dragElement.hasClass('triggerField')) {
                            switch (element.data('type')) {
                            case 'DATE': emText = 'task.placeholder.dateOnly'; break;
                            case 'TIME': emText = 'task.placeholder.timeOnly'; break;
                            case 'BOOLEAN': emText = 'task.placeholder.booleanOnly'; break;
                            default:
                            }

                            if (!(dragElement.data('popover') === 'no' && element.data('type') !== 'format')){
                                if (emText !== undefined) {
                                    element.empty();
                                    element.append('' + parent.msg(emText) + '');
                                }

                                element.find('em').remove();

                                dragElement = dragElement.clone();
                                dragElement.css("position", "relative");
                                dragElement.css("left", "0px");
                                dragElement.css("top", "0px");
                                dragElement.attr("unselectable", "on");

                                if ((dragElement.data('type') !== 'INTEGER' || dragElement.data('type') !== 'DOUBLE') && dragElement.data('popover') !== 'no') {
                                    if (dragElement.data('type') === 'UNICODE' || dragElement.data('type') === 'TEXTAREA') {
                                        dragElement.attr("manipulationpopover", "STRING");
                                    } else if (dragElement.data('type') === 'DATE') {
                                        if (element.data('type') === 'DATE') {
                                            dragElement.attr("manipulationpopover", "DATE2DATE");
                                        } else {
                                            dragElement.attr("manipulationpopover", "DATE");
                                        }
                                    }
                                }

                                dragElement.addClass('pointer');
                                dragElement.addClass('popoverEvent');
                                dragElement.addClass('nonEditable');
                                dragElement.removeAttr("ng-repeat");
                                dragElement.removeAttr("draggable");

                                position(element, dragElement);
                            }
                        }

                        parent.$digest();
                        scope.$apply();
                    }
                });
            }
        };
    });

    directives.directive('integer', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.keypress(function (evt) {
                    var charCode = evt.which || evt.keyCode,
                        allow = [8, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // char code: <Backspace> 0 1 2 3 4 5 6 7 8 9

                    return allow.indexOf(charCode) >= 0;
                });
            }
        };
    });

    directives.directive('double', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.keypress(function (evt) {
                    var charCode = evt.which || evt.keyCode,
                        allow = [8, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]; // char code: <Backspace> . 0 1 2 3 4 5 6 7 8 9

                    return allow.indexOf(charCode) >= 0;
                });
            }
        };
    });

    directives.directive('readOnly', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.keypress(function (evt) {
                    return false;
                });
            }
        };
    });

    directives.directive('contenteditable', function ($compile) {
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ngModel) {
                var read = function () {
                    var container = $('

');
                    if (element.html() === "
") {
                        element.find('br').remove();
                    }
                    container.html($.trim(element.html()));
                    container.find('.editable').attr('contenteditable', false);
                    container.find('.popover').remove();
                    ngModel.$setViewValue(container.html());
                    scope.$apply();
                };

                if (!ngModel) {
                    return;
                }

                ngModel.$render = function () {
                    var container = $('

');
                    container.html(ngModel.$viewValue);
                    container.find('.editable').attr('contenteditable', true);

                    if (container.text() !== "") {
                        container = container.contents();
                        container.each(function () {
                            if (this.localName === 'span') {
                                return $compile(this)(scope);
                            }
                        });
                    } else {
                        container = container.html();
                    }

                    return element.html(container);
                };

                element.on('focusin', function (event) {
                    var el = this;

                    event.stopPropagation();

                    window.setTimeout(function () {
                        var sel, range;
                        if (window.getSelection && document.createRange) {
                            range = document.createRange();
                            range.selectNodeContents(el);

                            if (el.childNodes.length !== 0) {
                                range.setStartAfter(el.childNodes[el.childNodes.length - 1]);
                            }

                            range.collapse(true);

                            sel = window.getSelection();
                            sel.removeAllRanges();
                            sel.addRange(range);
                        } else if (document.body.createTextRange) {
                            range = document.body.createTextRange();

                            if (el.childNodes.length !== 0) {
                                range.moveToElementText(el.childNodes[el.childNodes.length - 1]);
                            }

                            range.collapse(true);
                            range.select();
                        }
                    }, 1);

                    if (ngModel.$viewValue !== $.trim(element.html())) {
                        return scope.$eval(read);
                    }
                });

                element.on('keypress', function (event) {
                    var type = $(this).data('type');

                    if (type !== 'TEXTAREA' && type !== 'MAP' && type !== 'LIST') {
                        return event.which !== 13;
                    }
                });

                element.bind('blur keyup change mouseleave', function (event) {
                    event.stopPropagation();
                    if (ngModel.$viewValue !== $.trim(element.html())) {
                        return scope.$eval(read);
                    }
                });

                return read;
            }
        };
    });

    directives.directive('editableContent', function ($compile, $timeout, $http, $templateCache) {
        var templateLoader;

        return {
            restrict: 'E',
            replace : true,
            transclude: true,
            scope: {
                'data': '=',
                'index': '@',
                'action': '@'
            },
            compile: function (tElement, tAttrs, scope) {
                var url = '../tasks/partials/widgets/content-editable-' + tAttrs.type.toLowerCase() + '.html',

                templateLoader = $http.get(url, {cache: $templateCache})
                    .success(function (html) {
                        tElement.html(html);
                    });

                return function (scope, element, attrs) {
                    templateLoader.then(function () {
                        element.html($compile(tElement.html())(scope));
                    });

                    $timeout(function () {
                        element.find('div').focusout();
                    });
                };
            }
        };
    });

    directives.directive('manipulationpopover', function ($compile, $templateCache, $http) {
        return {
            restrict: 'A',
            link: function (scope, el, attrs) {
                var manipulationOptions = '', title = '', loader, manType = attrs.manipulationpopover,
                elType = attrs.type, msgScope = scope, filter = scope.$parent.filter;

                while (msgScope.msg === undefined) {
                    msgScope = msgScope.$parent;
                }

                if (manType === 'STRING') {
                    title = msgScope.msg('task.stringManipulation', '');
                    loader = $http.get('../tasks/partials/widgets/string-manipulation.html', {cache: $templateCache})
                        .success(function (html) {
                            manipulationOptions = html;
                        });
                } else if (manType === 'DATE') {
                    title = msgScope.msg('task.dateManipulation', '');
                    loader = $http.get('../tasks/partials/widgets/date-manipulation.html', {cache: $templateCache})
                        .success(function (html) {
                            manipulationOptions = html;
                        });
                } else if (manType === 'DATE2DATE') {
                  title = msgScope.msg('task.dateManipulation', '');
                   loader = $http.get('../tasks/partials/widgets/date2date-manipulation.html', {cache: $templateCache})
                       .success(function (html) {
                           manipulationOptions = html;
                       });
                }

                el.on('click', function () {
                    var man = $("[ismanipulate=true]").text();
                    if (man.length === 0) {
                        angular.element(this).attr('ismanipulate', 'true');
                    } else {
                        angular.element(this).removeAttr('ismanipulate');
                    }
                });

                if (elType === 'UNICODE' || elType === 'TEXTAREA' || elType === 'DATE') {
                    el.popover({
                        template : '

',
                        title: title,
                        html: true,
                        content: function () {
                            var elem = $(manipulationOptions), element, manipulation;
                            scope.sortableArrayTemp = [];
                            $compile(elem)(msgScope);
                            msgScope.$apply(elem);
                            element = $("[ismanipulate=true]");
                            manipulation = element.attr('manipulate');

                            if (elem.length === 0) {
                                elem = $(manipulationOptions);
                                $compile(elem)(msgScope);
                                msgScope.$apply(elem);
                            }

                            elem.find("span").replaceWith(function () {
                                return $(this)[0].outerHTML;
                            });

                            if (manipulation !== undefined) {

                                scope.cleanArray = function() {
                                    var indexArray = scope.sortableArrayTemp.indexOf("");
                                    if (indexArray !== -1) {
                                        scope.sortableArrayTemp.splice(indexArray,1);
                                    }
                                };

                                scope.setSortable = function(elemen, index) {
                                // Every new manipulation should be added to options array.
                                // Add name and input for each manipulation and
                                // pattern only if manipulation takes parameters
                                var isValid = false, reg, i, options = [{
                                        name: 'join',
                                        input: 'input[join-update]',
                                        pattern: 5
                                    }, {
                                        name: 'split',
                                        input: 'input[split-update]',
                                        pattern: 6
                                    }, {
                                        name: 'substring',
                                        input: 'input[substring-update]',
                                        pattern: 10
                                    }, {
                                        name: 'dateTime',
                                        input: 'input[date-update]',
                                        pattern: 9
                                    }, {
                                        name: 'plusDays',
                                        input: 'input[manipulation-kind="plusDays"]',
                                        pattern: 9
                                    }, {
                                        name: 'minusDays',
                                        input: 'input[manipulation-kind="minusDays"]',
                                        pattern: 10
                                    }, {
                                        name: 'plusHours',
                                        input: 'input[manipulation-kind="plusHours"]',
                                        pattern: 10
                                    }, {
                                        name: 'minusHours',
                                        input: 'input[manipulation-kind="minusHours"]',
                                        pattern: 11
                                    }, {
                                        name: 'plusMinutes',
                                        input: 'input[manipulation-kind="plusMinutes"]',
                                        pattern: 12
                                    }, {
                                        name: 'minusMinutes',
                                        input: 'input[manipulation-kind="minusMinutes"]',
                                        pattern: 13
                                    }, {
                                        name: 'format',
                                        input: ''
                                    }, {
                                        name: 'capitalize',
                                        input: ''
                                    }, {
                                        name: 'toUpper',
                                        input: ''
                                    }, {
                                        name: 'toLower',
                                        input: ''
                                    }, {
                                        name: 'URLEncode',
                                        input: ''
                                    }, {
                                        name: 'parseDate',
                                        input: 'input[parsedate-update]',
                                        pattern: 10
                                    } ];

                                    for(i=0; i<options.length; i+=1) {
                                        if(elemen.indexOf(options[i].name) !== -1) {
                                            elemen = elemen.replace(elemen, options[i].name);
                                            isValid = true;
                                            break;
                                        }
                                    }

                                    if (isValid) {
                                        elem.find("span[setmanipulation="+elemen+"]").replaceWith(function () {
                                            if (elemen !== undefined && elemen.indexOf(this.attributes.getNamedItem('setmanipulation').value) !== -1) {
                                                $(this).parent().children().css({ 'display' : '' });
                                                $(this).parent().addClass('active');

                                                for(i=0; i<options.length; i+=1) {
                                                    if (options[i].input !== '') {
                                                        if (manipulation.indexOf(options[i].name) !== -1 && elemen.indexOf(options[i].name) !== -1) {
                                                            $(this.nextElementSibling).css({ 'display' : '' });
                                                            elem.find(options[i].input).val(manipulation.slice(manipulation.indexOf(options[i].name) + options[i].pattern, manipulation.indexOf(")", manipulation.indexOf(options[i].name))));
                                                            break;
                                                        }
                                                    }
                                                }

                                                $(elem[0]).append($(this).parent().clone().end());
                                            }
                                            return $(this)[0].outerHTML;
                                        });
                                    } else {
                                        // invalid manipulation
                                        reg = new RegExp("\\(.*?\\)", "g");
                                        elemen = elemen.replace(reg,"");
                                        elem.filter("ul#sortable").append('
'+elemen+'
');
                                    }
                                };

                            scope.sortableArrayTemp = manipulation.split(" ");
                            scope.sortableArrayTemp.forEach(scope.cleanArray);
                            scope.sortableArrayTemp.forEach(scope.setSortable);
                            }

                            return $compile(elem)(msgScope);
                        },
                        placement: "auto left",
                        trigger: 'manual'
                    }).click(function (event) {
                        event.stopPropagation();
                        if (!$(this).hasClass('hasPopoverShow')) {
                            var otherPopoverElem = $('.hasPopoverShow');

                            window.getSelection().removeAllRanges();

                            if (otherPopoverElem !== undefined && $(this) !== otherPopoverElem) {
                                otherPopoverElem.popover('hide');
                                otherPopoverElem.removeClass('hasPopoverShow');
                                otherPopoverElem.removeAttr('ismanipulate');
                            }
                            if (filter.key) {
                                $(this).attr('manipulate', filter.key.split("?").slice(1).join(" "));
                            }

                            $(this).addClass('hasPopoverShow');
                            $(this).attr('ismanipulate', 'true');
                            $(this).popover('show');
                        } else {
                            $(this).popover('hide');
                            $(this).removeClass('hasPopoverShow');
                            $(this).removeAttr('ismanipulate');
                            $(this).focus();
                        }

                        $('.dragpopover').click(function (event) {
                            event.stopPropagation();
                        });

                        $('.dragpopover').mousedown(function (event) {
                            event.stopPropagation();
                        });

                        $('.create-edit-task').click(function () {
                            $('.hasPopoverShow').each(function () {
                                $(this).popover('hide');
                                $(this).removeClass('hasPopoverShow');
                                $(this).removeAttr('ismanipulate');
                            });
                        });
                    });

                    el.on("manipulateChanged", function () {
                        if (filter.key) {
                            var manipulateAttributes = el.attr('manipulate'),
                                key = filter.key.split("?")[0], array, i;

                            if (manipulateAttributes !== "") {
                                array = manipulateAttributes.split(" ");

                                for (i = 0; i < array.length; i += 1) {
                                    key = key.concat("?" + array[i]);
                                }
                                key = key.replace(/\?+(?=\?)/g, '');
                            }
                            filter.key = key;
                        }
                    });
                }
            }
        };
    });

    directives.directive('datetimePicker', function () {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element.click(function () {
                    $(this).prev('input').datetimepicker('show');
                });
            }
        };
    });

    directives.directive('datetimePickerStartDateInput', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var parent = scope;

                element.datetimepicker({
                    showTimezone: true,
                    useLocalTimezone: true,
                    dateFormat: 'yy-mm-dd',
                    timeFormat: 'HH:mm z',
                    showOn: true,
                    constrainInput: false,
                    onSelect: function (dateTex) {
                        parent.task.trigger.startDate = dateTex;
                        parent.$apply();
                    }
                });
            }
        };
    });

    directives.directive('datetimePickerEndDateInput', function () {
            return {
                restrict: 'A',
                link: function (scope, element, attrs) {
                    var parent = scope;

                    element.datetimepicker({
                        showTimezone: true,
                        useLocalTimezone: true,
                        dateFormat: 'yy-mm-dd',
                        timeFormat: 'HH:mm z',
                        showOn: true,
                        constrainInput: false,
                        onSelect: function (dateTex) {
                            parent.task.trigger.endDate = dateTex;
                            parent.$apply();
                        }
                    });
                }
            };
        });

    directives.directive('datetimePickerInput', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var parent = scope;

                while (parent.selectedAction === undefined) {
                    parent = parent.$parent;
                }

                element.datetimepicker({
                    showTimezone: true,
                    useLocalTimezone: true,
                    dateFormat: 'yy-mm-dd',
                    timeFormat: 'HH:mm z',
                    showOn: true,
                    constrainInput: false,
                    onSelect: function (dateTex) {
                        parent.filter(parent.selectedAction[$(this).data('action')].actionParameters, {hidden: false})[$(this).data('index')].value = dateTex;
                        parent.$apply();
                    }
                });
            }
        };
    });

    directives.directive('timePickerInput', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var parent = scope;

                while (parent.selectedAction === undefined) {
                    parent = parent.$parent;
                }

                element.datetimepicker({
                    showTimezone: true,
                    timeOnly: true,
                    useLocalTimezone: true,
                    timeFormat: 'HH:mm z',
                    onSelect: function (dateTex) {
                        parent.filter(parent.selectedAction[$(this).data('action')].actionParameters, {hidden: false})[$(this).data('index')].value = dateTex;
                        parent.$apply();
                    }
                });
            }
        };
    });

    directives.directive('setmanipulation', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {

                var manipulateElement = $("[ismanipulate=true]"), sortableElement, manipulateAttr;
                scope.sortableArray = [];
                scope.manipulations = '';

                scope.cleanArray = function() {
                    var indexArray = scope.sortableArray.indexOf("");
                    if (indexArray !== -1) {
                        scope.sortableArray.splice(indexArray,1);
                    }
                };

                scope.normalizeArray = function(element, index) {
                    scope.sortableArray.splice(index, 1, element + ' ');
                };

                scope.setSortableArray = function() {
                manipulateAttr = manipulateElement.attr("manipulate");
                    if (manipulateAttr !== undefined) {
                        scope.sortableArray = manipulateAttr.split(" ");
                        scope.sortableArray.forEach(scope.cleanArray);
                        scope.sortableArray.forEach(scope.normalizeArray);
                    }
                };

                scope.setSortableArray();

                el.on('mouseenter mousedown', function() {

                    scope.dragStart = function(e, ui) {
                        ui.originalPosition.top = 0;
                        scope.setSortableArray();
                        ui.item.data('start', ui.item.index());
                    };

                    scope.dragEnd = function(e, ui) {
                        var start = ui.item.data('start'),
                        end = ui.item.index();
                        scope.sortableArray.splice(end, 0,
                        scope.sortableArray.splice(start, 1)[0]);
                        if(scope.sortableArray.length) {
                            scope.manipulations = scope.sortableArray.join("");
                        }
                        manipulateElement.attr('manipulate', scope.manipulations);
                        manipulateElement.trigger('manipulateChanged');
                        scope.$apply();
                    };

                    sortableElement = $('#sortable').sortable({
                        placeholder: 'ui-state-highlight',
                        axis: 'y',
                        cursor: 'move',
                        opacity: 0.95,
                        tolerance: 'pointer',
                        zIndex: 9999,
                        start: scope.dragStart,
                        update: scope.dragEnd
                    });
                });

                el.on("click", function () {
                    var manipulateElement = $("[ismanipulate=true]"), joinSeparator = "", reg, manipulation, manipulateAttributes, manipulationAttributesIndex, nonParamManip = true, i, found,
                    // Every new manipulation that takes parameter should be added to
                    // paramOptions array. Name is just a name of manipulation
                    // and id is id of input field for that manipulation
                    paramOptions = [
                        {
                            name: 'join',
                            id: '#joinSeparator'
                        },
                        {
                            name: 'split',
                            id: '#splitSeparator'
                        },
                        {
                            name: 'substring',
                            id: '#substringSeparator'
                        },
                        {
                            name: 'dateTime',
                            id: '#dateFormat'
                        },
                        {
                            name: 'plusDays',
                            id: '#plusDays'
                        },
                        {
                            name: 'minusDays',
                            id: '#minusDays'
                        },
                        {
                            name: 'plusHours',
                            id: '#plusHours'
                        },
                        {
                            name: 'minusHours',
                            id: '#minusHours'
                        },
                        {
                            name: 'plusMinutes',
                            id: '#plusMinutes'
                        },
                        {
                            name: 'minusMinutes',
                            id: '#minusMinutes'
                        },
                        {
                            name: 'parseDate',
                            id: '#parseDate'
                        },
                        {
                            name: 'format',
                            id: ''
                        }
                    ];

                    manipulation = this.getAttribute("setManipulation");
                    manipulateAttributes = manipulateElement.attr("manipulate") || "";
                    document.getSelection().removeAllRanges();

                    if ($(this).parent(".invalid").remove().length) {
                        if (manipulateAttributes.indexOf(manipulation) !== -1) {
                            reg = new RegExp(manipulation + "(\\(.*\\))?( |$)", "g");
                            manipulateAttributes = manipulateAttributes.replace(reg, '');
                            manipulateElement.attr('manipulate', manipulateAttributes);
                            scope.setSortableArray();
                        }
                        return;
                    }

                    if (manipulateAttributes.charAt(manipulateAttributes.length - 1) !== " ") {
                        manipulateAttributes = manipulateAttributes + " ";
                    }

                    if (manipulateAttributes.indexOf(manipulation) !== -1) {
                        manipulationAttributesIndex = manipulateElement.attr("manipulate").indexOf(manipulation);

                        if (manipulation === "format") {
                            reg = new RegExp("format(\\((\\{.*\\})*\\))", "g");
                            manipulateAttributes = manipulateAttributes.replace(reg, '');
                        } else {

                            for (i = 0; i < paramOptions.length; i += 1) {
                                if(manipulation === paramOptions[i].name) {
                                    nonParamManip = false;
                                    break;
                                }
                            }

                            if (nonParamManip) {
                                reg = new RegExp(manipulation + "(\\(.*\\))?( |$)", "g");
                                manipulateAttributes = manipulateAttributes.replace(reg, '');
                            } else {
                                joinSeparator = manipulation + "\\(" + this.nextElementSibling.value + "\\)( |$)";
                                reg = new RegExp(joinSeparator, "g");
                                manipulateAttributes = manipulateAttributes.replace(reg, '');
                            }
                        }
                    } else {
                        manipulateAttributes = manipulateAttributes.replace(/ +(?= )/g, '');

                        for(i=0; i<paramOptions.length; i+=1) {
                            if(manipulation === paramOptions[i].name) {
                                if(paramOptions[i].id !== '') {
                                    $(paramOptions[i].id).val("");
                                }
                                manipulateAttributes = manipulateAttributes + manipulation + "()" + " ";
                                found = true;
                                break;
                            }
                        }
                        if(!found) {
                            manipulateAttributes = manipulateAttributes + manipulation + " ";
                        }
                    }

                    manipulateElement.attr('manipulate', manipulateAttributes);
                    manipulateElement.trigger('manipulateChanged');
                    scope.setSortableArray();

                    if (!$(this).parent().hasClass('active')) {
                        $(this).parent().children().css({ 'display' : '' });
                        $(this).parent().addClass('active');
                        $('#sortable').append($(this.parentElement).clone().end());
                    } else {
                        $(this).parent().children('.glyphicon').css({ 'display' : 'none' });
                        $(this.nextElementSibling).css({ 'display' : 'none' });
                        $(this).parent().removeClass("active");
                        $('#sortable-no').append($(this.parentElement).clone().end());
                    }
                });
            }
        };
    });

    directives.directive('joinUpdate', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var manipulateElement = $("[ismanipulate=true]"),
                        manipulation = "join(" + $("#joinSeparator").val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp("join\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('splitUpdate', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var manipulateElement = $("[ismanipulate=true]"),
                        manipulation = "split(" + $("#splitSeparator").val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp("split\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('substringUpdate', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var manipulateElement = $("[ismanipulate=true]"),
                        manipulation = "substring(" + $("#substringSeparator").val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp("substring\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('dateUpdate', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var manipulateElement = $("[ismanipulate=true]"),
                        manipulation = "dateTime(" + $("#dateFormat").val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp("dateTime\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('dateManipulationUpdate', function() {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var
                        manipKind = attrs.manipulationKind,
                        manipulateElement = $("[ismanipulate=true]"),
                        manipulation = manipKind + "(" + $("#" + manipKind).val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp(manipKind + "\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('parsedateUpdate', function () {
        return {
            restrict : 'A',
            require: '?ngModel',
            link : function (scope, el, attrs) {
                el.on("focusout focusin keyup", function (event) {
                    event.stopPropagation();
                    var manipulateElement = $("[ismanipulate=true]"),
                        manipulation = "parseDate(" + $("#parseDate").val() + ")",
                        elementManipulation = manipulateElement.attr("manipulate"),
                        regex = new RegExp("parseDate\\(.*?\\)", "g");

                    elementManipulation = elementManipulation.replace(regex, manipulation);
                    manipulateElement.attr("manipulate", elementManipulation);
                    manipulateElement.trigger('manipulateChanged');
                });
            }
        };
    });

    directives.directive('selectEvent', function() {
        return function(scope, element, attrs) {
            var elm = angular.element(element);
            elm.click(function (event) {
                var li = elm.parent('li'),
                    content = $(element).find('.content-task'),
                    visible = content.is(":visible"),
                    other = $('[select-event=' + attrs.selectEvent + ']').not('#' + $(this).attr('id')),
                    contentOffsetTop = $('#inner-center').offset().top,
                    setContentCss;

                    other.parent('li').not('.selectedTrigger').removeClass('active');
                    other.find('.content-task').hide();

                    if (visible) {
                        if (!li.hasClass('selectedTrigger')) {
                            li.removeClass('active');
                        }

                        content.hide();
                    } else {
                        li.addClass('active');
                        content.show();
                        content.removeClass('left right bottom top');
                        content.parent().find('div.arrow').css({'top':'50%'});
                        setContentCss = function () {
                            if ($(content).children('.popover-content').height() > 200) {
                                content.css({'height': '290'});
                                content.children('.popover-content').css({'height': 200, 'overflow-y': 'auto'});
                                content.parent().find('div.arrow').css({'top': function () {return ($(content).height()/2);}});
                                content.css({'top': function () {return -($(content).height()/2  - 60);}});
                            } else {
                                content.css({'top': function () {return -($(content).height()/2 - 60);}});
                            }
                        };
                        if (($(window).width() - $(this).offset().left) < 138 + $(content).width() && $(this).offset().left > $(content).width() && $(this).parent().parent().offset().left + ($(content).width()/2) < $(this).offset().left) {
                            content.addClass('left');
                            content.css({'left': function () {return -($(content).width() + 3);}});
                            setContentCss();
                        } else if (($(window).width() - ($(this).offset().left + 138)) > $(content).width() && !($(this).parent().parent().offset().left + ($(content).width()/2) < $(this).offset().left && $(this).offset().top - contentOffsetTop - 71 > 200 && $(content).children('.popover-content').height() + 11 < 200))  {
                            content.addClass('right');
                            content.css({'left': '125px'});
                            setContentCss();
                        } else if ($(this).offset().top - contentOffsetTop - 71 > 200 && $(content).children('.popover-content').height() + 11 < 200 && ($(window).width() - ($(this).offset().left + 108)) > $(content).width()) {
                            content.addClass('top');
                            content.children('.popover-content').css({'height': function () {return (content.children('.popover-content').children('ul').height()+15);}, 'overflow-y': 'auto'});
                            content.css({'height': function () {return (content.children('.popover-content').children('ul').height() + content.children('.popover-title').height() + 33);}});
                            content.css({'top': function () {return -($(content).height() + 8);}});
                            content.css({'left': function () {return -($(content).width()/2 - 70);}});
                            content.parent().find('div.arrow').css({'top': function() {return ($(content).height() + 2);}});
                        } else {
                            content.addClass('bottom');
                            content.css({'top': '115px', 'height': '240'});
                            if ($(content).children('.popover-content').children('ul').height() < 200) {
                                content.css({'height': function () {return (content.children('.popover-content').children('ul').height() + content.children('.popover-title').height() + 30);}});
                            } else {
                                content.children('.popover-content').css({'height': 200, 'overflow-y': 'auto'});
                            }
                            if (($(window).width() - ($(this).offset().left + 108)) < $(content).width()) {
                                content.css({'left': function () {return -($(content).width()/2 - 40);}});
                            } else {
                                content.css({'left': function () {return -($(content).width()/2 - 80);}});
                            }
                            content.parent().find('div.arrow').css({'top':'-11px'});
                        }
                    }
            });
        };
    });

    directives.directive('helpPopover', function($compile, $http) {
        return function(scope, element, attrs) {
            var msgScope = scope;

            while (msgScope.msg === undefined) {
                msgScope = msgScope.$parent;
            }

            $http.get('../tasks/partials/help/' + attrs.helpPopover + '.html').success(function (html) {
                $(element).popover({
                    placement: 'top',
                    trigger: 'hover',
                    html: true,
                    content: function() {
                        var elem = angular.element(html);

                        $compile(elem)(msgScope);
                        msgScope.$apply(elem);

                        return $compile(elem)(msgScope);
                    }
                });
            });
        };
    });

    directives.directive('divPlaceholder', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                var parent = scope, curText;

                while (parent.msg === undefined) {
                    parent = parent.$parent;
                }

                curText = parent.msg(attrs.divPlaceholder);

                if (!element.text().trim().length) {
                    element.html('' + curText + '');
                }

                element.focusin(function() {
                    if ($(this).text().toLowerCase() === curText.toLowerCase() || !$(this).text().length) {
                        $(this).empty();
                    }
                });

                element.focusout(function() {
                    if ($(this).text().toLowerCase() === curText.toLowerCase() || !$(this).text().length) {
                        $(this).html('' + curText + '');
                    }
                });
            }
        };
    });

    directives.directive('actionSortableCursor', function () {
       return {
           restrict: 'A',
           link: function (scope, element, attrs) {
                angular.element(element).on({
                    mousedown: function () {
                        $(this).css('cursor', 'move');
                    },
                    mouseup: function () {
                        $(this).css('cursor', 'auto');
                    }
                });
           }
       };
    });

    directives.directive('actionsPopover', function () {
       return {
           restrict: 'A',
           link: function (scope, element, attrs) {
                angular.element(element).popover({
                    placement: 'right',
                    trigger: 'hover',
                    html: true,
                    content: function () {
                        var html = angular.element('
'),
                            actions = (scope.item && scope.item.task && scope.item.task.actions) || scope.actions || [];

                        angular.forEach(actions, function (action) {
                            var div = angular.element('
'),
                                img = angular.element(''),
                                name = angular.element('');

                            img.attr('src', '../tasks/api/channel/icon?moduleName=' + action.moduleName);
                            img.addClass('task-list-img');

                            name.text(scope.msg(action.channelName) + ": " + scope.msg(action.displayName));

                            div.append(img);
                            div.append(name);

                            html.append(div);
                        });

                        return html;
                    }
                });
           }
       };
    });

    directives.directive('triggerPopover', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                angular.element(element).popover({
                    placement: 'right',
                    trigger: 'hover',
                    html: true,
                    content: function () {
                        var html = angular.element('
'),
                            div = angular.element('
'),
                            img = angular.element(''),
                            name = angular.element('');

                        img.attr('src', '../tasks/api/channel/icon?moduleName=' + scope.item.task.trigger.moduleName);
                        img.addClass('task-list-img');
                        name.text(scope.msg(scope.item.task.trigger.channelName) + ": " + scope.msg(scope.item.task.trigger.displayName));
                        div.append(img);
                        div.append(name);
                        html.append(div);

                        return html;
                    }
                });
            }
        };
    });

    directives.directive('taskStopPropagation', function () {
        return function(scope, elem, attrs) {
            elem.on('click', function (e) {
               e.stopPropagation();
            });
        };
    });

}());

redpajama_set_name: RedPajamaGithub


text:
{% extends "base/base.html" %}
{% load roots_tags  %}

{% block content_wrapper %}

{% define def_content_heading %}
{% block content_heading %}{% endblock %}
{% enddefine %}

{% define def_content %}
{% block content %}{% endblock %}
{% enddefine %}

{% define def_content_footer %}
{% block content_footer %}{% endblock %}
{% enddefine %}

{% include "base/panel.html" with content_heading=def_content_heading content=def_content content_footer=def_content_footer %}

{% endblock %}


text:
package com.panoramagl;

import java.util.List;

import com.panoramagl.enumerations.PLCameraAnimationType;
import com.panoramagl.hotspots.PLIHotspot;
import com.panoramagl.ios.UITouch;
import com.panoramagl.ios.structs.CGPoint;
import com.panoramagl.ios.structs.UIAcceleration;
import com.panoramagl.loaders.PLILoader;
import com.panoramagl.structs.PLPosition;
import com.panoramagl.transitions.PLITransition;

import android.hardware.SensorEvent;
import android.view.MotionEvent;

public abstract class PLViewListener
{
	/**touch methods*/

	public void onTouchesBegan(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	public void onTouchesMoved(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	public void onTouchesEnded(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	public boolean onShouldBeginTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
		return true;
	}

	public void onDidBeginTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	public boolean onShouldMoveTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
		return true;
	}

	public void onDidMoveTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	public boolean onShouldEndTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
		return true;
	}

	public void onDidEndTouching(PLIView view, List<UITouch> touches, MotionEvent event)
	{
	}

	/**accelerate methods*/

	public boolean onShouldAccelerate(PLIView view, UIAcceleration acceleration, SensorEvent event)
	{
		return true;
	}

	public void onDidAccelerate(PLIView view, UIAcceleration acceleration, SensorEvent event)
	{
	}

	/**inertia methods*/

	public boolean onShouldBeginInertia(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
		return true;
	}

	public void onDidBeginInertia(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	public boolean onShouldRunInertia(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
		return true;
	}

	public void onDidRunInertia(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	public void onDidEndInertia(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	/**scrolling methods*/

	public boolean onShouldBeingScrolling(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
		return true;
	}

	public void onDidBeginScrolling(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	public void onDidEndScrolling(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	/**zooming methods*/

	public boolean onShouldBeginZooming(PLIView view)
	{
		return true;
	}

	public void onDidBeginZooming(PLIView view, CGPoint startPoint, CGPoint endPoint)
	{
	}

	public boolean onShouldRunZooming(PLIView view, float distance, boolean isZoomIn, boolean isZoomOut)
	{
		return true;
	}

	public void onDidRunZooming(PLIView view, float distance, boolean isZoomIn, boolean isZoomOut)
	{
	}

	public void onDidEndZooming(PLIView view)
	{
	}

	/**reset methods*/

	public boolean onShouldReset(PLIView view)
	{
		return true;
	}

	public void onDidReset(PLIView view)
	{
	}

	/**camera methods*/

	public void onDidBeginCameraAnimation(PLIView view, Object sender, PLICamera camera, PLCameraAnimationType type)
	{
	}

	public void onDidEndCameraAnimation(PLIView view, Object sender, PLICamera camera, PLCameraAnimationType type)
	{
	}

	public void onDidResetCamera(PLIView view, Object sender, PLICamera camera)
	{
	}

	public void onDidLookAtCamera(PLIView view, Object sender, PLICamera camera, float pitch, float yaw, boolean animated)
	{
	}

	public void onDidRotateCamera(PLIView view, Object sender, PLICamera camera, float pitch, float yaw, float roll)
	{
	}

	public void onDidFovCamera(PLIView view, Object sender, PLICamera camera, float fov, boolean animated)
	{
	}

	/**scene element methods*/

	public void onDidOverElement(PLIView view, PLISceneElement element, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	public void onDidClickElement(PLIView view, PLISceneElement element, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	public void onDidOutElement(PLIView view, PLISceneElement element, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	/**hotspot methods*/

	public void onDidOverHotspot(PLIView view, PLIHotspot hotspot, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	public void onDidClickHotspot(PLIView view, PLIHotspot hotspot, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	public void onDidOutHotspot(PLIView view, PLIHotspot hotspot, CGPoint screenPoint, PLPosition scene3DPoint)
	{
	}

	/**transition methods*/

	public void onDidBeginTransition(PLIView view, PLITransition transition)
	{
	}

	public void onDidProcessTransition(PLIView view, PLITransition transition, int progressPercentage)
	{
	}

	public void onDidStopTransition(PLIView view, PLITransition transition, int progressPercentage)
	{
	}

	public void onDidEndTransition(PLIView view, PLITransition transition)
	{
	}

	/**loader methods*/

	public void onDidBeginLoader(PLIView view, PLILoader loader)
	{
	}

	public void onDidCompleteLoader(PLIView view, PLILoader loader)
	{
	}

	public void onDidStopLoader(PLIView view, PLILoader loader)
	{
	}

	public void onDidErrorLoader(PLIView view, PLILoader loader, String error)
	{
	}
}


text:
if [ "$1" == "" ]; then
    echo Usage: travisScript.sh '<name of plugin to be tested> <name of project to be tested>'
    exit 2
fi
PLUGIN_NAME="$1"
cd "$TRAVIS_BUILD_DIR"/../PocketMine

if [ "$2" == "" ]; then
    PROJECT_NAME="$1"
else
    PROJECT_NAME="$2"
fi

echo Staging "$PROJECT_NAME".phar
cp unstaged/"$PROJECT_NAME".phar plugins/"$PROJECT_NAME".phar || (echo "Project $PROJECT_NAME is not built in this commit" && exit 0)

echo Loading .travis.pmcommands.txt
pmcommands_file="$TRAVIS_BUILD_DIR"/.travis.pmcommands.txt
if [ ! -f "$pmcommands_file" ]; then
    echo version >> "$pmcommands_file"
    echo check-plugins >> "$pmcommands_file"
fi
egrep "^stop\$" "$pmcommands_file" || (echo stop >> "$pmcommands_file" && echo >> "$pmcommands_file")

cmds_to_run="$(cat "$pmcommands_file")"
echo Running the following commands:
echo ===
echo "$cmds_to_run"
echo ===

echo Server plugins directory:
ls plugins/*.phar
php PocketMine-MP.phar --no-wizard --enable-ansi --settings.asyncworker=2 --debug.level=2 --debug.commands=true --disable-readline --settings.enable-dev-builds=1 --pluginchecker.target="$PLUGIN_NAME" < "$pmcommands_file" | tee stdout.log

rm plugins/"$PROJECT_NAME".phar

if grep "PluginChecker passed" stdout.log >/dev/null; then
    if grep "PluginChecker disabled fluently" stdout.log >/dev/null; then
        echo Test passed
        exit 0
    else
        echo Server did not shutdown normally
        exit 1
    fi
else
    echo Plugin could not be loaded
    exit 1
fi


text:
``extends``
===========

The ``extends`` tag can be used to extend a template from another one.

.. note::

    Like PHP, Twig does not support multiple inheritance. So you can only have
    one extends tag called per rendering. However, Twig supports horizontal
    :doc:`reuse<use>`.

Let's define a base template, ``base.html``, which defines a simple HTML
skeleton document:

.. code-block:: html+jinja

    <!DOCTYPE html>

            {% block head %}
                <link rel="stylesheet" href="style.css" />
                <title>{% block title %}{% endblock %} - My Webpage</title>
            {% endblock %}

{% block content %}{% endblock %}

                {% block footer %}
                    © Copyright 2011 by you.
                {% endblock %}

In this example, the :doc:`block<block>` tags define four blocks that child
templates can fill in. All the ``block`` tag does is to tell the template
engine that a child template may override those portions of the template.

Child Template
--------------

A child template might look like this:

.. code-block:: jinja

    {% extends "base.html" %}

    {% block title %}Index{% endblock %}
    {% block head %}
        {{ parent() }}

    {% endblock %}
    {% block content %}

Index

            Welcome on my awesome homepage.

    {% endblock %}

The ``extends`` tag is the key here. It tells the template engine that this
template "extends" another template. When the template system evaluates this
template, first it locates the parent. The extends tag should be the first tag
in the template.

Note that since the child template doesn't define the ``footer`` block, the
value from the parent template is used instead.

You can't define multiple ``block`` tags with the same name in the same
template. This limitation exists because a block tag works in "both"
directions. That is, a block tag doesn't just provide a hole to fill - it also
defines the content that fills the hole in the *parent*. If there were two
similarly-named ``block`` tags in a template, that template's parent wouldn't
know which one of the blocks' content to use.

If you want to print a block multiple times you can however use the
``block`` function:

.. code-block:: jinja

    <title>{% block title %}{% endblock %}</title>

{{ block('title') }}

    {% block body %}{% endblock %}

Parent Blocks
-------------

It's possible to render the contents of the parent block by using the
:doc:`parent<../functions/parent>` function. This gives back the results of
the parent block:

.. code-block:: jinja

    {% block sidebar %}

Table Of Contents

        ...
        {{ parent() }}
    {% endblock %}

Named Block End-Tags
--------------------

Twig allows you to put the name of the block after the end tag for better
readability:

.. code-block:: jinja

    {% block sidebar %}
        {% block inner_sidebar %}
            ...
        {% endblock inner_sidebar %}
    {% endblock sidebar %}

Of course, the name after the ``endblock`` word must match the block name.

Block Nesting and Scope
-----------------------

Blocks can be nested for more complex layouts. Per default, blocks have access
to variables from outer scopes:

.. code-block:: jinja

    {% for item in seq %}

{% block loop_item %}{{ item }}{% endblock %}

    {% endfor %}

Block Shortcuts
---------------

For blocks with few content, it's possible to use a shortcut syntax. The
following constructs do the same:

.. code-block:: jinja

    {% block title %}
        {{ page_title|title }}
    {% endblock %}

.. code-block:: jinja

    {% block title page_title|title %}

Dynamic Inheritance
-------------------

Twig supports dynamic inheritance by using a variable as the base template:

.. code-block:: jinja

    {% extends some_var %}

If the variable evaluates to a ``Twig_Template`` object, Twig will use it as
the parent template::

    // {% extends layout %}

    $layout = $twig->loadTemplate('some_layout_template.twig');

    $twig->display('template.twig', array('layout' => $layout));

.. versionadded:: 1.2
    The possibility to pass an array of templates has been added in Twig 1.2.

You can also provide a list of templates that are checked for existence. The
first template that exists will be used as a parent:

.. code-block:: jinja

    {% extends ['layout.html', 'base_layout.html'] %}

Conditional Inheritance
-----------------------

As the template name for the parent can be any valid Twig expression, it's
possible to make the inheritance mechanism conditional:

.. code-block:: jinja

    {% extends standalone ? "minimum.html" : "base.html" %}

In this example, the template will extend the "minimum.html" layout template
if the ``standalone`` variable evaluates to ``true``, and "base.html"
otherwise.

.. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`


text:
FactoryGirl.define do
  factory :ecm_tournaments_set, :class => 'Ecm::Tournaments::Set' do
    ecm_tournaments_match
    first_team_score 0
    second_team_score 0
  end
end


text:
"""DataUpdateCoordinator for the Tailscale integration."""
from __future__ import annotations

from tailscale import Device, Tailscale, TailscaleAuthenticationError

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from .const import CONF_TAILNET, DOMAIN, LOGGER, SCAN_INTERVAL

class TailscaleDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Device]]):
    """The Tailscale Data Update Coordinator."""

    config_entry: ConfigEntry

    def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
        """Initialize the Tailscale coordinator."""
        self.config_entry = entry

        session = async_get_clientsession(hass)
        self.tailscale = Tailscale(
            session=session,
            api_key=entry.data[CONF_API_KEY],
            tailnet=entry.data[CONF_TAILNET],
        )

        super().__init__(hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)

    async def _async_update_data(self) -> dict[str, Device]:
        """Fetch devices from Tailscale."""
        try:
            return await self.tailscale.devices()
        except TailscaleAuthenticationError as err:
            raise ConfigEntryAuthFailed from err


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
Uses of Package kea.stopwords
</TITLE>

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Uses of Package
kea.stopwords

Packages that use kea.stopwords

kea.filters

kea.main

kea.stopwords

kea.vocab

Classes in kea.stopwords used by kea.filters

Stopwords

          Class that can test whether a given string is a stop word.

Classes in kea.stopwords used by kea.main

Stopwords

          Class that can test whether a given string is a stop word.

Classes in kea.stopwords used by kea.stopwords

Stopwords

          Class that can test whether a given string is a stop word.

Classes in kea.stopwords used by kea.vocab

Stopwords

          Class that can test whether a given string is a stop word.

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes


text:
===================
License and Credits
===================

``prometheus_async`` is licensed under the `Apache License 2 <https://choosealicense.com/licenses/apache-2.0/>`_ license.
The full license text can be also found in the `source code repository <https://github.com/hynek/prometheus_async/blob/master/LICENSE>`_.

.. _authors:

.. include:: ../AUTHORS.rst


text:
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddMeasurementsStationIdForeign extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('measurements', function (Blueprint $table) {
            $table->foreign('station_id')
                ->references('id')
                ->on('stations')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('measurements', function (Blueprint $table) {
            $table->dropForeign('measurements_station_id_foreign');
        });
    }
}