text:
/*eslint-disable no-console*/

sap.ui.define([
	"sap/ui/table/Table",
	"sap/ui/table/Column",
	"sap/ui/table/library",
	"sap/m/Text",
	"sap/m/Label",
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"sap/ui/performance/Measurement",
	"sap/base/Log",
	"sap/ui/core/Core"
], function(Table, Column, library, Text, Label, Controller, JSONModel, Measurement, Log, oCore) {
	"use strict";

	var VisibleRowCountMode = library.VisibleRowCountMode;

	Measurement.setActive(false);
	Log.setLevel(Log.Level.ERROR);

	return Controller.extend("sap.ui.table.mvc.Performance", {
		onInit: function() {
			var oSettings = localStorage.getItem("settings");
			var oView = this.getView();

			try {
				oSettings = JSON.parse(oSettings);
			} catch (e) {
			if (oSettings) {
					oSettings = null;
				}
			}

			if (!oSettings) {
				oSettings = {
					visibleRowCount: 10,
					visibleRowCountMode: VisibleRowCountMode.Auto,
					jsonModel: true,
					testSequence: ["bindTable", "renderTable"],
					dataLength: 200,
					columnCount: 10,
					autoRun: false
				};
			}

			oView.setModel(new JSONModel(oSettings), "settings");
			oView.addStyleClass("flexView");
			this.oTable = null;
			this.prepareTest();
		},

		onAfterRendering: function() {
			// Create and render the table to make sure all sources are loaded before the actual test starts.
			this.createTable();
			this.bindTable();
			this.renderTable();

			this.oTable.attachEventOnce("rowsUpdated", function() {
				this.destroyTable();
				this.clearTestResult();

				if (this.getView().getModel("settings").getProperty("/autoRun")) {
					window.setTimeout(this.runTest.bind(this), 100);
				}
			}.bind(this));
		},

		onSettingsPress: function(oEvent) {
			if (!this.oSettingsPopover) {
				this.oSettingsPopover = sap.ui.xmlfragment("sap.ui.table.mvc.PerformanceSettings", this);
				this.getView().addDependent(this.oSettingsPopover);
			}

			this.oSettingsPopover.openBy(oEvent.getSource());
		},

		onSettingsPopoverClose: function() {
			this.destroyTable();
			this.prepareTest();
			localStorage.setItem("settings", JSON.stringify((this.getView().getModel("settings").getData())));
		},

		onCreateTablePress: function() {
			this.destroyTable();
			this.clearTestResult();
			this.createMark("TestStart");
			this.createTable();
		},

		onBindTablePress: function() {
			if (!this.oTable) {
				return;
			}

			this.clearTestResult();
			this.createMark("TestStart");
			this.bindTable();
		},

		onUnbindTablePress: function() {
			if (!this.oTable) {
				return;
			}

			this.clearTestResult();
			this.createMark("TestStart");
			this.unbindTable();
		},

		onRenderTablePress: function() {
			if (!this.oTable) {
				return;
			}

			this.clearTestResult();
			this.createMark("TestStart");
			this.renderTable();
		},

		onDestroyTablePress: function() {
			if (!this.oTable) {
				return;
			}

			this.clearTestResult();
			this.createMark("TestStart");
			this.destroyTable();
		},

		onRunPress: function() {
			this.runTest();
		},

		runTest: function() {
			var aSequence = this.getView().getModel("settings").getProperty("/testSequence");

			this.destroyTable();
			this.clearTestResult();

			this.createMark("TestStart");
			this.createTable(); // Any test sequence has to start with the creation of the table.

			for (var i = 0; i < aSequence.length; i++) {
				this[aSequence[i]]();
			}
		},

		prepareTest: function() {
			var oView = this.getView();
			var oSettingsModel = oView.getModel("settings");
			var oModel;

			if (oSettingsModel.getProperty("/jsonModel")) {
				oModel = new JSONModel();
				oModel.setData(this.getTestData(oSettingsModel.getProperty("/dataLength"), oSettingsModel.getProperty("/columnCount")));
			} else {
				// start mockserver
			}

			oView.setModel(oModel);
		},

		createTable: function() {
			var oSettingsModel = this.getView().getModel("settings");
			var oSettings = oSettingsModel.getData();

			this.createMark("CreateTableStart");
			this.oTable = new Table({
				visibleRowCount: oSettings.visibleRowCount,
				visibleRowCountMode: oSettings.visibleRowCountMode,
				columns: this.createColumns(oSettings.columnCount)
			});
			this.createMeasure( "Table creation", "CreateTableStart");

			this.measureFunction(this.oTable, "onRowsUpdated");
			this.measureFunction(this.oTable, "onRowsContentUpdated");
			this.measureFunction(this.oTable, "_updateTableSizes");
			this.measureFunction(this.oTable, "refreshRows");
			this.measureFunction(this.oTable, "updateRows");

			this.oTable.addDelegate({
				onBeforeRendering: function() {
					this.createMark("RenderingStart");
					this.createMark("BeforeRenderingStart");
				},
				onAfterRendering: function() {
					this.createMark("AfterRenderingStart");
				}
			}, true, this);

			this.oTable.addDelegate({
				onBeforeRendering: function() {
					this.createMeasure("onBeforeRendering", "BeforeRenderingStart");
				},
				onAfterRendering: function() {
					this.createMeasure("onAfterRendering", "AfterRenderingStart");
					detectRenderingFinished(this);
				}
			}, false, this);

			this.getView().addDependent(this.oTable);
			this.oTable.setModel(this.getView().getModel());
			window.oTable = this.oTable;
		},

		bindTable: function() {
			var sMeasureName = "Table#bindRows";

			if (this.oTable.isBound("rows")) {
				sMeasureName += " (rebind)";
			}

			this.createMark("BindTableStart");
			this.oTable.bindRows("/");
			this.createMeasure(sMeasureName, "BindTableStart");
		},

		unbindTable: function() {
			this.createMark("UnbindTableStart");
			this.oTable.unbindRows();
			this.createMark("Table#unbindRows", "UnbindTableStart");
		},

		renderTable: function() {
			if (this.oTable.getDomRef()) {
				this.oTable.invalidate();
			} else {
				this.oTable.placeAt("tableContainer");
			}

			oCore.applyChanges();
		},

		destroyTable: function() {
			if (!this.oTable) {
				return;
			}

			this.oTable.destroy();
			this.oTable = null;
			delete window.oTable;
		},

		createTestResult: function() {
			var aPerformanceEntries = window.performance.getEntriesByType("measure");
			var oResultContainer = document.getElementById("results");

			aPerformanceEntries.forEach(function(oPerformanceEntry) {
				oResultContainer.innerHTML += "<p>" + oPerformanceEntry.name + " - " + oPerformanceEntry.duration + "</p>";
			});
		},

		clearTestResult: function() {
			window.performance.clearMarks();
			window.performance.clearMeasures();
			document.getElementById("results").innerHTML = "";
		},

		createMark: function(sName) {
			if (window.performance.getEntriesByName(sName, "mark").length === 0) {
				window.performance.mark(sName);
			}
		},

		createMeasure: function(sMeasureName, sStartMark, bKeepMark) {
			window.performance.measure(sMeasureName, sStartMark);
			if (bKeepMark !== true) {
				window.performance.clearMarks(sStartMark);
			}
		},

		measureFunction: function(oObject, sFunctionName) {
			wrap(oObject, sFunctionName, function() {
				this.createMark(sFunctionName + "Start");
			}.bind(this), function() {
				var sObjectName = oObject.getMetadata().getName().substring(oObject.getMetadata().getName().lastIndexOf(".") + 1);
				this.createMeasure(sObjectName + "#" + sFunctionName, sFunctionName + "Start");
			}.bind(this));
		},

		createColumns: function(iColumns) {
			var aColumns = [];

			this.createMark("CreateColumnsStart");

			for (var i = 0; i < iColumns; i++) {
				var oColumn = new Column({
					label: new Label({text: "m.Text"}),
					template: new Text({text: "{c" + i + "}"})
				});
				aColumns.push(oColumn);
			}

			this.createMeasure("Column creation", "CreateColumnsStart");

			return aColumns;
		},

		getTestData: function(iRows, iColumns) {
			var oDataColumns = {};
			var aDataRows = [];
			var i;
			var j;

			for (i = 0; i < iRows; i++) {
				oDataColumns = {};
				for (j = 0; j < iColumns; j++) {
					oDataColumns["c" + j] = i + "-" + j;
				}
				aDataRows[i] = oDataColumns;
			}

			return aDataRows;
		}
	});

	/**
	 * Wraps a method.
	 *
	 * @param {Object} oObject The object whose method is to be wrapped.
	 * @param {string} sFunctionName The name of the function to wrap.
	 * @param {Function} [fnBefore] This function is called before the wrapped function is executed.
	 * @param {Function} [fnAfter] This function is called after the wrapped function is executed.
	 */
	function wrap(oObject, sFunctionName, fnBefore, fnAfter) {
		var fnOriginalFunction = oObject[sFunctionName];

		oObject[sFunctionName] = function() {
			if (fnBefore) {
				fnBefore.apply(oObject, arguments);
			}

			fnOriginalFunction.apply(oObject, arguments);

			if (fnAfter) {
				fnAfter.apply(oObject, arguments);
			}
		};
	}

	function detectRenderingFinished(oController) {
		if (oController.fnRowsUpdated) {
			oController.oTable.detachRowsUpdated(oController.fnRowsUpdated);
			delete oController.fnRowsUpdated;
		}

		oController.fnRowsUpdated = function() {
			oController.createMeasure("Rendering", "RenderingStart");
			oController.createMeasure("Overall", "TestStart");
			oController.createTestResult();
		};

		if (oController.oTable.getBinding()) {
			oController.oTable.attachEventOnce("rowsUpdated", oController.fnRowsUpdated);
		} else {
			oController.fnRowsUpdated();
		}
	}
});


text:
FROM gcr.io/google_appengine/debian8

RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends cron curl python python-pip && \
    apt-get clean
RUN pip install google-compute-engine

RUN mkdir /iap_watcher
VOLUME /iap_watcher

RUN mkdir -p /home/vmagent/iap_watcher
WORKDIR /home/vmagent/iap_watcher
ADD iap_watcher.py .
ENV OUTPUT_KEY_FILE /iap_watcher/iap_verify_keys.txt
ENTRYPOINT [ \
    "./iap_watcher.py", \
    "--iap_metadata_key=AEF_IAP_state", \
    "--output_state_file=/iap_watcher/iap_state", \
    "--fetch_keys=True", \
    "--output_key_file=${OUTPUT_KEY_FILE}"]

RUN echo "15 */1 * * * curl 'https://www.gstatic.com/iap/verify/public_key-jwk' > ${OUTPUT_KEY_FILE}" >> .tmp_cron
RUN crontab .tmp_cron
RUN rm .tmp_cron

redpajama_set_name: RedPajamaGithub


text:
/**
 * \file
 *
 * This file contains functions to help maintain a stack of modules.
 */
#include "config.h"
#include <ctype.h>
#include "services/modstack.h"
#include "util/module.h"
#include "util/fptr_wlist.h"
#include "dns64/dns64.h"
#include "iterator/iterator.h"
#include "validator/validator.h"

#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif

/** count number of modules (words) in the string */
static int
count_modules(const char* s)
{
        int num = 0;
        if(!s)
                return 0;
        while(*s) {
                /* skip whitespace */
                while(*s && isspace((int)*s))
                        s++;
                if(*s && !isspace((int)*s)) {
                        /* skip identifier */
                        num++;
                        while(*s && !isspace((int)*s))
                                s++;
                }
        }
        return num;
}

void
modstack_init(struct module_stack* stack)
{
	stack->num = 0;
	stack->mod = NULL;
}

int
modstack_config(struct module_stack* stack, const char* module_conf)
{
        int i;
        verbose(VERB_QUERY, "module config: \"%s\"", module_conf);
        stack->num = count_modules(module_conf);
        if(stack->num == 0) {
                log_err("error: no modules specified");
                return 0;
        }
        if(stack->num > MAX_MODULE) {
                log_err("error: too many modules (%d max %d)",
                        stack->num, MAX_MODULE);
                return 0;
        }
        stack->mod = (struct module_func_block**)calloc((size_t)
                stack->num, sizeof(struct module_func_block*));
        if(!stack->mod) {
                log_err("out of memory");
                return 0;
        }
        for(i=0; i<stack->num; i++) {
                stack->mod[i] = module_factory(&module_conf);
                if(!stack->mod[i]) {
                        log_err("Unknown value for next module: '%s'",
                                module_conf);
                        return 0;
                }
        }
        return 1;
}

/** The list of module names */
const char**
module_list_avail(void)
{
        /* these are the modules available */
        static const char* names[] = {
		"dns64",
#ifdef WITH_PYTHONMODULE
		"python",
#endif
		"validator",
		"iterator",
		NULL};
	return names;
}

/** func block get function type */
typedef struct module_func_block* (*fbgetfunctype)(void);

/** The list of module func blocks */
static fbgetfunctype*
module_funcs_avail(void)
{
        static struct module_func_block* (*fb[])(void) = {
		&dns64_get_funcblock,
#ifdef WITH_PYTHONMODULE
		&pythonmod_get_funcblock,
#endif
		&val_get_funcblock,
		&iter_get_funcblock,
		NULL};
	return fb;
}

struct
module_func_block* module_factory(const char** str)
{
        int i = 0;
        const char* s = *str;
	const char** names = module_list_avail();
	fbgetfunctype* fb = module_funcs_avail();
        while(*s && isspace((int)*s))
                s++;
	while(names[i]) {
                if(strncmp(names[i], s, strlen(names[i])) == 0) {
                        s += strlen(names[i]);
                        *str = s;
                        return (*fb[i])();
                }
		i++;
        }
        return NULL;
}

int
modstack_setup(struct module_stack* stack, const char* module_conf,
	struct module_env* env)
{
        int i;
        if(stack->num != 0)
                modstack_desetup(stack, env);
        /* fixed setup of the modules */
        if(!modstack_config(stack, module_conf)) {
		return 0;
        }
        env->need_to_validate = 0; /* set by module init below */
        for(i=0; i<stack->num; i++) {
                verbose(VERB_OPS, "init module %d: %s",
                        i, stack->mod[i]->name);
                fptr_ok(fptr_whitelist_mod_init(stack->mod[i]->init));
                if(!(*stack->mod[i]->init)(env, i)) {
                        log_err("module init for module %s failed",
                                stack->mod[i]->name);
			return 0;
                }
        }
	return 1;
}

void
modstack_desetup(struct module_stack* stack, struct module_env* env)
{
        int i;
        for(i=0; i<stack->num; i++) {
                fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
                (*stack->mod[i]->deinit)(env, i);
        }
        stack->num = 0;
        free(stack->mod);
        stack->mod = NULL;
}

int
modstack_find(struct module_stack* stack, const char* name)
{
	int i;
        for(i=0; i<stack->num; i++) {
		if(strcmp(stack->mod[i]->name, name) == 0)
			return i;
	}
	return -1;
}


text:
package org.guideme.guideme.model;

import java.time.LocalTime;
import java.util.ArrayList;

import org.guideme.guideme.settings.ComonFunctions;

public class LoadGuide {

	private String guidePath; //path to guide to load
	private String target; //page to load in new guide
	private String returnTarget; //page to return to when this guide is loaded next
	private String prejScript;
	private String postjScript;
	private String ifSet;
	private String ifNotSet;
	private LocalTime ifBefore; //Time of day must be before this time
	private LocalTime ifAfter; //Time of day must be after this time
	private ComonFunctions comonFunctions = ComonFunctions.getComonFunctions();

	public LoadGuide(String guidePath, String target, String returnTarget, String ifSet, String ifNotSet, String ifAfter, String ifBefore, String prejScript, String postjScript) {
		this.guidePath = guidePath;
		this.target = target;
		this.returnTarget = returnTarget;
		this.prejScript = prejScript;
		this.postjScript = postjScript;
		this.ifSet = ifSet;
		this.ifNotSet = ifNotSet;
		if (ifBefore.equals("")) {
			this.ifBefore = null;
		} else {
			this.ifBefore = LocalTime.parse(ifBefore);
		}
		if (ifAfter.equals("")) {
			this.ifAfter = null;
		} else {
			this.ifAfter = LocalTime.parse(ifAfter);
		}
	}

	public String getGuidePath() {
		return guidePath;
	}

	public String getTarget() {
		return target;
	}

	public String getReturnTarget() {
		return returnTarget;
	}

	public boolean canShow(ArrayList<String> setList) {
		boolean retVal = comonFunctions.canShowTime(ifBefore, ifAfter);
		if (retVal) {
			retVal =  comonFunctions.canShow(setList, ifSet, ifNotSet);
		}
		return retVal;
	}

	public String getIfSet() {
		return ifSet;
	}

	public String getIfNotSet() {
		return ifNotSet;
	}

	public LocalTime getIfBefore() {
		return ifBefore;
	}

	public void setIfBefore(String ifBefore) {
		if (ifBefore.equals("")) {
			this.ifBefore = null;
		} else {
			this.ifBefore = LocalTime.parse(ifBefore);
		}
	}

	public LocalTime getIfAfter() {
		return ifAfter;
	}

	public void setIfAfter(String ifAfter) {
		if (ifAfter.equals("")) {
			this.ifAfter = null;
		} else {
			this.ifAfter = LocalTime.parse(ifAfter);
		}
	}

	public String getPrejScript() {
		return prejScript;
	}

	public String getPostjScript() {
		return postjScript;
	}

}


text:
<?php

namespace EvaTest\Form;

use PHPUnit_Framework_TestCase as TestCase;
use stdClass;
use Zend\Form\Element;
use Zend\Form\Factory;
use Zend\Form\Fieldset;
use Eva\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFilterFactory;
use Zend\Stdlib\Hydrator;
use ZendTest\Form\TestAsset\Entity;

class FormTest extends TestCase
{
    /**
     * @var Form
     */
    protected $form;

    public function setUp()
    {
        $this->form = new Form();
    }
}


text:
// UIImage+Resize.h
// Created by Trevor Harmon on 8/5/09.
// Free for personal or commercial use, with or without modification.
// No warranty is expressed or implied.

// Extends the UIImage class to support resizing/cropping

@interface UIImage (Resize)

#define imageBytesPerMB 1048576.0f
#define imageBytesPerPixel 4.0f
#define imagePixelsPerMB ( imageBytesPerMB / imageBytesPerPixel ) // 262144 pixels, for 4 bytes per pixel.

//from StandardPaths.h
#ifndef __IPHONE_OS_VERSION_MAX_ALLOWED
#define SP_SCREEN_SCALE() ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]? [[NSScreen mainScreen] backingScaleFactor]: 1.0f)
#else
#define SP_SCREEN_SCALE() ([UIScreen mainScreen].scale)
#endif

- (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode
                                  bounds:(CGSize)bounds
                    interpolationQuality:(CGInterpolationQuality)quality;
- (UIImage *)resizedImageWithUncompressedSizeInMB:(CGFloat)destImageSize
                             interpolationQuality:(CGInterpolationQuality)quality;

// helper functions
- (UIImage *)resizedImage:(CGSize)newSize
     interpolationQuality:(CGInterpolationQuality)quality;
- (UIImage *)resizedImage:(CGSize)newSize
                transform:(CGAffineTransform)transform
           drawTransposed:(BOOL)transpose
     interpolationQuality:(CGInterpolationQuality)quality;
- (CGAffineTransform)transformForOrientation:(CGSize)newSize;

@end


text:
/// <reference path="tsdef/jquery.d.ts"/>
/// <reference path="tsdef/jquerymobile.d.ts"/>
/// <reference path="tsdef/knockout-3.3.d.ts"/>

module StopByStop {
    export const PAGENAME_HOME = "sbs-homePG";
    export const PAGENAME_Route = "route-page";
    export const PAGENAME_POIGroup = "poigroup-page";
    export const PAGENAME_Exit = "exit-page";
    export const PAGENAME_About = "about-page";
    export const N_LAT_BOUNDARY = 50.00;
    export const S_LAT_BOUNDARY = 25.00;
    export const W_LON_BOUNDARY = -125.00;
    export const E_LON_BOUNDARY = -66.00;
    export const ROUTE_PLAN_STORAGE_KEY = "sbsroutes";

    export class Utils {
        public static getNonHighwayDrivingTimeToPlaceInSeconds(distance: number): number {
            // for now let's assume 20mph non-highway speed
            return distance / 20 * 3600;
        }

        public static updateNavigationLocation(hash: string, navigationLocation: ISBSNavigationLocation): void {
            if (!hash) {
                hash = "#home";
            }
            hash = hash.toLowerCase();
            var hashIndex = hash.indexOf("#");
            var queryStringPart: string = null;

            if (hashIndex < 0) {
                hash = "#home";
                hashIndex = 0;
            }

            if (hashIndex >= 0) {
                var indexOfPageNameEnd = hash.indexOf("&", hashIndex) - 1;
                if (indexOfPageNameEnd < 0) {
                    indexOfPageNameEnd = hash.length - 1;
                } else {
                    queryStringPart = hash.substr(indexOfPageNameEnd + 1);
                }
                var pageName = hash.substr(hashIndex + 1, indexOfPageNameEnd - hashIndex);
                if (SBSPage[pageName] !== undefined) {
                    navigationLocation.page = SBSPage[pageName];
                }

                if (queryStringPart) {
                    var queryStringParameterPairs: string[] = queryStringPart.split("&");
                    for (var i = 0; i < queryStringParameterPairs.length; i++) {
                        var qsParts = queryStringParameterPairs[i].split("=");
                        if (qsParts.length === 2) {
                            var parameter = qsParts[0];
                            var val = qsParts[1];
                            switch (parameter) {
                                case "routeid":
                                    navigationLocation.routeId = val;
                                    navigationLocation.poiType = undefined;
                                    break;
                                case "exitid":
                                    navigationLocation.exitId = val;
                                    break;
                                case "poiid":
                                    navigationLocation.poiId = val;
                                case "poitype":
                                    navigationLocation.poiType = PoiType.all;
                                    if (val) {
                                        navigationLocation.poiType = PoiType[val] || navigationLocation.poiType;
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
        }

        public static getHashFromNavigationLocation(navigationLocation: ISBSNavigationLocation): string {
            var loc = "#";

            if (SBSPage[navigationLocation.page]) {
                loc += SBSPage[navigationLocation.page];
            } else {
                loc += "home";
            }

            if (navigationLocation.routeId) {
                loc += ("&routeid=" + navigationLocation.routeId);
            }

            if (navigationLocation.exitId &&
                (navigationLocation.page === SBSPage.exit || navigationLocation.page === SBSPage.poi)) {
                loc += ("&exitid=" + navigationLocation.exitId);
            }

            if (navigationLocation.poiId && navigationLocation.page === SBSPage.poi) {
                loc += ("&poiid=" + navigationLocation.poiId);
            }

            if (navigationLocation.poiType && navigationLocation.page === SBSPage.exit && PoiType[navigationLocation.poiType]) {
                loc += ("&poitype=" + PoiType[navigationLocation.poiType]);
            }

            return loc.toLowerCase();
        }

        public static getMileString(distance: number): string {
            if (distance < 0.1) {
                return "<0.1mi";
            }

            return distance.toString() + "mi";
        }

        public static getHours(seconds: number): number {
            return Math.floor(((seconds % 31536000) % 86400) / 3600);
        }

        public static getMinutes(seconds: number): number {
            return Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
        }

        public static getTimeString(time: Date, msOffset: number = 0): string {
            time = new Date(time.getTime() + msOffset);
            return Utils.formatTime(time);
        }

        public static formatTime(date: Date) {
            var hours = date.getHours();
            var minutes = date.getMinutes();
            var minutesString: string = minutes.toString();
            var ampm = hours >= 12 ? "pm" : "am";
            hours = hours % 12;
            if (hours === 0) {
                hours = 12;
            }

            if (minutes < 10) {
                minutesString = "0" + minutesString;
            }
            return hours.toString() + ":" + minutesString + " " + ampm;

        }

        // http://stackoverflow.com/questions/3219758/detect-changes-in-the-dom
        public static observeDOM: (obj: Element, callback: () => void) => void = (() => {
            var MutationObserver = (<any>window).MutationObserver || (<any>window).WebKitMutationObserver,
                eventListenerSupported = window.addEventListener;

            return function (obj, callback) {
                if (MutationObserver) {
                    // define a new observer
                    var obs = new MutationObserver(function (mutations, observer) {
                        if (mutations[0].addedNodes.length || mutations[0].removedNodes.length)
                            callback();
                    });
                    // have the observer observe foo for changes in children
                    obs.observe(obj, { childList: true, subtree: true });
                }
                else if (eventListenerSupported) {
                    obj.addEventListener('DOMNodeInserted', callback, false);
                    obj.addEventListener('DOMNodeRemoved', callback, false);
                }
            }
        })();

        public static hasAnyOwnProperties(obj: Object): boolean {
            for (var prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    return true;
                }
            }
            return false;
        }

        public static runOnce<T>(func: (...args: any[]) => T): (...args: any[]) => T {
            var ran = false;
            var memo: T;
            return function (...args: any[]) {
                if (!ran) {
                    ran = true;
                    memo = func.apply(this, arguments);
                }
                return memo;
            };
        };

        public static spaPageNavigate(
            navigationLocation: ISBSNavigationLocation,
            changeHash: boolean = true): void {
            var pageId = "#home";
            switch (navigationLocation.page) {
                case SBSPage.about:
                    pageId = "#about";
                    break;
                case SBSPage.exit:
                    pageId = "#exit";
                    break;
                case SBSPage.poi:
                    pageId = "#poi";
                    break;
                case SBSPage.route:
                    pageId = "#route";
                    break;
            }

            var dataUrl = pageId;
            if (navigationLocation.routeId) {
                dataUrl += "&routeid=" + navigationLocation.routeId;
            }
            if (navigationLocation.exitId) {
                dataUrl += "&exitid=" + navigationLocation.exitId;
            }
            if (navigationLocation.poiType) {
                dataUrl += "&poitype=" + PoiType[navigationLocation.poiType].toLowerCase();
            }
            if (navigationLocation.poiId) {
                dataUrl += "&poiId=" + navigationLocation.poiId;
            }

            var reverse = (AppState.current.navigationLocation && AppState.current.navigationLocation.page > navigationLocation.page);

            AppState.current.knownHashChangeInProgress = true;

            $.mobile.pageContainer.pagecontainer(
                "change",
                pageId, { dataUrl: dataUrl, changeHash: changeHash, transition: "slide", reverse: reverse });
        }

        public static getShareUrl(basePortalUrl: string, navLocation: ISBSNavigationLocation) {
            var shareUrl = basePortalUrl;
            if (shareUrl.substr(shareUrl.length - 1) !== "/") {
                shareUrl += "/";
            }

            switch (navLocation.page) {
                case SBSPage.route:
                case SBSPage.exit:
                    shareUrl += "route/" + navLocation.routeId;

                    if (navLocation.page === SBSPage.exit) {
                        shareUrl += "/exit/osm-" + navLocation.exitId;

                        if (navLocation.poiType) {
                            shareUrl += "/" + PoiType[navLocation.poiType];
                        }
                    }
                    break;
                case SBSPage.poi:
                    shareUrl += "poi/" + navLocation.poiPath;
                    break;
            }

            return shareUrl;
        }

        public static getRouteTitleFromRouteId(routeId: string): string {
            var routeTitle = "";

            if (routeId && routeId.indexOf("-to-") > 1) {
                var fromAndTo = routeId.split("-to-");
                var fromString = fromAndTo[0];
                var toString = fromAndTo[1];

                if (fromString.length > 1 && toString.length > 1) {
                    if ($.isNumeric(fromString[0])) {
                        fromString = "your location";
                    } else {
                        fromString = Utils.getPlaceNameFromPlaceId(fromString);
                    }
                }

                toString = Utils.getPlaceNameFromPlaceId(toString);
                if (fromString && toString) {
                    routeTitle = "from " + fromString + " to " + toString;
                } else {
                    routeTitle = "";
                }
            }

            return routeTitle;
        }

        public static isHistoryAPISupported(): boolean {
            return !!(window.history && history.pushState);
        }

        public static windowOpen(url: string) {
            if (AppState.current.windowOpenTarget === "_blank") {
                window.location.assign(url);
            } else {
                window.open(url, AppState.current.windowOpenTarget, "location=yes");
            }
        }

        public static getPoiIconUrl(poiType: PoiType, iconFormat: PoiIconFormat, baseImageUrl: string) {
            var poiTypeString = PoiType[poiType].toLowerCase();
            return baseImageUrl + "poi/" + poiTypeString + "/" + poiTypeString + "_" + iconFormat.toString() + ".png";
        }

        public static getNavigationUrlFromCurrentLocation(...stops: ILocation[]): JQueryPromise<string> {
            var deferred = $.Deferred<string>();
            if (stops && stops.length > 0) {
                if (navigator && navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(
                        (position: Position) => {
                            var srcLat = position.coords.latitude;
                            var srcLon = position.coords.longitude;

                            var daddrStr = "";
                            for (var i = 0; i < stops.length - 1; i++) {
                                if (i > 0) {
                                    daddrStr += "+to:";
                                }
                                daddrStr += (stops[i].a + "," + stops[i].o);
                            }

                            if (daddrStr !== "") {
                                daddrStr += "+to:";
                            }

                            var destination = stops[stops.length - 1];
                            daddrStr += destination.a + "," + destination.o;
                            var navigationUrl = "https://maps.google.com/maps?saddr="
                                + srcLat + ","
                                + srcLon + "&daddr="
                                + daddrStr;
                            deferred.resolve(navigationUrl);
                        },
                        (positionError: PositionError) => {
                            var error = positionError.message;
                            Telemetry.trackError(new Error("getCurrentPositionError: " + error));
                            console.error("Please allow StopByStop.com to share your location.");
                            deferred.reject(error);
                        });
                }
            } else {
                deferred.reject();
            }
            return deferred.promise();
        }

        private static getPlaceNameFromPlaceId(placeId: string) {
            var placeName = "";
            var usIndex = placeId.indexOf("-united-states");
            if (usIndex > 0) {
                placeId = placeId.substr(0, usIndex);

                var state = placeId.substr(placeId.length - 2, 2).toUpperCase();
                placeId = placeId.substr(0, placeId.length - 3);
                placeId = placeId.replace(/-/g, ' ');
                placeName = placeId.replace(/([^ \t]+)/g, (_, word: string) => {
                    return word[0].toUpperCase() + word.substr(1);
                }) + ", " + state;
            }

            return placeName;
        }

    }
}


text:
Editor

Editor is rich text editor component based on Quill.

    <app-demoActions github="editor"></app-demoActions>

Default

Custom Toolbar

            <ng-template pTemplate="header">

                    <button type="button" class="ql-bold" aria-label="Bold"></button>
                    <button type="button" class="ql-italic" aria-label="Italic"></button>
                    <button type="button" class="ql-underline" aria-label="Underline"></button>

            </ng-template>

Import

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import {EditorModule} from 'primeng/editor';
</app-code>

Getting Started

Two-way value binding is defined with ngModel.

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
<p-editor [(ngModel)]="text" [style]="{'height':'320px'}"></p-editor>
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class EditorDemo {

    text: string;

}
</app-code>

Model Driven Forms

Editor can be used in a model driven form as well.

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
<p-editor formControlName="description" [style]="{'height':'320px'}"></p-editor>
</app-code>

Toolbar

Editor provides a default toolbar with common options, to customize it define your elements inside the header element. Refer to Quill documentation for available controls.

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
<p-editor [(ngModel)]="text2" [style]="{'height':'320px'}">
    <ng-template pTemplate="header">
        <span class="ql-format-group">
            <span title="Bold" class="ql-format-button ql-bold"></span>
            <span class="ql-format-separator"></span>
            <span title="Italic" class="ql-format-button ql-italic"></span>
            <span class="ql-format-separator"></span>
            <span title="Underline" class="ql-format-button ql-underline"></span>
            <span class="ql-format-separator"></span>
            <span title="Strikethrough" class="ql-format-button ql-strike"></span>
        </span>
    </ng-template>
</p-editor>
</app-code>

Properties

                            Name
                            Type
                            Default
                            Description

                            style
                            string
                            null
                            Inline style of the container.

                            styleClass
                            string
                            null
                            Style class of the container.

                            placeholder
                            string
                            null
                            Placeholder text to show when editor is empty.

                            readonly
                            boolean
                            false
                            Whether to instantiate the editor to read-only mode.

                            formats
                            string[]
                            null
                            Whitelist of formats to display, see here for available options.

                            modules
                            any
                            null
                            Modules configuration of Editor, see here for available options.

                            debug
                            string
                            null
                            Shortcut for debug. Note debug is a static method and will affect other instances of Quill
                                editors on the page. Only warning and error messages are enabled by default.

                            bounds
                            Element
                            document.body
                            DOM Element or a CSS selector for a DOM Element, within which the editor's p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries..

                            scrollingContainer
                            Element
                            null
                            DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS.
                                Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling..

Events

                            Name
                            Parameters
                            Description

                            onTextChange
                            event.delta: Representation of the change.

                                event.source: Source of change. Will be either "user" or "api".

                                event.htmlValue: Current value as html.

                                event.textValue: Current value as text.

                            Callback to invoke when the text of the editor is changed by the user.

                            onSelectionChange
                            event.range: Object with index and length keys indicating where the selection exists.

                                event.oldRange: Object with index and length keys indicating where the previous selection was..

                                event.source: Source of change. Will be either "user" or "api".
                            Callback to invoke when selected text of editor changes.

                            onInit
                            event.editor: Quill editor instance.

                                event.oldRange: Object with index and length keys indicating where the previous selection was..

                                event.source: Source of change. Will be either "user" or "api".
                            Callback to invoke after editor is initialized.

Refer to Quill documentation for more information.

Methods

                            Name
                            Parameters
                            Description

                            getQuill
                            -
                            Returns the underlying quill instance.

Templates

                            Name
                            Parameters

                            header
                            -

Styling

Following is the list of structural style classes, for theming classes visit theming page.

                            Name
                            Element

                            p-editor-container
                            Container element

                            p-editor-toolbar
                            Toolbar of the editor

                            p-editor-content
                            Editable area

Dependencies

Quill Editor 1.0.

Resources of quill needs to be added to your application. Example setup with CLI is as follows;

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
npm install quill --save
</app-code>

Add Quill to scripts in angular.json

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
"scripts": [... "../node_modules/quill/dist/quill.js"],
</app-code>

Add Quill css to styles in angular.json

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
"styles": [ ... "../node_modules/quill/dist/quill.core.css", "../node_modules/quill/dist/quill.snow.css"],
</app-code>

                View on GitHub

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
<h5>Default</h5>
<p-editor [(ngModel)]="text1" [style]="{'height':'320px'}"></p-editor>
<p>Value: {{text1||'empty'}}</p>

<h5>Custom Toolbar</h5>
<p-editor [(ngModel)]="text2" [style]="{'height':'320px'}">
    <ng-template pTemplate="header">
        <span class="ql-formats">
            <button type="button" class="ql-bold" aria-label="Bold"></button>
            <button type="button" class="ql-italic" aria-label="Italic"></button>
            <button type="button" class="ql-underline" aria-label="Underline"></button>
        </span>
    </ng-template>
</p-editor>

</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import {Component} from '@angular/core';

@Component({
    templateUrl: './editordemo.html'
})
export class EditorDemo {

    text1: string = '<div>Hello World!</div><div>PrimeNG <b>Editor</b> Rocks</div><div><br></div>';

    text2: string;
}
</app-code>


text:
import os
from threading import Thread
from multiprocessing import Process

from PyQt5.QtCore import Qt
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
"""
from PyQt4.QtCore import Qt, QDir, QFile, QFileInfo, QMimeData, QIODevice, QTextStream, QUrl
from PyQt4.QtGui import QAction, QCursor, QFileDialog, QFont, QTextCursor, QTextEdit, QMessageBox, QKeySequence, QApplication
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest
"""
import markdown
from whoosh.index import open_dir
from whoosh.writing import AsyncWriter
try:
    import html2text
    HAS_HTML2TEXT=True # let's make this user configurable later?
except ImportError:
    HAS_HTML2TEXT=False

from urllib import parse as urlparse
from .utils import LineEditDialog, parseTitle, JSCRIPT_TPL, METADATA_CHECKER
from .mikibook import Mikibook

class SimpleMikiEdit(QtWidgets.QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.settings = parent.settings
        self.setFontPointSize(12)
        self.setVisible(False)

        # Spell checker support
        try:
            import enchant
            enchant.Dict()
            self.speller = enchant.Dict()
        except ImportError:
            print("Spell checking unavailable. Need to install pyenchant.")
            self.speller = None
        except enchant.errors.DictNotFoundError:
            print("Spell checking unavailable. Need to install dictionary (e.g. aspell-en).")
            self.speller = None

    def insertFromRawHtml(self):
        qclippy = QtWidgets.QApplication.clipboard()
        if qclippy.mimeData().hasHtml():
            self.insertFromMimeData(self.mimeFromText(qclippy.mimeData().html()))
        else:
            self.insertFromMimeData(qclippy.mimeData())

    def keyPressEvent(self, event):
        """ for Qt.Key_Tab, expand as 4 spaces (if expandTab is enabled)
            for other keys, use default implementation
        """

        moddies = QtWidgets.QApplication.keyboardModifiers()
        expandTab = Mikibook.settings.value(
            'tabInsertsSpaces',
            type=bool,
            defaultValue=True
        )
        if event.key() == Qt.Key_Tab and expandTab:
            tabWidth = Mikibook.settings.value('tabWidth', type=int, defaultValue=4)
            self.insertPlainText(' ' * tabWidth) # use the tabWidth for tabstop!
        elif moddies & Qt.ControlModifier and moddies & Qt.ShiftModifier and event.key() == Qt.Key_V:
            self.insertFromRawHtml()
        else:
            QtWidgets.QTextEdit.keyPressEvent(self, event)

    def contextMenuEvent(self, event):

        def correctWord(cursor, word):
            # From QTextCursor doc:
            # if there is a selection, the selection is deleted and replaced
            return lambda: cursor.insertText(word)

        popup_menu = self.createStandardContextMenu()
        paste_action = popup_menu.actions()[6]
        paste_formatted_action = QtWidgets.QAction(self.tr("Paste raw HTML"), popup_menu)
        paste_formatted_action.triggered.connect(self.insertFromRawHtml)
        paste_formatted_action.setShortcut(QtGui.QKeySequence("Ctrl+Shift+V"))
        popup_menu.insertAction(paste_action, paste_formatted_action)

        # Spellcheck the word under mouse cursor, not self.textCursor
        cursor = self.cursorForPosition(event.pos())
        cursor.select(QtGui.QTextCursor.WordUnderCursor)

        text = cursor.selectedText()
        if self.speller and text:
            if not self.speller.check(text):
                lastAction = popup_menu.actions()[0]
                for word in self.speller.suggest(text)[:10]:
                    action = QtWidgets.QAction(word, popup_menu)
                    action.triggered.connect(correctWord(cursor, word))
                    defaultFamily = QtWidgets.QApplication.font().family()
                    action.setFont(QtGui.QFont(defaultFamily, weight=QtGui.QFont.Bold))
                    popup_menu.insertAction(lastAction, action)
                popup_menu.insertSeparator(lastAction)

        popup_menu.exec_(event.globalPos())

    def mimeFromText(self, text):
        mime = QtCore.QMimeData()
        mime.setText(text)
        return mime

    def createMimeDataFromSelection(self):
        """ Reimplement this to prevent copied text taken as hasHtml() """
        plaintext = self.textCursor().selectedText()

        # From QTextCursor doc:
        # if the selection obtained from an editor spans a line break,
        # the text will contain a Unicode U+2029 paragraph separator character
        # instead of a newline \n character
        text = plaintext.replace('\u2029', '\n')
        return self.mimeFromText(text)

    def insertFromMimeData(self, source):
        if source.hasHtml():
            html = source.html()
            if HAS_HTML2TEXT:
                backToMarkdown = html2text.HTML2Text()
                markdown = backToMarkdown.handle(html)
                super(SimpleMikiEdit, self).insertFromMimeData(self.mimeFromText(markdown))
            else:
                super(SimpleMikiEdit, self).insertFromMimeData(self.mimeFromText(source.text()))
        else:
            super(SimpleMikiEdit, self).insertFromMimeData(source)

class MikiEdit(SimpleMikiEdit):
    def __init__(self, parent=None):
        super(MikiEdit, self).__init__(parent)
        self.ix = open_dir(self.settings.indexdir)

        self.imageFilter = ""
        self.documentFilter = ""
        for ext in self.settings.attachmentImage:
            self.imageFilter += " *" + ext
        for ext in self.settings.attachmentDocument:
            self.documentFilter += " *" + ext
        self.imageFilter = "Image (" + self.imageFilter.strip() + ")"
        self.documentFilter = "Document (" + self.documentFilter.strip() + ")"

        self.downloadAs = ""
        self.networkManager = QtNetwork.QNetworkAccessManager()
        self.networkManager.finished.connect(self.downloadFinished)

    def updateIndex(self):
        ''' Update whoosh index, which cost much computing resource '''
        page = self.parent.notesTree.currentPage()
        content = self.toPlainText()
        try:
            #writer = self.ix.writer()
            writer = AsyncWriter(self.ix)
            if METADATA_CHECKER.match(content) and 'meta' in self.settings.extensions:
                no_metadata_content = METADATA_CHECKER.sub("", content, count=1).lstrip()
                self.settings.md.reset().convert(content)
                writer.update_document(
                    path=page, title=parseTitle(content, page), content=no_metadata_content,
                    tags=','.join(self.settings.md.Meta.get('tags', [])).strip())
                writer.commit()
            else:
                writer.update_document(
                    path=page, title=parseTitle(content, page), content=content, tags='')
                writer.commit()
        except:
            print("Whoosh commit failed.")

    def downloadFinished(self, reply):
        if reply.error():
            print("Failed to download")
        else:
            attFile = QtCore.QFile(self.downloadAs)
            attFile.open(QtCore.QIODevice.WriteOnly)
            attFile.write(reply.readAll())
            attFile.close()
            print("Succeeded")
        reply.deleteLater()

    def insertFromMimeData(self, source):
        """ Intended behavior
        If copy/drag something that hasUrls, then check the extension name:
            if image then apply image pattern ![Alt text](/path/to/img.jpg)
                     else apply link  pattern [text](http://example.net)
        If copy/drag something that hasImage, then ask for file name
        If copy/drag something that hasHtml, then html2text
        Else use the default insertFromMimeData implementation
        """

        item = self.parent.notesTree.currentItem()
        attDir = self.parent.notesTree.itemToAttachmentDir(item)
        if not QtCore.QDir(attDir).exists():
            QtCore.QDir().mkpath(attDir)

        if source.hasUrls():
            for qurl in source.urls():
                url = qurl.toString()
                filename, extension = os.path.splitext(url)
                filename = os.path.basename(filename)
                newFilePath = os.path.join(attDir, filename + extension).replace(os.sep, '/')
                relativeFilePath = newFilePath.replace(self.settings.notebookPath, "..")
                quotedRFPath = urlparse.quote(relativeFilePath)
                attachments = self.settings.attachmentImage + self.settings.attachmentDocument

                if QtCore.QUrl(qurl).isLocalFile():
                    if extension.lower() in attachments:
                        nurl = url.replace("file://", "")
                        QtCore.QFile.copy(nurl, newFilePath)
                        self.parent.updateAttachmentView()

                        if extension.lower() in self.settings.attachmentImage:
                            text = "![%s](%s)" % (filename, quotedRFPath)
                        elif extension.lower() in self.settings.attachmentDocument:
                            text = "[%s%s](%s)\n" % (filename, extension, quotedRFPath)
                    else:
                        text = "[%s%s](%s)\n" % (filename, extension, url)
                else:
                    if extension.lower() in attachments:
                        self.downloadAs = newFilePath
                        self.networkManager.get(QtNetwork.QNetworkRequest(qurl))

                        if extension.lower() in self.settings.attachmentImage:
                            text = "![%s](%s)" % (filename, quotedRFPath)
                        elif extension.lower() in self.settings.attachmentDocument:
                            text = "[%s%s](%s)\n" % (filename, extension, quotedRFPath)
                    else:
                        text = "[%s%s](%s)\n" % (filename, extension, url)

                super(MikiEdit, self).insertFromMimeData(self.mimeFromText(text))
        elif source.hasImage():
            img = source.imageData()
            attDir = self.parent.notesTree.itemToAttachmentDir(item)
            dialog = LineEditDialog(attDir, self)
            if dialog.exec_():
                fileName = dialog.editor.text()
                if not QtCore.QFileInfo(fileName).suffix():
                    fileName += '.jpg'
                filePath = os.path.join(attDir, fileName).replace(os.sep, '/')
                img.save(filePath)
                relativeFilePath = filePath.replace(self.settings.notebookPath, "..")
                text = "![%s](%s)" % (fileName, quotedRFPath)
                super(MikiEdit, self).insertFromMimeData(self.mimeFromText(text))
        else:
            super(MikiEdit, self).insertFromMimeData(source)

    def insertAttachment(self, filePath, fileType):
        item = self.parent.notesTree.currentItem()
        attDir = self.parent.notesTree.itemToAttachmentDir(item)
        filename, extension = os.path.splitext(filePath)
        filename = os.path.basename(filename)
        newFilePath = os.path.join(attDir, filename + extension).replace(os.sep, '/')
        relativeFilePath = newFilePath.replace(self.settings.notebookPath, "..")
        quotedRFPath = urlparse.quote(relativeFilePath)
        if not os.path.exists(attDir):
            os.makedirs(attDir)
        QtCore.QFile.copy(filePath, newFilePath)
        self.parent.updateAttachmentView()
        if fileType == self.imageFilter:
            text = "![%s](%s)" % (filename, quotedRFPath)
        else:
            text = "[%s%s](%s)\n" % (filename, extension, quotedRFPath)
        self.insertPlainText(text)

    def insertAttachmentWrapper(self):
        (filePath, fileType) = QtWidgets.QFileDialog.getOpenFileName(
            self, self.tr('Insert attachment'), self.settings.notePath,
            self.imageFilter + ";;" + self.documentFilter)
        if filePath == "":
            return
        self.insertAttachment(filePath, fileType)

    '''
    def closeEvent(self, event):
        self.ix.close()
        print('closed idx')
        event.accept()
    '''
    def save(self, item):
        pageName = self.parent.notesTree.itemToPage(item)
        filePath = self.parent.notesTree.itemToFile(item)
        htmlFile = self.parent.notesTree.itemToHtmlFile(item)

        fh = QtCore.QFile(filePath)
        try:
            if not fh.open(QtCore.QIODevice.WriteOnly):
                raise IOError(fh.errorString())
        except IOError as e:
            QtWidgets.QMessageBox.warning(self, self.tr("Save Error"),
                                self.tr("Failed to save %s: %s") % (pageName, e))
            raise
        finally:
            if fh is not None:
                savestream = QtCore.QTextStream(fh)
                savestream.setCodec("UTF-8")
                savestream << self.toPlainText()
                fh.close()
                self.document().setModified(False)

                # Fork a process to update index, which benefit responsiveness.
                Thread(target=self.updateIndex).start()

    def toHtml(self):
        '''markdown.Markdown.convert v.s. markdown.markdown
            ~~Previously `convert` was used, but it doens't work with fenced_code~~
            fixed that by calling markdown.Markdown.reset before each conversion
        '''
        htmltext = self.toPlainText()
        if 'asciimathml' in self.settings.extensions:
            stuff=JSCRIPT_TPL.format(self.settings.mathjax)
        else:
            stuff=''
        return self.settings.md.reset().convert(htmltext)+stuff
        # md = markdown.Markdown(extensions)
        # return md.convert(htmltext)

    def saveAsHtml(self, htmlFile = None):
        """ Save as Complete (with css and images) or HTML Only
            To be merged with saveNoteAs
        """
        if not htmlFile:
            (htmlFile, htmlType) = QtWidgets.QFileDialog.getSaveFileNameAndFilter(
                self, self.tr("Export to HTML"), "", "Complete;;HTML Only")
        if htmlFile == '':
            return
        if not QtCore.QFileInfo(htmlFile).suffix():
            htmlFile += '.html'

        if htmlType == "Complete":
            self.saveCompleteHtml(htmlFile)
        else:
            self.saveHtmlOnly(htmlFile)

    def saveCompleteHtml(self, htmlFile):
        html = QtCore.QFile(htmlFile)
        html.open(QtCore.QIODevice.WriteOnly)
        savestream = QtCore.QTextStream(html)
        savestream.setCodec("UTF-8")
        css = QtCore.QFile(self.settings.cssfile)
        css.open(QtCore.QIODevice.ReadOnly)
        # Use a html lib may be a better idea?
        savestream << "<meta charset='utf-8'>"
        # Css is inlined.
        savestream << ""
        # Note content
        savestream << self.toHtml()
        savestream << ""
        html.close()

    def saveHtmlOnly(self, htmlFile):
        fileDir = os.path.dirname(htmlFile)
        QtCore.QDir().mkpath(fileDir)

        html = QtCore.QFile(htmlFile)
        html.open(QtCore.QIODevice.WriteOnly)
        savestream = QtCore.QTextStream(html)
        savestream.setCodec("UTF-8")
        savestream << """

                        <meta charset="utf-8">
                        <link rel="stylesheet" href="/css/notebook.css" type="text/css" />

                      """
        # Note content
        savestream << self.toHtml()
        savestream << ""
        html.close()


text:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using DbFriend.Core.Provider.MsSql.Adapters;
using Microsoft.SqlServer.Management.Smo;

namespace DbFriend.Core.Provider.MsSql
{
    /// <summary>
    /// </summary>
    public class MsSqlStoredProc : IMsSqlStoredProc
    {
        /// <summary>
        /// </summary>
        private readonly IStoredProcedureAdapter storedProcedure;

        /// <summary>
        /// </summary>
        private IMsSqlStatementsTransformer statementTransformer;

        /// <summary>
        /// Initializes a new instance of the <see cref="MsSqlStoredProc"/> class.
        /// </summary>
        /// <param name="storedProcedure">
        /// The stored procedure.
        /// </param>
        /// <param name="transformer">
        /// </param>
        /// <param name="dependencyRepository">
        /// </param>
        public MsSqlStoredProc(
                IStoredProcedureAdapter storedProcedure, IMsSqlStatementsTransformer transformer)
        {
            this.storedProcedure = storedProcedure;
            statementTransformer = transformer;
        }

        #region IMsSqlStoredProc Members

        public int Id
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// Gets DbObjectName.
        /// </summary>
        /// <value>
        /// The name.
        /// </value>
        public string Name
        {
            get { return storedProcedure.Name; }
        }

        /// <summary>
        /// Gets Type.
        /// </summary>
        /// <value>
        /// The type.
        /// </value>
        public string Type
        {
            get { return "storedprocedure"; }
        }

        public string Schema
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// Gets Owner.
        /// </summary>
        /// <value>
        /// The owner.
        /// </value>
        public string Owner
        {
            get { return storedProcedure.Owner; }
        }

        /// <summary>
        /// Gets UrnString.
        /// </summary>
        /// <value>
        /// The urn string.
        /// </value>
        public string UrnString
        {
            get { return storedProcedure.Urn; }
        }

        /// <summary>
        /// </summary>
        /// <returns>
        /// </returns>
        public string Script()
        {
            string dropScript = ScriptDrop(new BaselineScriptingOptionsAdapter().Options);

            string createScript = ScriptCreate(new BaselineScriptingOptionsAdapter().Options);

            return dropScript + createScript;
        }

        #endregion

        /// <summary>
        /// </summary>
        /// <param name="options">
        /// The options.
        /// </param>
        /// <returns>
        /// </returns>
        private string ScriptCreate(ScriptingOptions options)
        {
            options.ScriptDrops = false;
            options.IncludeIfNotExists = false;

            StringCollection lines = storedProcedure.Script(options);
            StringBuilder stringBuilder = new StringBuilder();

            foreach (string line in lines)
            {
                statementTransformer.Process(line, stringBuilder);
            }

            if (stringBuilder.Length > 0)
            {
                stringBuilder.Append(Environment.NewLine + "GO" + Environment.NewLine);
            }

            return stringBuilder.ToString();
        }

        /// <summary>
        /// </summary>
        /// <param name="options">
        /// The options.
        /// </param>
        /// <returns>
        /// </returns>
        private string ScriptDrop(ScriptingOptions options)
        {
            options.ScriptDrops = true;
            options.IncludeIfNotExists = true;

            StringCollection lines = storedProcedure.Script(options);
            StringBuilder stringBuilder = new StringBuilder();

            foreach (string line in lines)
            {
                statementTransformer.Process(line, stringBuilder);
            }

            if (stringBuilder.Length > 0)
            {
                stringBuilder.Append("GO" + Environment.NewLine + Environment.NewLine);
            }

            return stringBuilder.ToString();
        }

        public int Compare(IDbObject x, IDbObject y)
        {
            throw new NotImplementedException();
        }

        public int Compare(object x, object y)
        {
            throw new NotImplementedException();
        }
    }
}


text:
package com.sequenceiq.cloudbreak.cmtemplate.configproviders.profilermanager;

public class ProfilerManagerRoles {
    public static final String PROFILER_MANAGER = "PROFILER_MANAGER";

    public static final String DATA_DISCOVERY_SERVICE_AGENT = "DATA_DISCOVERY_SERVICE_AGENT";

    public static final String PROFILER_ADMIN_AGENT = "PROFILER_ADMIN_AGENT";

    public static final String PROFILER_METRICS_AGENT = "PROFILER_METRICS_AGENT";

    private ProfilerManagerRoles() {
    }
}


text:
#ifndef EDITOR_H
#define EDITOR_H

#include <QQuickItem>
#include <vector>

/**
*   @breif
*
*   Graphical editor for creating awesome stuff. ;D
*
*
*
*/
class Level;
class UiInternal;

class Editor : public QQuickItem
{
    Q_OBJECT
public:
    ~Editor();

    /**
    * Init the resources to the engine.
    * -- Create the EditorUI component
    * -- Add *this, as a property into the qml context for easing access from qml.
    * -- Call @initUi();
    *
    * Try to load saved levels, and maybe a config.
    */
    void init();
    /**
    *   The Application will have top menu, defined in qml.
    */
    void initUi();

    /**
    *   Initialize a new level properties.
    */
    void initLevel(Level* level);

    /**
    *  Save the currently editing level.
    */
    void saveLevel();

    /**
    *   Delete level by name.
    */
    void deleteLevel(QString name);

    /**
    *   Create a new level, is the optional name.
    */
    Q_INVOKABLE void newLevel(QString levelName = QString());

    /**
    *   Export levels to another directory.
    *   http://stackoverflow.com/questions/18711421/partial-serialization-of-qml-object-properties
    */
    void exportLevel(QString path);

    static Editor* getInstance();
signals:

public slots:

    /**
    *   When loading UI component, sometimes is not ready.
    *   This is the callback used to set things up.
    */
    void onLoadingUiChanged(QQmlComponent::Status);

    /**
    *   Exit from the menu.
    */
    void onMenuExit();

private:
    Editor(QQuickItem* parent = 0);

    QString m_default_save_path;
    bool m_initialized;
    bool m_ui_initialized;
    QQmlComponent *editorUiComponent;
    UiInternal* ui = nullptr;

    //All levels Available.
    std::vector<Level*> m_levels;
    Level* m_current;
    static Editor* editorInstance;
};
Q_DECLARE_METATYPE(Editor*)

#endif // EDITOR_H


text:
package fi.testee.flyway;

import fi.testee.spi.DataSourceMigrator;
import fi.testee.utils.AnnotationUtils;
import org.flywaydb.core.Flyway;

import javax.sql.DataSource;
import java.util.List;
import java.util.function.Function;

/**
 * Implementation of a {@link DataSourceMigrator}
 *
 * @author Alex Stockinger, IT-Stockinger
 */
public class FlywayDataSourceMigrator implements DataSourceMigrator {

    @Override
    public void migrate(
            final Class<?> testSetupClass,
            final Function<String, DataSource> dataSourceProvider
    ) {
        final List<fi.testee.flyway.annotation.Flyway> annotations =
                AnnotationUtils.collectAnnotations(testSetupClass, fi.testee.flyway.annotation.Flyway.class);
        if (annotations == null) {
            return;
        }
        for (final fi.testee.flyway.annotation.Flyway annotation : annotations) {
            final org.flywaydb.core.Flyway flyway = new Flyway();
            final DataSource ds = dataSourceProvider.apply(annotation.dataSource());
            flyway.setDataSource(ds);
            flyway.setLocations(annotation.locations());
            flyway.migrate();
        }
    }
}


text:
import {DOWN_ARROW, TAB, UP_ARROW} from '@angular/cdk/keycodes';
import {first} from 'rxjs/operators/first';
import {QueryList} from '@angular/core';
import {fakeAsync, tick} from '@angular/core/testing';
import {createKeyboardEvent} from '../testing/event-objects';
import {ActiveDescendantKeyManager} from './activedescendant-key-manager';
import {FocusKeyManager} from './focus-key-manager';
import {ListKeyManager} from './list-key-manager';

class FakeFocusable {
  constructor(private _label = '') { }
  disabled = false;
  focus() {}
  getLabel() { return this._label; }
}

class FakeHighlightable {
  disabled = false;
  setActiveStyles() {}
  setInactiveStyles() {}
}

class FakeQueryList<T> extends QueryList<T> {
  items: T[];
  get length() { return this.items.length; }
  get first() { return this.items[0]; }
  toArray() { return this.items; }
  some() { return this.items.some.apply(this.items, arguments); }
}

describe('Key managers', () => {
  let itemList: FakeQueryList<any>;
  let fakeKeyEvents: {
    downArrow: KeyboardEvent,
    upArrow: KeyboardEvent,
    tab: KeyboardEvent,
    unsupported: KeyboardEvent
  };

  beforeEach(() => {
    itemList = new FakeQueryList<any>();
    fakeKeyEvents = {
      downArrow: createKeyboardEvent('keydown', DOWN_ARROW),
      upArrow: createKeyboardEvent('keydown', UP_ARROW),
      tab: createKeyboardEvent('keydown', TAB),
      unsupported: createKeyboardEvent('keydown', 192) // corresponds to the tilde character (~)
    };
  });

  describe('ListKeyManager', () => {
    let keyManager: ListKeyManager<FakeFocusable>;

    beforeEach(() => {
      itemList.items = [
        new FakeFocusable('one'),
        new FakeFocusable('two'),
        new FakeFocusable('three')
      ];
      keyManager = new ListKeyManager<FakeFocusable>(itemList);

      // first item is already focused
      keyManager.setFirstItemActive();

      spyOn(keyManager, 'setActiveItem').and.callThrough();
    });

    describe('Key events', () => {

      it('should set subsequent items as active when down arrow is pressed', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex)
            .toBe(1, 'Expected active item to be 1 after 1 down arrow event.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(1);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(2);

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, 'Expected active item to be 2 after 2 down arrow events.');
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(2);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
      });

      it('should set first item active when down arrow pressed if no active item', () => {
        keyManager.setActiveItem(-1);
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex)
            .toBe(0, 'Expected active item to be 0 after down key if active item was null.');
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(1);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(2);
      });

      it('should set previous items as active when up arrow is pressed', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex)
            .toBe(1, 'Expected active item to be 1 after 1 down arrow event.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(1);

        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(keyManager.activeItemIndex)
            .toBe(0, 'Expected active item to be 0 after 1 down and 1 up arrow event.');
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(0);
      });

      it('should do nothing when up arrow is pressed if no active item and not wrap', () => {
        keyManager.setActiveItem(-1);
        keyManager.onKeydown(fakeKeyEvents.upArrow);

        expect(keyManager.activeItemIndex)
            .toBe(-1, 'Expected nothing to happen if up arrow occurs and no active item.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(1);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(2);
      });

      it('should skip disabled items using arrow keys', () => {
        itemList.items[1].disabled = true;

        // down arrow should skip past disabled item from 0 to 2
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, 'Expected active item to skip past disabled item on down arrow.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(1);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(2);

        // up arrow should skip past disabled item from 2 to 0
        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(keyManager.activeItemIndex)
            .toBe(0, 'Expected active item to skip past disabled item on up arrow.');
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(1);
      });

      it('should work normally when disabled property does not exist', () => {
        itemList.items[0].disabled = undefined;
        itemList.items[1].disabled = undefined;
        itemList.items[2].disabled = undefined;

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(1, 'Expected active item to be 1 after 1 down arrow when disabled not set.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(1);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(2);

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, 'Expected active item to be 2 after 2 down arrows when disabled not set.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(2);
      });

      it('should not move active item past either end of the list', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected last item of the list to be active.`);

        // this down arrow would move active item past the end of the list
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected active item to remain at the end of the list.`);

        keyManager.onKeydown(fakeKeyEvents.upArrow);
        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected first item of the list to be active.`);

        // this up arrow would move active item past the beginning of the list
        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected active item to remain at the beginning of the list.`);
      });

      it('should not move active item to end when the last item is disabled', () => {
        itemList.items[2].disabled = true;
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected second item of the list to be active.`);

        // this down arrow would set active item to the last item, which is disabled
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected the second item to remain active.`);
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(2);
      });

      it('should emit tabOut when the tab key is pressed', () => {
        let spy = jasmine.createSpy('tabOut spy');
        keyManager.tabOut.pipe(first()).subscribe(spy);
        keyManager.onKeydown(fakeKeyEvents.tab);

        expect(spy).toHaveBeenCalled();
      });

      it('should prevent the default keyboard action when pressing the arrow keys', () => {
        expect(fakeKeyEvents.downArrow.defaultPrevented).toBe(false);
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(fakeKeyEvents.downArrow.defaultPrevented).toBe(true);

        expect(fakeKeyEvents.upArrow.defaultPrevented).toBe(false);
        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(fakeKeyEvents.upArrow.defaultPrevented).toBe(true);
      });

      it('should not prevent the default keyboard action when pressing tab', () => {
        expect(fakeKeyEvents.tab.defaultPrevented).toBe(false);

        keyManager.onKeydown(fakeKeyEvents.tab);

        expect(fakeKeyEvents.tab.defaultPrevented).toBe(false);
      });

      it('should not do anything for unsupported key presses', () => {
        keyManager.setActiveItem(1);

        expect(keyManager.activeItemIndex).toBe(1);
        expect(fakeKeyEvents.unsupported.defaultPrevented).toBe(false);

        keyManager.onKeydown(fakeKeyEvents.unsupported);

        expect(keyManager.activeItemIndex).toBe(1);
        expect(fakeKeyEvents.unsupported.defaultPrevented).toBe(false);
      });

      it('should activate the first item when pressing down on a clean key manager', () => {
        keyManager = new ListKeyManager<FakeFocusable>(itemList);

        expect(keyManager.activeItemIndex).toBe(-1, 'Expected active index to default to -1.');

        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex).toBe(0, 'Expected first item to become active.');
      });

      it('should emit an event whenever the active item changes', () => {
        const spy = jasmine.createSpy('change spy');
        const subscription = keyManager.change.subscribe(spy);

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(spy).toHaveBeenCalledTimes(1);

        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(spy).toHaveBeenCalledTimes(2);

        subscription.unsubscribe();
      });

      it('should not emit an event if the item did not change', () => {
        const spy = jasmine.createSpy('change spy');
        const subscription = keyManager.change.subscribe(spy);

        keyManager.setActiveItem(2);
        keyManager.setActiveItem(2);

        expect(spy).toHaveBeenCalledTimes(1);

        subscription.unsubscribe();
      });

    });

    describe('programmatic focus', () => {

      it('should setActiveItem()', () => {
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected first item of the list to be active.`);

        keyManager.setActiveItem(1);
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected activeItemIndex to be updated when setActiveItem() was called.`);
      });

      it('should expose the active item correctly', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex).toBe(1, 'Expected active item to be the second option.');
        expect(keyManager.activeItem)
            .toBe(itemList.items[1], 'Expected the active item to match the second option.');

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex).toBe(2, 'Expected active item to be the third option.');
        expect(keyManager.activeItem)
            .toBe(itemList.items[2], 'Expected the active item ID to match the third option.');
      });

      it('should setFirstItemActive()', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected last item of the list to be active.`);

        keyManager.setFirstItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected setFirstItemActive() to set the active item to the first item.`);
      });

      it('should set the active item to the second item if the first one is disabled', () => {
        itemList.items[0].disabled = true;

        keyManager.setFirstItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected the second item to be active if the first was disabled.`);
      });

      it('should setLastItemActive()', () => {
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected first item of the list to be active.`);

        keyManager.setLastItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected setLastItemActive() to set the active item to the last item.`);
      });

      it('should set the active item to the second to last item if the last is disabled', () => {
        itemList.items[2].disabled = true;

        keyManager.setLastItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected the second to last item to be active if the last was disabled.`);
      });

      it('should setNextItemActive()', () => {
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected first item of the list to be active.`);

        keyManager.setNextItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected setNextItemActive() to set the active item to the next item.`);
      });

      it('should set the active item to the next enabled item if next is disabled', () => {
        itemList.items[1].disabled = true;
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected first item of the list to be active.`);

        keyManager.setNextItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected setNextItemActive() to only set enabled items as active.`);
      });

      it('should setPreviousItemActive()', () => {
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(1, `Expected second item of the list to be active.`);

        keyManager.setPreviousItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected setPreviousItemActive() to set the active item to the previous.`);
      });

      it('should skip disabled items when setPreviousItemActive() is called', () => {
        itemList.items[1].disabled = true;
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(2, `Expected third item of the list to be active.`);

        keyManager.setPreviousItemActive();
        expect(keyManager.activeItemIndex)
            .toBe(0, `Expected setPreviousItemActive() to skip the disabled item.`);
      });

    });

    describe('wrap mode', () => {

      it('should return itself to allow chaining', () => {
        expect(keyManager.withWrap())
            .toEqual(keyManager, `Expected withWrap() to return an instance of ListKeyManager.`);
      });

      it('should wrap focus when arrow keying past items while in wrap mode', () => {
        keyManager.withWrap();
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        expect(keyManager.activeItemIndex).toBe(2, 'Expected last item to be active.');

        // this down arrow moves down past the end of the list
        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex).toBe(0, 'Expected active item to wrap to beginning.');

        // this up arrow moves up past the beginning of the list
        keyManager.onKeydown(fakeKeyEvents.upArrow);
        expect(keyManager.activeItemIndex).toBe(2, 'Expected active item to wrap to end.');
      });

      it('should set last item active when up arrow is pressed if no active item', () => {
        keyManager.withWrap();
        keyManager.setActiveItem(-1);
        keyManager.onKeydown(fakeKeyEvents.upArrow);

        expect(keyManager.activeItemIndex)
            .toBe(2, 'Expected last item to be active on up arrow if no active item.');
        expect(keyManager.setActiveItem).not.toHaveBeenCalledWith(0);
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(2);

        keyManager.onKeydown(fakeKeyEvents.downArrow);
        expect(keyManager.activeItemIndex)
            .toBe(0, 'Expected active item to be 0 after wrapping back to beginning.');
        expect(keyManager.setActiveItem).toHaveBeenCalledWith(0);
      });

    });

    describe('typeahead mode', () => {
      const debounceInterval = 300;

      beforeEach(() => {
        keyManager.withTypeAhead(debounceInterval);
        keyManager.setActiveItem(-1);
      });

      it('should throw if the items do not implement the getLabel method', () => {
        const invalidQueryList = new FakeQueryList();

        invalidQueryList.items = [{ disabled: false }];

        const invalidManager = new ListKeyManager(invalidQueryList);

        expect(() => invalidManager.withTypeAhead()).toThrowError(/must implement/);
      });

      it('should debounce the input key presses', fakeAsync(() => {
        keyManager.onKeydown(createKeyboardEvent('keydown', 79, undefined, 'o')); // types "o"
        keyManager.onKeydown(createKeyboardEvent('keydown', 78, undefined, 'n')); // types "n"
        keyManager.onKeydown(createKeyboardEvent('keydown', 69, undefined, 'e')); // types "e"

        expect(keyManager.activeItem).not.toBe(itemList.items[0]);

        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should focus the first item that starts with a letter', fakeAsync(() => {
        keyManager.onKeydown(createKeyboardEvent('keydown', 84, undefined, 't')); // types "t"

        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[1]);
      }));

      it('should focus the first item that starts with sequence of letters', fakeAsync(() => {
        keyManager.onKeydown(createKeyboardEvent('keydown', 84, undefined, 't')); // types "t"
        keyManager.onKeydown(createKeyboardEvent('keydown', 72, undefined, 'h')); // types "h"

        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[2]);
      }));

      it('should cancel any pending timers if a navigation key is pressed', fakeAsync(() => {
        keyManager.onKeydown(createKeyboardEvent('keydown', 84, undefined, 't')); // types "t"
        keyManager.onKeydown(createKeyboardEvent('keydown', 72, undefined, 'h')); // types "h"
        keyManager.onKeydown(fakeKeyEvents.downArrow);

        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should handle non-English input', fakeAsync(() => {
        itemList.items = [
          new FakeFocusable('едно'),
          new FakeFocusable('две'),
          new FakeFocusable('три')
        ];

        const keyboardEvent = createKeyboardEvent('keydown', 68, undefined, 'д');

        keyManager.onKeydown(keyboardEvent); // types "д"
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[1]);
      }));

      it('should handle non-letter characters', fakeAsync(() => {
        itemList.items = [
          new FakeFocusable('[]'),
          new FakeFocusable('321'),
          new FakeFocusable('`!?')
        ];

        keyManager.onKeydown(createKeyboardEvent('keydown', 192, undefined, '`')); // types "`"
        tick(debounceInterval);
        expect(keyManager.activeItem).toBe(itemList.items[2]);

        keyManager.onKeydown(createKeyboardEvent('keydown', 51, undefined, '3')); // types "3"
        tick(debounceInterval);
        expect(keyManager.activeItem).toBe(itemList.items[1]);

        keyManager.onKeydown(createKeyboardEvent('keydown', 219, undefined, '[')); // types "["
        tick(debounceInterval);
        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should not focus disabled items', fakeAsync(() => {
        expect(keyManager.activeItem).toBeFalsy();

        itemList.items[0].disabled = true;
        keyManager.onKeydown(createKeyboardEvent('keydown', 79, undefined, 'o')); // types "o"
        tick(debounceInterval);

        expect(keyManager.activeItem).toBeFalsy();
      }));

      it('should start looking for matches after the active item', fakeAsync(() => {
        itemList.items = [
          new FakeFocusable('Bilbo'),
          new FakeFocusable('Frodo'),
          new FakeFocusable('Pippin'),
          new FakeFocusable('Boromir'),
          new FakeFocusable('Aragorn')
        ];

        keyManager.setActiveItem(1);
        keyManager.onKeydown(createKeyboardEvent('keydown', 66, undefined, 'b'));
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[3]);
      }));

      it('should wrap back around if there were no matches after the active item', fakeAsync(() => {
        itemList.items = [
          new FakeFocusable('Bilbo'),
          new FakeFocusable('Frodo'),
          new FakeFocusable('Pippin'),
          new FakeFocusable('Boromir'),
          new FakeFocusable('Aragorn')
        ];

        keyManager.setActiveItem(3);
        keyManager.onKeydown(createKeyboardEvent('keydown', 66, undefined, 'b'));
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should wrap back around if the last item is active', fakeAsync(() => {
        keyManager.setActiveItem(2);
        keyManager.onKeydown(createKeyboardEvent('keydown', 79, undefined, 'o'));
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should be able to select the first item', fakeAsync(() => {
        keyManager.setActiveItem(-1);
        keyManager.onKeydown(createKeyboardEvent('keydown', 79, undefined, 'o'));
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[0]);
      }));

      it('should not do anything if there is no match', fakeAsync(() => {
        keyManager.setActiveItem(1);
        keyManager.onKeydown(createKeyboardEvent('keydown', 87, undefined, 'w'));
        tick(debounceInterval);

        expect(keyManager.activeItem).toBe(itemList.items[1]);
      }));

    });

  });

  describe('FocusKeyManager', () => {
    let keyManager: FocusKeyManager<FakeFocusable>;

    beforeEach(() => {
      itemList.items = [new FakeFocusable(), new FakeFocusable(), new FakeFocusable()];
      keyManager = new FocusKeyManager<FakeFocusable>(itemList);

      // first item is already focused
      keyManager.setFirstItemActive();

      spyOn(itemList.items[0], 'focus');
      spyOn(itemList.items[1], 'focus');
      spyOn(itemList.items[2], 'focus');
    });

    it('should focus subsequent items when down arrow is pressed', () => {
      keyManager.onKeydown(fakeKeyEvents.downArrow);

      expect(itemList.items[0].focus).not.toHaveBeenCalled();
      expect(itemList.items[1].focus).toHaveBeenCalledTimes(1);
      expect(itemList.items[2].focus).not.toHaveBeenCalled();

      keyManager.onKeydown(fakeKeyEvents.downArrow);
      expect(itemList.items[0].focus).not.toHaveBeenCalled();
      expect(itemList.items[1].focus).toHaveBeenCalledTimes(1);
      expect(itemList.items[2].focus).toHaveBeenCalledTimes(1);
    });

    it('should focus previous items when up arrow is pressed', () => {
      keyManager.onKeydown(fakeKeyEvents.downArrow);

      expect(itemList.items[0].focus).not.toHaveBeenCalled();
      expect(itemList.items[1].focus).toHaveBeenCalledTimes(1);

      keyManager.onKeydown(fakeKeyEvents.upArrow);

      expect(itemList.items[0].focus).toHaveBeenCalledTimes(1);
      expect(itemList.items[1].focus).toHaveBeenCalledTimes(1);
    });

    it('should allow setting the focused item without calling focus', () => {
      expect(keyManager.activeItemIndex)
          .toBe(0, `Expected first item of the list to be active.`);

      keyManager.updateActiveItemIndex(1);
      expect(keyManager.activeItemIndex)
          .toBe(1, `Expected activeItemIndex to update after calling updateActiveItemIndex().`);
      expect(itemList.items[1].focus).not.toHaveBeenCalledTimes(1);
    });

  });

  describe('ActiveDescendantKeyManager', () => {
    let keyManager: ActiveDescendantKeyManager<FakeHighlightable>;

    beforeEach(() => {
      itemList.items = [new FakeHighlightable(), new FakeHighlightable(), new FakeHighlightable()];
      keyManager = new ActiveDescendantKeyManager<FakeHighlightable>(itemList);

      // first item is already focused
      keyManager.setFirstItemActive();

      spyOn(itemList.items[0], 'setActiveStyles');
      spyOn(itemList.items[1], 'setActiveStyles');
      spyOn(itemList.items[2], 'setActiveStyles');

      spyOn(itemList.items[0], 'setInactiveStyles');
      spyOn(itemList.items[1], 'setInactiveStyles');
      spyOn(itemList.items[2], 'setInactiveStyles');
    });

    it('should set subsequent items as active with the DOWN arrow', () => {
      keyManager.onKeydown(fakeKeyEvents.downArrow);

      expect(itemList.items[1].setActiveStyles).toHaveBeenCalled();
      expect(itemList.items[2].setActiveStyles).not.toHaveBeenCalled();

      keyManager.onKeydown(fakeKeyEvents.downArrow);

      expect(itemList.items[2].setActiveStyles).toHaveBeenCalled();
    });

    it('should set previous items as active with the UP arrow', () => {
      keyManager.setLastItemActive();
      keyManager.onKeydown(fakeKeyEvents.upArrow);

      expect(itemList.items[1].setActiveStyles).toHaveBeenCalled();
      expect(itemList.items[0].setActiveStyles).not.toHaveBeenCalled();

      keyManager.onKeydown(fakeKeyEvents.upArrow);

      expect(itemList.items[0].setActiveStyles).toHaveBeenCalled();
    });

    it('should set inactive styles on previously active items', () => {
      keyManager.onKeydown(fakeKeyEvents.downArrow);
      expect(itemList.items[0].setInactiveStyles).toHaveBeenCalled();

      keyManager.onKeydown(fakeKeyEvents.upArrow);
      expect(itemList.items[1].setInactiveStyles).toHaveBeenCalled();
    });

  });

});


text:
<?php

namespace Spika\Controller;

use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;

class AsyncTaskController extends SpikaBaseController
{
    public function connect(Application $app)
    {

        $controllers = $app['controllers_factory'];

        $self = $this;

        $controllers->post('/notifyNewDirectMessage', function (Request $request) use ($self,$app) {

            set_time_limit(60 * 10);

            $host = $request->getHttpHost();

            $requestBody = $request->getContent();
            $requestData = json_decode($requestBody,true);

            if(empty($requestData['messageId']))
                return $self->returnErrorResponse("insufficient params");

            $messageId = $requestData['messageId'];
            $message = $app['spikadb']->findMessageById($messageId);

            // send push notification
            $fromUserId = $message['from_user_id'];
            $toUserId = $message['to_user_id'];

            $fromUser = $app['spikadb']->getUserById($fromUserId);
            $toUser = $app['spikadb']->getUserById($toUserId);

            $app['spikadb']->updateActivitySummaryByDirectMessage($message['to_user_id'],$message['from_user_id']);

            $pushnotificationMessage = $self->generatePushNotificationMessage($fromUser,$toUser);

            // send iOS push notification
            if(!empty($toUser['ios_push_token'])){
                $body = array();
                $body['aps'] = array('alert' => $pushnotificationMessage, 'badge' => 0, 'sound' => 'default', 'value' => "");
                $body['data'] =array('from' => $fromUserId);
                $payload = json_encode($body);

                $app['sendProdAPN'](array($toUser['ios_push_token']),$payload);
                $app['sendDevAPN'](array($toUser['ios_push_token']),$payload);
            }

            // send Android push notification
            if(!empty($toUser['android_push_token'])){

                $registrationIDs = array($toUser['android_push_token']);

                $fields = array(
                                'registration_ids' => $registrationIDs,
                                'data' => array(
                                        "message" => $pushnotificationMessage,
                                        "fromUser" => $fromUserId,
                                        "fromUserName"=>$fromUser['name'],
                                        "type" => "user",
                                        "groupId" => "",
					"message_id" => $messageId
                                        ),
                               );

                $payload = json_encode($fields);
                $app['sendGCM']($payload,$app);
            }

            return "";

        });

        $controllers->post('/notifyNewGroupMessage', function (Request $request) use ($self,$app) {

            set_time_limit(60 * 10);

            $host = $request->getHttpHost();

            $requestBody = $request->getContent();
            $requestData = json_decode($requestBody,true);

            if(empty($requestData['messageId']))
                return $self->returnErrorResponse("insufficient params");

            $messageId = $requestData['messageId'];
            $message = $app['spikadb']->findMessageById($messageId);

            $app['spikadb']->updateActivitySummaryByGroupMessage($message['to_group_id'],$message['from_user_id']);

            // send pushnotification too all subscribed members

            $users = $app['spikadb']->getAllUsersByGroupId($message['to_group_id']);
            $iosTokens = array();
            $androidTokens = array();

            foreach($users as $user){

                if(!empty($user['ios_push_token']))
                    $iosTokens[] = $user['ios_push_token'];

                if(!empty($user['android_push_token']))
                    $androidTokens[] = $user['android_push_token'];

            }

            $fromUserData = $app['spikadb']->findUserById($message['from_user_id']);
            $toGroupData = $app['spikadb']->findGroupById($message['to_group_id']);
            $pushMessage = sprintf(GROUPMESSAGE_NOTIFICATION_MESSAGE . "  test ",$fromUserData['name'],$toGroupData['name']);

            $fields = array(
                            'registration_ids' => $androidTokens,
                            'data' => array(
                                    "message" => $pushMessage,
                                    "fromUser" => $message['from_user_id'],
                                    "fromUserName"=>$fromUserData['name'],
                                    "type" => "group",
                                    "groupId" => $message['to_group_id'],
				    "message_id" => $messageId
                                    ),
                           );

            $payload = json_encode($fields);
            $app['sendGCM']($payload,$app);

            $body = array();
            $body['aps'] = array('alert' => $pushMessage, 'badge' => 0, 'sound' => 'default', 'value' => "");
            $body['data'] =array('type' => 'group','to_group' => $message['to_group_id']);
            $payload = json_encode($body);

            $app['sendProdAPN']($iosTokens,$payload);
            $app['sendDevAPN']($iosTokens,$payload);

            return "";

        });

        return $controllers;

    }

    function generatePushNotificationMessage($fromUser,$toUser){

        $message = sprintf(DIRECTMESSAGE_NOTIFICATION_MESSAGE, $fromUser['name']);

        return $message;

    }

}

?>